Communitygithub.com

代码解释视频生成

利用 Remotion + ElevenLabs 为代码行、代码块、文件或整个代码架构生成配有旁白的开发者讲解视频,用于帮助自己或队友快速上手。

代码解释视频生成 是什么?

该技能能够基于实际代码库生成专为开发者设计的、配有旁白和解说的动画视频。它通过 Remotion 的 Code Hike 模板实现语法高亮代码的平滑过渡动画,支持 Mermaid 架构图,并使用 ElevenLabs 生成自然语音旁白。用户需要指定要讲解的代码目标、视频时长,并在确认脚本大纲后启动制作流程(包括代码研究、节拍规划、事实核查、语音合成和最终渲染)。最终产出 MP4 视频文件和简洁摘要,非常适合用于代码审查、新功能讲解或新成员入职培训等场景。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/SkelegonDK/code_explainer_skill/tree/HEAD/skills/code-explainer-video

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

代码解释视频生成 是做什么的?

为开发者制作配有旁白和动画的代码讲解视频。观众是工程师:展示真实代码,说出真实文件名和函数名,解释“为什么”和“如何做”,绝不为了迎合非开发者而简化成比喻。

技术栈: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 时)。不要跳过或合并。

  1. 你需要理解什么? 获取目标(一行代码、一个代码块、函数、文件、流程或整个架构)以及原因(修复 bug、添加功能、审查 PR、入职学习)。如果回答很模糊(比如“身份验证那一堆”),请先阅读代码,然后提供 2-4 个具体角度供选择,例如“请求如何端到端完成身份验证” vs. “会话如何存储和过期”。
  2. 视频应该多长? 建议:约 30 秒(一行或一个代码块),1-2 分钟(一个函数或模块),约 5 分钟(一个子系统或流程),15-30 分钟(代码库入职学习,由并行智能体构建为多个章节)。如果他们不确定,请根据你在第一步中了解的情况推荐一个长度。
  3. 我对问题的理解是否正确? 阅读代码后,回复以下内容:
    • 视频要回答的一个问题(一句话概括);
    • 时长和节拍数;
    • 大纲:每行对应一个节拍(屏幕上显示的内容 + 它要说明的观点);
    • 你特意省略了哪些内容。 只有在收到肯定答复后才开始构建。如果收到否定答复,请修改并重新确认。这一步之所以存在,是因为旁白需要消耗 ElevenLabs 点数,而渲染需要数分钟。

当无人值守运行时(无人可回答),选择最合理的理解,在回复顶部说明它,然后继续。

2. 动笔前先研究代码

  • 阅读实际代码。追踪调用到它们的定义;不要仅凭名称推断行为。对于大型代码库,如果你的智能体支持子智能体,则使用每个区域一个只读子智能体的方式展开,并只保留它们的结论。
  • 旁白中的每个断言都必须映射到你阅读过的一个文件及其行号。在研究期间维护一个 notes.md 文件,记录 断言 → 路径:行号 的关系;你将在第 7 步修复问题时用到它。
  • 注意开发者可能会绊倒的地方:隐藏的副作用、顺序假设、错误路径、改变行为的配置、名不副实的命名。

3. 根据时间预算规划节拍

一个节拍包括一个视觉画面和 1-3 句旁白。旁白速度约为每分钟 150 个单词(2.5 单词/秒);每个节拍结尾有 0.6 秒的停顿。

预算节拍数单词数
30 秒3-4~70
1-2 分钟6-12150-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. 草稿检查(不消耗点数)

  1. 当 beats/ 中没有 .mp3 文件且没有密钥时,运行 node scripts/build.mjs,它会按估算时长写入静音占位音频并打印总时长。如果总时长超出或低于预算 15%,则现在添加或删减节拍。
  2. 渲染屏幕上内容最多的时刻以及每个高亮出现的时刻(大约在节拍开始后 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. 语音生成与渲染

  1. 阅读 references/voice.md,并使用第一个可用的选项为每个节拍生成一个旁白文件:ElevenLabs 连接器、ElevenLabs API 密钥、其他文本转语音提供商,或均不可用时则生成仅有字幕的无声视频。整个视频使用同一个声音。
  2. 再次运行 node scripts/build.mjs。当 beats/NN.mp3 存在时,它会使用该文件,因此更改一个节拍只需替换该文件。
  3. 渲染一次: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 文件,并附上一句话摘要说明它回答的问题。未经明确许可,不得在任何地方上传或发布该视频。

相关技能