feat: add frame caching demo documentation

This commit is contained in:
zhangheng
2026-05-19 16:19:55 +08:00
commit 3ffeb1ae62
18 changed files with 4002 additions and 0 deletions

58
README.md Normal file
View File

@@ -0,0 +1,58 @@
# Video Process Demo
Rust 后端原样提供 `video.h264`Next.js 前端用 WebCodecs 在浏览器里完成流式切帧、本地帧缓存、单画布播放和帧拖动定位。刷新后优先恢复本地帧,不需要重新拉完整视频再解码。
## 启动后端
```bash
cargo run
```
后端默认监听 `http://localhost:8080`,视频地址是 `http://localhost:8080/video.h264`
仓库里不包含这个大体积示例视频,请把 `video.h264` 放到项目根目录,或通过 `NEXT_PUBLIC_VIDEO_URL` 指向你自己的 H.264 地址。
## 启动前端
```bash
cd web
npm install
NEXT_PUBLIC_VIDEO_URL=http://localhost:8080/video.h264 npm run dev
```
打开 `http://localhost:3000` 即可。
## 前端架构
前端分成四层:
- 传输缓存:`web/lib/video-cache.ts``Cache Storage` 保存原始 `video.h264` 响应。
- 解析切帧:`web/lib/h264.ts` 把 Annex B 字节流拆成 access unit识别 SPS/PPS 和帧边界。
- 帧持久化:`web/lib/frame-store.ts``IndexedDB` 保存 `CachedFrameSession`,每帧以 `Blob` 形式落盘,刷新后可直接恢复。
- 播放控制:`web/components/VideoFrameViewer.tsx` 负责切帧、恢复、单画布播放、拖动条跳帧和缓存清理。
## 运行流程
1. 页面先查本地帧会话,命中则直接把 `Blob` 恢复成 `objectURL`,无需重新请求后端。
2. 未命中时再去请求 `video.h264`,并边下载边解析 SPS/PPS 和 access unit。
3. 每个 `VideoFrame` 会先画到离屏 canvas再导出成 WebP `Blob`,同时生成缩略图对象 URL。
4. 全部帧完成后,会把会话写入 `IndexedDB`,然后尽量清掉原始 `video.h264` 的缓存,减少重复占用。
5. 播放区只用一个 canvas通过 `requestAnimationFrame` 按时间戳切帧;拖动条则直接 `jumpToFrame()` 到指定帧。
## 缓存策略
- 原始视频缓存放在 `Cache Storage`,适合保存完整的 fetch 响应。
- 切好的帧和元数据放在 `IndexedDB`,避免把大体积帧塞进一个 JSON。
- 页面提供“申请持久化”按钮,会调用 `navigator.storage.persist()`,降低浏览器回收缓存的概率。
- “清空缓存”会同时删除帧会话和原始视频缓存;下次打开会重新请求后端并重新切帧。
- 当前实现还保留了旧版 `Cache Storage` 帧清单的迁移逻辑,便于升级已有缓存。
## 关键文件
- `web/components/VideoFrameViewer.tsx`:主界面、播放、拖动条、缓存状态。
- `web/lib/h264.ts`H.264 Annex B 解析、SPS/PPS、WebCodecs 配置。
- `web/lib/frame-store.ts`:帧会话读写、校验、迁移。
- `web/lib/video-cache.ts`:原始视频响应缓存。
## 备注
前端依赖浏览器的 WebCodecs、Cache Storage 和 IndexedDB 能力,建议使用 Chromium / Edge。