把视频剪辑能力集成进现有 Tauri 桌面工具箱 TooBox 也盒 的落地方案。 通用技术调研见 桌面视频剪辑调研;本文只写「在这个具体项目里怎么做」。 编写时间:2026-07-28。基线版本:
1.0.3。本文是方案文档,不是实现记录。除 §1 现状事实外,其余均为待实施设计,尚未落地到源码。
修订说明(以最新为准):
- 首版为「单视频轨 + 单音轨」,现已改为叠加型多轨(画中画 / B-roll)。
- 目标场景锁定短视频平台 + 微信分享:导出预设固定三档,预览改为代理预渲染为主,确定不采购商业 SDK。
- 现金支出 0 元,MVP 工时约 22~28 天(见 §10.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 万字节 |
— |
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)。这是本方案成立的核心前提。
| 能力 | 既有实现 | 源码位置 |
|---|---|---|
| 隐藏控制台的子进程调用 | 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 |
📌 这张表就是整份方案的地基。做视频剪辑需要四样底层能力:调外部程序、流式进度、按需下载运行时、在 WebView 里播本地文件——四样这个项目全都有现成范式。所以真正要新写的只有三块:FFmpeg 适配层、时间线数据模型、把原型 UI 接上真实数据。这也是为什么不该引入 MLT 或链接 FFmpeg 库:那等于把已经铺好的路推掉重修。
1080×1920、平台横屏 1920×1080、微信分享 720×1280;统一 30fps、H.264 + AACffmpeg 路径libx264 的版本由用户自行安装)melt 等第二套媒体引擎scripts/upload-r2-object.py 流程)whisper.cpp、auto-editor,均为 MIT)以消掉问题 1📌 前两个问题必须在 P4 之前定案。转录方案决定是「加一个 HTTP 调用」还是「再走一遍 WD14 那样的运行时下载 + 模型管理」,两者工期差好几倍——不要等做到 P4 才发现要重做架构。
| 候选 | 结论 | 理由 |
|---|---|---|
| Rust 侧以外部进程调用 FFmpeg | 采用 | 与 PoseDetector.exe、WD14 完全同构;零新增编译依赖;许可边界清晰 |
Rust 绑定 ffmpeg-next(链库) |
不采用 | Windows 构建链复杂;与闭源主程序静态链接存在许可风险 |
引入 MLT / melt |
不采用 | Windows 分发困难、体积大、GPL;本项目不需要多轨实时合成 |
| 决策 | 说明 |
|---|---|
| 构建类型 | 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 版就能用上最佳编码,分发行为不由本应用发生 |
🚧 GPL 程序的「独立进程调用」是否构成衍生作品,业界有共识倾向但存在法律解释空间。稳健做法就是本表写的:默认只分发 LGPL 构建,GPL 版一律由用户自行安装。商业发布前请自行确认。
按需下载而非随包的三个理由:
| 理由 | 说明 |
|---|---|
| 更新包不受影响 | 项目已开 createUpdaterArtifacts,随包会让每次更新都多传几十 MB |
| 不用剪辑的用户零成本 | 工具箱是多功能集合,剪辑只是其中一项 |
| 已有先例 | WD14 的 Python 运行时就是下载来的,实现成本低 |
📌 「按需下载」在这个项目里几乎是免费的。别的项目要为此新写下载器、校验、解压、进度 UI,而这里 download_wd14_model_blocking 已经把这套跑通了,连 Radix Progress 组件都是现成的——照抄即可。
基础不变:通过 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 |
📌 “只做短视频”把代理预渲染从兜底方案抬成了主方案,这是本方案最大的一项简化。三分钟的片子渲一个 480p 代理通常只需几十秒,配上“只重渲改动区间 + 缓存”,实际等待往往只有几秒。
换来的好处是两个高风险项直接消失:不再需要解决多路 <video> 帧级同步(浏览器本来就不提供这个保证),且预览与成片走同一套渲染管线,天然所见即所得。长片项目不能这么做,你能。
用系统编码器换来的是「合规 + 零体积 + 零成本」,代价是编码效率。
| 限制 | 表现 |
|---|---|
| 编码效率低 | 粗略经验:要追平 libx264 medium 的观感,h264_mf 大约需 1.3~2 倍码率 |
| 码率控制粗糙 | 无 CRF / 心理视觉优化 / 自适应量化,难以“按质量恒定”出片 |
| 高级参数缺失 | B 帧、参考帧、AQ 等基本不可调,无 preset/tune |
| 跨设备不一致 | MF 按机器情况走软/硬编码,同工程在不同电脑上画质与速度可能不同 |
| 场景 | 整片重编码 | 段级智能重编码 |
|---|---|---|
| 掐头去尾 | 画质掉一代,体积随编码器 | 几乎无损,体积≈原片 |
| 删语气词 / 压停顿 | 同上 | 99% 数据原样保留 |
| 盖 B-roll / 烧字幕 / 转场 | 必须重编码 | 仅那几段重编码,其余仍 copy |
📌 多轨叠加后,段级 copy 不是失效了,而是“按区间生效”,因此更该做。口播视频只在几处盖了 B-roll,那么这几处重编码、其余 80% 仍可无损 copy——它直接决定了那 80% 的画质与导出速度。
微信不经平台二压,画质直接可见;且发送有体积限制,目标是有限体积内画质最好。
| 招数 | 做法 | 成本 |
|---|---|---|
| 1. 降分辨率而非降码率 | 微信档导 720×1280,不导 1080p;同码率下每像素码率提升约 2.25 倍 |
0,最有效 |
| 2. 提示以「文件」发送 | 导出完成后提示用户;否则微信会再压一次,换任何编码器都无效 | 0 |
| 3. 引擎路径可自定义 | 愿意折腾的用户自己装含 libx264 的 GPL 版,即可获得最佳编码 |
约半天开发 |
📌 这三招比换编码器有用得多。用户被微信压过一次,你花多少钱买编码器都白搭;而在手机上看,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 元、无专利池 | 交付兼容性差、编码慢 |
📌 要修正一个常见误解:硬件编码并不能救「小体积高画质」。NVENC / QSV / AMF 强在速度与中高码率,但它们省掉了大量率失真优化,在低码率档画质通常不如 libx264。而微信分享恰好就是低码率档——把硬件编码当成画质方案去做,会白忙一场。
🚧 以下价格与条款来自公开渠道,会变动,采购前必须以厂商最新报价与合约为准,不要拿本文当依据。
| 类型 | 代表 | 计费 | 适用性 |
|---|---|---|---|
| A. 桌面原生 SDK | 美摄 PC、SolveigMM、MainConcept(VisioForge 已排除:.NET) | 授权费 | 均需重写渲染层 |
| B. 云端渲染 API | 阿里云 IMS 云剪辑、美摄云剪辑、Shotstack、JSON2Video | 按渲染分钟 | 仅适模板化批量出片 |
| C. 开源库 | FFmpeg、auto-editor、whisper.cpp |
0 元 | 本方案主线 |
| 项目 | 公开价格 | 备注 |
|---|---|---|
| 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 | 不公开,只能询价 | 均需重写渲染层 |
| 已排除:.NET 技术栈,跨平台不友好 |
注意:阿里云 / 腾讯云 / 火山引擎 / 商汤 / 涂图 / 七牛的短视频 SDK 绝大多数只有 iOS / Android,对 Windows 桌面不适用,直接排除。
📌 算下来你的账单就是 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,闭源商用谨慎 | 不推荐 |
不采购。 理由:
仅当以下同时成立时重新评估:年出货接近 10 万台(已有规模与收入)、且本地交付成为主场景、且三招均不满意。
| 模块 | 文件 | 职责 |
|---|---|---|
| 编辑器页面 | 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 叠加还是代理预渲染 |
| 模块 | 文件 | 职责 |
|---|---|---|
| 模块入口 | 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 |
📌 lib.rs 已 4816 行、App.tsx 已 62 万字节——视频功能代码量不小,如果继续往这两个文件里堆,它们会成为压垮维护性的最后一根稻草。所以「必须分模块」不是洁癖,而是硬约束:从第一行代码就分,因为事后拆比一开始分难十倍。
| 模型 | 来源 / 存储 | 主要使用模块 | 说明 |
|---|---|---|---|
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 事件负载,不持久化 | 导出面板 | 渲染进度快照 |
| 字段 | 类型 | 说明 |
|---|---|---|
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 | 时间戳毫秒 |
| 字段 | 类型 | 说明 |
|---|---|---|
id |
string | 素材 ID,客户端生成,工程内唯一 |
path |
string | 素材绝对路径;打开工程时校验存在性 |
durationMs |
number | 时长,毫秒 |
width / height |
number | 像素 |
fps |
number | 帧率;变帧率素材记平均帧率 |
hasAudio |
boolean | 是否含音轨,影响导出滤镜图 |
proxyPath |
string | null | 代理文件绝对路径,未生成为 null |
status |
string | 枚举:ready / missing / unsupported |
| 字段 | 类型 | 说明 |
|---|---|---|
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。不支持用户新增轨道。
| 字段 | 类型 | 说明 |
|---|---|---|
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 | 音频淡入淡出时长,毫秒 |
| 字段 | 类型 | 说明 |
|---|---|---|
id |
string | 转场 ID |
fromClipId / toClipId |
string | 相邻两片段,必须同轨 |
kind |
string | 首期仅 crossfade |
durationMs |
number | 重叠时长;不得超过任一片段时长,校验失败则拒绝建立 |
📌 转场必须独立建模,不能塞进 TimelineClip。因为它天生属于“两个片段之间”,一旦当成某一侧的属性,删片段、换顺序、ripple 时就会出现孤儿转场或重复转场。
📌 时间线总时长不存字段,由 clips 推导。这是刻意的:任何「可以从别处算出来的状态」一旦落成字段,就多了一个会不一致的地方。同理,源内 inMs/outMs 与时间线 startMs 必须分开——把两者混成一个「位置」是新手最常见的模型错误,一做 ripple 删除就全乱。
| 字段 | 类型 | 说明 |
|---|---|---|
runId |
string | 本次导出任务 ID,前端据此过滤事件 |
stage |
string | 枚举:preparing / rendering / finalizing / done / failed / cancelled |
percent |
number | 0-100,由 out_time_ms 与时间线总时长推导 |
etaMs |
number | null | 预估剩余毫秒,样本不足为 null |
message |
string | 失败时为错误摘要,其余为空字符串 |
以下 Tauri command 与事件均为待实现,命名对齐既有 command 风格(动词前缀 + 模块名)。
| 编号 | 命令 / 事件 | 类型 | 调用方 | 计划源码位置 | 说明 |
|---|---|---|---|---|---|
| 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 |
工程持久化 |
render_video_projectfeatures/ai-video-editor/video-api.tssrc-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 存在,缺失则直接失败并列出缺失素材,不产出半成品scale/crop/overlay 与 amix 滤镜链 → 区间间 concatoutput.width/height 画布计算,前端预览必须用同一套换算,否则预览与成片位置对不上ffmpeg -progress pipe:1 -nostats 按行解析 out_time_ms,换算百分比后 app.emit('video-render-progress', …)AtomicBool + 活动 PID + child.kill();取消后删除未完成输出h264_mf 初始化失败时降规格重试一次;仍失败则回报「当前设备不支持系统编码器」📌 文稿剪辑是这个产品真正的差异化点。原型 UI 里已经有 transcript 模式和「删语气词 / 压停顿 / 补空镜」建议,说明产品方向是对的——口播和短剧场景下,「改文字就等于改视频」比拖时间线快一个数量级,而且不需要多轨、不需要调色,正好落在能力范围内。
| 既有能力 | 在剪辑中的用途 |
|---|---|
PoseDetector.exe(batch-crop 用) |
横屏转竖屏时按主体位置智能重构图 |
| WD14 打标 | 素材库自动标签,支撑页面已有的素材搜索框 |
ai-short-drama |
脚本分镜转初始 EDL 草稿 |
ai-cover |
从时间线抽帧生成封面 |
tauri-plugin-opener |
导出完成后打开输出目录 |
rfd |
素材选择与导出路径选择 |
📌 这一节才是「集成进工具箱」而不是「做个独立剪辑软件」的理由。单看剪辑功能,永远打不过剪映;但「AI 生成脚本 → 自动排 EDL → 人像检测智能裁竖屏 → 抽帧出封面」这条流水线,独立剪辑软件做不到,因为它没有前后两端的能力。别用剪辑功能去对标剪映,要用整条链路去对标。
validate_pose_detector_path..、绝对路径),避免写出安装目录之外allow_directory(parent, false),不整盘放开missing 而非静默丢弃| 阶段 | 内容 | 可验证交付 |
|---|---|---|
| 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) |
可产出竖屏成品 |
📌 按「竖切」而不是「横切」推进:先打通 P0→P2 的完整链路(选文件 → 切一刀 → 导出成片),再回头补交互细节。因为原型 UI 已经相当完整,当前缺的不是界面,而是界面背后那根线。先把线接上,才知道哪些 UI 是真需要的。
现金支出: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 个月。
📌 “只做短视频 + 导出规格写死”相比通用方案省下约 6~8 天,主要来自两处:预览改为代理预渲染(绕开多路同步)、不做自定义参数面板与 4K/HDR。限定场景在这里是真金白银,不是妥协。
timeline-model.ts 为纯函数,必须有单元测试:分割、删除、ripple、边界(零长片段、相邻片段、越界 in/out)missing 并给出重新定位入口| 风险 | 影响 | 对策 |
|---|---|---|
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 前必须定案 |
| 日期 | 版本基线 | 变更 |
|---|---|---|
| 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 许可与专利细则、功能限制清单 | 桌面视频剪辑调研 |
| 本项目的现状、模块划分、接口契约、排期 | 本文 |