make-video 是做什么的?
根据提示词生成一部带旁白的影片。每一帧都是时间 t 的纯函数,在画布(@napi-rs/canvas)上绘制,并利用 ffmpeg 编码。语音由本地 Kokoro 模型生成。音乐通过 Python 合成。每个画面都精确对应旁白中提及该画面的单词的时刻。
流程是固定的: 提示词 → 故事板(真实语音、真实音乐、每个场景一帧真实画面)→ 用户在故事板上迭代 → 完整渲染。在用户批准故事板之前,不要渲染完整影片。每一步都采样真实帧,在展示之前修正你看到的问题。
下面的 <skill> 指代存放此 SKILL.md 的文件夹。
要求
node 20+、ffmpeg、uv(用于运行 Python 脚本并安装其依赖)以及 python3。运行 ./make.sh setup 会检查这些依赖。Kokoro 模型(约 115 MB)在首次运行语音功能时下载到 ~/.cache/make-video/models。字体不随工具提供:参见 references/fonts.md。
1. 理解影片(从提示词出发)
在写任何代码之前,先阅读影片的内容:PR、仓库、文档、应用、公告。找出影片可以展示的真实元素:真实的屏幕截图、真实的代码、真实的输出。确定这些内容,只对你无法确认的信息向用户提问:
- 类型和时长。 功能简介或公告:30–75 秒,6–10 个场景,展示真实应用界面。解说视频:2–6 分钟,包含章节标题卡片、图表和代码。经验法则:每秒约 2.5 个单词的旁白。
- 观众和最终目标:他们必须知道或做什么的一件事。
- 视觉风格。
theme.mjs中的ink调色板(接近黑色,红色强调色)或navy(深蓝、天蓝和琥珀色),或者产品自身的颜色和字体。 - 音乐风格。
pop(明亮、欢快)或chip(安静芯片音乐),或none。
2. 创建项目
<skill>/scripts/new-project.sh ~/Developer/<主题>-video <主题>-video
这会复制 <skill>/template(一个可用的 30 秒示例影片)并运行 npm install。获取字体(references/fonts.md)。项目是独立的。编辑以下文件:
| 文件 | 作用 |
|---|---|
video.json | 脚本:场景、旁白行、提示、时间码、音乐、故事板简要说明 |
scenes/*.mjs | 每个场景 ID 对应的一个绘制函数 |
theme.mjs | 调色板、字体、背景 |
music.py | 当默认设置不合适时,用于修改配乐(和弦、主旋律、乐器) |
shots/plan.mjs | 需要捕获的真实应用截图计划,当影片展示应用时 |
不要编辑 timeline.json。timeline.py 会生成它。
3. 编写脚本(video.json)
先阅读 references/script.md。简而言之:每个场景一个核心想法,使用简短平实的句子,以吸引人的开头开始,以下一步行动结束。一行可以是一个字符串,或者当字幕和发音形式不同时使用 {"text", "say"}(例如 "video.json" 发音为 "video dot jason")。提示词(cue) 用于指定某个画面落在哪个单词上:{"label": "badge", "at": "badge", "sound": "chime"}。为每个重要的出现设置提示词。填写 brief(导语、方法、未解决的问题);故事板会显示它。
4. 绘制场景(scenes/*.mjs)
阅读 references/drawing.md(场景 API、辅助函数、布局和运动规则)。每个场景接收 (ctx, t, S)。让每个元素在 S.cue(label) 或 S.w('word') 时出现,并通过 S.tout 离开。使用真实素材:
- 应用界面: 使用
shots/capture.mjs捕获真实 UI,并使用screens.mjs(相机、光标、圆环)展示。参见references/screens.md。 - 代码:
code.mjs按行号读取真实文件,因此引用的代码不会出错。 - 程序输出: 运行真实程序并绘制其真实输出。不要绘制你未亲眼见过的输出。
边画边采样。 在进入下一个场景之前,为每个场景运行 ./make.sh scene <id> 并查看 out/sheet.jpg。对于每个棘手的移动或过渡,运行 ./make.sh clip A B 并观看 out/clip.mp4。references/review.md 中有检查清单。
5. 故事板:用户在此迭代
./make.sh storyboard
此操作依次执行:语音 → 时间线 → 音乐 → 音频混合 → 每个场景一帧 → storyboard.html:一个自包含的页面,包含真实的语音和音乐混音、每个场景的一帧画面、标注了每个提示词的脚本、时间码和简要说明。播放时,它会高亮显示当前场景和旁白行。
在展示之前,查看 out/board/ 中的每一帧画面,并修正错误。然后将页面交给用户。如果你的工具可以发布 HTML 页面或工件,请发布 storyboard.html 并分享链接。否则,给出文件路径,让用户在浏览器中打开。
然后与用户一起迭代。每次修改都小而快:编辑 video.json 中的一行(只有修改过的行会重新生成语音)、移动提示词、改变某个场景的能量、重新调整样式、重绘某个场景。然后再次运行 ./make.sh storyboard。保持 brief 中的未解决问题最新。一直循环,直到用户批准故事板。
6. 完整渲染
仅在用户批准后:
./make.sh film # 或:./make.sh film --blur 4 (运动模糊,约慢 4 倍)
这会生成 out/<名称>.mp4(1920×1080,60 fps,AAC,响度 −16 LUFS)、out/<名称>.srt 和 out/<名称>.vtt。然后检查真实输出,而不是代码(参见 references/review.md,“最终检查”):从编码后的 MP4 中提取帧,确认时长和流信息,并在修改过的点聆听混音。运行 python3 storyboard.py --final 使故事板页面包含完成的影片。交付 MP4、字幕和故事板。如果影片是公告,则提供一个简短的发布文案,使用相同的脚本编写。
命令
| 命令 | 功能 |
|---|---|
./make.sh storyboard | 语音、时间线、音乐、混音、故事板帧、storyboard.html |
./make.sh scene ID [0.3,0.6,0.9] | 一个场景在指定时刻的静止帧,加上 out/sheet.jpg |
./make.sh samples [24] | 在整个影片中均匀分布的静止帧,加上 out/sheet.jpg |
./make.sh stills 3,20.5 | 在精确秒数的静止帧,加上 out/sheet.jpg |
./make.sh clip A B | out/clip.mp4:从 A 秒到 B 秒的真实影片片段,带声音 |
./make.sh voice / music / timeline | 只执行单个步骤 |
./make.sh film [--blur N] | 完整渲染和混音 |
uv run tts.py --voices | 列出可用的 Kokoro 语音 |
参考文档
references/script.md:如何编写旁白,以及video.json的完整说明references/drawing.md:场景 API、lib.mjs辅助函数、布局、运动、场景模式references/screens.md:捕获真实应用屏幕并在其上移动镜头references/audio.md:语音、音乐风格、提示音、混音、额外音频references/review.md:如何采样、精修检查清单、最终检查references/fonts.md:获取字体的途径