代码解释视频生成 是做什么的?
为开发者制作配有旁白和动画的代码讲解视频。观众是工程师:展示真实代码,说出真实文件名和函数名,解释“为什么”和“如何做”,绝不为了迎合非开发者而简化成比喻。
技术栈:Remotion 的 Code Hike 模板(语法高亮的代码在步骤间平滑过渡)、用于架构图的 Mermaid、用于旁白的 ElevenLabs(通过 ElevenLabs 连接器或 API 密钥),以及内置字幕。当你修改 template/ 中的 Remotion 代码时,请加载 remotion-best-practices 技能。
本 SKILL.md 所在目录(“技能目录”)中包含以下文件:
template/:每次创建视频项目时都会复制进去的 Remotion 源文件。references/voice.md:在第 8 步生成旁白前阅读。references/long-form.md:当视频时长为 15-30 分钟时优先阅读;它会将工作拆分为多个章节,每个章节都要执行步骤 2-9。
1. 需求收集:开始任何工作前,按顺序先问这三个问题
每次只问一个问题(可使用 AskUserQuestion 时)。不要跳过或合并。
- 你需要理解什么? 获取目标(一行代码、一个代码块、函数、文件、流程或整个架构)以及原因(修复 bug、添加功能、审查 PR、入职学习)。如果回答很模糊(比如“身份验证那一堆”),请先阅读代码,然后提供 2-4 个具体角度供选择,例如“请求如何端到端完成身份验证” vs. “会话如何存储和过期”。
- 视频应该多长? 建议:约 30 秒(一行或一个代码块),1-2 分钟(一个函数或模块),约 5 分钟(一个子系统或流程),15-30 分钟(代码库入职学习,由并行智能体构建为多个章节)。如果他们不确定,请根据你在第一步中了解的情况推荐一个长度。
- 我对问题的理解是否正确? 阅读代码后,回复以下内容:
- 视频要回答的一个问题(一句话概括);
- 时长和节拍数;
- 大纲:每行对应一个节拍(屏幕上显示的内容 + 它要说明的观点);
- 你特意省略了哪些内容。 只有在收到肯定答复后才开始构建。如果收到否定答复,请修改并重新确认。这一步之所以存在,是因为旁白需要消耗 ElevenLabs 点数,而渲染需要数分钟。
当无人值守运行时(无人可回答),选择最合理的理解,在回复顶部说明它,然后继续。
2. 动笔前先研究代码
- 阅读实际代码。追踪调用到它们的定义;不要仅凭名称推断行为。对于大型代码库,如果你的智能体支持子智能体,则使用每个区域一个只读子智能体的方式展开,并只保留它们的结论。
- 旁白中的每个断言都必须映射到你阅读过的一个文件及其行号。在研究期间维护一个
notes.md文件,记录断言 → 路径:行号的关系;你将在第 7 步修复问题时用到它。 - 注意开发者可能会绊倒的地方:隐藏的副作用、顺序假设、错误路径、改变行为的配置、名不副实的命名。
3. 根据时间预算规划节拍
一个节拍包括一个视觉画面和 1-3 句旁白。旁白速度约为每分钟 150 个单词(2.5 单词/秒);每个节拍结尾有 0.6 秒的停顿。
| 预算 | 节拍数 | 单词数 |
|---|---|---|
| 30 秒 | 3-4 | ~70 |
| 1-2 分钟 | 6-12 | 150-280 |
| 5 分钟 | 20-30 | ~700 |
| 15-30 分钟 | 3-5 分钟的章节,参见 references/long-form.md |
节拍规则:
- 以要回答的问题开头,以一句话总结结尾。不要有开场白,也不要有“在这个视频中”之类的废话。
- 先架构,再深入:先放图,再放入口代码,最后放关键行。
- 解释目的,而不是逐行解释代码。每个代码节拍都要说明代码的用途以及它与前一个节拍的联系,然后指出关键的一两行。永远不要逐行解释一个代码块。
- 代码节拍:最多 16 行(屏幕底部为字幕保留空间),每行最多 80 个字符。剪掉无关行,用
// ...注释替换。连续显示同一代码片段但高亮位置不同的节拍会平滑过渡,因此可以复用代码片段并移动高亮。 - 用紧挨着高亮行上方的 Code Hike 注释来标示旁白正在讨论的内容:
// !mark(高亮下一行)或// !mark(1:4)(高亮接下来四行)。使用相应语言的注释语法(Python 中为# !mark)。 - 图解节拍:Mermaid
flowchart,最多 8 个节点。对于超过四个节点的链,使用TD。保持连续图解节拍的节点完全相同,只移动class X hot这一行,这样布局就不会跳动。 - 旁白要适合听觉:短句,说出开发者常用的标识符(比如“handle-request 函数”),不要逐字读代码,不要念出行号。
4. 项目初始化(每个视频一次)
将 SKILL_DIR 设置为技能目录,然后执行:
npx create-video@latest --yes --code-hike explainer && cd explainer
npx remotion add @remotion/media && npm rm twoslash-cdn && rm public/code*
rm src/calculate-metadata/process-snippet.ts src/annotations/Callout.tsx src/annotations/Error.tsx src/ProgressBar.tsx src/ReloadOnCodeChange.tsx
cp -R "$SKILL_DIR/template/." .
command -v mmdc || npm i -g @mermaid-js/mermaid-cli
特意移除了 Twoslash:它会把代码片段中每个未解决的导入都标记为红色错误。复制过来的文件会用由 beats/ 驱动的新组件替换模板的原组件:
scripts/build.mjs将beats/转换为public/beats/(音频、渲染好的图表、manifest.json),并测量每个节拍的音频时长。src/Main.tsx按顺序播放节拍:标题、代码或图表、音频、字幕。src/annotations/Mark.tsx实现了!mark高亮。src/Captions.tsx在每个节拍的音频中为字幕块计时。
5. 编写节拍
在 beats/ 目录中,每个节拍一对文件,按数字顺序编号(01,02,… 10):
NN.txt:可选的首行# <屏幕标题>(代码节拍使用path/to/file.ts:42-60,图解节拍使用简短标题),然后是旁白文字。- 一个视觉文件:带有代码片段的
NN.<扩展名>(扩展名设置高亮语言:.ts,.py,.go,…)或带有 Mermaid 图表的NN.mmd。使用classDef hot fill:#facc15,color:#000,stroke:#facc15和class NodeId hot高亮图表节点。
示例对:
beats/04.txt
# src/auth/session.ts:31-44
会话是延迟刷新的。过期检查仅在请求到达时运行,因此空闲的会话永远不会在这里被清理。
beats/04.ts
export async function getSession(id: string) {
const s = await store.get(id);
// !mark(1:3)
if (s && s.expiresAt < Date.now()) {
return renew(s);
}
return s;
}
6. 草稿检查(不消耗点数)
- 当
beats/中没有.mp3文件且没有密钥时,运行node scripts/build.mjs,它会按估算时长写入静音占位音频并打印总时长。如果总时长超出或低于预算 15%,则现在添加或删减节拍。 - 渲染屏幕上内容最多的时刻以及每个高亮出现的时刻(大约在节拍开始后 1.5 秒):
npx remotion still Main out/check.png --frame=<n> --scale=0.5。检查它们。修复超出行、无法阅读的图表以及高亮位置错误。
7. 独立事实核查(在生成任何旁白之前)
脚本的作者最不适合检查它。请让一个未参与编写脚本的审核者对照代码检查每个断言。即使无人值守也要执行此操作。
- 如果你的智能体支持子智能体,请启动一个新的子智能体。向其提供仓库路径、每个
beats/NN.txt及其视觉文件,以及以下简要说明,但不要提供notes.md或你的大纲,以便它自行理解代码:对照代码检查此解释脚本。列出旁白和屏幕标题中的每个事实性断言。对于每个断言,找到确认或反驳它的代码,追踪调用到它们的定义。每个断言返回一行:
节拍 | 断言 | 正确/错误/无法验证 | 路径:行号 | 原因。同时标记与源代码不同的代码片段(除// ...裁切和!mark注释外)、path:line范围错误的标题、脚本对代码重要内容存在误导性陈述的部分,以及旁白逐行解释代码而未说明代码用途的代码节拍。 - 否则,自己进行第二轮检查:对于每个断言,重新打开引用的代码并在那里(而不是在
notes.md中)进行检查。
修复所有标记为 错误 的断言,删除或弱化所有标记为 无法验证 的断言,并围绕其用途重写被标记的逐行解释节拍。重新运行草稿构建,并仅将更改过的节拍发回进行第二轮检查。
8. 语音生成与渲染
- 阅读
references/voice.md,并使用第一个可用的选项为每个节拍生成一个旁白文件:ElevenLabs 连接器、ElevenLabs API 密钥、其他文本转语音提供商,或均不可用时则生成仅有字幕的无声视频。整个视频使用同一个声音。 - 再次运行
node scripts/build.mjs。当beats/NN.mp3存在时,它会使用该文件,因此更改一个节拍只需替换该文件。 - 渲染一次:
npx remotion render Main out/explainer.mp4。检查视频和音频时长是否匹配(ffprobe -v error -show_entries stream=codec_type,duration -of csv=p=0 out/explainer.mp4),并且除非视频是无声的,否则检查音频是否非静音(ffmpeg -i out/explainer.mp4 -af volumedetect -vn -f null - 2>&1 | grep mean_volume;占位音频大约为 -91 dB)。
9. 交付前
- 观看(或至少听一下)第一个和最后一个节拍,以及中间的一个节拍。如果某个标识符发音错误,请在
NN.txt中用音标重新拼写,并仅重新生成该节拍的语音。字幕会显示旁白文本,因此音标重拼写也会在字幕中显示;请确保重拼写可读。 - 第 7 步之后更改过的任何旁白都需要重新经过第 7 步的检查。
- 交付 MP4 文件,并附上一句话摘要说明它回答的问题。未经明确许可,不得在任何地方上传或发布该视频。