TooBox 也盒 · 视频剪辑功能集成方案

把视频剪辑能力集成进现有 Tauri 桌面工具箱 TooBox 也盒 的落地方案。 通用技术调研见 桌面视频剪辑调研;本文只写「在这个具体项目里怎么做」。 编写时间:2026-07-28。基线版本:1.0.3。

本文是方案文档,不是实现记录。除 §1 现状事实外,其余均为待实施设计,尚未落地到源码。

修订说明(以最新为准):

  1. 首版为「单视频轨 + 单音轨」,现已改为叠加型多轨(画中画 / B-roll)。
  2. 目标场景锁定短视频平台 + 微信分享:导出预设固定三档,预览改为代理预渲染为主,确定不采购商业 SDK。
  3. 现金支出 0 元,MVP 工时约 22~28 天(见 §10.1)。

怎么用这份笔记

  1. 判断可行性 → 看 §1.3 可复用范式(结论都在这里)
  2. 对齐范围 → 看 §2,尤其 §2.3 待确认问题
  3. 动手前 → 看 §5 数据模型、§6 接口清单
  4. 排期 → 看 §10
  5. 踩坑预防 → 看 §12

1 · 现状事实

以下均来自当前源码,可直接核对。

1.1 技术栈基线

项 事实 来源
桌面框架 Tauri 2.11.2,protocol-asset 已启用 src-tauri/Cargo.toml、src-tauri/tauri.conf.json
前端 React 19、TypeScript ~6.0、Vite 8、Tailwind 4 package.json
本地数据库 rusqlite 0.32(bundled) src-tauri/Cargo.toml
打包 NSIS,createUpdaterArtifacts: true src-tauri/tauri.conf.json
随包资源 tools/PoseDetector.exe、裁剪参考图 bundle.resources
代码规模 lib.rs 4816 行(60+ command)、App.tsx 62 万字节 —

1.2 视频剪辑页面现状

  • 页面已存在:src-ui/features/ai-video-editor/AIVideoEditorPage.tsx(474 行)+ 同目录 CSS。
  • 已在 src-ui/App.tsx 注册并渲染(import 约 86 行,使用点约 1558 行)。
  • 页面当前不含任何 invoke、convertFileSrc 或 Tauri API 调用,属于纯静态 UI 原型:
数据 现状
素材列表 常量 mediaItems
文稿 常量 transcriptLines
AI 建议 常量 aiSuggestions
时间线片段 常量 timelineClips(宽度写死百分比)
预览区 一张静态图片
  • 已实现的真实能力:双模式切换(timeline / transcript)、三区可拖拽布局并持久化(localStorage 键 toobox-ai-video-editor-layouts-v1)。

1.3 可直接复用的既有范式

这是本方案成立的核心前提。

能力 既有实现 源码位置
隐藏控制台的子进程调用 SystemProcessRunner(Windows CREATE_NO_WINDOW) src-tauri/src/process_runner.rs
长任务流式进度 WD14 打标:spawn + stdout 按行读 NDJSON + app.emit lib.rs:1433-1600
任务取消 AtomicBool 取消标志 + Mutex<Option<pid>> + child.kill() lib.rs:1455-1530
stderr 收集 独立线程 read_to_end 后统一回传 lib.rs:1470-1474
外部工具路径探测 resource_dir/tools → exe_dir/tools → cwd/tools lib.rs:3361-3383
运行时按需下载 WD14 模型 / Python 运行时下载 + 进度事件 lib.rs:1132-1250
本地媒体进 WebView asset_protocol_scope().allow_directory() + asset 协议 lib.rs:3409-3430
CSP 已放行媒体 media-src 'self' data: blob: http: https: asset: http://asset.localhost src-tauri/tauri.conf.json
TIP

📌 这张表就是整份方案的地基。做视频剪辑需要四样底层能力:调外部程序、流式进度、按需下载运行时、在 WebView 里播本地文件——四样这个项目全都有现成范式。所以真正要新写的只有三块:FFmpeg 适配层、时间线数据模型、把原型 UI 接上真实数据。这也是为什么不该引入 MLT 或链接 FFmpeg 库:那等于把已经铺好的路推掉重修。


2 · 需求范围

2.1 当前已确认需求

  • 导入本地视频素材,读取真实时长、分辨率、帧率等元数据
  • 非破坏剪辑:裁切、分割、删除、排序
  • 叠加型多轨:主视频轨 ×1 + 叠加视频轨 ×1(画中画 / B-roll,支持位置、缩放、裁切、不透明度、z 序)+ 字幕轨 ×1 + 音频轨 ×2(原声 + BGM,含音量与淡入淡出)
  • 基础转场:仅交叉溶解一种
  • 时间线预览播放与拖动定位;叠加区间走代理预渲染,与成片一致(见 §3.3)
  • 导出 MP4,含进度显示与取消
  • 导出预设固定三档(不做自定义参数面板):平台竖屏 1080×1920、平台横屏 1920×1080、微信分享 720×1280;统一 30fps、H.264 + AAC
  • 引擎路径可自定义:设置里允许用户指定本机 ffmpeg 路径
  • 导出完成后对微信场景给出提示:请以「文件」形式发送,避免被二次压缩
  • 项目保存与再次打开
  • 文稿剪辑:基于转录文本删语气词、压缩长停顿,并反写时间线
  • 字幕烧制与画面比例裁切
  • 视频引擎按需下载,不增大安装包体积

2.2 非目标范围

  • 不做通用专业非线编:无限轨、嵌套序列、节点式调色、关键帧动画均不做
  • 叠加轨只做静态参数(位置/缩放/不透明度固定),不做“画中画飞入”类动画
  • 不做绿幕抠像、混合模式、交叉溶解以外的转场
  • 不做实时特效预览与 GPU 合成管线
  • 不做 4K / 8K / HDR 导出,不做码率与编码参数自定义面板
  • 不随包分发任何 GPL 构建(含 libx264 的版本由用户自行安装)
  • 不采用 .NET 系商业 SDK(跨平台不友好,见 §3.5)
  • 不自研解码器,不把 FFmpeg 链接进主程序进程内
  • 不引入 MLT / melt 等第二套媒体引擎
  • 不承诺专业交换格式(ProRes、DNxHR)与冷门摄像机格式
  • 语音转录的服务端实现不属客户端职责,客户端只调用
  • macOS / Linux 不在首期范围

2.3 待确认问题

  1. 语音转录由服务端接口提供,还是本地运行时(如 whisper.cpp)?影响 P4 工期与体积
  2. 引擎下载包托管位置与校验方式(是否复用 WD14 的 R2 与 scripts/upload-r2-object.py 流程)
  3. 导出是否计积分;若计,扣减时机是提交任务还是导出成功
  4. 工程是否跨设备同步;若同步,素材路径缺失如何处理
  5. 是否需要「快速模式(关键帧对齐、无损切)/ 精确模式(重编码)」两档
  6. 是否采购商业 SDK(见 §3.5);叠加型多轨使自研工期增加约 4 周,采购的性价比随之上升
  7. 转录与“压停顿”是否直接复用开源件(whisper.cpp、auto-editor,均为 MIT)以消掉问题 1
TIP

📌 前两个问题必须在 P4 之前定案。转录方案决定是「加一个 HTTP 调用」还是「再走一遍 WD14 那样的运行时下载 + 模型管理」,两者工期差好几倍——不要等做到 P4 才发现要重做架构。


3 · 技术选型

3.1 视频处理引擎

候选 结论 理由
Rust 侧以外部进程调用 FFmpeg 采用 与 PoseDetector.exe、WD14 完全同构;零新增编译依赖;许可边界清晰
Rust 绑定 ffmpeg-next(链库) 不采用 Windows 构建链复杂;与闭源主程序静态链接存在许可风险
引入 MLT / melt 不采用 Windows 分发困难、体积大、GPL;本项目不需要多轨实时合成

3.2 FFmpeg 构建与分发

决策 说明
构建类型 LGPL 构建,不含 libx264 / libx265 / libfdk-aac,不启用 --enable-gpl / --enable-nonfree
导出编码 Windows 走系统编码器 h264_mf,音频走系统 AAC 通道
分发方式 按需下载,不写入 bundle.resources
安装位置 优先 resource_dir/tools/ffmpeg/,其次 exe_dir/tools/ffmpeg/,下载安装落用户数据目录
许可义务 引擎目录附 LICENSE / COPYING.LGPLv2.1 / NOTICE(版本号 + 源码地址),「关于」页加开源许可入口
路径可覆盖 设置里允许用户指定本机 ffmpeg;用户自己装了含 libx264 的 GPL 版就能用上最佳编码,分发行为不由本应用发生
WARNING

🚧 GPL 程序的「独立进程调用」是否构成衍生作品,业界有共识倾向但存在法律解释空间。稳健做法就是本表写的:默认只分发 LGPL 构建,GPL 版一律由用户自行安装。商业发布前请自行确认。

按需下载而非随包的三个理由:

理由 说明
更新包不受影响 项目已开 createUpdaterArtifacts,随包会让每次更新都多传几十 MB
不用剪辑的用户零成本 工具箱是多功能集合,剪辑只是其中一项
已有先例 WD14 的 Python 运行时就是下载来的,实现成本低
TIP

📌 「按需下载」在这个项目里几乎是免费的。别的项目要为此新写下载器、校验、解压、进度 UI,而这里 download_wd14_model_blocking 已经把这套跑通了,连 Radix Progress 组件都是现成的——照抄即可。

3.3 预览方案(叠加型多轨下已修订)

基础不变:通过 asset_protocol_scope().allow_directory(parent, false) 授权素材目录,再用 asset 协议交给 <video>,与 resolve_crop_default_reference_image 一致。

因为要叠加,单 <video> 方案不再成立。又因为目标场景是短视频(1~5 分钟),主次关系如下:

方案 定位 实现
A. 代理预渲染(主方案) 所有叠加/滤镜区间 后台渲 480p 低码率代理并缓存,直接播它;只重渲被改动的构图区间
B. 多路 <video> DOM 叠加(可选优化) 仅平移/缩放/不透明度的简单叠加 绝对定位 + CSS transform;主时钟纠偏,超阈值强制 seek
  • 单图层区间仍直接用 asset 协议播原素材,不需代理
  • 非 H.264 素材、4K 长素材先生成低码率代理文件再预览
  • 不引入 WebCodecs / canvas 逐帧合成
TIP

📌 “只做短视频”把代理预渲染从兜底方案抬成了主方案,这是本方案最大的一项简化。三分钟的片子渲一个 480p 代理通常只需几十秒,配上“只重渲改动区间 + 缓存”,实际等待往往只有几秒。

换来的好处是两个高风险项直接消失:不再需要解决多路 <video> 帧级同步(浏览器本来就不提供这个保证),且预览与成片走同一套渲染管线,天然所见即所得。长片项目不能这么做,你能。

3.4 导出画质与体积(方案的主要代价)

用系统编码器换来的是「合规 + 零体积 + 零成本」,代价是编码效率。

限制 表现
编码效率低 粗略经验:要追平 libx264 medium 的观感,h264_mf 大约需 1.3~2 倍码率
码率控制粗糙 无 CRF / 心理视觉优化 / 自适应量化,难以“按质量恒定”出片
高级参数缺失 B 帧、参考帧、AQ 等基本不可调,无 preset/tune
跨设备不一致 MF 按机器情况走软/硬编码,同工程在不同电脑上画质与速度可能不同

主要对策:段级智能重编码(必做)

构图区间只有单图层且切点对齐关键帧 → stream copy(零损失、零膨胀、极快)
切点落在 GOP 中间                     → 只重编码这一个 GOP,其余 copy
区间内有叠加 / 转场 / 字幕         → 必须重编码(无解)
场景 整片重编码 段级智能重编码
掐头去尾 画质掉一代,体积随编码器 几乎无损,体积≈原片
删语气词 / 压停顿 同上 99% 数据原样保留
盖 B-roll / 烧字幕 / 转场 必须重编码 仅那几段重编码,其余仍 copy
TIP

📌 多轨叠加后,段级 copy 不是失效了,而是“按区间生效”,因此更该做。口播视频只在几处盖了 B-roll,那么这几处重编码、其余 80% 仍可无损 copy——它直接决定了那 80% 的画质与导出速度。

微信分享场景:三招免费对策(优先做)

微信不经平台二压,画质直接可见;且发送有体积限制,目标是有限体积内画质最好。

招数 做法 成本
1. 降分辨率而非降码率 微信档导 720×1280,不导 1080p;同码率下每像素码率提升约 2.25 倍 0,最有效
2. 提示以「文件」发送 导出完成后提示用户;否则微信会再压一次,换任何编码器都无效 0
3. 引擎路径可自定义 愿意折腾的用户自己装含 libx264 的 GPL 版,即可获得最佳编码 约半天开发
TIP

📌 这三招比换编码器有用得多。用户被微信压过一次,你花多少钱买编码器都白搭;而在手机上看,720p 与 1080p 几乎无差别,体积却能砍一半。先优化交付链路,再优化编码器。

编码器升级路线

路线 画质 花钱 结论
系统 h264_mf 基准线 0 元 首期默认
用户自备含 libx264 的 GPL 构建 最佳 0 元(不由本应用分发) 唯一现实的高画质出路
硬件编码 NVENC / QSV / AMF 中上(低码率下反而不如 x264) 0 元 主要收益是速度 3~10 倍,优先级下调到 P3 之后
买 x264 商业授权 + AVC 专利 最佳 见 §3.5 价格表,约 $10,000 起 个人开发者不现实
VP9 / AV1 优 0 元、无专利池 交付兼容性差、编码慢
TIP

📌 要修正一个常见误解:硬件编码并不能救「小体积高画质」。NVENC / QSV / AMF 强在速度与中高码率,但它们省掉了大量率失真优化,在低码率档画质通常不如 libx264。而微信分享恰好就是低码率档——把硬件编码当成画质方案去做,会白忙一场。

3.5 商业 SDK 对比与采购决策

WARNING

🚧 以下价格与条款来自公开渠道,会变动,采购前必须以厂商最新报价与合约为准,不要拿本文当依据。

三类方案

类型 代表 计费 适用性
A. 桌面原生 SDK 美摄 PC、SolveigMM、MainConcept(VisioForge 已排除:.NET) 授权费 均需重写渲染层
B. 云端渲染 API 阿里云 IMS 云剪辑、美摄云剪辑、Shotstack、JSON2Video 按渲染分钟 仅适模板化批量出片
C. 开源库 FFmpeg、auto-editor、whisper.cpp 0 元 本方案主线

桌面 SDK 候选

项目 公开价格 备注
FFmpeg LGPL + 系统编码器 $0 本方案默认
用户自行安装 GPL 版 ffmpeg $0 配合「路径可覆盖」(§3.2)
x264 商业授权 不公开定价,只能询价。官方公告过的起步价:$1/台,最低 1 万台起 → 约 $10,000 起 个人开发者不现实
AVC 专利费(Via LA,原 MPEG-LA) 每年前 10 万台免费;10 万~500 万台 $0.20/台;超 500 万台 $0.10/台,有年度封顶 你处于免费档
美摄 PC SDK 不公开,只能询价(已判定偏贵) 4K/8K、HDR、广电级
SolveigMM / MainConcept 不公开,只能询价 均需重写渲染层
VisioForge €750 / €1000 / €1500 终身 已排除:.NET 技术栈,跨平台不友好

注意:阿里云 / 腾讯云 / 火山引擎 / 商汤 / 涂图 / 七牛的短视频 SDK 绝大多数只有 iOS / Android,对 Windows 桌面不适用,直接排除。

TIP

📌 算下来你的账单就是 0 元:AVC 专利在年出货 10 万台以内是免费档;x264 商业授权又有 1 万台最低消费(约 $10,000 起),对个人开发者相当于不存在。

所以付费编码器这条路应该直接划掉,把精力放到 §3.4 那三招上。若有一天真要升级,买 x264 授权是唯一不用改架构的选项(仍是 FFmpeg 外部进程,三平台一致),而美摄/SolveigMM/MainConcept 都要重写渲染层。

可直接复用的开源件

项目 许可 用途
auto-editor MIT 自动检测并删除静音段,直接对应 P4 的“压缩长停顿”
whisper.cpp MIT 本地语音转录,可解 §2.3 问题 1
LosslessCut 思路参考 FFmpeg 无损切割的最小闭环实现
MLT / Kdenlive、GES GPL,闭源商用谨慎 不推荐

采购结论

不采购。 理由:

  1. .NET 系方案(VisioForge)跨平台不友好,直接排除
  2. 其余桌面 SDK 均需重写渲染层,且不公开报价
  3. x264 商业授权约 $10,000 起,不符合个人开发者量级
  4. 画质需求可用 §3.4 的三招以 0 元 解决

仅当以下同时成立时重新评估:年出货接近 10 万台(已有规模与收入)、且本地交付成为主场景、且三招均不满意。


4 · 功能模块划分

4.1 前端模块

模块 文件 职责
编辑器页面 features/ai-video-editor/AIVideoEditorPage.tsx 现有 UI,改为消费真实状态,移除假数据常量
时间线状态 features/ai-video-editor/editor-store.ts 持有当前工程,唯一真相来源
时间线模型 features/ai-video-editor/timeline-model.ts EDL 类型 + 纯函数(分割、删除、ripple、吸附),不依赖 UI
文稿映射 features/ai-video-editor/transcript-edit.ts 转录文本与时间线片段双向映射
接口封装 features/ai-video-editor/video-api.ts invoke 封装与事件订阅,风格对齐 src-ui/lib/*-api.ts
多路预览同步 features/ai-video-editor/preview-sync.ts 主时钟选择、多路 <video> 纠偏、超阈值强制 seek
构图区间推导 features/ai-video-editor/composite-range.ts 按片段起止点切区间,判定该区间走 DOM 叠加还是代理预渲染

4.2 Rust 模块

模块 文件 职责
模块入口 src-tauri/src/video/mod.rs 导出 command,注册到 invoke_handler
引擎定位 video/ffmpeg_locator.rs 多候选路径探测与可执行校验,复刻 crop_pose_detector_candidates
引擎安装 video/runtime_install.rs 下载、校验、解压引擎,复刻 WD14 下载器进度事件
元数据 video/probe.rs ffprobe → 结构化元数据
预览素材 video/thumbnail.rs 缩略图、波形、代理文件
渲染 video/render.rs 渲染编排,解析 -progress,支持取消
滤镜图生成 video/composite_graph.rs 时间切片 → 活动图层 → overlay/scale/crop/amix 滤镜链;判定哪些区间可 stream copy
工程存储 video/project_store.rs 基于既有 rusqlite 读写工程 JSON
TIP

📌 lib.rs 已 4816 行、App.tsx 已 62 万字节——视频功能代码量不小,如果继续往这两个文件里堆,它们会成为压垮维护性的最后一根稻草。所以「必须分模块」不是洁癖,而是硬约束:从第一行代码就分,因为事后拆比一开始分难十倍。


5 · 数据模型

5.1 模型清单

模型 来源 / 存储 主要使用模块 说明
VideoProject SQLite 表 video_projects(JSON 文本列) editor-store.ts、project_store.rs 工程全量状态
VideoSource VideoProject 内嵌 probe.rs、素材面板 素材及探测结果
TimelineTrack VideoProject 内嵌 timeline-model.ts、composite_graph.rs 轨道定义与层级顺序
TimelineClip VideoProject 内嵌 timeline-model.ts、render.rs 时间线片段(EDL 条目)
TransitionItem VideoProject 内嵌 composite_graph.rs 转场(涉及两个片段的重叠区)
CaptionItem VideoProject 内嵌 文稿模式、字幕烧制 字幕条目
RenderProgress Tauri 事件负载,不持久化 导出面板 渲染进度快照

5.2 VideoProject

字段 类型 说明
version number 模型版本,首版 1,用于后续迁移
id string 工程 ID,客户端生成,作数据库主键,不参与文件路径
name string 工程名称,用户可编辑
sources VideoSource[] 素材列表
tracks TimelineTrack[] 轨道表,按 order 升序(下层到上层)
clips TimelineClip[] 时间线片段,按 trackId + startMs 维护
transitions TransitionItem[] 转场条目
captions CaptionItem[] 字幕条目
output object 导出参数:width、height、fps、bitrate
updatedAt number 时间戳毫秒

5.3 VideoSource

字段 类型 说明
id string 素材 ID,客户端生成,工程内唯一
path string 素材绝对路径;打开工程时校验存在性
durationMs number 时长,毫秒
width / height number 像素
fps number 帧率;变帧率素材记平均帧率
hasAudio boolean 是否含音轨,影响导出滤镜图
proxyPath string | null 代理文件绝对路径,未生成为 null
status string 枚举:ready / missing / unsupported

5.4 TimelineTrack

字段 类型 说明
id string 轨道 ID,客户端生成
kind string 枚举:video_main / video_overlay / caption / audio
order number 层级顺序,数值大者盖在上方
muted / hidden boolean 整轨静音 / 隐藏(仅影响预览与导出,不删数据)
opacity number 整轨不透明度,0~1

首期轨道数量固定:video_main ×1、video_overlay ×1、caption ×1、audio ×2。不支持用户新增轨道。

5.5 TimelineClip

字段 类型 说明
id string 片段 ID,客户端生成
sourceId string 关联 VideoSource.id
trackId string 关联 TimelineTrack.id
inMs / outMs number 源文件内入点与出点,毫秒;outMs > inMs
startMs number 该片段在时间线上的起始位置,毫秒
zIndex number 同一时刻的遮盖顺序;缺省继承所属轨道的 order
transform object | null 叠加轨必填:x、y(目标画布内像素)、scale、cropRect;静态值,无关键帧
opacity number 0~1
volume number 音量倍数,默认 1
fadeInMs / fadeOutMs number 音频淡入淡出时长,毫秒

5.6 TransitionItem

字段 类型 说明
id string 转场 ID
fromClipId / toClipId string 相邻两片段,必须同轨
kind string 首期仅 crossfade
durationMs number 重叠时长;不得超过任一片段时长,校验失败则拒绝建立
TIP

📌 转场必须独立建模,不能塞进 TimelineClip。因为它天生属于“两个片段之间”,一旦当成某一侧的属性,删片段、换顺序、ripple 时就会出现孤儿转场或重复转场。

TIP

📌 时间线总时长不存字段,由 clips 推导。这是刻意的:任何「可以从别处算出来的状态」一旦落成字段,就多了一个会不一致的地方。同理,源内 inMs/outMs 与时间线 startMs 必须分开——把两者混成一个「位置」是新手最常见的模型错误,一做 ripple 删除就全乱。

5.7 RenderProgress

字段 类型 说明
runId string 本次导出任务 ID,前端据此过滤事件
stage string 枚举:preparing / rendering / finalizing / done / failed / cancelled
percent number 0-100,由 out_time_ms 与时间线总时长推导
etaMs number | null 预估剩余毫秒,样本不足为 null
message string 失败时为错误摘要,其余为空字符串

6 · 接口设计

以下 Tauri command 与事件均为待实现,命名对齐既有 command 风格(动词前缀 + 模块名)。

6.1 接口清单

编号 命令 / 事件 类型 调用方 计划源码位置 说明
V01 resolve_video_runtime command 编辑器页面 video/ffmpeg_locator.rs 探测引擎可用性,返回路径与版本
V02 install_video_runtime command 引擎缺失提示 video/runtime_install.rs 下载并安装引擎
V03 video-runtime-install-progress event Rust → 前端 video/runtime_install.rs 下载与解压进度
V04 probe_video_source command 素材导入 video/probe.rs 读元数据并授权素材目录
V05 generate_video_thumbnails command 时间线渲染 video/thumbnail.rs 生成缩略图序列
V06 generate_video_proxy command 预览优化 video/thumbnail.rs 生成低码率代理
V07 render_video_project command 导出面板 video/render.rs 按 EDL 导出 MP4
V08 video-render-progress event Rust → 前端 video/render.rs 渲染进度
V09 cancel_video_render command 导出面板 video/render.rs 取消当前渲染
V10 save_video_project / load_video_project / list_video_projects command 编辑器页面 video/project_store.rs 工程持久化

6.2 render_video_project(关键接口)

  • 命令:render_video_project
  • 调用方:features/ai-video-editor/video-api.ts
  • 提供方:src-tauri/src/video/render.rs

用途:把当前时间线编译为一次 FFmpeg 调用并导出 MP4,用户在导出面板确认参数后触发。

请求字段

字段 类型 必填 说明
runId string 是 前端生成,用于事件过滤与取消
project VideoProject 是 完整工程快照,Rust 侧不回读数据库
outputPath string 是 导出目标绝对路径
mode string 是 precise(重编码)或 fast(关键帧对齐、尽量 stream copy)

响应字段

字段 类型 说明
outputPath string 实际写入路径
durationMs number 成品时长
elapsedMs number 耗时

处理规则

  • 渲染前校验所有 sources[].path 存在,缺失则直接失败并列出缺失素材,不产出半成品
  • 构图流程:按所有片段与转场的起止点把时间线切成区间 → 逐区间确定活动图层与 z 序 → 生成 scale/crop/overlay 与 amix 滤镜链 → 区间间 concat
  • 单图层且切点对齐关键帧的区间走 stream copy;含叠加/转场/字幕的区间重编码(见 §3.4)
  • 叠加轨坐标与缩放统一基于 output.width/height 画布计算,前端预览必须用同一套换算,否则预览与成片位置对不上
  • ffmpeg -progress pipe:1 -nostats 按行解析 out_time_ms,换算百分比后 app.emit('video-render-progress', …)
  • 取消复用 WD14 机制:AtomicBool + 活动 PID + child.kill();取消后删除未完成输出
  • 同一时刻只允许一个渲染任务;已有任务时返回明确错误,不排队
  • h264_mf 初始化失败时降规格重试一次;仍失败则回报「当前设备不支持系统编码器」

7 · 业务流程

7.1 首次进入剪辑页面

进入页面
  → invoke resolve_video_runtime
  → 可用:进入编辑器
  → 不可用:提示需要下载视频引擎(约 80 MB)
      → invoke install_video_runtime
      → 监听 video-runtime-install-progress(复用现有 Progress 组件)
      → 校验通过后进入编辑器

7.2 导入到导出

选择素材(rfd 文件对话框)
  → probe_video_source:元数据 + 授权素材目录
  → 加入 sources,时间线追加 clip
  → generate_video_thumbnails 异步补缩略图
  → 用户裁切 / 分割 / 排序(仅改内存 EDL)
  → 预览:构图区间判定 → 简单叠加走多路 <video>;滤镜区间走代理预渲染
  → 导出:render_video_project + 进度事件
  → 完成后用 tauri-plugin-opener 打开所在目录

7.3 文稿剪辑(P4)

选定素材
  → 取得转录结果(服务端接口或本地运行时,见 §2.3)
  → 生成 transcriptLines(替换现有常量)
  → 用户勾选「删除语气词 / 压缩停顿」建议
  → transcript-edit.ts 把文本删除区间映射为时间区间
  → 转成 EDL 的裁切与分割操作
  → 时间线与文稿双向同步
TIP

📌 文稿剪辑是这个产品真正的差异化点。原型 UI 里已经有 transcript 模式和「删语气词 / 压停顿 / 补空镜」建议,说明产品方向是对的——口播和短剧场景下,「改文字就等于改视频」比拖时间线快一个数量级,而且不需要多轨、不需要调色,正好落在能力范围内。


8 · 与既有功能的协同

既有能力 在剪辑中的用途
PoseDetector.exe(batch-crop 用) 横屏转竖屏时按主体位置智能重构图
WD14 打标 素材库自动标签,支撑页面已有的素材搜索框
ai-short-drama 脚本分镜转初始 EDL 草稿
ai-cover 从时间线抽帧生成封面
tauri-plugin-opener 导出完成后打开输出目录
rfd 素材选择与导出路径选择
TIP

📌 这一节才是「集成进工具箱」而不是「做个独立剪辑软件」的理由。单看剪辑功能,永远打不过剪映;但「AI 生成脚本 → 自动排 EDL → 人像检测智能裁竖屏 → 抽帧出封面」这条流水线,独立剪辑软件做不到,因为它没有前后两端的能力。别用剪辑功能去对标剪映,要用整条链路去对标。


9 · 安全与权限

9.1 权限边界

  • 引擎只允许从既定候选目录加载,并校验为可执行文件,规则同 validate_pose_detector_path
  • 引擎下载仅允许项目自有分发地址,下载后必须校验哈希再解压
  • 解压时拒绝路径穿越条目(..、绝对路径),避免写出安装目录之外

9.2 本地文件系统

  • 素材目录按需授权 allow_directory(parent, false),不整盘放开
  • 导出路径必须来自用户在文件对话框中的选择,不接受前端任意字符串直接写盘
  • 代理文件、缩略图、波形统一写入应用数据目录下独立缓存目录,提供清理入口
  • 工程内素材为绝对路径,打开时逐一校验,缺失标记 missing 而非静默丢弃

9.3 待补充

  • 是否限制单次导出最大时长与分辨率,防止长任务占满磁盘
  • 缓存目录容量上限与淘汰策略尚未确定

10 · 实施计划

阶段 内容 可验证交付
P0 video/ 骨架、引擎探测、按需下载、probe_video_source 能选文件并显示真实时长与分辨率
P1 timeline-model.ts + editor-store.ts + 轨道/图层模型,原型 UI 接真实状态(1.5~2 周) 可增删片段与叠加片段,页面不再有假数据
P2 composite_graph.rs 滤镜图生成 + render_video_project + 进度 + 取消;子项:段级智能重编码、导出三档预设、自定义引擎路径(6~8 天) 能导出带画中画的 MP4,闭环打通
P2' 代理预渲染预览 + 增量缓存(composite-range.ts),取代原 P2.5(4~5 天) 叠加区间可预览,与成片一致
P3 工程存读(SQLite)、撤销重做、缩略图与波形 可保存并重新打开工程
P4 文稿剪辑:转录接入、删语气词、压停顿 差异化能力可演示
P5 字幕烧制、比例裁切(接 PoseDetector) 可产出竖屏成品
TIP

📌 按「竖切」而不是「横切」推进:先打通 P0→P2 的完整链路(选文件 → 切一刀 → 导出成片),再回头补交互细节。因为原型 UI 已经相当完整,当前缺的不是界面,而是界面背后那根线。先把线接上,才知道哪些 UI 是真需要的。

10.1 成本与工时估算

现金支出:0 元。

项目 费用
FFmpeg(LGPL 构建)、whisper.cpp、auto-editor 0
AVC 专利池 0(年出货 10 万台以内为免费档)
引擎包托管(约 80 MB,复用现有 R2) 每月几分钱量级
商业 SDK 0(不采购,见 §3.5)
导出算力 0(全在用户本机)

工时(自行开发):

范围 天数
MVP(P0 + P1 + P2 + P2') 约 22~28 天
完整(含 P3~P5) 约 35~46 天

换算日历:全职约 5 周完成 MVP;每天 3 小时约 2.5 个月。

TIP

📌 “只做短视频 + 导出规格写死”相比通用方案省下约 6~8 天,主要来自两处:预览改为代理预渲染(绕开多路同步)、不做自定义参数面板与 4K/HDR。限定场景在这里是真金白银,不是妥协。


11 · 测试与验证

  • timeline-model.ts 为纯函数,必须有单元测试:分割、删除、ripple、边界(零长片段、相邻片段、越界 in/out)
  • 导出冒烟:样例素材集须含手机竖屏、无音轨、变帧率、含中文空格路径,逐项验证导出成功
  • 取消验证:渲染中取消后确认进程退出且无残留输出文件
  • 引擎缺失验证:清空引擎目录后进入页面,确认走下载流程而非崩溃
  • 素材缺失验证:移动素材后打开工程,确认标记 missing 并给出重新定位入口
  • 叠加一致性验证:同一工程分别取预览截图与成片对应帧,比对叠加层位置与缩放是否一致(允许时间上 1~2 帧偏差,不允许空间位置偏差)
  • 混音验证:双音轨 + 淡入淡出导出后检查无爆音、无削波
  • 转场边界验证:转场时长等于/超过片段时长时应被拒绝,不得生成非法滤镜图

12 · 风险与约束

风险 影响 对策
lib.rs 与 App.tsx 已过大 高 视频代码强制放 video/ 与 features/ai-video-editor/
预览与导出两条管线结果不一致 高 EDL 为唯一真相,两侧都从同一模型推导
WebView2 对非 H.264 预览能力有限 中 仅承诺 H.264 预览,其余先转代理
系统编码器致跨设备画质与速度差异 中 界面明示依赖系统编码器;提供失败回退
精确剪辑必须重编码,速度慢 中 提供快速模式,UI 说明差异
导出画质与体积不如 x264 中 段级智能重编码 + §3.4 三招(720p 档 / 以文件发送 / 自定义引擎路径);不采购 SDK
用户自备的 ffmpeg 版本异常或缺少编码器 中 启动时校验版本与编码器列表,不兼容则回退到内置 LGPL 构建并提示
多路 <video> 帧级同步 已消除 改用代理预渲染为主方案(§3.3),预览与成片同一管线
代理预渲染等待时间影响体验 中 只重渲改动区间 + 缓存;480p 低码率;短视频时长短,实际等待多为几秒
滤镜图复杂度失控 高 轨道数量写死(1 主 + 1 叠加 + 1 字幕 + 2 音频);不支持用户新增轨
叠加型多轨增加工期 中 范围收窄(无关键帧/无绿幕/仅交叉溶解)+ 导出规格写死 + 代理预渲染预览,MVP 控制在 22~28 天
变帧率、损坏、旋转元数据素材 中 建样例素材集回归;异常素材标 unsupported
许可与专利 中 LGPL 构建 + 独立进程 + 系统编码器;随包附许可
语音转录方案未定 中 属 §2.3 待确认,P4 前必须定案

13 · 变更日志

日期 版本基线 变更
2026-07-28 1.0.3 首版方案:确认外部进程调用 FFmpeg、按需下载 LGPL 引擎、EDL 数据模型、接口清单与分期计划
2026-07-28 1.0.3 面向短视频 + 微信分享定稿:导出预设固定三档(含 720p 微信档)、引擎路径可自定义、预览改为代理预渲染为主(消除多路同步风险)、确定不采购商业 SDK(VisioForge 因 .NET 排除)、写入 x264/AVC 公开价格、新增 §10.1 成本估算,工期改为 MVP 22~28 天
2026-07-28 1.0.3 需求变更为叠加型多轨:新增轨道/图层/转场数据模型、滤镜图生成模块、多路预览同步与 P2.5;新增 §3.4 导出画质与体积、§3.5 商业 SDK 对比;工期由约 3 周调至 6~7 周

附录 · 与通用调研的分工

内容 看哪里
线编 / 非线编概念、开源 NLE 全景、FFmpeg 许可与专利细则、功能限制清单 桌面视频剪辑调研
本项目的现状、模块划分、接口契约、排期 本文