视频自动化流水线
把视频生产从手工活变成流水线。你只给两样东西——选题和素材,剩下四环自动跑完:
选题 + 素材
│
▼
[想] 脚本分镜 ──► script.json
│ ⛔ 停下等用户确认(硬关卡)
▼
[说] AI 配音 ──► narration.json → voice.wav + timings.json
│
▼
[动] 动态画面 ──► src/**(Remotion)→ 预览
│
▼
[字] 字幕对齐 ──► captions.json / .srt → 烧入
│
▼
验收(三处时长一致)──► 成片 MP4 + SRT
核心设计:四个环节通过文件交接,不通过记忆。因此任一环都能单独重跑,不用从头再来。
一、何时使用
- 用户给出选题 / 文案 / 零散素材,想要一条成品短视频,不想手工在剪辑软件里倒腾
- 用户说「自动做条视频」「快速出片」「脚本配音画面字幕一条龙」「批量出片」
- 需要可复用、可重跑、参数可调的批量视频生产时
调用示例(照说即可)
选题:如何做好一人OPC,帮我做成一条竖屏短视频
把这个脚本做成视频,用男声、语速快一点,横屏
帮我把这段文案配上音、烧上字幕,输出 MP4 和 SRT
二、参数:默认可用,按需覆盖
所有参数都有默认值,不填任何参数也能跑通整条流水线。 需要调整时,用下面三种方式之一即可。
覆盖优先级(高 → 低)
| 层级 | 位置 | 用途 |
|---|---|---|
| 1 | CLI 参数(--voice / --speed / --set …) |
一次性临时调整 |
| 2 | 工程内 pipeline.config.json |
本工程的固定设定,随工程走 |
| 3 | 技能默认 config/defaults.json |
兜底默认值 |
> 想在任意字段上覆盖但没找到对应 CLI 参数?用 --set 点号路径=值,例如
> --set audio.bitrate=256k、--set caption.bottomPx=420、--set timeline.gapSecBetweenShots=0.6。
> 用 pipeline.py params 可打印合并后的最终参数,确认覆盖是否生效。
常用可调参数速查
| 想要的效果 | CLI 写法 | 默认值 |
|---|---|---|
| 换音色 | --voice Tingting / --voice <ElevenLabs voice_id> |
Tingting(本地)/ 21m00Tcm4TlvDq8ikWAM(EL) |
| 调语速 | --speed 1.1(0.7–1.2 保守) |
1.0 |
| 指定引擎 | --engine elevenlabs\|edge\|say\|espeak |
auto |
| 配音情绪·稳 | --stability 0.7 |
0.5 |
| 配音情绪·风格强度 | --style 0.4 |
0.0 |
| 配音相似度 | --similarity 0.85 |
0.75 |
| 换画幅 | --aspect 16:9(9:16 / 16:9 / 1:1 / 4:5) |
9:16 |
| 换帧率 | --fps 60 |
30 |
| 字幕字号 | --caption-size 64 |
56 |
| 关键词高亮色 | --highlight-color '#00E5FF' |
#FFD400 |
| 句间/镜间停顿 | --set timeline.gapSecBetweenShots=0.6 |
0.42 |
| 音频码率 | --set audio.bitrate=256k |
192k |
完整参数表(含每个字段的含义、取值范围、引擎差异)见 references/parameters.md。
三、分步 SOP
第 1 步|想(脚本分镜)—— 产出后停下确认
- 问清楚(最多 1 个最关键的问题:时长?横屏竖屏?平台?风格?);信息够就直接写。
- 按
references/pipeline-contract.md的字段定义写script.json,结构参考templates/script.json:
每镜要有narration(口播文案)、visual(画面描述)、visualType、keywords(高亮词)、designDurationSec。 - 同时给人读的分镜表(钩子 → 结构 → 收尾)+ 字幕样式令牌,一起交付。
- 停在确认关卡:明说「确认后我就按 说 → 动 → 字 一路跑完成片」。未获确认不得进入下一步。
# 需要脚手架时
python3 scripts/pipeline.py init --project ./my-video --title "视频标题"
第 2 步|说(配音 + 时间轴)
python3 scripts/pipeline.py voice --project ./my-video # 默认参数
python3 scripts/pipeline.py voice --project ./my-video --voice Tingting --speed 1.05
python3 scripts/pipeline.py voice --project ./my-video --engine elevenlabs --stability 0.65 --style 0.3
这一步脚本自动完成:按语义断句 → 逐句合成 → 实测每句时长 → 反解时间轴 → 拼整轨 voice.wav → 写 timings.json。
- 断句按标点与语义(强标点切分、过长按弱标点二次切、过短并入上句),不按字数硬切
- 时间轴由音频实测长度算出,禁止手填、禁止变速凑画面
- 已有
narration.json会复用;要按新文案重新断句加--rebuild-narration - 抽听自检:至少听首句、最长句、末句,确认没截断、没怪读法
第 3 步|动(动态画面)
用 Remotion 按 timings.json 搭画面:每镜一个 Sequence,镜头时长按 timings.json 的 shots 反解(配音多长画面就多长)。
python3 scripts/pipeline.py frames --project ./my-video # 生成 src/data.ts 数据源
frames 会产出含 FPS / WIDTH / HEIGHT / TOTAL_FRAMES / AUDIO_SRC / LINES / SHOTS / CAPTION_STYLE 的 TypeScript 数据模块,直接给 Remotion 合成读。整轨音轨用单个 <Audio> 挂上,按绝对帧位置对轴。
先起 Studio 预览让用户看片,确认后再渲染 —— 这是默认动作,不要闷头渲染。
第 4 步|字(字幕对齐)
python3 scripts/pipeline.py captions --project ./my-video
python3 scripts/pipeline.py captions --project ./my-video --caption-size 64 --highlight-color '#00E5FF'
- 对齐依据是音频时间戳:每条字幕窗口起点 == 该句配音起音点(逐帧相等),不靠估算
- 断句沿用「说」环节的语义断句,一字不改
- 样式令牌全局唯一、全片一致;关键词从
script.json的keywords里取,只高亮真正出现在本句的词 - 输出
captions.json(供烧入)+out/video.srt(独立字幕文件)
第 5 步|验收与交付
python3 scripts/pipeline.py check --project ./my-video # 自动从 src/data.ts 读主合成时长
python3 scripts/pipeline.py check --project ./my-video --frames 2330
三个数必须相等,不等不许渲染:
音轨时长 × fps == timings.total == 主合成 durationInFrames
通过后渲染并交付:成片 MP4(H.264 + AAC) + SRT + 配置卡(音色/语速/引擎、字幕样式、画幅与时长、是否降级)。
四、脚本速查
| 用途 | 命令 |
|---|---|
| 初始化工程 | python3 scripts/pipeline.py init --project ./my-video --title "标题" |
| 看最终参数(排查覆盖) | python3 scripts/pipeline.py params --project ./my-video |
| 配音 + 生成时间轴 | python3 scripts/pipeline.py voice --project ./my-video [--voice X --speed 1.05] |
| 生成字幕 | python3 scripts/pipeline.py captions --project ./my-video |
| 生成 Remotion 数据源 | python3 scripts/pipeline.py frames --project ./my-video |
| 渲染前验收 | python3 scripts/pipeline.py check --project ./my-video |
依赖:Python 3.9+ 与 ffmpeg/ffprobe(必需)。ffmpeg 不在 PATH 时用环境变量指定:
export FFMPEG_BIN=/path/to/ffmpeg/bin # 目录,或直接给可执行文件路径
Edge TTS 可选增强:pip install edge-tts(装了就在 auto 里优先于系统 TTS)。
五、执行铁律
- 脚本先行、确认后跑 ——
script.json未获用户确认,不进「说/动/字」,不建工程、不渲染。
「确认 / 可以 / 开始 / 做吧」才算确认;「嗯 / 还行」要再确认一次。 - 单一源头 —— 后三环一律读
script.json,不允许中途各写各的文案,否则音画字必然对不上。 - 时间轴是算出来的 ——
timings.json由「说」环节生成。换音色、改语速、改文案后必须重跑voice,否则时长变了时间轴没变,立刻错位。 - 长度靠改文案,不靠变速 —— 如果必须大幅加速才塞得下,说明文案太长,回去改文案。
- 三处时长一致才渲染 —— 用
check子命令把关。 - 先预览后渲染 —— 每次重大改动先给预览。
- 可单独重跑 —— 改字幕样式只重跑
captions;改画面只重跑frames+ 渲染。
六、降级策略(换引擎不换流程)
| 环节 | 首选 | 降级顺序 | 触发条件 |
|---|---|---|---|
| 说 | ElevenLabs(需 ELEVENLABS_API_KEY) |
edge-tts → macOS say → espeak |
无 key / 网络受限 / 未安装 |
| 字 | 语音识别 + 时间戳对齐 | 直接由 timings.json 对齐(本技能默认路径) |
无需识别即可对齐 |
voice 会在开头打印实际使用的引擎。降级时必须向用户明确说明当前引擎,不要让用户误以为用的仍是 ElevenLabs。
断网环境不要反复重试,直接降级。
七、边界
- 本技能负责可脚本化的三环(说 / 字 / 验收)与「想」的格式契约;「动」的画面由 Remotion 代码实现,可配合 Remotion 相关技能完成。
- 不虚构事实:数据、引文、结论不确定时如实限定,绝不编造。
- 不越界发布:只交付成片与字幕文件,不擅自上传到任何平台。
- 输出语言与用户输入语言一致(默认简体中文)。