工作原理 - ZLHad/OpenVideoHarness GitHub Wiki

English · 中文

模型不直接画像素,而是写一段程序:给定时间 t,画出 t 时刻的那一帧。渲染器(无头 Chrome、Manim)逐帧调用这段程序,最后由 FFmpeg 把帧和声音合成 MP4。OpenVideoHarness 管的是这个循环外面的一整套做法:做什么、按什么顺序做、怎么检查。规则本身写在 CLAUDE.md(agent 的入口;AGENTS.md 是给 Codex 等 agent 的同内容副本)和 playbook 里。

OpenVideoHarness 全局图:一句话需求经过判断类型、三道人工关卡、声音先行的代码渲染和自查闭环变成成片,右侧是仓库提供的知识库、工具与引擎、记录与回流

视频即代码

每一帧都是 t 的纯函数,由此带来三点:

  • 确定:同一个 t 永远得到同一帧,所以能并行渲染、断点续渲,也能跳到任意时刻单独渲。
  • 能自查:任何时刻都能单独渲出来,agent 把帧拼成一张图自己看。它看不了视频,也听不了声音,只能看静帧,读转写文本、时间戳和响度数据。
  • 能 fork:换语言、换歌、换风格,都只是改代码再重渲。

引擎:默认用 HyperFrames(HTML + GSAP);要精确的数学图形用 Manim CE;要手绘质感用自带的 ClaudeAnimationBase(p5.js + p5.brush);习惯 React 可以用 Remotion;要路径追踪的 3D 用 Blender;要真人或真实物理,就接生成式视频,再在上面叠一层代码。选型表见 playbook/00。

用代码驱动 Blender:有些画面网页引擎给不了:真玻璃的折射、星云和体积光、真实的景深、上百万个粒子的运动模糊。这时 agent 写 Python 驱动 Blender,每一帧仍然是 t 的函数:numpy 算出每个点在 t 时刻的位置,Cycles 路径追踪渲成底片,再和网页引擎的字、界面接在同一支片子里。在 macOS 上,bpy 脚本跑在沙箱里(不联网、只能写输出目录、拿不到环境变量里的 API key);长渲染先渲 3–5 帧校准,再分块渲、可以续渲。介绍片开场的 15.8 秒和风格样片 tabletop-miniature 都是这样做的。什么时候值得用、踩过哪些坑,见 engines/blender.md(部分已实测,文中标明了哪些跑过)。import bpy 的文件按 GPL-3.0-or-later 分发,仓库其余部分仍是 MIT。

流程:十个阶段,三道关卡

阶段 产物
0 选路径 按 CLAUDE.md 的路由表定类型和引擎
1 素材、立意、Brief、大纲 NOTES.md 里的素材清单;2–3 张立意卡;BRIEF.md(立意、受众、平台、时长、画幅、帧率、分辨率、在哪看、有无声音、验收项)和 3–7 段大纲 → 关卡 ①
2 风格 STYLE.md:调色板、字体、缓动、安全区、禁止项,都从立意推出来;借了哪个预设,在 DECISIONS.md 记一行
3 脚本与分镜 有旁白时写 SCRIPT.md;STORYBOARD.md(写出每个镜头的 reads)、按段落分页的关键帧,可选 animatic → 关卡 ②
4 音频先行 配音、词级时间、节拍表;用实测时长回写分镜,然后锁定时间表
5 搭引擎 渲染脚本、公共库、一个样板场景;乱序渲同一帧,结果必须一致
6 写场景 一个场景一个文件;长片按章节分给多个 subagent 并行
7 Review 先过 20 条清单,再由全新上下文的 reviewer 打分
8 渲染 先出 draft → 关卡 ③ → 再出成片
9 交付 MP4、源码、渲染命令、素材台账、LESSONS.md
flowchart LR
  A["0 选路径<br/>类型 + 引擎"] --> B["1 立意、Brief<br/>+ 大纲"]
  B --> G1{{"关卡 ①"}}
  G1 --> C["2 风格<br/>3 分镜"]
  C --> G2{{"关卡 ②"}}
  G2 --> D["4 音频先行"]
  D --> E["5–6 搭引擎 + 写场景"]
  E --> F{"7 Review<br/>20 条 · 8 项打分"}
  F -- 不合格 --> E
  F -- 合格 --> H["8 出 draft"]
  H --> G3{{"关卡 ③"}}
  G3 -- 要改 --> E
  G3 -- 通过 --> I["8 出成片<br/>9 交付 + 经验写回"]
Loading

每个阶段的通过条件见 playbook/01-pipeline.md。

先有立意

定风格、挑配方、套类型默认值之前,agent 先找这支片子的立意:一句话说得清的装置,让片子的形式本身就在讲内容,比如"把回车之后的 3 秒放慢成 2 分钟,计时器一直挂在屏幕上"。它先把只属于这份材料的数字、原话、物件列进 NOTES.md,在打开风格库、配方和案例之前自己想 5–8 个点子,再收敛成 2–3 张立意卡。每张卡写明由它推出的画面(专属的,或借一个、几个预设)和钩子,所以在关卡 ① 选一张卡,三样就一起定了。检验立意的一条办法:换个题材就不成立;还成立,就只是风格。做法见 playbook/12;cases/oneshot-five.md 拆了五支各从一个点子出发的社区作品。

底线和默认口味:清单里标了【底线】的条目管的是看得清、读得完、事实对、不出事故:安全框、读时、字号、字不被光烧白、reads 不被盖掉、循环接缝、分镜里声明的卡点、没有占位和编造,以及有声片里不出现数字静音。它们对任何立意、任何档位都成立。其余的(类型文档的语域和节拍、BRIEF 的 Motion defaults、镜头配方、风格预设、清单里没标底线的条目)都是默认值,立意需要时可以反着来,在写用到它的场景之前,在 DECISIONS.md 记一行。你选定的立意卡上写了的覆盖,算你的决定,reviewer 只查有没有做到。

规格一开始就定

画幅、分辨率、帧率、时长和在哪看,在建项目时就定下来,每类视频有默认值(bin/vh new … --aspect --watch --res),关卡 ① 把它们列在"替你定了"里。只有需求没说发在哪、而它又会改变画幅或字号下限时,agent 才问。在哪看(BRIEF 的 Watch on:)决定最小字号,单位是 1080p 合成里的 px:

Watch on 指什么 主标题 辅助、标签 字幕
phone 手机竖屏(1:1、4:5 也算) ≥ 84 ≥ 44 ≥ 65
desktop 电脑,或手机转成横屏全屏(B 站、YouTube、官网) ≥ 84 ≥ 44 ≥ 48
feed 横屏片放在手机信息流里,竖着拿、不转屏(抖音、视频号、小红书、微博、X) ≥ 150 ≥ 80 ≥ 115

可读性检查按这块屏幕缩联系表(phone 和 feed 每格 360 px 宽,desktop 640 px)。4K(Resolution: 4k)照常按 1080p 写,出片时渲成两倍大,字在屏幕上看起来一样大。细节见 playbook/01 的"规格"和 playbook/03 §4。

为什么要有关卡

人的判断在改动还便宜的时候最值钱:改分镜只要几分钟,改写好的代码要几个小时。所以 agent 在立意和大纲、分镜(附关键帧预览图)、初版这三处停下来等你。只有你选了 quick,或者在对话里明确说不用审,它才会跳过;你的原话和日期会记进 REVIEW.md,被跳过的关卡由一个全新上下文的 reviewer 代审。

导演模式

努力程度管 agent 自己查得多细,导演模式管哪些事由你来定。可以点名的有十二件:立意、规格、大纲、风格、主角、主旋律、配音、旁白稿、钩子、分镜、剪辑节奏、标题和封面。每件事有三种处理方式:

怎么处理
own agent 出几个选项,附推荐,然后停下来等你选
review 它出一个结果放进下一页,接着往下做;你不说话就算通过
delegate 它自己定,把理由写进 DECISIONS.md,你随时可以翻案

在对话里说,或者写在 BRIEF.md 的 Director: 一行,或者在 LOCAL.md 里设个默认:Director: hook=own, character=own, theme=own, packaging=own, rest=delegate。没点名的事按努力程度来:quick 全部 delegate;standard 的立意由你选(风格和钩子写在立意卡上,一起定;你单独点名时另问),大纲和分镜是 review,其余 delegate;studio 也是这样,只是其余的改成 review。

standard 和 studio 的三道关卡是底线:导演模式只加停,不减停。它加的停落在六个检查点上,按时间顺序排;你点了哪几站,才会停在哪几站(stop=E3 可以直接点名加一站):

检查点 什么时候 能定什么
E0 样帧 分镜之前 主角、主旋律(两版短试听加一张谱面图);风格,当你只能说"感觉不对"时(look-dev 变体)
E1 脚本 分镜之前 配音(和旁白稿一起选,每句时长才是按选定的音色量的)、旁白稿、钩子
E2 声音 写配乐之前 主旋律放在哪几段、哪里留白
E3 锁时 声音做完之后 最终的配音和配乐给你听一遍,然后锁定时间表;之后改一句台词要重新对时间
E4 样板章 开始写场景时,长片 主 agent 亲手做的第一章,当后面各章的标准
E5 锁画面 关卡 ③ 之后 之后只改声音、颜色和收尾

每件事最早在哪一站能定、以后再改要花多少,页面上都会写明("现在改:低 · 分镜后改:高")。完整的表在 playbook/01,规则在 CLAUDE.md,README 里有白话版。

审阅页

每次停下来,默认都是一页本地 HTML。bin/vh review <项目> <关卡> 把 out/review/gate-<n>.json 变成 gate-<n>.html(最新的一页同时是 index.html)。从上往下是:

  1. 要你定的事,默认最多 3 件。每件有推荐的选项、理由、以后再改要花多少、怎么回复(H1 / H2),最后是一句照所有推荐来的回复。
  2. 图和选项:每个决定配图,尽量并排放;声音给能直接播放的文件,agent 听不到的地方会明说。
  3. 分镜按段一页:关键帧、这一段的 animatic、agent 最没把握的镜头标红。
  4. 折叠的附录,放不影响你拍板的内容。

页面直接从磁盘打开,跟随你的浅色或深色主题;聊天里只发几行:要定的事和页面路径。只有一两个纯文字的选择时,直接在聊天里问也行。你的回复会逐字记进 REVIEW.md。

看图做决定

评估分镜或风格,不该靠读表。几个小命令负责出图:

命令 给你什么
bin/vh storyboard <项目> 按 shots.json 出分镜页:每镜一张关键帧,带时间、长度和 reads,没把握的镜头标红,太长的镜头标出来
bin/vh rhythm <项目> 一条时间轴:镜头、旁白、字幕、画面文字和配乐的段落与重音;超过这一类"每 N 秒要有新回报"的镜头、停得不够读完的字,都标红
bin/vh style compare a,b,c 几个风格并排,放封面或各样片的同一时刻;bin/vh style apply 把你挑的几个作为参考挂到项目上
bin/vh cover-preview <图> 封面在各平台信息流里的实际大小(B 站、抖音、YouTube、小红书),带平台的角标,外加小字可读性检查
bin/vh music … --roll 每个声部的谱面和响度曲线:给听不见的一方一张能看的图
bin/vh readcheck <项目> 不开浏览器,直接读 HyperFrames 合成里的画面文字,查每条字停得够不够久;--budget <秒> 告诉你一段时间里放得下多少字:上屏的、做字幕的、念出来的

reads:节奏的计量单位

一个 read 是观众必须看懂的一条信息。每个镜头按顺序列出它的 reads,每条标起止时间。每条 read 都要给观众留出找到、看懂、消化的时间,两条重要的 read 不能重叠。放不下就把镜头加长,或者删掉一条 read,不要硬挤。节奏是 AI 做视频最容易出问题的地方,所以先分镜、后代码。(这个概念来自 ClaudeAnimationBase 的 ANIMATION_GUIDE.md。)

声音先行

有声音时,声音定时长。agent 先做旁白或配乐,量出每句话、每个词、每一拍落在哪里(timeline.json、music.beats.json),画面再去对齐。静音视频的时长由 reads 决定,而且关掉声音也要看得懂。详见声音与配音。

自查

检查分层做,便宜的在前(playbook/02):

  1. 能不能跑:lint、编译、dry-run。
  2. 不看图的检查:包围盒有没有重叠,有没有黑场、冻帧、静音,帧数对不对,抽几帧比对确定性。
  3. 看静帧:联系表看构图,strip(一串连续帧)看时序,crop 看脸和细节;每个切点前后 0.5 秒单独看;再按目标屏的大小看一遍(手机和手机信息流每格 360 px,电脑 640 px)。
  4. 让模型做选择题:视觉模型从锚点网格或几个渲好的变体里挑,而不是猜"往左挪几个像素"。
  5. 没参与制作的 reviewer:开一个全新上下文的 agent,扮演严苛的动效导演,只给它帧、清单和分镜,外加 BRIEF 的立意一行和 DECISIONS.md 里口味覆盖的那几行,不给作者的自评。
  6. 整片观看(可选):Gemini 能直接读视频,但大约每秒只取一帧,看得出叙事问题,看不出快动作里的问题。
  7. 你:听感和品味的最后一关。

每个 draft 都要过两道线(TASTE_CHECKLIST.md):

  • 20 条 PASS/FAIL,覆盖构图、文字、色彩、运动、节奏和内容,任何一条 FAIL 都要返工;标了底线的条目,不管什么立意都要过;
  • 8 个维度打分(1–10):立意(选定的点子落到画面上没有)、hook、目标屏可读、运动质量、变化、构图与完成度、内容准确、声画同步。每一项都要 ≥ 8,不看平均分。打分的永远不是作者:给最早那 26 个风格样片打分时,制作方的自评普遍比独立 reviewer 高 1–2 分。

原来的七个维度、8 分线和至少 3 轮,都来自社区经验;清单里写明了原始出处没能逐条核实。"立意"一项是 2026-10-02 加的:cases/oneshot-five.md 拆的五支片子赢在点子,而原来的七项里没有一项问点子。立意分低时,修法是让画面更贴着选定的立意,不是换立意;reviewer 觉得立意本身就弱,就写进关卡 ③ 交给你定。

声音也用数据查:bin/vh qa 扫描最终混音里的数字静音、掉音、抽吸和爆音,并检查每个卡点是否落在 1 帧以内。用了 profile= 的混音还会出一份混音报告:音乐在每句旁白下面压到了多低、哪些词有被盖住的风险、音效有没有落在各自那一类的范围里。

努力程度

一个开关决定上面这些做多少(见 CLAUDE.md 的"努力程度"一节,或运行 bin/vh effort):

quick 快出 standard 标准(默认) studio 精品
适合 试方向、草稿 大多数正式视频 发布片、旗舰内容
人工关卡 无(你点名要定的事照样停) ① ② ③ ① ② ③,另附每张立意卡的 10–20 秒草图和全长 animatic
立意 自己想 3 个一句话点子,挑 1 个 关卡 ① 给 2–3 张立意卡,各配一帧画面 同左,每张配一段 10–20 秒的草图
自查 整片一张联系表、一张按目标屏缩的联系表、前 2 秒的逐帧 strip 每个场景:联系表、strip、crop 同左,再加目标屏尺寸测试、循环接缝、无损确定性、静默故障扫描
独立打分 不做 1 轮,修最差的 3 处 至少 3 轮,8 项都 ≥ 8
声音 可以没有,或配乐、配音加基础混音 配乐或配音、关键动作音效、按类型的混音 profile、bin/vh qa 同左,再加每个动作的拟音和声像,混音报告没有硬失败
30 秒的片子大约要 10–30 分钟 1–2 小时 3 小时以上

降档只能由你决定,agent 不能为了省时间自己降。有些底线在任何档位都不降:每一帧是 t 的纯函数,事实照抄原文,文件里不写 API key,有声片中不出现数字静音,全屏闪白每秒不超过 3 次,字号不低于"在哪看"那一档的下限,素材许可记清楚,清单里标了底线的条目,出片前跑一次 bin/vh check。

七条硬规则

  1. 每一帧都是 t 的纯函数:不用 Math.random()、Date.now()、CSS transition 或 @keyframes,需要随机就用带种子的 hash。
  2. 有声音时,音频决定时长。
  3. 先分镜,后代码。
  4. 每个场景都自查。
  5. 事实照抄原文;拿不准的写进 NOTES.md,不编进视频。
  6. 只在 projects/ 里改东西;引擎是模板,参考仓库只读。
  7. 文件里不写 API key,一律从环境变量读。

规则冲突时,按这个顺序:你在对话里说的,类型文档,项目的 STYLE.md,playbook/,外部参考。这个顺序管的是规则;审美默认(语域、配色、节拍、运动和转场的口味)立意需要时可以改,在 DECISIONS.md 记一行。

经验写回

每个项目都有自己的 LESSONS.md,其中通用的条目会并进 playbook/ 或类型文档的自查重点,让下一支片子直接受益。仓库里不少规则就是这么来的。比如"戏剧性的停顿要做成屏息,不能是数字静音",出自介绍片:它的第二版在停顿处用了真静音,用户听到的是音乐卡住了。

研究笔记

上面有些规则来自测量。docs/research/ 里有六篇实验记录(也有英文版),每篇写了问题、怎么量的、量到的数字、因此改了仓库里的什么、还有哪些没弄清楚:

  1. 旁白、配乐、音效的响度层级,混音 profile 就是从这里来的;
  2. 28 份配乐怎么量"太像";
  3. 同一份代码为什么渲出不同的像素:样片现在改在 CPU 上渲;
  4. 画面上的字要停多久,bin/vh readcheck 的依据;
  5. 配乐的篇章、主题和起伏,见 playbook/11;
  6. 先有立意对比只守底线,用两个一句话需求做的 A/B:quick 路径多出的两项自查由此而来,字号下限按屏幕分档的问题也是它提出的。

它们是记录,不是规则(规则在 playbook 里),数字主要是仪表读数,不是听测结论。

⚠️ **GitHub.com Fallback** ⚠️