HeyGen 虚拟主播(Avatar)选型与生成实战指南:OpenMontage 中的预览、样式与视频生成全流程
【免费下载链接】OpenMontageWorld's 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
导读
HeyGen 的 Avatar(虚拟主播)是生成式 AI 视频中的数字主持人:你可以直接使用 HeyGen 官方提供的公共主播,也可以基于自己的训练素材创建定制主播,并通过 v2 API 以avatar_id精确指定主播形象,配合文本脚本合成"说话人视频"。本文以 OpenMontage 仓库中.claude/skills/heygen/references/avatars.md为核心骨架,系统讲解从"列出主播、预览形象、筛选样式、匹配默认语音"到"生成单场景/多场景视频"的完整链路,并结合仓库中tools/video/heygen_video.py、tools/video/_shared.py以及avatar-spokesperson流水线给出源码级印证。读完本文,你将掌握如何在 OpenMontage 的项目语境下正确挑选 Avatar、规避常见坑,并写出可直接落地的curl/ TypeScript / Python 调用代码。
HeyGen Avatars 是什么
Avatar 是 HeyGen 生成视频中的 AI 数字主持人。OpenMontage 仓库对这类能力有明确的产品化定位:在pipeline_defs/avatar-spokesperson.yaml中,avatar-spokesperson流水线被描述为"Presenter-led avatar pipeline for spokesperson videos, internal updates, onboarding, sales intros, and short scripted explainers",即"以数字主持人为锚点、辅助图形保持简单的演示人视频"。其编排模式为executive-producer(执行制片人),并在各阶段设置针对"口型同步质量、主持人取景、CTA 落地"的质量门禁(quality gates)。
在 API 层面,Avatar 分为两类:
- 公共 Avatar(Public Avatars):HeyGen 提供的公开主播库,任何用户都可用;
- 私有/定制 Avatar(Private/Custom Avatars):基于你自己的训练素材创建的主播,
avatar_id通常以custom_前缀标识。
仓库的avatar-spokesperson流水线同样把 Avatar 来源视为关键决策点:其idea阶段的成功标准要求"brief 明确记录 avatar path、narration source 与输出形态",并支持heygen_api / sadtalker / musetalk / stock等多种路径(见skills/pipelines/avatar-spokesperson/executive-producer.md)。
生成前先预览:保证主播符合用户偏好
Always preview avatars before generating a video to ensure they match user preferences.(生成前始终先预览主播,确保其符合用户偏好。)每个 Avatar 都带有可直接在浏览器打开的预览 URL,无需下载即可查看。
列出并展示主播预览
以下 TypeScript 函数列出前 5 个主播并打印其预览地址:
async function listAndPreviewAvatars(openInBrowser = true): Promise<void> { const response = await fetch("https://api.heygen.com/v2/avatars", { headers: { "X-Api-Key": process.env.HEYGEN_API_KEY! }, }); const { data } = await response.json(); for (const avatar of data.avatars.slice(0, 5)) { console.log(`\n${avatar.avatar_name} (${avatar.gender})`); console.log(` ID: ${avatar.avatar_id}`); console.log(` Preview: ${avatar.preview_image_url}`); } // Preview URLs can be opened directly in any browser for (const avatar of data.avatars.slice(0, 3)) { console.log(`Open in browser: ${avatar.preview_image_url}`); } }预览-生成工作流
- 列出可用主播——获取名称、性别与预览 URL;
- 向用户展示预览 URL——分享
preview_image_url供视觉确认; - 用户按名称或 ID 选择心仪主播;
- 获取主播详情得到
default_voice_id; - 用选定的主播生成视频。
响应中的预览字段
| 字段 | 说明 |
|---|---|
preview_image_url | 主播静态形象图(JPG),公开可访问的 URL |
preview_video_url | 展示主播动画效果的短视频片段 |
两个 URL 均为公开可访问地址,查看时无需任何鉴权。
列出可用主播:curl / TypeScript / Python
curl
curl -X GET "https://api.heygen.com/v2/avatars" \ -H "X-Api-Key: $HEYGEN_API_KEY"TypeScript
interface Avatar { avatar_id: string; avatar_name: string; gender: "male" | "female"; preview_image_url: string; preview_video_url: string; } interface AvatarsResponse { error: null | string; data: { avatars: Avatar[]; talking_photos: TalkingPhoto[]; }; } async function listAvatars(): Promise<Avatar[]> { const response = await fetch("https://api.heygen.com/v2/avatars", { headers: { "X-Api-Key": process.env.HEYGEN_API_KEY! }, }); const json: AvatarsResponse = await response.json(); if (json.error) { throw new Error(json.error); } return json.data.avatars; }Python
import requests import os def list_avatars() -> list: response = requests.get( "https://api.heygen.com/v2/avatars", headers={"X-Api-Key": os.environ["HEYGEN_API_KEY"]} ) data = response.json() if data.get("error"): raise Exception(data["error"]) return data["data"]["avatars"]响应格式
{ "error": null, "data": { "avatars": [ { "avatar_id": "josh_lite3_20230714", "avatar_name": "Josh", "gender": "male", "preview_image_url": "https://files.heygen.ai/...", "preview_video_url": "https://files.heygen.ai/..." }, { "avatar_id": "angela_expressive_20231010", "avatar_name": "Angela", "gender": "female", "preview_image_url": "https://files.heygen.ai/...", "preview_video_url": "https://files.heygen.ai/..." } ], "talking_photos": [] } }注意响应中还有talking_photos(会说话的照片)数组,它来自 HeyGen 的 Talking Photo 能力,与 Avatar 属于不同的演示者形态。在 OpenMontage 中,HeyGen 的鉴权方式统一为X-Api-Key请求头:仓库工具tools/video/heygen_video.py的get_status()实现即为"存在HEYGEN_API_KEY环境变量才标记为可用",其install_instructions也明确提示需在 https://app.heygen.com/settings/api 申请密钥。
Avatar 类型:公共与定制
公共 Avatar(Public Avatars)
HeyGen 提供任何人都可以使用的公共主播库:
// List only public avatars const avatars = await listAvatars(); const publicAvatars = avatars.filter((a) => !a.avatar_id.startsWith("custom_"));私有/定制 Avatar(Private/Custom Avatars)
由你自己的训练素材创建的定制主播:
const customAvatars = avatars.filter((a) => a.avatar_id.startsWith("custom_"));关键判别规则:avatar_id是否以custom_开头,是区分定制与公共主播的可靠信号。
Avatar 样式(Styles)与适用场景
Avatar 支持不同的渲染样式:
| 样式 | 说明 |
|---|---|
normal | 全身镜头,标准取景 |
closeUp | 面部特写,更具表现力 |
circle | 圆形取景框内的主播(说话人头像) |
voice_only | 仅音频,不渲染视频 |
各样式推荐使用场景
| 使用场景 | 推荐样式 |
|---|---|
| 全屏演示人视频 | normal |
| 个人化/亲密感内容 | closeUp |
| 画中画叠加(Picture-in-Picture) | circle |
| 小尺寸角落小部件 | circle |
| 播客/纯音频内容 | voice_only |
| 动态图形叠加主播 | normal或closeUp+ 透明背景 |
在视频配置中使用样式
const videoConfig = { video_inputs: [ { character: { type: "avatar", avatar_id: "josh_lite3_20230714", avatar_style: "normal", // "normal" | "closeUp" | "circle" | "voice_only" }, voice: { type: "text", input_text: "Hello, world!", voice_id: "1bd001e7e50f421d891986aad5158bc8", }, }, ], };Circle 样式用于说话人头像
Circle 样式非常适合叠加合成:
// Circle avatar for picture-in-picture { character: { type: "avatar", avatar_id: "josh_lite3_20230714", avatar_style: "circle", }, voice: { ... }, background: { type: "color", value: "#00FF00", // Green for chroma key, or use webm endpoint }, }背景指定为纯绿色#00FF00是为了后续抠像(chroma key);也可以改用 WebM 端点直接输出透明背景。这与 OpenMontage 中"透明/抠像视频用于合成"的思路一致——仓库提供tools/video/green_screen_processor.py与tools/video/green_screen_composite.py专门处理绿幕合成,而 HeyGen 官方技能文档中也特别强调"Transparent video for compositing — see video-generation.md (WebM section)"(见.claude/skills/heygen/SKILL.md)。
搜索与过滤主播
按性别过滤
function filterByGender(avatars: Avatar[], gender: "male" | "female"): Avatar[] { return avatars.filter((a) => a.gender === gender); } const maleAvatars = filterByGender(avatars, "male"); const femaleAvatars = filterByGender(avatars, "female");按名称搜索
function searchByName(avatars: Avatar[], query: string): Avatar[] { const lowerQuery = query.toLowerCase(); return avatars.filter((a) => a.avatar_name.toLowerCase().includes(lowerQuery) ); } const results = searchByName(avatars, "josh");Avatar 分组(Groups)
主播按组(group)组织,便于管理。
列出主播分组
curl -X GET "https://api.heygen.com/v2/avatar_group.list?include_public=true" \ -H "X-Api-Key: $HEYGEN_API_KEY"查询参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
include_public | bool | false | 是否在结果中包含公共主播 |
TypeScript
interface AvatarGroupItem { id: string; name: string; created_at: number; num_looks: number; preview_image: string; group_type: string; train_status: string; default_voice_id: string | null; } interface AvatarGroupListResponse { error: null | string; data: { avatar_group_list: AvatarGroupItem[]; }; } async function listAvatarGroups( includePublic = true ): Promise<AvatarGroupListResponse["data"]> { const params = new URLSearchParams({ include_public: includePublic.toString(), }); const response = await fetch( `https://api.heygen.com/v2/avatar_group.list?${params}`, { headers: { "X-Api-Key": process.env.HEYGEN_API_KEY! } } ); const json: AvatarGroupListResponse = await response.json(); if (json.error) { throw new Error(json.error); } return json.data; }注意AvatarGroupItem中的train_status字段用于表示定制主播组的训练状态,default_voice_id可能为null。
获取分组内的主播
curl -X GET "https://api.heygen.com/v2/avatar_group/{group_id}/avatars" \ -H "X-Api-Key: $HEYGEN_API_KEY"在视频生成中使用 Avatar
基础用法
const videoConfig = { video_inputs: [ { character: { type: "avatar", avatar_id: "josh_lite3_20230714", avatar_style: "normal", }, voice: { type: "text", input_text: "Welcome to our product demo!", voice_id: "1bd001e7e50f421d891986aad5158bc8", }, }, ], dimension: { width: 1920, height: 1080 }, };character.type固定为"avatar",avatar_id指定主播,voice.input_text指定要朗读的文本,dimension控制画幅(1920×1080 为横屏 1080p)。
多场景使用不同主播
const multiSceneConfig = { video_inputs: [ { character: { type: "avatar", avatar_id: "josh_lite3_20230714", avatar_style: "normal", }, voice: { type: "text", input_text: "Hi, I'm Josh. Let me introduce my colleague.", voice_id: "1bd001e7e50f421d891986aad5158bc8", }, }, { character: { type: "avatar", avatar_id: "angela_expressive_20231010", avatar_style: "normal", }, voice: { type: "text", input_text: "Hello! I'm Angela. Nice to meet you!", voice_id: "2d5b0e6a8c3f47d9a1b2c3d4e5f60718", }, }, ], };video_inputs数组中的每个元素即一个独立场景,可分别指定主播、脚本与(配合video-generation.md中的背景配置)场景背景。这正是 OpenMontage 中"精确控制每场景主播/背景"的用途——见.claude/skills/heygen/SKILL.md对 v2/video/generate 的定位:"Exact script without AI modification、Specific voice_id selection、Different avatars/backgrounds per scene、Precise per-scene timing control"。
使用主播的默认语音(Default Voice)
很多主播带有预匹配的default_voice_id,官方推荐直接使用默认语音,而不是手动挑选语音。
推荐流程
1. GET /v2/avatars → Get list of avatar_ids 2. GET /v2/avatar/{id}/details → Get default_voice_id for chosen avatar 3. POST /v2/video/generate → Use avatar_id + default_voice_id获取主播详情(v2 API)
curl -X GET "https://api.heygen.com/v2/avatar/{avatar_id}/details" \ -H "X-Api-Key: $HEYGEN_API_KEY"响应格式
{ "error": null, "data": { "type": "avatar", "id": "josh_lite3_20230714", "name": "Josh", "gender": "male", "preview_image_url": "https://files.heygen.ai/...", "preview_video_url": "https://files.heygen.ai/...", "premium": false, "is_public": true, "default_voice_id": "1bd001e7e50f421d891986aad5158bc8", "tags": ["AVATAR_IV"] } }premium表示是否高级(付费)主播,is_public表示是否公共主播,tags携带主播技术标签(如AVATAR_IV表示基于 IV 版本模型)。
TypeScript
interface AvatarDetails { type: "avatar"; id: string; name: string; gender: "male" | "female"; preview_image_url: string; preview_video_url: string; premium: boolean; is_public: boolean; default_voice_id: string | null; tags: string[]; } async function getAvatarDetails(avatarId: string): Promise<AvatarDetails> { const response = await fetch( `https://api.heygen.com/v2/avatar/${avatarId}/details`, { headers: { "X-Api-Key": process.env.HEYGEN_API_KEY! } } ); const json = await response.json(); if (json.error) { throw new Error(json.error); } return json.data; } // Usage: Get default voice for a known avatar const details = await getAvatarDetails("josh_lite3_20230714"); if (details.default_voice_id) { console.log(`Using ${details.name} with default voice: ${details.default_voice_id}`); } else { console.log(`${details.name} has no default voice, select manually`); }完整示例:用任意主播的默认语音生成视频
async function generateWithAvatarDefaultVoice( avatarId: string, script: string ): Promise<string> { // 1. Get avatar details to find default voice const avatar = await getAvatarDetails(avatarId); if (!avatar.default_voice_id) { throw new Error(`Avatar ${avatar.name} has no default voice`); } // 2. Generate video with the avatar's default voice const videoId = await generateVideo({ video_inputs: [{ character: { type: "avatar", avatar_id: avatar.id, avatar_style: "normal", }, voice: { type: "text", input_text: script, voice_id: avatar.default_voice_id, }, }], dimension: { width: 1920, height: 1080 }, }); return videoId; }为什么使用默认语音
- 性别必然匹配——主播与语音已预先配对;
- 自然的唇形同步——默认语音针对该主播做了优化;
- 代码更简单——无需单独拉取并匹配语音;
- 质量更好——HeyGen 已测试过该组合。
如何选对主播:类别、指南与避坑
主播类别
| 类别 | 示例 | 最佳用途 |
|---|---|---|
| 商务/专业 | Josh, Angela, Wayne | 企业视频、产品演示、培训 |
| 休闲/亲和 | Lily 及各类生活化主播 | 社交媒体、非正式内容 |
| 主题/季节性 | 节日主题、Cosplay 主播 | 特定营销活动、季节性内容 |
| 表现力强(Expressive) | 名称中含 "expressive" 的主播 | 有感染力的叙事、动态内容 |
选型指南
商务/专业内容:
- 选择着装中性(商务休闲或正装)的主播;
- 避免主题性或季节性主播(节日服装、休闲服饰);
- 生成前预览,确认形象专业;
- 结合目标受众的画像(人口统计特征)选择性别与外形。
休闲/社交内容:
- 主播选择更灵活;
- 特定营销活动可使用主题性主播;
- 让主播能量与内容基调匹配。
常见错误
- 商务内容使用主题性主播——产品演示里出现节日装扮会显得不专业;
- 生成前不预览——务必打开预览 URL 核对形象;
- 忽略主播样式——
circle样式主播不一定适合全屏演示; - 语音性别不匹配——始终使用
default_voice_id,或手动保证性别一致。
生成前自检清单
- 已在浏览器预览主播图片/视频
- 主播形象与内容基调(专业 vs 休闲)匹配
- 主播样式(
normal、closeUp、circle)适配视频格式 - 语音性别与主播性别匹配
- 可用时使用
default_voice_id
这套"选型纪律"在 OpenMontage 的avatar-spokesperson流水线中有对应体现:其executive-producer技能强调对"唇形同步质量、主持人取景、音频清晰度、CTA 落地"把关,并明确警告"Uncanny valley: If avatar quality is low, it undermines the entire video. Be honest about tool capabilities."(若主播质量低会拖垮整条视频,要诚实面对工具能力边界)——见skills/pipelines/avatar-spokesperson/executive-producer.md。
辅助函数与常用主播 ID
按 ID 获取主播
async function getAvatarById(avatarId: string): Promise<Avatar | null> { const avatars = await listAvatars(); return avatars.find((a) => a.avatar_id === avatarId) || null; }校验主播 ID
async function isValidAvatarId(avatarId: string): Promise<boolean> { const avatar = await getAvatarById(avatarId); return avatar !== null; }随机获取主播
async function getRandomAvatar(gender?: "male" | "female"): Promise<Avatar> { let avatars = await listAvatars(); if (gender) { avatars = avatars.filter((a) => a.gender === gender); } const randomIndex = Math.floor(Math.random() * avatars.length); return avatars[randomIndex]; }常用公共主播 ID
以下为常用公共主播 ID(可用性可能随时间变化):
| Avatar ID | 名称 | 性别 |
|---|---|---|
josh_lite3_20230714 | Josh | 男 |
angela_expressive_20231010 | Angela | 女 |
wayne_20240422 | Wayne | 男 |
lily_20230614 | Lily | 女 |
使用前务必先调用 list 端点核实主播可用性,不要硬编码假设其存在。
在 OpenMontage 中落地的工程化视角
OpenMontage 对 HeyGen 能力的工程封装可以从三个层面佐证上述 API 用法:
- 工具层:
tools/video/heygen_video.py定义HeyGenVideo工具,provider = "heygen",通过HEYGEN_API_KEY环境变量鉴权,get_status()在未配置密钥时返回UNAVAILABLE,并提供fallback到wan_video等本地方案的降级链路; - 实现层:
tools/video/_shared.py中的generate_heygen_video()调用https://api.heygen.com/v1/workflows/executions(Workflow API,GenerateVideoNode节点),poll_heygen()以 5 秒起步、1.2 倍退避(上限 30 秒)的轮询策略等待completed状态,超时上限 600 秒;upload_image_heygen()则优先走v2/assets/upload预签名上传,失败时回退到 fal.ai 存储——这与本文讲解的 v2 头像 API 同属 HeyGen 生态,可作为"如何将主播视频能力接入自动化流水线"的参考实现; - 技能层:
.claude/skills/heygen/SKILL.md声明该技能已弃用并推荐使用avatar-video(面向"精确主播/场景控制")与create-video(面向"提示词驱动生成")两个聚焦技能,其中avatar-video的默认工作流第一步就是"GET /v2/avatars→ 挑选主播、预览、记录avatar_id与default_voice_id",与本文全流程一一对应。
值得注意的边界:OpenMontage 的HeyGenVideo工具走的是v1/workflows生成管线(面向 VEO、Sora、Kling、Runway、Seedance 等视频生成 provider 的provider_variant路由),而本文讲解的v2/avatars+/v2/video/generate是"主播发言人"场景的接口;两者都是 HeyGen 平台的正式 API,选型时应根据目标(AI 生成镜头 vs 数字主持人口播)决定走哪条链路。
参考文件
如需深入,可直接阅读 OpenMontage 仓库中的以下文档与源码:
- 本文主体来源:
.claude/skills/heygen/references/avatars.md - 语音列表与音色参数:
.claude/skills/heygen/references/voices.md - 视频生成与多场景配置:
.claude/skills/heygen/references/video-generation.md - 状态轮询与下载 URL:
.claude/skills/heygen/references/video-status.md - 照片转主播:
.claude/skills/heygen/references/photo-avatars.md - 聚焦技能 avatar-video:
.claude/skills/avatar-video/SKILL.md - HeyGen 工具封装:
tools/video/heygen_video.py - HeyGen 请求实现与轮询逻辑:
tools/video/_shared.py - 发言人流水线定义:
pipeline_defs/avatar-spokesperson.yaml - 执行制片人技能(质量门禁):
skills/pipelines/avatar-spokesperson/executive-producer.md
【免费下载链接】OpenMontageWorld's 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),仅供参考