35 个镜头约 15 美元:拆开「古人说唱 Battle」这个 Claude Code Skill
一句「做一期 曹操 vs 刘备」,Claude Code 带你做完一条一分半左右的古人说唱对决——真正值得抄的不是视频,是它怎么把一个多工具、易翻车的流程写成 Skill。

这个 Skill 叫「古人说唱 Battle」(ancient-rap-battle),作者是硅基废话(GitHub 仓库 10291124jcjc-dotcom/ancient-rap-battle,首个提交 10 月 13 日),MIT 协议。我把仓库 clone 下来(截至 2026-10-17 的提交),读完了 SKILL.md、15 个脚本和 6 份参考文档。下面只讲仓库里真有的东西。
先纠正一个印象:H3 现在是备选
仓库 README 展示的第一期成片《周瑜 vs 诸葛亮》走的是 MiniMax H3 路线(SKILL.md 里是 35 条镜头模板、逐句生成、自动检查口型),README 写明视频生成花了约 16 美元。但当前仓库的 README 和 SKILL.md 把即梦 Seedance 2.5 网页版设成了默认路线,H3 写在「可选」一节,脚本(make_clips.py / h3run.py / qa.py)都还在。两条路线共用前后段,下文都会讲。
流水线:9 步,每步落一个文件
| 步骤 | 谁做 | 脚本 / 文档 | 产物 |
|---|---|---|---|
| 1 写词 | Claude 写,你确认 | lyrics-guide.md | episode.json、01_歌词.md |
| 2 做歌 | 你在 Suno | suno.md | song.mp3 |
| 3 分析剪歌 | 自动 | analyze_song.py / retrim.py | 音乐_最终.wav、字幕.srt、work/lines.json |
| 4 定妆图 | 你在 Midjourney | midjourney.md | refs/ 下 9 张图 |
| 5 分镜与提示词 | 自动 | seedance_packs.py(H3:make_clips.py) | 11 个素材包(H3:clips.json、edl.json、分镜表.md) |
| 6 生成 | 你在即梦(H3:脚本调 API) | seedance.md / h3run.py | 每段 mp4 |
| 7 对口型 | 自动 | seedance_align.py(H3:qa.py) | preview/ 配音乐小样 |
| 8 拼接包装 | 自动 | seedance_assemble.py / package.py | final/成片.mp4 |
| 9 封面文案 | 自动 | cover.py | 竖版 3:4 + 横版 16:9 |
状态全在一个期数文件夹里:episode.json 存歌词、注释、人设、镜头;work/ 下是机器状态——lines.json(每句起止秒)、grid.json(BPM、保留区间)、H3 的 picks.json(每条采用哪个 take)和 shifts.json(画面要提前几秒)。脚本之间不传参,只读写这些文件,所以哪一步坏了就从哪一步重跑。
人只在 4 个地方出手,因为机器替不了
H3 路线下人只动 4 次:定歌词、在 Suno 做歌、在 Midjourney 出图、看小样。前三个是账号和审美——Skill 不碰你的 Suno/MJ 账号,只把每一栏填好给你抄。第四个是口型:SKILL.md 原话是「用户的眼睛是标准」。H3 还有个隐形关口:h3run.py --estimate 先报价,你点头才提交。Seedance 路线多一步:你得在即梦网页上传、生成、下载。
切歌:一句歌词 = 一个小节
analyze_song.py 是整个 Skill 的地基,7 步全自动:
- demucs 分出人声和伴奏;
- faster-whisper(large-v3-turbo,CPU int8)给人声出逐字时间戳,识别文字多是同音字,只用时间;
- 对伴奏做 onset 能量谱、在 70–120 BPM 里搜出节拍网格;
- 用前 4 句歌词去模糊匹配识别文本,定位每段主歌起点,之后一句一小节往后排;
- 只认本小节 −0.13 秒以后的字,跳过上一句拖过来的尾音(否则字幕会早 0.4–0.8 秒);
- 按小节剪短前奏和片尾,必要时用 rubberband 给两人各移 ±1 半音拉开声线;
- 写出 lines.json 和字幕.srt。
Suno 爱在间奏口号后自己多唱一句,这时用 retrim.py --keep 手动指定保留段,规则是「保留 Suno 原样的过渡,在相隔整数小节的同一位置跳过去」,不留静音。
H3 调用和口型检查:比的是声音,不是嘴
h3run.py 只用标准库:先 /v1/files/upload 传参考图和这一句的人声(按 sha256 缓存 6 天),再 POST /v2/video_generation,每 15 秒轮询一次。请求体很短:
{"model": "MiniMax-H3", "content": [...], "resolution": "768P", "duration": 5, "ratio": "16:9"}
Key 只从环境变量 MINIMAX_API_KEY 读,10 路并发、间隔 8 秒提交,一条失败不影响其他条。
口型检查的思路很巧:H3 会照它输出的音轨对口型,所以 qa.py 只需比较成片音轨和你发过去的人声是不是同一段。它取 10 毫秒对数能量包络,在 −0.2 到 +0.6 秒里找最佳偏移,相关系数 ≥ 0.85 且一直没漂移才算过;过了就自动写进 picks.json,晚放的秒数写进 shifts.json。不过就提示「re-roll」。lipcheck.py 用 MediaPipe 量嘴部开合,但文档写明只作参考:有一次按它挪了 0.58 秒反而错了。
Seedance 路线换了解法:提示词里写死「0.30–1.48 秒唱『那年我在宛城』」这种半句时间;生成后 seedance_align.py 识别成片逐字时间,按拼音和原人声配对,每个镜头拟合「歌曲时间 = 速率 × 片内时间 + 偏移」,速率限 ±20%。
把每一次翻车写成默认值,下一期就不用再翻一次——这个 Skill 的「智能」,一大半是踩坑记录。
坑是怎么「写死」的
作者说的四个坑——AI 偷偷重唱、镜头太远、台上空、群演抢戏——分三层落地:
- 提示词常量:
make_clips.py里的SOUND要求「Audio 1 原样,不重唱不改速」;FRAMING写「NOT a wide shot」;观众镜头写「The circle is never empty」。 - 代码结构:一条只给一句歌词;近景改用从三视图裁出的半身图(全身图会让 H3 拍远景);气氛组只排 3 次;同一镜头不连放。
- 文档表格:
references/pitfalls.md按「坑 / 表现 / 解决」列了 30 多条,标题就叫「都已写进脚本的默认规则」。
剪辑、字幕、封面:全是 ffmpeg + Pillow
H3 的 assemble.py 按 edl.json 把每条摆到歌曲时间上,不够长就定格最后一帧,绝不往前挪(挪了口型就错);没生成的条用深灰占位,节奏先看得见。package.py 做调色 B(压高光、降饱和、锐化、加颗粒,去 AI 蜡感)、金色 (255,228,92) 字幕、每句下面一行史料注释、名字卡、片尾提问、水印;文字全部用 Pillow 画成透明 PNG 再叠,因为 ffmpeg drawtext 常缺 fontconfig 崩溃。cover.py 取两人对峙帧,出竖版 1080×1440 和横版 16:9。
成本:15 美元是怎么算出来的
| 项目 | 仓库里的数 |
|---|---|
| H3 单价 | 768P $0.08/秒,2K $0.13/秒(h3run.py) |
| 一期素材 | 35 条,约 180 秒(27 条说唱各 5 秒 + 8 条开场/观众/反应等镜头,按 16+18 句模板) |
| 视频生成 | 768P 约 $14.4;README 记第一期视频生成约 $16 |
| 不含 | Suno、Midjourney 订阅;Seedance 路线按即梦积分 |
想试一下:5 步
- 准备:Claude Code、Python 3.9+、带 rubberband 的 ffmpeg;
pip install demucs faster-whisper pypinyin soundfile scipy numpy pillow(首次约 2GB 模型)。 - 账号:Suno、Midjourney,外加即梦会员或 MiniMax API Key(
export MINIMAX_API_KEY=...,别写进文件)。 - 安装:
git clone https://github.com/10291124jcjc-dotcom/ancient-rap-battle.git ~/.claude/skills/ancient-rap-battle - 在 Claude Code 里说「做一期 岳飞 vs 秦桧」,它会先跑
setup_check.py。 - 走 H3 时先让它跑
h3run.py --estimate看报价,再--all。
常见坑:Windows 上 python3 是微软商店占位,要用 python;Suno 免费版的歌不能商用;史料注释是 AI 凭记忆写的,发布前要核原文;红线是不做近现代政治人物和在世真人。
完成标准:analyze_song 的 line check 里 32 句都唱到;preview 小样你看着嘴对得上;final/ 出成片、cover/ 出两张封面,片头「AI 生成 仅供娱乐」保留。
写自己的 Skill,抄这 5 条
- 文件即状态:一个工作区 + 一个 JSON 设定,脚本各自读写,可断点重跑。
- 人做判断,机器做测量:审美和账号留给人,时间戳、偏移、报价全交给脚本。
- 先报价再花钱:
--estimate/--dry-run,付费 API 必备。 - 自动验收要可解释:qa.py 比音轨相关系数,阈值写死,结论只有「采用 / 重抽」。
- 踩坑表 + 默认值:每个坑写成提示词常量或代码规则,再在文档里留一行原因。
最后
不做视频也值得读一遍 references/pitfalls.md 和 scripts/qa.py,两个文件加起来不到 7KB,是这套 Skill 最值钱的部分。