背景
OpenTake 预览是双解码路径:暂停/scrub 走 Rust 系统 ffmpeg 解码合成帧(<img>);播放 走 WebKit 原生 <video>(Tauri asset 协议 convertFileSrc)。两条路径能力不对称,是用户『暂停能看、一播放黑屏』观感的根源。
编解码现状(已核实)
- 暂停帧(ffmpeg):本机
ffmpeg -decoders 含 hevc/prores/vp9/av1/h264,decode/frame.rs 用 -pix_fmt rgba 对解码器无关 → 只要主机 ffmpeg 装了对应解码器,H.265/ProRes/VP9/AV1 暂停帧都能解。导出 encode/preset.rs 已支持 H264/H265/ProRes422。
- 播放(WebKit
<video>):macOS 原生支持 H.264/HEVC(H.265)/ProRes;VP9 支持有限、AV1 无硬解时通常不支持 → 这些格式播放时黑帧/卡死,且无回退、无提示(TimelinePlaybackLayer.tsx:243-253 的 <video> 无 onError/canPlayType)。
缺口
- ffmpeg 未随包(
src-tauri/src/lib.rs:185 仅查 PATH/绝对路径)→ 用户机器没装 ffmpeg → 暂停合成帧整条路径黑屏(跨机致命)。
<video> 无错误回退:WebKit 解不了的编码(VP9/AV1)播放黑帧无提示;应加 onError → 回退到 ffmpeg 合成帧 <img> 或弹『该编码需暂停查看』。
- clip 边界 remount:每 clip 单独
<video key=clip.id>,跨边界 React remount → 重 load+seek → 黑帧卡顿;需双缓冲或按 mediaRef 稳定 key(覆盖 split 场景)。
- 无缝切换:scrub/暂停帧每次单帧 spawn ffmpeg 冷启动;
frame.rs 默认 tolerance=1.0s 偏大。常驻解码会话 + 自适应 tolerance 可降落帧。
建议(性价比排序)
① ffmpeg 随包(bundle.externalBin)+ 缺失 toast;② <video> 加 onError 回退;③ clip 边界双缓冲/稳定 key;④ 常驻 ffmpeg 解码会话。架构正解仍是 #53 单 composition 流式解码单面。
验收
背景
OpenTake 预览是双解码路径:暂停/scrub 走 Rust 系统 ffmpeg 解码合成帧(
<img>);播放 走 WebKit 原生<video>(Tauri asset 协议convertFileSrc)。两条路径能力不对称,是用户『暂停能看、一播放黑屏』观感的根源。编解码现状(已核实)
ffmpeg -decoders含 hevc/prores/vp9/av1/h264,decode/frame.rs用-pix_fmt rgba对解码器无关 → 只要主机 ffmpeg 装了对应解码器,H.265/ProRes/VP9/AV1 暂停帧都能解。导出encode/preset.rs已支持 H264/H265/ProRes422。<video>):macOS 原生支持 H.264/HEVC(H.265)/ProRes;VP9 支持有限、AV1 无硬解时通常不支持 → 这些格式播放时黑帧/卡死,且无回退、无提示(TimelinePlaybackLayer.tsx:243-253的<video>无onError/canPlayType)。缺口
src-tauri/src/lib.rs:185仅查 PATH/绝对路径)→ 用户机器没装 ffmpeg → 暂停合成帧整条路径黑屏(跨机致命)。<video>无错误回退:WebKit 解不了的编码(VP9/AV1)播放黑帧无提示;应加onError→ 回退到 ffmpeg 合成帧<img>或弹『该编码需暂停查看』。<video key=clip.id>,跨边界 React remount → 重 load+seek → 黑帧卡顿;需双缓冲或按mediaRef稳定 key(覆盖 split 场景)。frame.rs默认 tolerance=1.0s 偏大。常驻解码会话 + 自适应 tolerance 可降落帧。建议(性价比排序)
① ffmpeg 随包(
bundle.externalBin)+ 缺失 toast;②<video>加onError回退;③ clip 边界双缓冲/稳定 key;④ 常驻 ffmpeg 解码会话。架构正解仍是 #53 单 composition 流式解码单面。验收