Files
video-process/README.md
2026-05-19 16:27:31 +08:00

86 lines
3.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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`:原始视频响应缓存。
## 生成图谱
`graphify-out/` 是生成物,不建议提交到仓库。你在其他项目里想复用这套分析方式时,可以在目标项目根目录重新生成:
```bash
graphify .
```
增量更新:
```bash
graphify . --update
```
如果你在 Codex 里操作,直接对目标项目说这句就够了:
```text
请对当前项目目录运行 graphify生成 graphify-out并重点输出 God Nodes、Surprising Connections 和 Suggested Questions。
```
生成后会得到这些文件:
- `graphify-out/graph.json`
- `graphify-out/graph.html`
- `graphify-out/GRAPH_REPORT.md`
- `graphify-out/manifest.json`
## 备注
前端依赖浏览器的 WebCodecs、Cache Storage 和 IndexedDB 能力,建议使用 Chromium / Edge。