先说结论:video_tools 这个项目做成了,但做成的原因和大多数人以为的不一样。它的仓库里确实塞了不少 AI 模块——ASR、TTS、生图、抠像、调研多智能体——但这些都不是核心,也都可以替换。真正的核心是时间线操作:一份可以在有限篇幅内穷举的 timeline.json。正是这种近似于人类剪辑师的操作模式,让 AI 在视频制作上第一次具备了和人类近似的天花板。

我用它验证过一件此前没做到的事:AI 独立完成了一期视频,从素材编排、动效、字幕到混音响度,全程没有我插手,成片质量达到了可以发布的水平。这篇复盘想讲清楚的是:这件事为什么成立,以及它在哪个方向上至今完全失败。

它是什么:一个中间层,不是一个大盒子

video_tools(v2.0.1)是我 B 站视频产线的程序本体,定位一句话就能说完:以 timeline.json 为单一事实源的视频剪辑中间层。时间线进,成片出,中间是 FFmpeg 的帧精确合成。

渲染管线七阶段:validate → prepare → gfx → video → audio → mux → qc。其中只混了两种「执行件」:HTML 动效和 FFmpeg。HTML 负责 gfx 轨——常驻 headless Chrome 通过 CDP 逐帧截图,把 HTML/CSS/JS 动画变成透明 PNG 序列(透明页走黑白双截图法,数学上无损解出 alpha);FFmpeg 负责其余一切——分层 overlay、滤镜图混音、-14 LUFS 响度归一、封装。

时间线本身长这样(节选自 skill-demo 范例):

{"version": 2,
 "project": {"fps": 30, "width": 1920, "height": 1080, "duration_frames": 90},
 "video_tracks": [
  {"name": "aroll", "kind": "aroll", "clips": [
    {"src": "v01", "src_in": 0, "src_out": 90, "dst_in": 0, "dur": 90}]},
  {"name": "gfx-overlay", "kind": "gfx", "clips": [
    {"src": "gfxA.html", "dst_in": 0, "dur": 90}]}]}

所有时间量都是整数帧,轨道数组顺序就是图层顺序,kind 只是语义标注、渲染机制完全不区分——v2 把「轨道等价」定成了架构信条。HTML 动效并不特殊,它只是 gfx 轨上一种源。

至于 asr、tts、imgen、matting、blender_bridge 这些,我在架构上用一条「关停测试」划界:关停之后主链产物不可信的组件进内核,关停了仍能可信出一期片的统统划为可卸载的 apps/plugins。它们是我真实使用中沉淀下来的方便件,不是这个项目的灵魂。

核心判断:时间线操作给了 AI 人类的操作模式

为什么偏偏是时间线?

剪视频这件事,人类剪辑师的工作本质是在一条时间线上做决定:这段素材从第几帧用到第几帧、放在哪一层、什么时候淡入。这不是一个感觉问题,是一个可以完整量化表达的问题。视频数据、音频数据,最终都能落成帧号、轨名、音量、淡入淡出长度这些有限集合里的整数与枚举——一份九十秒的工程,JSON 写下来不过一两百行,可以在有限篇幅内穷举。

这一条比听起来重要。可穷举意味着两件事同时成立:AI 可读(模型能在上下文里装下完整工程状态,逐 clip 修改而不是盲改),人类可预览(我打开 JSON 就能看懂 AI 改了什么)。AI 可读与人类可预览并存,是 AI 工具成熟的先决条件——只有前者,人类失去审查能力;只有后者,AI 根本接不了手。

确定性是可迭代的地基

这条产线的主链渲染不依赖扩散模型。HTML 和 FFmpeg 的输出是精确、稳定、可复现的:同样的 timeline.json,跑一百次得到逐帧一致的结果。没有扩散模型那种「同一提示词两次结果不同」的不稳定,迭代才有意义——改错了能定位,改对了能固化。可复现是可迭代的前提,而可迭代是 AI 做出高质量成片的前提。

所以那期 AI 独立完成的视频,机制上并不神秘:AI 在一份可穷举的 JSON 上反复做小决策,每次决策的后果都由确定性渲染如实反馈,好坏可验证、回退零成本。这和人类剪辑师在时间线软件里的工作方式是同构的——操作模式近似人类,天花板才近似人类。这是我整个项目最核心的一条经验。

它的姊妹仓库 Music Tools 从反面印证了同一条原理:两个工具能成,是因为音乐和视频恰好都是可量化、可 JSON 穷举的媒体。Music Tools 产出的 BGM 工程通过 plugins/bgm-render 直接作为源挂进 timeline.json,缓存命中就免渲染——配乐、床乐、响度 QC 一路打通,背景音乐问题就此解决。

反面:角色设计,我在这个领域完全失败

同一个思路推到角色设计上,至今全军覆没。

我想解决的问题很明确:用文本程序化的方式,可迭代地构建优秀的角色动画。漫长尝试下来,路线基本穷尽了:CSV 参数表、Blender、扩散模型、ControlNet、图像编辑模型、Nano Banana,以及别的什么——都没有达到一个足够高的天花板。要么可控但丑(CSV、Blender:确定性有了,表现力上不去),要么好看但不可控(扩散系:单帧可以惊艳,迭代时上一版优点保不住,一致性和连续性无从谈起)。

两者的失败方式是对称的,而根源是同一个:角色数据不可在有限篇幅内量化穷举。一段视频是几百个 clip 的排列,一个角色是连续高维空间里的形态、神韵与生命力,JSON 写不下它,也就既没有稳定的中间表示供 AI 修改,也没有确定性渲染供迭代收敛。

这里的教训我想说得重一点:天花板是最重要的。一条流水线如果天花板只有 60 分,确定性再好、迭代再快,也只是更快地抵达 60 分。视频和音乐的成功让我确认了「可穷举 + 确定性」这套方法论的有效边界——它恰好停在角色设计门外。

下一步:这是游戏之前的最后一块基石

所以未来的核心研究方向只有一个:角色设计如何被智能体接管。目标不是「能生成角色的图」,而是最终获得一条与人类画师近似天花板的、可迭代构建角色动画的实现流程。

这不是锦上添花。我们是要做游戏的,角色是游戏内容里绕不开的主体。视频工具和音频工具这两块小基石已经就位——场景、动效、配乐、成片都能智能体化了——角色设计是制作游戏的最后一块核心基石,一道不可不跨越的技术鸿沟。跨过去,从视频到游戏的路就通了;跨不过去,前面的一切都只能做「没有角色的内容」。

仓库在这里:git.ruochongliang.top/lrc/video_tools,姊妹项目 Music Tools 同站可寻。欢迎拍砖。相关的前文还可以看 Mova:AI 辅助 2D 动画工具的架构与性能债 和 鹈鹕测试:SVG 动画的生成与验证管线。