
OpenMontage 网站转视频工作流 Step 4 实战VO 配音生成、时间校准与字幕制作【免费下载链接】OpenMontageWorlds first open-source, agentic video production system. 12 production pipelines, 100 tools, 700 agent skill and production-knowledge files. Turn your AI coding assistant into a full video production studio.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMontage本文是 OpenMontage 仓库内website-to-video网站转视频技能体系中 Step 4 的完整实战指南对应仓库文件 step-4-vo.md。Step 4 是整个工作流中承上启下的关键环节在 Step 3 产出STORYBOARD.md分镜与SCRIPT.md脚本并通过用户评审后Step 4 负责把文字脚本变成真实可用的配音音频、把音频转写成词级时间戳、再把时间戳回填到分镜的每个 beat最终为 Step 5构建index.html组合提供精确的data-start/data-duration时序数据。读完本文你将掌握三个 TTS 提供商HeyGen / ElevenLabs / Kokoro的选型与实操命令、以2 句话测试片段为核心的时间校准方法论、词级时间戳的获取与规范化、以及字幕Captions从询问到落地的完整决策链。一、前置判断Step 2 判定无旁白时的分支路径Step 4 的第一步不是生成配音而是回到 Step 2 的结论。如果简报阶段已确定视频不需要旁白如纯音乐驱动的品牌短片、快节奏社交广告那么跳过本文中所有 TTS 小节。此时分镜已经基于节奏与韵律规划了每个 beat 的时长——这些时长会直接作为data-start与data-duration写入 Step 5 的index.html不需要再经过音频校准。无旁白路线下唯一必须做的事是在进入 Step 5 之前询问用户背景音乐你有这首歌的配乐吗如果没有我可以建议去哪里找Artlist.io或Musicbed—— 授权商用音乐Uppbeat.io或Pixabay Music—— 免费曲目需署名Freesound.org—— 免费音效采样与循环或者分享一首参考曲类似这样的感觉我可以帮你找到相似的音乐。如果用户提供了曲目在STORYBOARD.md中记录文件路径和 BPM供 Step 5 接入index.html使用如果用户完全跳过音乐视频将只使用 SFX音效——必须向用户确认这是有意的选择。完成此分支后直接进入 Step 5。仓库中该技能的主文件 SKILL.md 对 Step 4 的门禁Gate也做了明确约定要么a无旁白且分镜已含手动 beat 时长要么bnarration.wavtranscript.json均已存在且 beat 时长已更新为真实值二者满足其一才能放行到 Step 5。二、先校准再全量2 句话测试片段方法论不要在投入全部旁白生成之前就锁定 beat 数量与时长。脚本长度公式按字数估算时长假设语速恒定但标点、戏剧性停顿、静音提示都会拉伸真实音频。最可靠的方式永远是实测。2.1 为什么必须实测Kokoro 的 ~40% 压缩效应实战经验表明Kokoro 会把脚本压缩约 40%例如规划 35 秒实际只有 19 秒而HeyGen 的实际时长往往比预期更快。如果提前发现音频比预期短 40%你就有机会在投入全量生成之前修订分镜的 beat 时长而不是在生成完所有配音后才发现整条片子的节奏全部偏离。2.2 测试命令与估算法用脚本开头的前 2 句话生成测试片段然后实测时长# Kokoro 快速测试2 句话 npx hyperframes tts First sentence. Second sentence. --voice af_nova --output /tmp/test-tts.wav # 估算实测秒数 ÷ 字数 × 脚本总字数 预计全片音频长度2.3 偏差处理的三种情形估算结果与规划时长相比若在±15% 以内可以继续推进超过 15% 则必须先校准脚本长度情形处置方法音频太短比规划短 15% 以上在narration.txt中有策略地插入停顿段落间空行 ≈ 0.6 秒/处句子间...≈ 0.4 秒/处。让停顿落在分镜 beat 的边界上使静默显得有设计感而非冷场音频太长比规划长 15% 以上找出分镜中每秒字数密度最高的那个 beat删掉该 beat 台词中的一句支撑句——但保留点名该 beat 核心思想的引导句。删完再用另一个测试片段重新测量再决定是否全量生成音频与计划匹配但 beat 边界漂移调整分镜时长去贴合真实旁白而不是反过来。一旦旁白生成音频就是基准事实ground truth核心原则脚本公式只作为起点标点、戏剧停顿与静音提示都会拉伸真实音频永远相信实测片段而不是公式。三、背景音乐即使有旁白也必问即使 Step 4 主路线有旁白也必须主动询问用户是否要背景音乐你需要在旁白下面加背景音乐吗Artlist.io、Musicbed 用于授权Uppbeat/Pixabay 免费或者分享参考曲。即使是微妙的氛围底音也会让句子之间的停顿听起来是有意的而不是空洞的。如果用户要音乐同样把曲目记录到STORYBOARD.md供 Step 5 接入index.html。仓库配套技能 hyperframes-media 提供了这条决策链的工程化底座它维护一个统一的音频引擎scripts/audio.mjs通过一份audio_request.json同时产出 TTS、BGM、SFX。BGM 的默认策略是有 HeyGen 凭证时从 HeyGen 音乐库检索retrieve无凭证时回退到本地 Lyria / MusicGen 生成generate且生成是脱离主流程的异步任务bgm_pending: true组装前需运行scripts/wait-bgm.mjs。SFX 同理有凭证走 HeyGen 音效检索min_score 0.4无凭证回退到技能内置的 21 个文件音效库assets/sfx/。因此 Step 4 里用户提供曲目与让用户选免费/授权平台这两条路径在 OpenMontage 工程体系内都有对应的自动化落地方式。四、TTS 提供商选型HeyGen / ElevenLabs / Kokoro必须向用户询问配音提供商。三者的核心差异在于音质、是否自带词级时间戳、是否需要 API Key提供商音质词级时间戳凭证要求适用场景HeyGen TTS好自带省去单独转写步骤需要 HeyGen API Key质量优先、想一步到位拿到时间戳ElevenLabs非常自然声音库大不返回需单独转写需要 ElevenLabs API Key看重自然度、声音库丰富Kokoro免费尚可偏机械不返回需转写无需 Key本地运行草稿、预算受限的快速产出4.1 凭证配置用户选择 ElevenLabs 或 HeyGen 但尚未配置 Key 时帮助其完成设置ElevenLabs在项目根目录的.env文件中添加ELEVENLABS_API_KEYyour-key或者直接粘贴给我我来配置。HeyGen在.env文件中添加HEYGEN_API_KEYyour-key或者直接粘贴。若用户直接在聊天中粘贴 Key不要评判或批评直接使用并继续。4.2 仓库工程化视角的提供商链在 OpenMontage 的 hyperframes-media SKILL.md 中TTS 提供商链被明确为首个可用者胜出顺序提供商检测条件词级时间戳1HeyGenStarfish$HEYGEN_API_KEY或hyperframes auth login原生支持加--words narration.words.json即可捕获2ElevenLabs$ELEVENLABS_API_KEY已设置无需后续链式transcribe3Kokoro-82M本地54 个声音始终可用无需 Key无需后续链式transcribe值得注意的工程细节发布版hyperframes ttsCLI 通常是仅本地的构建--help显示 Kokoro-82M无--provider/--words即使设置了$HEYGEN_API_KEY也会静默回退到 Kokoro。因此仓库专门提供了自包含的 HeyGen 路径scripts/heygen-tts.mjs直接调 REST APICLI 只用于 Kokoro 路径。这解释了为什么 Step 4 文档中 HeyGen 与 ElevenLabs 都演示了直接调 REST API 的方式——它们比 CLI 更可靠。另外tts.md 还补充了速度参数的经验值0.7-0.8教程/复杂内容/无障碍、1.0自然语速默认、1.1-1.2片头/转场/轻快内容、1.5很少适用需谨慎测试。注意ElevenLabs 会忽略--speed需在其控制台的声音设置里调整Kokoro 与 HeyGen 则支持。五、试听声音至少对比 2 个候选选定提供商后用SCRIPT.md的第一句话试听至少 2 个声音再定稿。选择听感最自然、最有对话感的声音——注意听它是否在句子间呼吸像人还是像机器人。5.1 ElevenLabs 试听若 ElevenLabs MCP 可用用mcp__elevenlabs__search_voices浏览、mcp__elevenlabs__text_to_speech生成若无 MCP直接调 REST API# 列出声音 curl -s https://api.elevenlabs.io/v1/voices \ -H xi-api-key: $ELEVENLABS_API_KEY | jq .voices[:5] | .[].name # 生成语音VOICE_ID 换成所选声音 curl -s -X POST https://api.elevenlabs.io/v1/text-to-speech/VOICE_ID \ -H xi-api-key: $ELEVENLABS_API_KEY \ -H Content-Type: application/json \ -d {text:First sentence of your script,model_id:eleven_multilingual_v2} \ --output narration.mp3注意ElevenLabs 不返回词级时间戳生成后需单独转写。5.2 HeyGen TTS 试听若 HeyGen MCP 可用直接用 TTS 工具若无 MCP使用v3 API当前版本v1/v2 已弃用支持至 2026 年 10 月。鉴权方式取决于凭证类型下面的x-api-key头只对账号 API KeyHEYGEN_API_KEY有效若你通过OAuth认证如 claude.ai / HeyGen MCP 登录x-api-key会返回 401——此时应发送Authorization: Bearer $HEYGEN_OAUTH_TOKEN或者直接用 MCP TTS 工具。# 列出声音 —— 响应结构{ data: [...], has_more: bool } # data 是直接列表注意不是 data.voices那是 v2 的格式 curl -s https://api.heygen.com/v3/voices?enginestarfishtypepubliclimit20 \ -H x-api-key: $HEYGEN_API_KEY | python3 -c \ import json,sys; vjson.load(sys.stdin)[data]; [print(x[voice_id], x[name], x[language]) for x in v[:10]] # 生成音频 —— 响应{ data: { audio_url: ..., word_timestamps: [...] } } curl -s -X POST https://api.heygen.com/v3/voices/speech \ -H x-api-key: $HEYGEN_API_KEY \ -H Content-Type: application/json \ -d {text:Your script here,voice_id:VOICE_ID,speed:1.0} \ | python3 -c import json,sys rjson.load(sys.stdin) dr[data] print(d[audio_url]) open(transcript_raw.json,w).write(json.dumps(d.get(word_timestamps,[]),indent2)) # 然后下载音频 curl -sL AUDIO_URL_FROM_ABOVE --output narration.mp3HeyGen 直接在响应中返回词级时间戳无需单独的转写步骤。5.3 Kokoro 试听免费、本地npx hyperframes tts SCRIPT.md --voice af_nova --output narration.wav无需 API Key、无需 MCP本地运行。用--list可查看全部54 个可用声音。仓库 tts.md 还给出了按内容类型选声的参考表例如产品演示用af_heart/af_nova教程用am_adam/bf_emma营销推广用af_sky/am_michael。六、脚本长度检查消灭死点全量生成前验证脚本与视频是否匹配。字数完全取决于创意方向——分镜的节奏与风格决定视频需要多少旁白。关键在于检查是否存在这样的段落既没有旁白也没有吸引人的视觉运动——这就是会流失观众的死点。每一秒要么有口播词要么有强烈的视觉能量在承载。从仓库 step-3-storyboard.md 的脚本写作规范可以呼应这一点自然语速约为2.5 词/秒15 秒 ≈ 37 词30 秒 ≈ 75 词且 CTA 结尾 beat 应在最后一句口播词后只停留 2–3 秒而不是用 8–10 秒的静默填充。七、生成完整旁白产物、超时升级与发音问题全量生成整个脚本为narration.wav或.mp3存放在项目目录中。7.1 命令卡住的升级策略严禁空等任何命令挂起超过 60 秒都不要干等——用户正在旁边看着你无所事事。按此顺序升级重试一次—— 杀掉进程原命令重跑瞬时失败很常见换参数—— 更小的模型如--model tiny.en、换声音、先用更短的测试句同一任务换工具—— 若hyperframes transcribe挂起直接在音频上运行whisper-cli整体切换提供商—— ElevenLabs 挂了就换 HeyGen 或 KokoroKokoro 挂了就换 ElevenLabs。绝不坐在那里等 10 分钟祈祷卡死的进程自己完成。7.2 Kokoro 发音问题生成前必须做替换Kokoro 会念错产品名和技术术语所以必须先在文本上应用替换再生成。已知问题与修复API→A P I逐个字母拼读UI→U I、SaaS→sass、DevOps→dev ops拼写不寻常的产品名先测第一句再听。常见失败Vercel 被念成 versatile、WorkOS 被念成 work O S、One API 被念成 Wanna PI名字听起来不对时在narration.txt中按音标改写如Vercel→Ver-sell、Supabase→Soopa-base全量生成前永远先用前 2 句话生成短测试片段不要用 SSML 标签—— Kokoro 会把它们当字面文本朗读。break time1s/会被念成 break time equals one slash。在narration.txt里用空行或...表示停顿对于ElevenLabs 与 HeyGen TTS替换通常不必要——它们能正确处理产品名。7.3 保存narration.txt精确口语文本同时保存应用了发音替换后的精确口播文本如API→A P I、$2T→two trillion等为narration.txt放在同一目录。注意这是实际传给 TTS 的字符串区别于SCRIPT.md面向人类阅读的创意文档保留narration.txt的价值在于日后换一个声音重新生成音频时无需重新推导替换规则文件名必须严格命名为narration.txt。八、转写获取词级时间戳词级时间戳是所有 beat 时长的基准事实source of truth获取路径取决于提供商8.1 使用 HeyGen v3 TTS直接规范化HeyGen 在生成调用时就返回了词级时间戳只需规范化格式再保存——HeyGen v3 用word字段而管线期望的是textimport json raw json.load(open(transcript_raw.json)) normalized [{text: w[word], start: w[start], end: w[end]} for w in raw] json.dump(normalized, open(transcript.json, w), indent2)无需单独的转写步骤。8.2 使用 ElevenLabs 或 Kokoro转写npx hyperframes transcribe narration.wav产出transcript.json包含每个词的[{ text, start, end }]。8.3 转写的语言规则不可协商仓库 transcribe.md 强调hyperframes transcribe的 CLI 默认是small.en它会静默地把非英语音频翻译成英语——这会无声摧毁原始语言。因此必须显式指定--model场景命令已知英语npx hyperframes transcribe audio.mp3 --model small.en已知非英语npx hyperframes transcribe video.mp4 --model small --language es语言未知npx hyperframes transcribe audio.mp3 --model small自动检测导入现有字幕npx hyperframes transcribe subtitles.srt/.vtt模型规模参考tiny75MB最快→base142MB→small466MB多语言默认→medium1.5GB带人声的音乐/嘈杂音频→large-v33.1GB生产级质量。带.en后缀的模型会做翻译纯音乐或含人声的曲目应从medium.en起步制作完成的音乐曲目可能需要人工歌词或外部 API。8.4 转写质量检查强制仓库 transcript-handling.md 规定每次转写后都必须通读转写结果做质量检查坏转写会产生荒谬的字幕。重点排查音符 token♪/说明 Whisper 把音乐当成了语音、乱码/无意义词、超长无词空白、大量 huh/uh/oh 填充、过短词跨度end - start 0.05。若超过 20% 条目是音乐 token 或明显乱码视为转写失败先升到medium.en重试仍失败则告知用户音频对本地转写太吵建议手动提供歌词SRT/VTT或改用 OpenAI / Groq Whisper 外部 API。构建字幕前必须先清理转写结果——过滤掉♪/token 和单个非单词字符只有真实单词才能进入字幕合成。九、把时间戳映射到分镜 beats逐 beat 遍历STORYBOARD.md对每个 beat在transcript.json中找到该 beat 的 VO 提示词VO cue的第一个词找到该 beat VO cue 的最后一个词设置beat.start firstWord.start、beat.end lastWord.end在结尾追加0.3–0.5 秒的视觉呼吸空间。然后用真实时长更新STORYBOARD.md把估计时间如 0:00-0:05替换为尽可能精确的实际时间戳如 0.00-3.21s。Beat 边界落在词首word onsets上——画面硬切对准旁白。从仓库 step-3-storyboard.md 的架构树可以看到这些产物的最终去向index.html是根组合VO 背景音乐 beat 编排transcript.json与narration.wav都位于项目根目录Step 5 会把每个 beat 的时序写入场景槽位的data-start/data-duration属性。十、时间校准进入 Step 5 前的必做检查映射完所有 beat 后必须比较真实音频总时长与分镜规划时长real_total last_word.end cta_hold通常 2–3 秒 planned_total 所有 beat 规划时长之和 delta |real_total - planned_total|若 delta 超过规划总时长的 15%未解决前不得进入 Step 5。常见原因与修复情形修复音频比规划短Kokoro 最常见Kokoro 生成压缩语音、停顿极少将所有非 CTA beat 时长按比例缩放以贴合真实音频。例规划 30 秒、音频 19 秒——每个 beat 时长乘以 19/30CTA 停留除外更新STORYBOARD.md音频比规划长很多超过 30%脚本对目标时长太长。删掉一个 beat 的 VO重新生成音频重新转写CTA beat 时机CTA beat 应在最后一句口播词后停留 2–3 秒不要拉长去填满空白。cta_start last_word.end 0.3scta_duration 2.5s这是硬上限。CTA 停留后的死寂同样会流失观众若你大幅调整了相对分镜计划的时长一定要告知用户。用户批准的是特定的 beat 结构——如果它变了用户需要知道。十一、字幕Captions询问、构建与样式11.1 先询问旁白生成并转写完成后询问用户你想在视频上加字幕吗要—— 与旁白同步的逐词字幕。非常适合社交媒体大多数观众静音观看与无障碍需求。不要—— 仅旁白音频无文字覆盖。11.2 构建方式若要字幕Step 5 会将其构建为独立组合compositions/captions.html由transcript.json驱动时序——每个词在念出时出现/高亮。字幕样式scale-pop、typewriter、fadeslide 等与定位规则详见仓库 captions/authoring.md 与 captions/motion.md。11.3 风格决策依据仓库的字幕参考给出了系统化的风格决策方法若用户未指定风格则从转写结果中推断基调四个维度是视觉感受、配色、字体情绪、动画性格。风格与内容的映射示例基调字体情绪动画配色字号发布/造势粗体压缩800-900scale-pop、back.out(1.7)、0.1-0.2s亮色配深底72-96px企业/专业干净无衬线600-700fadeslide、power3.out、0.3s白/中性色、低饱和强调色56-72px教程等宽/无衬线500-600typewriter/fade、0.4-0.5s高对比、极简48-64px叙事衬线/优雅400-500慢速淡入、power2.out、0.5-0.6s温暖柔和色调44-56px社交圆角无衬线700-800弹性弹跳、逐词俏皮彩色胶囊56-80px逐词分组按能量区分高能 2-3 词/组、对话式 3-5 词/组、沉稳 4-6 词/组按句子边界、150ms 停顿或最大词数断组。定位横屏1920×1080位于底部 80-120px 居中竖屏1080×1920位于距底部约 600-700px 的中间偏下永远不要遮挡人物面部每次只显示一组字幕。为避免溢出可使用运行时 APIwindow.__hyperframes.fitTextFontSize()按maxWidth自动收缩字号。11.4 现成字幕组件仓库还维护了 15 个开箱即用的字幕注册组件npx hyperframes catalog --tag caption-style可列出、npx hyperframes add name安装例如caption-highlightTikTok 风格高亮适合社交、caption-pill-karaoke卡拉 OK 胶囊适合歌词视频、caption-editorial-emphasis电影感编辑字幕适合纪录片、caption-kinetic-slam全屏冲击适合造势等。这些组件以子组合方式经data-composition-src挂载且自带动画退出保证每个词组在group.end处必须硬性tl.set隐藏否则会遗留残影。十二、为 Step 5 保存时序数据记录最终的 beat 时序start、duration供 Step 5构建组装index.html时使用。此时分镜已经包含真实时间戳——当根组合在 Step 5 组装时这些时间戳会变成每个场景槽位上的data-start与data-duration属性值。从 hyperframes.md 的工件映射表可以确认这条数据流OpenMontage 的audio.narration.segments[]对应audio元素及其data-start/data-durationsubtitles启用时对应注册表的 captions 块或手写的逐词 span。整条链路的验收在 SKILL.md 的 Step 4 Gate 中固化narration.wavtranscript.json存在、beat 时长已用真实时长更新二者齐备才允许进入 Step 5——这正是 Step 4先校准、后全量、再映射、终校准四步方法论的价值所在它保证进入构建阶段时音频、时间戳与画面节奏三者已经对齐而不是在渲染出 MP4 之后才发现整条片子的口播与画面错位。附Step 4 速查清单Step 2 无旁白→ 询问背景音乐Artlist/Musicbed/Uppbeat/Pixabay/Freesound记录曲目路径与 BPM 到STORYBOARD.md或确认纯 SFX然后跳 Step 5用脚本前 2 句生成测试片段实测时长验证是否在规划 ±15% 内超差则按加停顿/删支撑句/改分镜时长处理有旁白时也询问背景音乐询问并确认 TTS 提供商HeyGen / ElevenLabs / Kokoro配置对应 API Key用SCRIPT.md第一句试听至少 2 个声音选择最自然者脚本长度检查确认无无旁白且无视觉运动的死点全量生成narration.wav.mp3 保存替换后的精确口播文本narration.txt命令挂起超 60 秒按升级链处理Kokoro 必须预先做发音替换获取词级时间戳HeyGen 直接规范化word→textElevenLabs/Kokoro 走hyperframes transcribe显式--model注意语言规则完成转写质量检查与清理逐 beat 映射beat.start firstWord.start、beat.end lastWord.end 0.3–0.5s 呼吸空间更新STORYBOARD.md为真实时间戳时间校准delta |real_total - planned_total| 15% 必须解决比例缩放 / 删 beat 重新生成 / CTA 硬上限 2.5s并告知用户调整情况询问是否加字幕要则在 Step 5 构建compositions/captions.html由transcript.json驱动最终 beat 时序start、duration保存完毕供 Step 5 写入data-start/data-duration【免费下载链接】OpenMontageWorlds first open-source, agentic video production system. 12 production pipelines, 100 tools, 700 agent skill and production-knowledge files. Turn your AI coding assistant into a full video production studio.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMontage创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考