资讯动态

OpenMontage 中的 HeyGen 素材上传指南:单步二进制上传与三类素材实战

发布时间:2026/9/10 7:51:24 来源:尧图企业网站定制
OpenMontage 中的 HeyGen 素材上传指南单步二进制上传与三类素材实战【免费下载链接】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 仓库中create-video技能的参考文档 assets.md系统讲解 HeyGen 素材图片、视频、音频上传接口从POST https://upload.heygen.com/v1/asset单步上传的请求/响应结构到背景图、会说话照片、自定义音频三种素材的实际接入方式。读完本文你可以直接在脚本或 Agent 工作流中完成“本地素材 → HeyGen 资产 ID/URL → 视频生成配置”的完整链路。文档在 OpenMontage 技能体系中的位置assets.md 是create-video技能提示词驱动视频生成的 9 个参考文档之一。在 SKILL.md 的 Quick Reference 表中它对应“Upload reference files for prompt”这一任务定位为“Uploading images, videos, audio as references”——即把品牌图、产品截图等参考文件先上传到 HeyGen再让 Video Agent 在生成视频时引用。同一个技能族中avatar-video精确控制型技能也维护了同名的素材上传参考文档.claude/skills/avatar-video/references/assets.md两者服务于“先传素材、后引用”的同一模式。上传流程单步 POST 原始二进制HeyGen 的素材上传是单步流程把原始文件二进制直接 POST 到上传端点Content-Type头必须与文件的 MIME 类型一致。请求体就是文件数据本身不需要 JSON 包装也不需要表单字段——这与 multipart/form-data 风格的上传接口有明显区别。端点POST https://upload.heygen.com/v1/asset请求头Header必填说明X-Api-Key✓HeyGen API 密钥通常来自环境变量HEYGEN_API_KEYContent-Type✓文件的 MIME 类型如image/jpeg响应字段字段类型说明codenumber状态码100表示成功data.idstring唯一资产 ID供视频生成时引用data.namestring素材名称data.file_typestringimage、video或audiodata.urlstring上传后可访问的文件 URLdata.image_keystring | null创建“上传照片数字人”的密钥仅图片返回data.folder_idstring文件夹 ID未放入文件夹时为空data.metastring | null素材元数据data.created_tsnumber创建时间的 Unix 时间戳其中data.id和data.url是后续所有用途的“把手”引用类字段背景、音频用 URL实体类字段talking photo用 ID。各语言上传实现curl最小可用的验证命令适合在 shell 中确认密钥与端点连通性curl -X POST https://upload.heygen.com/v1/asset \ -H X-Api-Key: $HEYGEN_API_KEY \ -H Content-Type: image/jpeg \ --data-binary ./background.jpgTypeScriptBuffer 方式文档给出的标准实现包含完整响应类型定义便于在 TS 项目中做类型约束import fs from fs; import path from path; interface AssetUploadResponse { code: number; data: { id: string; name: string; file_type: string; url: string; image_key: string | null; folder_id: string; meta: string | null; created_ts: number; }; msg: string | null; message: string | null; } async function uploadAsset(filePath: string, contentType: string): PromiseAssetUploadResponse[data] { const resolvedPath path.resolve(filePath); const fileBuffer fs.readFileSync(resolvedPath); const response await fetch(https://upload.heygen.com/v1/asset, { method: POST, headers: { X-Api-Key: process.env.HEYGEN_API_KEY!, Content-Type: contentType, }, body: fileBuffer, }); const json: AssetUploadResponse await response.json(); if (json.code ! 100) { throw new Error(json.message ?? Upload failed); } return json.data; } // Usage const asset await uploadAsset(./background.jpg, image/jpeg); console.log(Uploaded asset: ${asset.id}); console.log(Asset URL: ${asset.url});注意错误处理的关键点判断依据是响应体里的code ! 100而不是 HTTP 状态码错误信息优先取message字段。TypeScript流式上传大文件当文件较大时用fs.createReadStream流式发送避免整文件读入内存需要显式设置Content-Length并加上 Node 侧fetch流式请求必需的duplex: halfimport fs from fs; import path from path; import { stat } from fs/promises; async function uploadLargeAsset(filePath: string, contentType: string): PromiseAssetUploadResponse[data] { const resolvedPath path.resolve(filePath); const fileStats await stat(resolvedPath); const fileStream fs.createReadStream(resolvedPath); const response await fetch(https://upload.heygen.com/v1/asset, { method: POST, headers: { X-Api-Key: process.env.HEYGEN_API_KEY!, Content-Type: contentType, Content-Length: fileStats.size.toString(), }, body: fileStream as any, // ts-ignore - duplex is needed for streaming duplex: half, }); const json: AssetUploadResponse await response.json(); if (json.code ! 100) { throw new Error(json.message ?? Upload failed); } return json.data; }Pythonimport requests import os def upload_asset(file_path: str, content_type: str) - dict: with open(file_path, rb) as f: response requests.post( https://upload.heygen.com/v1/asset, headers{ X-Api-Key: os.environ[HEYGEN_API_KEY], Content-Type: content_type }, dataf ) data response.json() if data.get(code) ! 100: raise Exception(data.get(message, Upload failed)) return data[data] # Usage asset upload_asset(./background.jpg, image/jpeg) print(fUploaded asset: {asset[id]}) print(fAsset URL: {asset[url]})Python 版用requests的dataf文件句柄直接作为请求体实现与 curl--data-binary等价的行为。支持的 Content-Type类型Content-Type用途JPEGimage/jpeg背景图、会说话照片PNGimage/png背景图、叠加层MP4video/mp4视频背景WebMvideo/webm视频背景MP3audio/mpeg自定义音频输入WAVaudio/wav自定义音频输入选型原则与文档“Best Practices”一致照片类素材用 JPEG带透明通道的图形用 PNG。从 URL 上传先下载再直传如果素材已经托管在线文档给出的策略是“校验 → 下载到内存 → 以二进制直传 HeyGen”而不是让 HeyGen 去拉取 URLasync function uploadFromUrl(sourceUrl: string, contentType: string): PromiseAssetUploadResponse[data] { // 1. Validate and download the file const url new URL(sourceUrl); if (url.protocol ! https:) { throw new Error(Only HTTPS URLs are supported); } const sourceResponse await fetch(sourceUrl); const buffer Buffer.from(await sourceResponse.arrayBuffer()); // 2. Upload directly to HeyGen const response await fetch(https://upload.heygen.com/v1/asset, { method: POST, headers: { X-Api-Key: process.env.HEYGEN_API_KEY!, Content-Type: contentType, }, body: buffer, }); const json: AssetUploadResponse await response.json(); if (json.code ! 100) { throw new Error(json.message ?? Upload failed); } return json.data; }这里的https:协议校验是一个值得保留的细节非 HTTPS 源会被显式拒绝避免中间人篡改素材内容。上传后的三类使用方式上传响应里的asset.url与asset.id分别对接三种场景1. 作为背景图video_inputs中的background对象使用上传响应的 URLconst videoConfig { video_inputs: [ { character: { type: avatar, avatar_id: josh_lite3_20230714, avatar_style: normal, }, voice: { type: text, input_text: Hello, this is a video with a custom background!, voice_id: 1bd001e7e50f421d891986aad5158bc8, }, background: { type: image, url: asset.url, // Use the URL from the upload response }, }, ], };2. 作为会说话照片Talking Phototalking_photo角色引用的是资产 ID而不是 URL——这是与背景图的关键区别const talkingPhotoConfig { video_inputs: [ { character: { type: talking_photo, talking_photo_id: asset.id, // Use the ID from the upload response }, voice: { type: text, input_text: Hello from my talking photo!, voice_id: 1bd001e7e50f421d891986aad5158bc8, }, }, ], };3. 作为自定义音频输入voice.type设为audio时audio_url填上传后的 URLconst audioConfig { video_inputs: [ { character: { type: avatar, avatar_id: josh_lite3_20230714, avatar_style: normal, }, voice: { type: audio, audio_url: asset.url, // Use the URL from the upload response }, }, ], };完整工作流背景图 脚本 → 生成视频把上传和生成串起来的端到端示例上传背景 → 组装配置 → 调用POST /v2/video/generate→ 返回video_idasync function createVideoWithCustomBackground( backgroundPath: string, script: string ): Promisestring { // 1. Upload background console.log(Uploading background...); const background await uploadAsset(backgroundPath, image/jpeg); // 2. Create video config const config { video_inputs: [ { character: { type: avatar, avatar_id: josh_lite3_20230714, avatar_style: normal, }, voice: { type: text, input_text: script, voice_id: 1bd001e7e50f421d891986aad5158bc8, }, background: { type: image, url: background.url, }, }, ], dimension: { width: 1920, height: 1080 }, }; // 3. Generate video console.log(Generating video...); 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(config), }); const { data } await response.json(); return data.video_id; }返回的video_id之后按create-video技能的 video-status.md 所述轮询GET /v2/videos/{video_id}直到completed。同样的“先传参考素材再引用”的模式也适用于 Video Agentvideo-agent.md 中展示了上传 logo、产品截图后以files: [{ asset_id: ... }]数组的形式把它们挂到POST /v1/video_agent/generate请求里。素材限制与最佳实践限制文件大小上限10MB图片尺寸建议与视频输出尺寸一致音频时长应与预期视频长度匹配资产保留策略长期不活跃的资产可能被删除因此不要依赖旧资产 ID 的永久有效性。最佳实践原文档五条先优化图片——上传前缩放到与视频尺寸一致选对格式——照片用 JPEG带透明通道的图形用 PNG上传前本地校验——先检查文件类型与大小避免无效请求处理上传错误——为失败上传实现重试逻辑缓存资产 ID——同一素材跨多次视频生成复用避免重复上传。源码佐证OpenMontage 工具层的另一种上传路径技能文档描述的是面向 API 直连场景的 v1 单步上传端点。而 OpenMontage 的 Python 工具层实现则采用了一套不同的上传路径从源码结构看可以印证“上传只是获取可用 URL 的手段端点形态可以互换”tools/video/_shared.py#L556-L592 中的upload_image_heygen(image_path, api_key)优先调用POST https://api.heygen.com/v2/assets/upload获取预签名上传地址两步拿upload_urlurl再 PUT 文件内容失败时降级到 fal.ai 存储上传upload_image_fal先initiate再PUT该函数由 tools/video/_shared.py#L617-L627 的generate_heygen_video()调用当operation为image_to_video且只给了本地reference_image_path时先把本地图片上传换取reference_image_url再交给POST /v1/workflows/executionsworkflow_type: GenerateVideoNode生成对应工具类 HeyGenVideo 声明了reference_image_url/reference_image_path两个输入字段get_status()以HEYGEN_API_KEY是否存在决定可用性且agent_skills明确关联create-video技能——即该工具在 Agent 侧的配套知识就是本文所讲的 assets 参考文档族。两条路径的差异值得注意技能文档的 v1 端点一次 POST 即完成并直接返回id/url/image_key等完整资产信息工具层源码走的 v2 预签名端点返回的是“上传地址 最终 URL”更偏向大文件与存储中转。二者都遵循同一个核心约定——先取得 HeyGen 可访问的 URL/ID再作为生成请求的引用字段。在实际选用时以你可访问的 API 版本与密钥权限为准若需要生成带自定义背景/音频的 avatar 视频create-video技能文档中给出的 v1 直传 video_inputs配置组合是最直接的可复现方案。小结assets.md 给出了 HeyGen 素材管理的完整闭环单步二进制上传curl/TypeScript/Python 三语言实现、六种 Content-Type 的用途映射、从 URL 转存的上传模式、背景图/会说话照片/音频三类引用方式以及 10MB 上限、保留策略等限制条件。结合仓库中 HeyGenVideo 工具 与 upload_image_heygen 实现 可以看到这套“上传换引用”的模式在 OpenMontage 的 Agent 技能文档与 Python 工具层中是同一契约的两种落法可直接用于在提示词视频生成与精确控制的 avatar 视频两条链路中接入自有素材。【免费下载链接】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 小时内与您沟通定制方案

免费获取报价