白板讲解视频
核心风格:语音和画面同步移动。 每样东西都在被说到的同时绘制、书写、下划线和圈出,每个幻灯片逐步构建。在编写故事板之前,请阅读 references/style-guide.md;它包含了颜色、屏幕上文字的规则、渐进式揭示、同步时间表和整个视频结构。
从 template/ 开始每个视频(复制它,不要从头开始):将此技能的 template/ 复制到 <project>/video/,然后运行 source env.sh && cargo build --release。二进制文件是 target/release/explainer(Windows 上是 explainer.exe;R ... 在 env.sh 中运行它)。该模板是一个约 95 秒的演示(“一分钟左右的二分查找”),包含四个可供复制的场景;template/README.md 中有所有命令。从项目文件夹运行 Python 脚本,格式为 python -I narration/<x>.py,需要安装 numpy、soundfile、librosa、faster-whisper 和 pillow。其内容包含:
src/kit.rs:绘图工具包(手绘笔画、hand/note文字、underline、circle、arrow、stamp、counter、用于论文图片的Card及其mark/ring/spot/zoom方法、camera、shrink_aside、图标)。整体使用。src/lib.rs:场景调度,带有 0.1 秒渐暗效果的章节标签,图像表,SceneCues(c.w(beat, "word")= 单词被说出的时刻)。演示场景:s_intro.rs(冷开场、标题、结束语回顾)、s_idea.rs(基于说出词语构建的幻灯片)、s_figure.rs(带有圈注/标记/笔记/亮点和缩放的图片卡片)、s_quiz.rs(带有陷阱图章的mcq测验)。src/objs.rs:可重用对象(mcq、grid、token、vecbar、hbar、code_panel、chat_card、quote_card、axes/trace、vec_arrow、photo……)加上一个“本视频”部分:将每个视频的重复对象放在此处,以便每个场景都能一致地绘制它们。src/duck.rs:主持人精灵(脚的位置、根据语音包络的说话摆动、每个场景的位置:冷开场/测验/结束语中为大尺寸,其他情况下为右下角小尺寸)。没有精灵表示没有主持人。src/t3d.rs(可选):即时模式的立方体和用于张量/数组 3D 插图的View3。narration/:script.py(场景 → 节拍,测验中使用PAUSE)、tts.py(语音设置;查找 local-tts 的say.py)、build_vo.py(语音 + 逐行缓存 + 暂停塑造 + 速度 + faster-whisper 单词对齐 →audio/narration.wav、src/cues.rs、src/envelope.rs)、words.py(检查每个c.w(...)键、缺失的分发分支和剩余的占位符;生成 WORDS.md)、est_cues.py(在语音生成前提供暂定提示和静音轨道)、audit_vo.py/tts_try.py(发音审核)、make_srt.py(带有 DISPLAY 映射、OVERRIDE 和--review的字幕)、envelope.py、glitch.py(最终文件检查)。tools/:prep_figs.py(从figs/*.png生成src/figs.rs)、get_pet.py(下载主持人精灵)、font_metrics.py、make_demo_fig.py、lowprio.py(以空闲优先级运行任务)。media/:字体。只有媒体文件可以放在其顶层(include_media_dir!会对其他文件报 panic),因此许可证文本位于media/licenses/。HELPERS.md:给每个场景助手的简要说明(规则、文件映射、构建和检查循环)。STORYBOARD.md:演示的故事板,展示了助手所需的详细程度。THIRD_PARTY.md:字体、精灵、fframes 和 FFmpeg 许可证。
要求
- Rust(稳定版)和来自 crates.io 的 fframes 1.3.0(固定在
template/Cargo.toml中;检查其许可证条款是否适合您的用途)。 - FFmpeg 共享库(FFmpeg 7+ "shared" 构建)和 LLVM/libclang 用于 fframes 构建。
template/env.sh读取FFMPEG_DIR和LIBCLANG_PATH;在 Windows 上,还需将 FFmpeg 的bin目录添加到 PATH 中,以便 cargo 和构建后的二进制文件都能找到(如果缺少 DLL,通过管道运行时它会静默退出并返回 127)。 - Python 3.10+,包含
faster-whisper(单词对齐、审核)和numpy。 - local-tts 技能(同一插件)用于生成语音。GPU 能显著加速;所有功能也都能在 CPU 上运行。
- 主持人精灵(可选):来自 github.com/gennadi-kuzmin/awesome-codex-pets 的 Codex 宠物(192x208 单元格)。运行
python -I tools/get_pet.py --list,然后运行python -I tools/get_pet.py <pet-id>下载并将一个精灵切片到sprites/。该仓库的 MIT 许可证涵盖其代码;在发布视频前请检查每个宠物精灵的图片使用权利。选择一个明亮的(深色宠物在黑色板子上会消失)。如果没有精灵,则视频渲染时不会有主持人。
fframes 版本和官方技能
新视频使用 fframes 1.3.0。创建者的官方技能 fframes-video 涵盖了通用 API 并随着每个版本而变化,因此请阅读它以了解本技能未涵盖的内容:先看其 SKILL.md,然后是 references/api.md、audio.md、design.md 和 3d.md。使用 npx skills add https://fframes.studio -g -a claude-code -y 安装它(如果您的权限阻止安装,请让用户运行该命令);相同的文件位于 github.com/dmtrKovalenko/fframes 下的 skills/fframes-video/。本技能仅保留该风格特有的内容:外观、流程和下面的注意事项。当两者在渲染上意见不一致时,以下面的陷阱提示为准。
1.3 版本的新特性,值得使用:
- 3D 镜头(
fframes::three_d):请参阅下一节。 - 更清晰的检查:
frame 3s --crop x,y,w,h(以视频像素为单位的缩放裁剪,用于精细笔画和小标签)、frame --ids(勾勒并命名每个有id的元素)、strip 2s,5s,9s(并排显示选定时间帧)和inspect --pops(找出在一帧中弹出或弹入的东西;对主持人的眨眼进行分组)。--pops检查的是帧,而不是编码后的 mp4,因此仍需在最终文件上运行glitch.py。 - Lottie:功能
lottie,frame.play_lottie(ctx, "x.json", LottieOptions { .. })用于使用现成的动画图标。手绘工具包笔画仍然是默认的;仅在 Lottie 与白板外观匹配时才使用它。 include_media_dir!(pub struct M, "media", stereo)保持立体声音频文件的立体声特性。
白板视频中的 3D 镜头
仅在深度或移动相机是解释的一部分时才使用 3D:例如,需要从堆栈中提起一层的层叠、张量形状、内存层次结构、物理设备、损失曲面、倾斜的论文图表卡片。文字、标签、图表和箭头保持手绘 SVG。每个章节最多保留一两个 3D 时刻:视频仍然是白板风格。references/three_d_example.rs 是一个 4 秒的测试(一个旋转的层叠,其中有一层被提起,一个手写标签固定在上面,一个论文卡片在 3D 平面上以 svgr 绘制)。
fframes = { version = "=1.3.0", features = ["compile-time-svgtree", "cli", "3d", "wgpu"] }。3D 功能可与 CPU 帧渲染器一起使用:使用wgpu时,3D 在 GPU 上渲染并读回(120 帧 1080p:在 RTX 4070 笔记本电脑上约 1.4 秒,使用Renderer::cpu()约 4.2 秒)。当 GPU 繁忙时,将渲染器切换为.cpu()(示例读取FF_3D=cpu),其他一切不变。wgpu类型可能需要在 main.rs 中添加#![recursion_limit = "256"]。- 黑板外观:在工具包的
BG矩形上使用Background::Transparent,Material::shadow_catcher地面,ToneMapping::Neutral以保持工具包调色板真实,以及Material::standard(c).roughness(0.45).clearcoat(0.4)用于在缩略图尺寸下也能读懂的厚实物体。 - 3D 物体上的手写标签:
camera.project(scene.local_to_world(id, local), w, h)给出插图内部的像素坐标;加上插图的x/y偏移。在触发词处使用工具包绘制标签。 - 3D 环境中的论文图片:
ctx.render_svgr(svgr!(..), w, h)→ 在具有Material::unlit(0xffffff)的Geometry::plane上使用Texture::from_image(&img)。同样的路径可将 PNG 图片放置到卡片上。 - 移动的对象必须保持在其插图渲染器的盒子内,否则会在边缘被裁切。
- 在
new()中构建场景一次,然后为每一帧克隆并变换其姿态(请参阅官方3d.md)。 - 张量/数组可视化:即时模式效果很好。场景函数根据
t每一帧构建一个Vec<Cube>(位置是简单的算术运算,因此方块可以折叠、分裂、展开、虚化填充),使用一个共享的rounded_box几何体渲染一个子视图,并投影点用于手绘箭头。仅在前层上书写立方体数字,并跳过淡出立方体(alpha < 0.6)的标签,否则它们会透出来。带有 3D 的完整inspect速度较慢(5400 帧约需 10 分钟):请在后台运行它。 - 在整个相机移动期间,保持固定标签与所有物体清晰分离(在镜头开始和结束时检查静止帧),并在
shrink_aside完成后开始 3D 镜头,而不是在其间。
工作流程
- 研究:将来源资料整理到
research/paper_notes.md中:每个数字及其表格/页码,以及措辞上的危险点(百分比 vs 点数等)。提取论文的图片作为图像(figs/,视频中为白色卡片)。在屏幕上显示论文自己的图表和图片。 - 脚本(
narration/script.py):约 150 wpm,每个节拍一个句子,为语音拼写出来(“Swee Bench”、“T zero”、数字用单词拼写)。以最令人惊讶的数字开始冷开场 → 标题 + 论文卡片 → 路线图 → 章节 → 3-4 个测验(问题、选项 A-D、PAUSE、答案)→ 使用之前绘制的相同对象总结评价海报 → 附则 → 结束语。在语音生成后检查长度;修剪行或提高TEMPO(1.06 可行),而不是加快语速。- 测验是困难且准确的多选题(风格指南第 6 节):推理问题,四个选项,其中错误选项是真实的误解,只有一个可辩护的答案。编写
research/quiz_keys.md(每个选项都附带页码/表格引用,派生数字在 Python 中计算),并在生成语音前进行检查。 - 教学,而非总结。 从零开始构建每个想法,并使用真实数字进行示例运算。在引入每个术语的行中定义它,并将行话简化为日常事物(“节点只是一项工作”)。大多数节拍以连接词开头(“所以”、“现在”、“但是”),以便转折点听起来清晰。保持在约 150 wpm:绘图需要时间。
- 在使用每个符号之前正确介绍它;在使用它的行中重复一个简短的提醒。
- 让它听起来像人,而非 AI。 在写作前阅读
references/natural-narration.md,然后运行python -I scripts/aispeak_scan.py <project>/narration/script.py。在生成语音之前,修正分阶段的引子(“这是关键”)、非 X 而 Y 的重新框架、可引用的结尾和自问自答的问题。 - 避免冒号片段行(“首先:...”、“三个基准。”):语音会在那里停顿,下一行听起来会很突兀。场景的第一个词单独出现(“探测。”)可能会被吞掉:写成“接下来,探测。”。为“感谢观看!”分配自己的节拍。
- 测验是困难且准确的多选题(风格指南第 6 节):推理问题,四个选项,其中错误选项是真实的误解,只有一个可辩护的答案。编写
- 故事板(
STORYBOARD.md):每个场景,哪个元素在哪个触发词上出现,其大致位置 (x, y)、大小和颜色,哪个图片/裁剪,以及重复出现的对象和颜色含义。足够具体以实现,而不是设计。为标签区域(左上角)和主持人区域(右下角)预留空间。 - 语音:
narration/build_vo.py通过 local-tts 技能的say.py生成语音,查找路径依次为LOCAL_TTS_SAY、~/.claude/skills/local-tts/和~/.claude/plugins/**。GPU 繁忙?使用GGML_BACKEND=CPU和WHISPER_DEVICE=cpu。按行缓存;修改一行会强制重新生成。shape()根据剪辑前的标点符号限制每个剪辑内的静音长度(无标点 0.14 秒,,0.24 秒,:;0.3 秒,.?!0.42 秒),行间为 0.5 秒(问号后为 0.7 秒)。在绘制场景前审核语音:audit_vo.py不使用脚本作为提示转录每个剪辑(build_vo 的提示式 Whisper 会隐藏误读),并将其与脚本进行差异比较。忽略美式拼写和同音词;修复真正的误读,使用tts_try.py测试修复(在整个句子中测试:一个名字单独很好,但在句子中间可能会出错)。已知的误读记录在 local-tts 技能的陷阱中。每次重新生成语音后重新运行审核(Qwen 偶尔会重复一个单词,如“the the”)。语音尚未准备好?est_cues.py会生成暂定提示和静音轨道,当 build_vo.py 覆盖两者时,场景会自动重新计时。 - 工具包 + 1-2 个示例场景由您绘制并以完整尺寸检查,以便助手有一个质量标准。
- 将场景组分发给并行子代理(小巧、快速的模型,配合高推理努力度,在指令紧凑时表现良好;仅示例场景需要更强的模型)。首先将重复对象放入
objs.rs并填写HELPERS.md,使用绝对路径指向research/。将项目复制到每个代理的work/<group>/中(跳过渲染和语音缓存),并将目标目录硬链接(cp -al target work/g/target,或每个助手使用CARGO_TARGET_DIR;然后删除该副本自身的explainer程序包构件)以节省磁盘和构建时间。每个助手只编辑其src/s_<group>.rs,构建,运行words.py和inspect,检查缩略图和完整帧。通过复制其s_*.rs文件来合并;首先对其他文件进行差异比较。- 保持助手速度。 构建是瓶颈:保持
[profile.release] incremental = true+codegen-units = 256(重建时间从 ~50 秒缩短到 ~25 秒),并且同时最多运行约 4 个助手;将后面的组分配给先完成的人。一个组 = 2 个权重相似的场景;将测验或密集的场景拆分出来。预算:每个场景最多 3 轮构建和查看,一个 12 帧的缩略图加上@end,然后列出剩余的疑问而不是润色。每个助手进行一轮有针对性的修复成本较低。 - 验证他们的事实:对照 paper_notes 检查屏幕上每个数字,并计算每个示例(助手可能发明数字、进位错误,或者演示中泄露了后续测验的答案)。检查图片是否与旁白匹配。
- 自己审查每个助手的缩略图和帧(他们自己的检查图像可能已过时),然后发送具体的修复指令。他们常见的错误是将每个阶段都挤在屏幕上半部分,使用小字号:给出 Y 轴范围和像素值...
- 保持助手速度。 构建是瓶颈:保持