关键词 → 一期像素风口播动画
用户给一个关键词,按第 0~5 步一口气做完。中途不等用户确认;每步做完用一两句话同步进度,最后在 Studio 里交给用户预览。不导出成片,不提交 git,除非用户另外要求。
动手前先读工程根目录的 CLAUDE.md 和 src/library/README.md。所有 npm、npx、node 命令前都要先执行 export NODE_OPTIONS=--max-old-space-size=4096。
依赖(开源版说明)
这个工作流原本串起了作者的几个私人 Skill,仓库里没有带。换成你自己的工具即可,接口只要求「输入文本 / 音频,输出文件」:
| 步骤 | 作者用的私人 Skill | 换成 |
|---|---|---|
| 写口播稿 | weilanx-creator-spoken-script(作者的写稿风格) | 自己写,或让 Agent 按「强钩子开头、句子连贯、不用冒号括号」写 |
| 配音 | weilanx-doubao-voice-clone(豆包复刻音色) | 任何 TTS 或真人录音,输出 wav / mp3 |
| 字幕 | weilanx-doubao-voice-srt(豆包录音识别) | 任何语音识别工具,输出 SRT |
字幕导入、出片、导出这些工程内的步骤都不依赖它们。
0. 定期数和目录
- 看
src/episodes/里最大的期号,新一期用下一个号。作品 ID 写成epNN-英文短名,比如ep06-context,下面统一记作<期>。 - 如果
materials/里已经有同主题的目录(例如之前写过稿子),就沿用它,不要重复建。 - 素材放
materials/<期>/,代码放src/episodes/<期>/,音频放public/audio/<期>/。 - 选题候选池在
materials/选题候选池.md。用户说“从候选池挑一个”时,优先选 ⭐ 的;开工时把那一行改成 🎬,导出后改成 ✅ 并填上期号。用户给的关键词不在池子里,就在“已做”表里补一行。
1. 写口播稿
调用 weilanx-creator-spoken-script Skill,把关键词交给它。
- 用户没说时长,默认成片 1 分半到 2 分钟,也就是 600~800 字。
- 稿子存到
materials/<期>/口播稿.txt。只存能直接念的正文,参考来源这类不念的内容不能写进去。 - 在回复里贴出全文,并说明字数,以及需要用户核对的事实。然后直接进入下一步。
2. 配音并加速 1.2 倍
调用 weilanx-doubao-voice-clone Skill。
python3 scripts/voice.py status确认音色可用。- 合成:
python3 scripts/voice.py synthesize --text-file <工程>/materials/<期>/口播稿.txt --output <工程>/materials/<期>/<期>-口播-中文标准版.mp3 - 加速 1.2 倍,保持音高,输出 48kHz 16-bit:
ffmpeg -i materials/<期>/<期>-口播-中文标准版.mp3 -filter:a atempo=1.2 -ar 48000 -c:a pcm_s16le materials/<期>/<期>-口播-1.2x.wav
3. 转 SRT
调用 weilanx-doubao-voice-srt Skill,识别已经加速的 <期>-口播-1.2x.wav,不要再加速一次。
- 用口播稿校对用字。每行一个完整意思,6~16 字,去掉标点。
- 输出
materials/<期>/字幕.srt和字幕稿.md,文件名固定用这两个,导出时会用到字幕稿。 - 识别结果和稿子对不上的地方,通常是 TTS 读错了,记下来,最后告诉用户去听。
4. 建工程并剪辑
照 CLAUDE.md 的“做新一期的流程”来做。画面一律竖屏 3:4(1080×1440),首帧放封面。 参照 ep06 的竖屏版:src/episodes/ep06-context/Ep06ContextTall.tsx(配置)、tall/part1.tsx、tall/part2.tsx(场景)、tall/Cover.tsx(封面)。新一期不用再做横屏版,场景直接放在 scenes/ 下。
- 人声:先用
ebur128测响度,再用volume=<增益>dB,alimiter=limit=0.8:level=false调到 −16 LUFS 左右(±0.5 以内),转成 48kHz 立体声 16-bit,存为public/audio/<期>/voice.wav。 - 字幕:
npm run cues -- materials/<期>/字幕.srt src/episodes/<期>/cues.json。cues.ts里的VOICE_SECONDS取人声时长加 0.3~0.5 秒,而且必须不短于最后一条字幕的结束时间。 - 配乐:新建
audio/episodes/<期>.mjs写段落表,只跑node audio/episodes/<期>.mjs,不跑npm run audio,免得把其他期重新生成一遍。 - 场景:新建
src/episodes/<期>/,包括Ep*.tsx、cues.ts、scenes/part1.tsx、part2.tsx、scenes/Cover.tsx、index.ts。- 版式:
w: 1080, h: 1440,stage: {top: 120, h: 1080},subY: 1250,chapter: {y: 34, align: 'center'},look: 'sticker',keywords放本期要在字幕里高亮的词。舞台是 1080×1080 的正方形,内容上下排列,字号比横屏大:大标题 80~140,便签 40 左右,正文不小于 34。 - 风格:只有 CC 和 AI 小人是像素风(根组件包
<CharStyle.Provider value="pixel">),字体、卡片、背景都用手绘贴纸风,不要用像素字体。 - A-roll 用
HostTall(竖屏演播室,主持人居中,上方 960×360 放标题);B-roll 里主持人用PiP放在右下角:{x: 950, y: 1050, s: 0.7}。 - 钩子场景要把钩子画出来,比如测验、反差、宣言;过渡和收尾用 A-roll 演播室
Host;正文用 B-roll,主持人PiP站在右下角。 - 每个概念都要配一个看得懂的图解,关键时刻加强调效果:
Burst、FocusLines、jolt、红色贴纸大字。每个场景都要配音效。 - 皮肤只用
headphones、santa、cowboy、chef、detective,而且场景之间要轮换。CC 没有嘴。 - 示意用的数字要在画面上标“示意”,不能编造真实数据。
- 版式:
- 封面:写
scenes/Cover.tsx,在配置里挂cover: {C: 封面组件, frames: 第一句字幕开始帧 − 5},这样封面会在前几帧整屏显示,再用 6 帧淡出,赶在第一句口播画面出来之前。版式照ep06-context/tall/Cover.tsx:- 左上角斜贴标签:“一分钟看懂 AI”,不写期数
- 大标题两行:第一行白字,第二行更大的红字,放钩子里的问题
- 核心词横幅放到最大:居中黄色横幅,中文 80 号 + 英文 120 号白色描边大字,比如“上下文 context”“智能体 Agent”
- 中间放本期最有代表性的画面:像素 AI 小人、CC,加上本期的道具
- 底部黑色横条写一句“这期能带走什么”,比如“3 个做法,让它重新变聪明”
- 渲染第 0 帧另存一张图:
npx remotion still src/index.ts <期> materials/<期>/封面-3x4.png --frame=0
- 注册和测试:在
src/Root.tsx注册作品,仿照tests/episodes/ep05-token.test.ts加测试,然后npm run typecheck和npm test都要通过。 - 抽帧自查:第 0 帧(封面)和封面淡出的那几帧必看,每个场景至少抽一帧,关键动画的中间状态也要抽,用
ffmpeg hstack/vstack拼成图,看有没有重叠、越界、出现得太晚。发现问题就修,修完再抽帧确认。
容易踩的坑
cw(n, '词')如果挂在句尾的词上,贴纸刚出来场景就切走了。笑点要挂在更早的词上,或者让下一个场景晚几帧开始。- 有章节标签的场景,舞台上的标题要从
y ≥ 30开始,否则会压住标签;右下角x ≥ 820、y ≥ 860的区域留给主持人。 - 竖屏舞台只有 1080 宽,两个窗口不要左右并排,改成上下排,或者旧的滑出去、新的滑进来。
- 这台机器的 shell 是 zsh,
for fr in $FR不会按空格拆开,要用bash -c '…'。remotion still一次只渲一帧、按顺序跑,同时跑太多个会卡死。 - 不要对整个文件跑 prettier,工程没有 prettier 配置,会把整个文件重排一遍。
$TMPDIR里的识别中间文件可能被系统清掉,需要时重新跑识别。- 不要在
src/library/里 importsrc/episodes/。新做的组件如果以后还能用,挪进素材库,并更新README.md。
5. 写发布文案,打开 Studio 交给用户
- 调用
dbs-xhs-titleSkill,按本期内容给出标题:主标题 1 个、备选 2 个,每个都注明用的是公式库里的第几号公式,标题含标点不超过 20 字。 - 描述照
out/ep07-agent/发布文案.md的写法:第一句用钩子,然后是本期的要点清单和观众能用的做法,最后一行是话题标签。数据只写口播里讲过的。 - 存为
materials/<期>/发布文案.md,导出时会自动复制到out/<期>/。 - 用
lsof -i :3000 -sTCP:LISTEN看 Studio 有没有在跑。在跑就直接用,它会自动热更新;没在跑就在后台启动npm run studio。 - 把预览地址
http://localhost:3000/<期>给用户,不要执行npm run export。 - 最后汇报:
- 口播字数和时长
- 人声响度
- 字幕条数
- 封面:第 0 帧的样子和
封面-3x4.png的路径 - 发布文案:主标题和两个备选
- 场景表(每个场景的时间和画面内容)
- 需要用户确认的事实、TTS 可能读错的地方、示意数据
- 提醒用户:听感只能靠用户自己听
- 用户确认之后,再按第 6 步导出。
6. 导出(用户确认之后)
npm run export -- <期> 会生成:
out/<期>/
├── <期>.mp4 成片,音轨已按分轨重新混音限幅
├── stems/ voice.wav、bgm.wav、sfx.wav
├── 封面-3x4.png 首帧封面的单独图片,平台要单独上传封面时用
├── 字幕稿.md 完整中文字幕稿
└── 发布文案.md 标题(带公式编号)、备选标题、描述、话题
- 封面图、字幕稿和发布文案由
scripts/export.sh从materials/<期>/自动复制过去。所以第 3 步转字幕时,文件名必须是字幕稿.md。如果中途重做过字幕,最新版也要叫这个名字,旧版改名为字幕稿-v1.md等。 - 导出后检查:成片时长、1080×1440、首帧是封面、整体响度约 −16 LUFS、峰值低于 −1 dBFS,
封面-3x4.png、字幕稿.md、发布文案.md都已在out/<期>/里。 - 同时把成片复制一份到
materials/<期>/。