86 lines
3.4 KiB
Markdown
86 lines
3.4 KiB
Markdown
# 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。
|