
OpenMontage 中的 HeyGen 语音接入实战从 API 鉴权到多语言数字人配音的完整指南【免费下载链接】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 开源仓库中的 HeyGen 语音参考文档 为骨架系统讲解 HeyGen AI 语音的查询、筛选、参数调优语速/音调/停顿以及与数字人Avatar配对的最佳实践并结合仓库内的heygen_video工具源码与实际配置帮助你在对话式 AI 视频生产管线中快速落地多语言、多角色的配音能力。为什么需要一份「语音」参考文档在 OpenMontage 的 Agent 视频生产体系中HeyGen 被用于生成说话人视频talking-head、产品解说explainer与演示类内容。无论是走avatar-video精确控制角色、语音、脚本与场景的 v2 API还是create-video提示词驱动工作流语音voice都是决定成片听感的核心要素voice_id 选择是否正确、语速是否自然、停顿是否贴合脚本直接决定了数字人是否像真人。.claude/skills/heygen/references/voices.md这份文档就是给 Agent如 Claude Code在调用 HeyGen 语音能力时使用的手册它与avatars.md、scripts.md、video-generation.md等参考文档共同构成一套可被 LLM 直接检索调用的技能知识库。本文所有示例均来自该文档并辅以仓库源码佐证。前置条件API Key 与鉴权所有语音查询接口都需要在请求头携带X-Api-Key。在 OpenMontage 仓库中HEYGEN_API_KEY是 HeyGen 相关工具的统一环境变量在 docs/PROVIDERS.md 的环境变量清单中登记为HEYGEN_API_KEY解锁heygen_video工具tools/video/heygen_video.py 中的HeyGenVideo.get_status()明确以os.environ.get(HEYGEN_API_KEY)是否为空来判断工具可用性未配置时返回ToolStatus.UNAVAILABLE并提示安装说明。# 注册并登录 HeyGen 后在设置页创建 API Key export HEYGEN_API_KEYyour_key_here列出可用语音Listing Available VoicesHeyGen 提供覆盖多种语言、口音与风格的 AI 语音语音引擎负责把文本脚本转换为自然发音的语音。查询入口为GET https://api.heygen.com/v2/voices文档给出了三种调用方式。curlcurl -X GET https://api.heygen.com/v2/voices \ -H X-Api-Key: $HEYGEN_API_KEYTypeScriptinterface Voice { voice_id: string; name: string; language: string; gender: male | female; preview_audio: string; support_pause: boolean; emotion_support: boolean; } interface VoicesResponse { error: null | string; data: { voices: Voice[]; }; } async function listVoices(): PromiseVoice[] { const response await fetch(https://api.heygen.com/v2/voices, { headers: { X-Api-Key: process.env.HEYGEN_API_KEY! }, }); const json: VoicesResponse await response.json(); if (json.error) { throw new Error(json.error); } return json.data.voices; }Pythonimport requests import os def list_voices() - list: response requests.get( https://api.heygen.com/v2/voices, headers{X-Api-Key: os.environ[HEYGEN_API_KEY]} ) data response.json() if data.get(error): raise Exception(data[error]) return data[data][voices]响应格式Response Format{ error: null, data: { voices: [ { voice_id: 1bd001e7e50f421d891986aad5158bc8, name: Sara, language: English, gender: female, preview_audio: https://files.heygen.ai/..., support_pause: true, emotion_support: true }, { voice_id: de8b5d78f2e0485f88d1e9f5c8e7f9a6, name: Paul, language: English, gender: male, preview_audio: https://files.heygen.ai/..., support_pause: true, emotion_support: false } ] } }响应中每个语音对象的关键字段含义如下字段含义用途voice_id语音唯一标识生成视频时填入voice配置name语音名称展示与检索language语言/口音描述按语言筛选gender性别male/female与数字人性别配对preview_audio试听音频 URL生成前试听support_pause是否支持break停顿标签决定脚本能否插停顿emotion_support是否支持情感表达挑选有表现力的语音支持的语言Supported LanguagesHeyGen 支持大量语言与口音文档给出了常用清单LanguageCodeNotesEnglish (US)en-USMultiple voice optionsEnglish (UK)en-GBBritish accentSpanishes-ESSpain SpanishSpanish (Latin)es-MXMexican SpanishFrenchfr-FRFrance FrenchGermande-DEStandard GermanPortuguesept-BRBrazilian PortugueseChinese (Mandarin)zh-CNSimplified ChineseJapaneseja-JPStandard JapaneseKoreanko-KRStandard KoreanItalianit-ITStandard ItalianDutchnl-NLStandard DutchPolishpl-PLStandard PolishArabicar-SASaudi Arabic注意该表以language字段的描述文本为主如 English语言代码en-US 等更多用于语义理解。实际可用语音以GET /v2/voices返回为准——这也是文档 Best Practices 中Validate availability的原因。在视频生成中使用语音Using Voices in Video Generation语音以voice子对象形式嵌入video_inputs与character数字人并列形成谁 说什么的最小配置单元。基础用法文本转语音const videoConfig { video_inputs: [ { character: { type: avatar, avatar_id: josh_lite3_20230714, avatar_style: normal, }, voice: { type: text, input_text: Hello! Welcome to our presentation., voice_id: 1bd001e7e50f421d891986aad5158bc8, }, }, ], };语速调节Speedconst videoConfig { video_inputs: [ { character: { type: avatar, avatar_id: josh_lite3_20230714, avatar_style: normal, }, voice: { type: text, input_text: This is spoken at a faster pace., voice_id: 1bd001e7e50f421d891986aad5158bc8, speed: 1.2, // 1.0 is normal, range: 0.5 - 2.0 }, }, ], };结合仓库中 scripts.md 的说明语速的实际选择建议为SpeedEffectUse Case0.8-0.9Slower, deliberateComplex topics, older audiences1.0NormalGeneral use1.1-1.2Slightly fasterEnergetic content, younger audiences1.3FastUse sparingly, may reduce clarity音调调节Pitchconst videoConfig { video_inputs: [ { character: { type: avatar, avatar_id: josh_lite3_20230714, avatar_style: normal, }, voice: { type: text, input_text: This has a higher pitch., voice_id: 1bd001e7e50f421d891986aad5158bc8, pitch: 10, // Range: -20 to 20 }, }, ], };用break标签添加停顿Adding PausesHeyGen 支持 SSML 风格的break标签用于在脚本中精确控制停顿让 AI 语音更接近真人语流。标签格式break timeXs/其中X为秒数如1s、1.5s、0.5s。格式硬性要求RuleExampleUse seconds with s suffixbreak time1.5s/✓Must have space before tagword break time1s/✓Must have space after tagbreak time1s/ word✓Self-closing tagbreak time1s/✓错误写法wordbreak time1s/word标签两侧无空格会被当作普通文本或被忽略正确写法word break time1s/ word典型用法示例// Single pause const script1 Hello and welcome. break time\1s\/ Let me introduce our product.; // Multiple pauses const script2 First point. break time\1.5s\/ Second point. break time\1s\/ Third point.; // Pause at start (dramatic opening) const script3 break time\0.5s\/ Welcome to our presentation.; // Longer pause for emphasis const script4 And the winner is... break time\2s\/ You!;完整示例带停顿的产品演示脚本const scriptWithPauses Welcome to our product demo. break time1s/ Today Ill show you three key features. break time0.5s/ First, lets look at the dashboard. break time1.5s/ As you can see, its incredibly intuitive. ; const videoConfig { video_inputs: [ { character: { type: avatar, avatar_id: josh_lite3_20230714, avatar_style: normal, }, voice: { type: text, input_text: scriptWithPauses, voice_id: 1bd001e7e50f421d891986aad5158bc8, }, }, ], };连续停顿自动合并多个连续的break标签会被合并为一个停顿// 这两个标签 Hello break time\1s\/ break time\0.5s\/ world // 等价于一个 1.5 秒的停顿停顿使用建议用于强调—— 在关键信息前加停顿时长保持合理—— 0.5s 到 2s 是典型区间更长会显得不自然贴近自然语流—— 在真人呼吸或停顿的位置插入试听验证—— 生成后回听确认节奏感符合预期。注意是否支持break标签取决于所选语音的support_pause字段这也是筛选语音时的重要依据。使用自定义音频替代 TTSCustom Audio除了文本转语音还可以直接提供自己的音频文件const videoConfig { video_inputs: [ { character: { type: avatar, avatar_id: josh_lite3_20230714, avatar_style: normal, }, voice: { type: audio, audio_url: https://example.com/my-audio.mp3, }, }, ], };该模式适合需要真人配音、已录制旁白或对发音有严格要求的场景——此时语音引擎完全被绕开数字人仅做口型与动作同步。语音筛选Filtering Voices语音列表可能很长文档提供了三种筛选维度均可组合使用。按语言筛选function filterByLanguage(voices: Voice[], language: string): Voice[] { return voices.filter((v) v.language.toLowerCase().includes(language.toLowerCase()) ); } const englishVoices filterByLanguage(voices, english); const spanishVoices filterByLanguage(voices, spanish);按性别筛选function filterByGender(voices: Voice[], gender: male | female): Voice[] { return voices.filter((v) v.gender gender); } const femaleVoices filterByGender(voices, female);按能力特性筛选function filterByFeatures( voices: Voice[], options: { supportPause?: boolean; emotionSupport?: boolean } ): Voice[] { return voices.filter((v) { if (options.supportPause ! undefined v.support_pause ! options.supportPause) { return false; } if (options.emotionSupport ! undefined v.emotion_support ! options.emotionSupport) { return false; } return true; }); } const expressiveVoices filterByFeatures(voices, { emotionSupport: true });综合选择辅助函数interface VoiceSelectionCriteria { language?: string; gender?: male | female; supportPause?: boolean; emotionSupport?: boolean; } async function findVoice(criteria: VoiceSelectionCriteria): PromiseVoice | null { const voices await listVoices(); const filtered voices.filter((v) { if (criteria.language !v.language.toLowerCase().includes(criteria.language.toLowerCase())) { return false; } if (criteria.gender v.gender ! criteria.gender) { return false; } if (criteria.supportPause ! undefined v.support_pause ! criteria.supportPause) { return false; } if (criteria.emotionSupport ! undefined v.emotion_support ! criteria.emotionSupport) { return false; } return true; }); return filtered[0] || null; } // 用法示例 const voice await findVoice({ language: english, gender: female, emotionSupport: true, });这套查询 组合筛选 取首个的模式正是 Agent 在不确定具体 voice_id 时推荐采用的稳健做法——避免硬编码一个可能已被下线的 ID。多语言视频Multi-Language Videos同一支视频的每个场景scene可以配置不同语言与语音实现一场一语言的全球化内容const multiLanguageConfig { video_inputs: [ { character: { type: avatar, avatar_id: josh_lite3_20230714, avatar_style: normal, }, voice: { type: text, input_text: Hello! Welcome to our global product launch., voice_id: english_voice_id, }, }, { character: { type: avatar, avatar_id: josh_lite3_20230714, avatar_style: normal, }, voice: { type: text, input_text: Hola! Bienvenidos al lanzamiento global de nuestro producto., voice_id: spanish_voice_id, }, }, ], };实际使用时应将english_voice_id、spanish_voice_id替换为通过listVoices()查询到的真实 ID例如英文可选用文档示例中的1bd001e7e50f421d891986aad5158bc8。语音与数字人配对Matching Voice to Avatar语音与数字人的匹配质量直接决定成片观感文档给出两条路径。推荐方案使用数字人的默认语音许多数字人avatar自带预匹配的default_voice_id这是最优做法// 使用 v2 API 获取带默认语音的数字人 const response await fetch( https://api.heygen.com/v2/avatar_group.list?include_publictrue, { headers: { X-Api-Key: process.env.HEYGEN_API_KEY! } } ); const { data } await response.json(); // 找到带默认语音的数字人 const avatar data.avatar_group_list.find((a: any) a.default_voice_id); if (avatar) { const videoConfig { video_inputs: [{ character: { type: avatar, avatar_id: avatar.id }, voice: { type: text, input_text: script, voice_id: avatar.default_voice_id, // 官方预匹配的语音 }, }], }; }完整的数字人列举、预览与详情接口含通过GET /v2/avatar/{id}/details获取default_voice_id的方法见仓库中的 avatars.md其中强调默认语音方案能保证性别一致、口型同步自然、代码更简单、质量经过官方验证。兜底方案手动按性别匹配如果数字人没有默认语音则手动按性别并尽量按语言匹配interface AvatarVoicePair { avatarId: string; voiceId: string; gender: male | female; } async function findMatchingAvatarAndVoice( preferredGender?: male | female ): PromiseAvatarVoicePair { const [avatars, voices] await Promise.all([ listAvatars(), listVoices(), ]); // 无偏好时默认 male const gender preferredGender || male; // 找性别匹配的数字人 const avatar avatars.find((a) a.gender gender); if (!avatar) { throw new Error(No ${gender} avatar available); } // 找性别 语言都匹配的语音 const voice voices.find( (v) v.gender gender v.language.toLowerCase().includes(english) ); if (!voice) { throw new Error(No ${gender} English voice available); } return { avatarId: avatar.avatar_id, voiceId: voice.voice_id, gender, }; }最佳实践Best Practices文档在结尾给出了 7 条可执行规范是 Agent 在编排配音时应当遵循的检查清单语音性别与数字人一致—— 男声配男性角色女声配女性角色语音匹配内容调性—— 商务内容使用专业音色先试听再选择—— 利用preview_audio试听考虑地区口音—— 语音口音与目标受众地域匹配自然语速—— 为保证清晰度通常控制在 0.9-1.1x善用停顿—— 用 SSMLbreak让语流更自然验证可用性—— 使用前始终通过列表接口确认voice_id仍存在。仓库中的落地形态heygen_video 工具在本仓库中HeyGen 语音/数字人能力之外还有一个重要的落地形态——tools/video/heygen_video.py 中定义的HeyGenVideo工具heygen_video它是基于 HeyGen 工作流 API 的云端视频生成工具其关键信息如下鉴权依赖HEYGEN_API_KEY环境变量未设置时get_status()返回UNAVAILABLE能力text_to_video、image_to_video支持通过provider_variant选择底层模型回退策略fallback wan_video备用工具链包含wan_video、hunyuan_video、ltx_video_local、cogvideo_video、image_selector等体现 OpenMontage 的容错路由设计成本/耗时估算estimate_cost与estimate_runtime依据 tools/video/_shared.py 中HEYGEN_PROVIDERS表的quality/speed字段推算。HEYGEN_PROVIDERS目前登记的 provider 包括veo_3_1、veo_3_1_fast、veo3、kling_pro、kling_v2、sora_v2、sora_v2_pro、runway_gen4、seedance_lite、seedance_pro、ltx_distilled等其中veo_3_1为默认quality 标记为 highest、速度标记为 slow。底层通过POST /v1/workflows/executions发起生成再由poll_heygen()以指数退避轮询GET /v1/workflows/executions/{execution_id}默认超时 600 秒获取成片 URL 并下载到本地。需要说明的是heygen技能本身在 SKILL.md 中已被标记为Deprecated官方指引改为使用create-video提示词驱动或avatar-video精确控制两个新技能——而 avatar-video 的 voices 参考文档 与本篇所讲的 voices.md 内容完全一致说明这套语音接入规范在新技能体系中依旧有效。结语从GET /v2/voices的三种调用姿势到speed/pitch/break的精细调参再到多语言场景编排与数字人默认语音优先的配对策略voices.md 为 Agent 提供了一套完整、可执行的语音接入协议。配合仓库中的 heygen_video.py、_shared.py 与 PROVIDERS.md开发者既可以直接按文中的 API 示例手工接入也可以把语音选择逻辑交给 Agent 技能自动完成从而在 OpenMontage 的任一数字人/解说类生产管线中获得稳定、自然、多语言的配音能力。【免费下载链接】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),仅供参考