资讯动态

OpenMontage HeyGen 照片数字人(Talking Photos)实战:从肖像上传、Avatar Group 创建到 Avatar IV 与 AI 生成头像

发布时间:2026/9/7 2:34:29 来源:尧图企业网站定制
OpenMontage HeyGen 照片数字人Talking Photos实战从肖像上传、Avatar Group 创建到 Avatar IV 与 AI 生成头像【免费下载链接】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 仓库中avatar-video技能下的参考文档 photo-avatars.md系统讲解如何用 HeyGen API 把一张静态照片变成会说话的数字人覆盖「上传图片 → 创建照片头像组 → 轮询处理状态 → 生成视频」的完整链路、Avatar IV 一步直出方案、AI 文本生成照片头像的参数约束以及头像组的管理接口与照片质量要求。读完后你可以在 OpenMontage 的头像视频流水线中独立完成照片数字人从资产创建到视频产出的全部操作。照片数字人在 OpenMontage 中的位置OpenMontage 把 HeyGen 集成在avatar-video技能中见 SKILL.md该技能面向「精确控制」场景自己选头像、写精确脚本、配置每个场景。其 frontmatter 声明了运行前提——需要HEYGEN_API_KEY环境变量且所有请求都要求X-Api-Key请求头curl -X GET https://api.heygen.com/v2/avatars \ -H X-Api-Key: $HEYGEN_API_KEY照片数字人Photo Avatars / Talking Photos是avatar-video技能「Advanced Features」分支之一SKILL.md 的 Quick Reference 表中将 “Create avatar from photo” 指向本文档。它与两个基础文档协同assets.md资产上传端点POST https://upload.heygen.com/v1/asset的完整字段说明是照片数字人流程第 1 步的基础video-generation.md/v2/video/generate端点的character字段定义其中character.type只允许avatar或talking_photo当 type 为talking_photo时talking_photo_id必填——这正是照片数字人产物的消费入口。在仓库的工具层tools/video/heygen_video.py中的HeyGenVideo工具封装了 HeyGen 云端视频生成install_instructions明确提示设置HEYGEN_API_KEY并配置了wan_video、hunyuan_video等回退工具tools/avatar/talking_head.py中的TalkingHead工具则提供本地化的「照片转说话头像」photo_to_video能力。本文档讲解的 API 链路是技能层直接调用 HeyGen 端点的完整参考实现。流程一从上传照片到生成视频四步链路官方工作流为Upload Image → Create Avatar Group → Use in Video。创建出来的照片头像id与group_id相同就是视频生成时的talking_photo_id。Step 1上传图片获取 image_key把肖像照以原始二进制 POST 到资产上传端点Content-Type必须与文件 MIME 类型一致curl -X POST https://upload.heygen.com/v1/asset \ -H X-Api-Key: $HEYGEN_API_KEY \ -H Content-Type: image/jpeg \ --data-binary ./portrait.jpg响应示例{ code: 100, data: { id: 741299e941764988b432ed3a6757878f, name: 741299e941764988b432ed3a6757878f, file_type: image, url: https://resource2.heygen.ai/image/.../original.jpg, image_key: image/741299e941764988b432ed3a6757878f/original.jpg } }注意必须保存image_key字段而不是id。image_key是创建照片头像时使用的 S3 路径。结合 assets.md 的完整字段说明上传响应中code: 100表示成功data.image_key为「仅图片类型」才有值的字段string | null用于创建上传类照片头像资产上限为 10MB且闲置资产可能被服务端清理。Step 2创建照片头像组Avatar Group用image_key调POST https://api.heygen.com/v2/photo_avatar/avatar_group/create服务端会处理该图片并产出一个可复用的照片头像curl -X POST https://api.heygen.com/v2/photo_avatar/avatar_group/create \ -H X-Api-Key: $HEYGEN_API_KEY \ -H Content-Type: application/json \ -d { image_key: image/741299e941764988b432ed3a6757878f/original.jpg, name: My Photo Avatar }字段类型必填说明image_keystring✓上传响应中的 S3 图片 keynamestring✓头像显示名称generation_idstring若使用 AI 生成的照片见下文「AI 照片头像」一节需携带生成任务 ID响应示例{ error: null, data: { id: 045c260bc0364727b2cbe50442c3a5bf, image_url: https://files2.heygen.ai/..., created_at: 1771798135.777256, name: My Photo Avatar, status: pending, group_id: 045c260bc0364727b2cbe50442c3a5bf, is_motion: false, business_type: uploaded } }返回的id与group_id相同即视频生成所需的talking_photo_id。Step 3轮询等待处理完成照片头像初始状态为status: pending通常数秒内转为completed。状态查询端点Endpoint:GET https://api.heygen.com/v2/photo_avatar/{id}curl https://api.heygen.com/v2/photo_avatar/045c260bc0364727b2cbe50442c3a5bf \ -H X-Api-Key: $HEYGEN_API_KEY在status变为completed之前不要发起视频生成。Step 4用于视频生成拿到talking_photo_id后构造/v2/video/generate的请求体character.type设为talking_photoconst videoConfig { video_inputs: [ { character: { type: talking_photo, talking_photo_id: 045c260bc0364727b2cbe50442c3a5bf, }, voice: { type: text, input_text: Hello! This is my photo avatar speaking., voice_id: 1bd001e7e50f421d891986aad5158bc8, }, }, ], dimension: { width: 1920, height: 1080 }, };对照 video-generation.md 的字段表talking_photo类型下还可用可选字段avatar_stylenormal/closeUp/circle、scale缩放系数和offset{x, y}位置偏移来调整人物在画面中的呈现voice支持text/audio/silence三种输入类型text时voice_id与input_text必填。完整工作流参考实现TypeScript / PythonTypeScript 版import fs from fs; import path from path; interface AssetUploadResponse { code: number; data: { id: string; image_key: string; url: string; }; } interface PhotoAvatarResponse { error: string | null; data: { id: string; group_id: string; image_url: string; name: string; status: string; is_motion: boolean; business_type: string; }; } async function createPhotoAvatar( imagePath: string, name: string ): Promisestring { // 1. 上传图片 const resolvedPath path.resolve(imagePath); const fileBuffer fs.readFileSync(resolvedPath); const uploadResponse await fetch(https://upload.heygen.com/v1/asset, { method: POST, headers: { X-Api-Key: process.env.HEYGEN_API_KEY!, Content-Type: image/jpeg, }, body: fileBuffer, }); const uploadJson: AssetUploadResponse await uploadResponse.json(); if (uploadJson.code ! 100) { throw new Error(Upload failed); } const imageKey uploadJson.data.image_key; // 2. 创建头像组 const createResponse await fetch( https://api.heygen.com/v2/photo_avatar/avatar_group/create, { method: POST, headers: { X-Api-Key: process.env.HEYGEN_API_KEY!, Content-Type: application/json, }, body: JSON.stringify({ image_key: imageKey, name }), } ); const createJson: PhotoAvatarResponse await createResponse.json(); if (createJson.error) { throw new Error(createJson.error); } const photoAvatarId createJson.data.id; // 3. 等待处理完成 await waitForPhotoAvatar(photoAvatarId); return photoAvatarId; } async function waitForPhotoAvatar(id: string): Promisevoid { for (let i 0; i 30; i) { const response await fetch( https://api.heygen.com/v2/photo_avatar/${id}, { headers: { X-Api-Key: process.env.HEYGEN_API_KEY! } } ); const json: PhotoAvatarResponse await response.json(); if (json.data.status completed) return; if (json.data.status failed) { throw new Error(Photo avatar processing failed); } await new Promise((r) setTimeout(r, 2000)); } throw new Error(Photo avatar processing timed out); } async function createVideoFromPhoto( photoPath: string, script: string, voiceId: string ): Promisestring { // 1. 创建照片头像 const talkingPhotoId await createPhotoAvatar(photoPath, Video Avatar); // 2. 生成视频 const response await fetch(https://api.heygen.com/v2/video/generate, { method: POST, headers: { X-Api-Key: process.env.HEYGEN_API_KEY!, Content-Type: application/json, }, body: JSON.stringify({ video_inputs: [ { character: { type: talking_photo, talking_photo_id: talkingPhotoId, }, voice: { type: text, input_text: script, voice_id: voiceId, }, }, ], dimension: { width: 1920, height: 1080 }, }), }); const { data } await response.json(); return data.video_id; }轮询策略从源码结构看是「最多 30 次、每次间隔 2 秒」即约 60 秒超时窗口pending之外的终态只有completed与failed。Python 版import requests import os import time def create_photo_avatar(image_path: str, name: str) - str: api_key os.environ[HEYGEN_API_KEY] # 1. 上传图片 with open(image_path, rb) as f: upload_resp requests.post( https://upload.heygen.com/v1/asset, headers{ X-Api-Key: api_key, Content-Type: image/jpeg, }, dataf, ) upload_data upload_resp.json() if upload_data.get(code) ! 100: raise Exception(Upload failed) image_key upload_data[data][image_key] # 2. 创建头像组 create_resp requests.post( https://api.heygen.com/v2/photo_avatar/avatar_group/create, headers{ X-Api-Key: api_key, Content-Type: application/json, }, json{image_key: image_key, name: name}, ) create_data create_resp.json() if create_data.get(error): raise Exception(create_data[error]) photo_avatar_id create_data[data][id] # 3. 等待处理完成 for _ in range(30): status_resp requests.get( fhttps://api.heygen.com/v2/photo_avatar/{photo_avatar_id}, headers{X-Api-Key: api_key}, ) status status_resp.json()[data][status] if status completed: return photo_avatar_id if status failed: raise Exception(Photo avatar processing failed) time.sleep(2) raise Exception(Photo avatar processing timed out)Avatar IV跳过头像组、直出视频Avatar IV 是 HeyGen 最新的照片数字人技术直接以「上传的image_key 脚本 音色」生成视频绕过 avatar group 创建步骤适合不需要跨视频复用同一头像的一次性生产。Endpoint:POST https://api.heygen.com/v2/video/av4/generatecurl -X POST https://api.heygen.com/v2/video/av4/generate \ -H X-Api-Key: $HEYGEN_API_KEY \ -H Content-Type: application/json \ -d { image_key: image/741299e941764988b432ed3a6757878f/original.jpg, script: Hello! This is Avatar IV with enhanced quality., voice_id: 1bd001e7e50f421d891986aad5158bc8, video_orientation: landscape, video_title: My Avatar IV Video }字段类型必填说明image_keystring✓资产上传得到的 S3 图片 keyscriptstring✓数字人要说出的文本voice_idstring✓使用的音色video_orientationstringportrait/landscape/squarevideo_titlestring视频标题fitstringcover或containcustom_motion_promptstring动作/表情描述enhance_custom_motion_promptboolean是否用 AI 增强动作提示词TypeScript 封装interface AvatarIVRequest { image_key: string; script: string; voice_id: string; video_orientation?: portrait | landscape | square; video_title?: string; fit?: cover | contain; custom_motion_prompt?: string; enhance_custom_motion_prompt?: boolean; } interface AvatarIVResponse { error: null | string; data: { video_id: string; }; } async function generateAvatarIVVideo( config: AvatarIVRequest ): Promisestring { const response await fetch( https://api.heygen.com/v2/video/av4/generate, { method: POST, headers: { X-Api-Key: process.env.HEYGEN_API_KEY!, Content-Type: application/json, }, body: JSON.stringify(config), } ); const json: AvatarIVResponse await response.json(); if (json.error) { throw new Error(json.error); } return json.data.video_id; }画幅方向与 Fit 取值Orientation尺寸适用场景portrait720x1280TikTok、Storieslandscape1280x720YouTube、Websquare720x720Instagram FeedFit行为cover铺满画面可能裁掉边缘contain完整放入画面可能露出背景自定义动作提示词custom_motion_prompt用于控制数字人的动作与表情可配合enhance_custom_motion_prompt: true让 AI 扩写提示词const videoId await generateAvatarIVVideo({ image_key: image/.../original.jpg, script: Let me tell you about our product., voice_id: 1bd001e7e50f421d891986aad5158bc8, custom_motion_prompt: nodding head and smiling, enhance_custom_motion_prompt: true, });两种方案怎么选需要多个视频复用同一张照片形象并叠加训练时走 Avatar Group 流程单条视频、追求最新质量时直接用 Avatar IV。流程二AI 生成照片头像无需本地照片当手头没有合适的肖像照时可以用文本描述直接生成合成照片再喂给数字人管线。Endpoint:POST https://api.heygen.com/v2/photo_avatar/photo/generate重要以下 8 个字段全部必填。API 会拒绝缺失任何字段的请求。当用户只给出「生成一个职业男性形象」这类模糊需求时需要追问或为缺失字段选定合理默认值。必填字段字段类型允许值namestring生成头像的名称ageenumYoung Adult/Early Middle Age/Late Middle Age/Senior/UnspecifiedgenderenumWoman/Man/UnspecifiedethnicityenumWhite/Black/Asian American/East Asian/South East Asian/South Asian/Middle Eastern/Pacific/Hispanic/Unspecifiedorientationenumsquare/horizontal/verticalposeenumhalf_body/close_up/full_bodystyleenumRealistic/Pixar/Cinematic/Vintage/Noir/Cyberpunk/Unspecifiedappearancestring外观文本提示词服装、氛围、灯光等最长 1000 字符curl 示例curl -X POST https://api.heygen.com/v2/photo_avatar/photo/generate \ -H X-Api-Key: $HEYGEN_API_KEY \ -H Content-Type: application/json \ -d { name: Sarah Product Demo, age: Young Adult, gender: Woman, ethnicity: White, orientation: horizontal, pose: half_body, style: Realistic, appearance: Professional woman with a friendly smile, wearing a navy blue blazer over a white blouse, soft studio lighting, clean neutral background }响应只返回生成任务 ID{ error: null, data: { generation_id: 6a7f7f2795de4599bec7cf1e06babe30 } }查询生成状态Endpoint:GET https://api.heygen.com/v2/photo_avatar/generation/{generation_id}成功后会返回多张候选图URL 与image_key成对给出{ error: null, data: { id: 6a7f7f2795de4599bec7cf1e06babe30, status: success, image_url_list: [ https://resource2.heygen.ai/photo_generation/.../image1.jpg, https://resource2.heygen.ai/photo_generation/.../image2.jpg, https://resource2.heygen.ai/photo_generation/.../image3.jpg, https://resource2.heygen.ai/photo_generation/.../image4.jpg ], image_key_list: [ photo_generation/.../image1.jpg, photo_generation/.../image2.jpg, photo_generation/.../image3.jpg, photo_generation/.../image4.jpg ] } }状态机为pending/processing/success/failed。TypeScript 参考实现interface GeneratePhotoAvatarRequest { name: string; age: Young Adult | Early Middle Age | Late Middle Age | Senior | Unspecified; gender: Woman | Man | Unspecified; ethnicity: White | Black | Asian American | East Asian | South East Asian | South Asian | Middle Eastern | Pacific | Hispanic | Unspecified; orientation: square | horizontal | vertical; pose: half_body | close_up | full_body; style: Realistic | Pixar | Cinematic | Vintage | Noir | Cyberpunk | Unspecified; appearance: string; } interface GeneratePhotoAvatarResponse { error: string | null; data: { generation_id: string; }; } interface PhotoGenerationStatus { error: string | null; data: { id: string; status: pending | processing | success | failed; msg: string | null; image_url_list?: string[]; image_key_list?: string[]; }; } async function generatePhotoAvatar( config: GeneratePhotoAvatarRequest ): Promisestring { const response await fetch( https://api.heygen.com/v2/photo_avatar/photo/generate, { method: POST, headers: { X-Api-Key: process.env.HEYGEN_API_KEY!, Content-Type: application/json, }, body: JSON.stringify(config), } ); const json: GeneratePhotoAvatarResponse await response.json(); if (json.error) { throw new Error(Photo avatar generation failed: ${json.error}); } return json.data.generation_id; } async function waitForPhotoGeneration( generationId: string ): Promisestring[] { for (let i 0; i 60; i) { const response await fetch( https://api.heygen.com/v2/photo_avatar/generation/${generationId}, { headers: { X-Api-Key: process.env.HEYGEN_API_KEY! } } ); const json: PhotoGenerationStatus await response.json(); if (json.error) throw new Error(json.error); if (json.data.status success) { return json.data.image_key_list!; } if (json.data.status failed) { throw new Error(json.data.msg ?? Photo generation failed); } await new Promise((r) setTimeout(r, 5000)); } throw new Error(Photo generation timed out); }从实现看照片生成的轮询比头像处理更保守60 次、间隔 5 秒约 5 分钟窗口因为文生图任务耗时更长。AI 照片 → 头像组 → 视频的组合链路选用某张 AI 生成图后把它当作image_key交给 avatar group 创建接口并额外携带generation_id// 1. 生成 AI 照片 const generationId await generatePhotoAvatar({ name: Product Demo Host, age: Young Adult, gender: Woman, ethnicity: Unspecified, orientation: horizontal, pose: half_body, style: Realistic, appearance: Professional woman, navy blazer, friendly smile, soft lighting, }); // 2. 等待生成完成并取第一张结果 const imageKeys await waitForPhotoGeneration(generationId); const selectedImageKey imageKeys[0]; // 3. 用 AI 照片创建头像组注意带上 generation_id const createResponse await fetch( https://api.heygen.com/v2/photo_avatar/avatar_group/create, { method: POST, headers: { X-Api-Key: process.env.HEYGEN_API_KEY!, Content-Type: application/json, }, body: JSON.stringify({ image_key: selectedImageKey, name: Product Demo Host, generation_id: generationId, }), } ); const { data } await createResponse.json(); const talkingPhotoId data.id; // 4. 状态变为 completed 后生成视频 const videoId await generateVideo({ video_inputs: [{ character: { type: talking_photo, talking_photo_id: talkingPhotoId, }, voice: { type: text, input_text: Welcome to our product demo!, voice_id: 1bd001e7e50f421d891986aad5158bc8, }, }], dimension: { width: 1920, height: 1080 }, });生成前检查清单Pre-Generation Checklist调用 AI 生成接口前确保 8 个字段全部有值#字段追问话术 / 建议默认值1name这个头像叫什么名字2ageYoung Adult / Early Middle Age / Late Middle Age / Senior3genderWoman / Man4ethnicity选哪个族裔见上方枚举值5orientationhorizontal横版/ vertical竖版/ square6posehalf_body推荐/ close_up / full_body7styleRealistic推荐/ Cinematic / 其他8appearance描述服装、表情、灯光、背景若用户只给出模糊需求如「生成一个看起来专业的男性」应追问缺失字段或采用合理默认值例如Early Middle Age、Realistic风格、half_body姿态、horizontal方向。Appearance 提示词写法appearance是文本提示词越具体越好好的示例Professional woman with shoulder-length brown hair, wearing a light blue button-down shirt, warm friendly smile, soft studio lighting, clean white backgroundYoung man with short black hair, casual tech startup style, wearing a dark hoodie, confident expression, modern office background with plants避免含糊描述如 a nice person相互冲突的属性指定具体真实人物头像组的管理接口列出已有 Talking Photos查询账号下全部照片数字人Endpoint:GET https://api.heygen.com/v1/talking_photo.listcurl https://api.heygen.com/v1/talking_photo.list \ -H X-Api-Key: $HEYGEN_API_KEY响应{ code: 100, data: [ { id: ef0ed70f72c6497793e5e36e434d2aea, image_url: https://files2.heygen.ai/talking_photo/.../image.WEBP, circle_image: } ] }列表中每个id都可以直接作为视频生成时的talking_photo_id。向已有头像组追加照片Endpoint:POST https://api.heygen.com/v2/photo_avatar/avatar_group/addasync function addPhotosToGroup( groupId: string, imageKeys: string[], name: string ): Promisevoid { const response await fetch( https://api.heygen.com/v2/photo_avatar/avatar_group/add, { method: POST, headers: { X-Api-Key: process.env.HEYGEN_API_KEY!, Content-Type: application/json, }, body: JSON.stringify({ group_id: groupId, image_keys: imageKeys, name, }), } ); const json await response.json(); if (json.error) { throw new Error(json.error); } }训练头像组对头像组进行训练可提升动画质量Endpoint:POST https://api.heygen.com/v2/photo_avatar/traincurl -X POST https://api.heygen.com/v2/photo_avatar/train \ -H X-Api-Key: $HEYGEN_API_KEY \ -H Content-Type: application/json \ -d {group_id: 045c260bc0364727b2cbe50442c3a5bf}查询训练状态Endpoint:GET https://api.heygen.com/v2/photo_avatar/train/status/{group_id}查询与删除查询详情GET https://api.heygen.com/v2/photo_avatar/{id}async function getPhotoAvatar(id: string): PromisePhotoAvatarResponse { const response await fetch( https://api.heygen.com/v2/photo_avatar/${id}, { headers: { X-Api-Key: process.env.HEYGEN_API_KEY! } } ); return response.json(); }删除单个照片头像DELETE https://api.heygen.com/v2/photo_avatar/{id}async function deletePhotoAvatar(id: string): Promisevoid { const response await fetch( https://api.heygen.com/v2/photo_avatar/${id}, { method: DELETE, headers: { X-Api-Key: process.env.HEYGEN_API_KEY! }, } ); if (!response.ok) { throw new Error(Failed to delete photo avatar); } }删除整个头像组DELETE https://api.heygen.com/v2/photo_avatar_group/{group_id}async function deletePhotoAvatarGroup(groupId: string): Promisevoid { const response await fetch( https://api.heygen.com/v2/photo_avatar_group/${groupId}, { method: DELETE, headers: { X-Api-Key: process.env.HEYGEN_API_KEY! }, } ); if (!response.ok) { throw new Error(Failed to delete photo avatar group); } }API 端点速查表端点方法说明upload.heygen.com/v1/assetPOST上传图片返回image_key/v2/photo_avatar/avatar_group/createPOST由image_key创建照片头像组/v2/photo_avatar/avatar_group/addPOST向已有组追加照片/v2/photo_avatar/trainPOST训练头像组/v2/photo_avatar/train/status/{group_id}GET查询训练状态/v2/photo_avatar/{id}GET查询照片头像详情/状态/v2/photo_avatar/{id}DELETE删除照片头像/v2/photo_avatar_group/{id}DELETE删除头像组/v2/photo_avatar/photo/generatePOST文本生成 AI 照片/v2/photo_avatar/generation/{id}GET查询 AI 生成状态/v2/video/av4/generatePOSTAvatar IV由image_key直出视频/v1/talking_photo.listGET列出账号下全部 talking photos/v2/video/generatePOST用talking_photo_id生成视频除首行为独立域名外其余路径均基于https://api.heygen.com。照片要求、最佳实践与限制技术要求项要求格式JPEG、PNG分辨率最低 512x512px文件大小10MB 以下面部可见度清晰、正面质量指引光线——面部光照均匀、自然表情——中性或轻微微笑背景——简洁、无杂乱元素面部位置——居中、不被裁切清晰度——锐利、对焦准确角度——正面或轻微侧角最佳实践使用高质量照片——输入质量直接决定输出质量优先正脸肖像——最适合动画化保持中性表情——动画效果更自然追求最佳画质时用 Avatar IV——最新一代技术训练头像组——可提升动画质量复用talking_photo_id——头像创建一次后在多个视频中复用同一 ID已知限制照片质量对输出影响显著侧面大角度照片支持有限全身照可能无法正常动画化部分表情可能显得不自然处理时长随复杂度波动小结OpenMontage 的photo-avatars参考文档给出的照片数字人能力可以归纳为三条路径一是「上传照片 → Avatar Group → 轮询 →talking_photo_id入video_inputs」的标准四步链路适合需要复用与训练的正式生产二是 Avatar IV/v2/video/av4/generate的一步直出牺牲组级复用换取最新画质与更短链路三是 AI 照片生成8 字段全必填的photo/generate再回流到头像组链路解决「没有合适肖像」的问题。三条路径共享同一套HEYGEN_API_KEY鉴权与image_key资产模型配合 assets.md 的上传规范与 video-generation.md 的场景化请求体即可在 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),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价