首页
/ OpenMontage 接入 HeyGen Avatar 视频生成指南:`/v2/video/generate` 单场景与多场景工作流实战

OpenMontage 接入 HeyGen Avatar 视频生成指南:`/v2/video/generate` 单场景与多场景工作流实战

2026-09-07 21:02:54作者:蔡丛锟

本文基于开源仓库 OpenMontage 中 HeyGen/avatar-video 技能链路的参考文档(.agents/skills/heygen/references/video-generation.md,同内容亦维护在 .agents/skills/avatar-video/references/video-generation.md)编写。它系统讲解 HeyGen /v2/video/generate 端点的请求字段、单/多场景编排、三种配音输入、状态轮询、透明背景 WebM 合成等完整生产流程,并结合仓库中对应的技能定义与源码佐证调用关系。读完本文,你将掌握在不依赖本地 GPU 的前提下,通过 HeyGen Avatar API 精确生成「指定形象 + 指定文案 + 指定音色 + 逐场景背景」的数字人视频,并能把透明背景头像无缝叠加进屏幕录制或 Remotion 合成画面。


一、为什么需要 Avatar API 精确生成:先看它在本仓库技能体系中的定位

在深入字段细节前,有必要先厘清仓库里 HeyGen 相关技能的分工。OpenMontage 将 HeyGen 能力拆成了三个技能目录(见 .agents/skills/heygen/SKILL.md):

  • heygen:历史遗留技能,Frontmatter 中已明确标记 [DEPRECATED],仅作向后兼容保留;
  • create-video:面向「给定一段描述、让 AI 全自动出片」的 Video Agent / prompt 式生成;
  • avatar-video:面向「我要让头像 Y 逐字说台词 Z、每个场景换背景」的精确控制路径,其默认工作流第一条就是 POST /v2/video/generate

技能文档给出了清晰的选用决策表:只有当用户明确需要"逐字脚本不被打断、指定 voice_id、每场景不同 avatar/background、精确的单场景节奏、批量按规格生成"时,才走 /v2/video/generate 这条链路;否则优先使用 .agents/skills/create-video/SKILL.md。这一点决定了本篇文章的适用范围:本指南是"精密仪器"而非"傻瓜相机",它服务的是有精确控片需求的生产流程。

二、视频输出格式:先选对端点

端点 格式 适用场景
/v2/video/generate MP4 标准(推荐)——带背景的视频,最常见
/v1/video.webm WebM 透明背景——仅在需要把头像内容叠在别的画面背后时使用

绝大多数情况应使用带背景的 MP4。WebM 只在需要"透过头像看到背后的内容"时使用(例如把数字人主播叠加在屏幕录制画面上)。透明背景视频的成本更高、兼容面更窄,详见下文第八节。

三、最基本的视频生成请求(curl 起手式)

以一个最小可运行请求开始,先拿到能出片的骨架:

curl -X POST "https://api.heygen.com/v2/video/generate" \
  -H "X-Api-Key: $HEYGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "video_inputs": [
      {
        "character": {
          "type": "avatar",
          "avatar_id": "josh_lite3_20230714",
          "avatar_style": "normal"
        },
        "voice": {
          "type": "text",
          "input_text": "Hello! Welcome to HeyGen.",
          "voice_id": "1bd001e7e50f421d891986aad5158bc8"
        }
      }
    ],
    "dimension": {
      "width": 1920,
      "height": 1080
    }
  }'

这个请求的核心逻辑是:一个 video_inputs 条目 = 一"景" =「谁来说(character)+ 说什么/怎么发声(voice)+ 背后是什么(background)」。请求成功后会返回一个 video_id,后续靠它轮询状态、取回下载地址(见 视频状态轮询)。

四、请求字段全解

/v2/video/generate异步任务提交语义,字段分三层:顶层字段、video_inputs[] 内的 character / voice / background 子对象。

4.1 顶层字段

字段 类型 必填 说明
video_inputs array 视频输入对象数组,可容纳 1–50 个(即最多 50 景)
dimension object 视频尺寸 {width, height}
title string 视频标题,用于账号内组织管理
test boolean 测试模式:输出带水印、不消耗额度
caption boolean 是否启用自动字幕
callback_id string 自定义 ID,用于 Webhook 追踪
callback_url string 完成通知回调地址
folder_id string 存储目录 ID(视频归入指定文件夹)

4.2 video_inputs[].character 字段

字段 类型 必填 说明
type string "avatar""talking_photo"
avatar_id string ✓* Avatar ID(type="avatar" 时必填)
talking_photo_id string ✓* 照片 ID(type="talking_photo" 时必填)
avatar_style string "normal""closeUp""circle"
scale number 头像缩放系数
offset object 位置偏移 {x, y}

4.3 video_inputs[].voice 字段

字段 类型 必填 说明
type string "text"(TTS)、"audio"(上传音频)或 "silence"(静默)
voice_id string ✓* 音色 ID(type="text" 时必填)
input_text string ✓* 台词文本(type="text" 时必填)
audio_url string ✓* 音频 URL(type="audio" 时必填)
duration number ✓* 时长秒数(type="silence" 时必填)
speed number 语速 0.5–2.0(默认 1.0)
pitch number 音高 −20~20(默认 0)

4.4 video_inputs[].background 字段

字段 类型 必填 说明
type string "color""image""video"
value string 十六进制色值(type="color" 时使用)
url string 图片/视频 URL(type="image"/"video" 时使用)
fit string "cover""contain"

背景图片/视频尺寸建议与 dimension 匹配,避免缩放裁切损失构图,详见 背景配置画幅与分辨率

4.5 TypeScript 类型定义(含必填逻辑)

// Required fields have no '?' - optional fields have '?'
interface VideoInput {
  character: {
    type: "avatar" | "talking_photo";           // Required
    avatar_id?: string;                         // Required when type="avatar"
    talking_photo_id?: string;                  // Required when type="talking_photo"
    avatar_style?: "normal" | "closeUp" | "circle";
    scale?: number;
    offset?: { x: number; y: number };
  };
  voice: {
    type: "text" | "audio" | "silence";         // Required
    input_text?: string;                        // Required when type="text"
    voice_id?: string;                          // Required when type="text"
    audio_url?: string;                         // Required when type="audio"
    duration?: number;                          // Required when type="silence"
    speed?: number;
    pitch?: number;
  };
  background?: {
    type?: "color" | "image" | "video";
    value?: string;
    url?: string;
    fit?: "cover" | "contain";
  };
}

interface VideoGenerateRequest {
  video_inputs: VideoInput[];                   // Required
  dimension?: { width: number; height: number };
  test?: boolean;
  title?: string;
  caption?: boolean;
  callback_id?: string;
  callback_url?: string;
  folder_id?: string;
}

interface VideoGenerateResponse {
  error: null | string;
  data: {
    video_id: string;
  };
}

async function generateVideo(config: VideoGenerateRequest): Promise<string> {
  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 json: VideoGenerateResponse = await response.json();

  if (json.error) {
    throw new Error(json.error);
  }

  return json.data.video_id;
}

4.6 Python 等价实现

import requests
import os

def generate_video(config: dict) -> str:
    response = requests.post(
        "https://api.heygen.com/v2/video/generate",
        headers={
            "X-Api-Key": os.environ["HEYGEN_API_KEY"],
            "Content-Type": "application/json"
        },
        json=config
    )

    data = response.json()
    if data.get("error"):
        raise Exception(data["error"])

    return data["data"]["video_id"]

鉴权方式说明:以上请求均通过请求头 X-Api-Key: $HEYGEN_API_KEY 完成鉴权。仓库内该技能的前置条件是在环境中配置 HEYGEN_API_KEY(见 .agents/skills/heygen/SKILL.md 的 metadata 声明及 鉴权文档)。OpenMontage 的 API 侧封装同样遵循此约定——见 tools/video/heygen_video.pyinstall_instructionsHEYGEN_API_KEY 的要求。

五、完整配置示例与多场景视频

5.1 一条请求写满全部字段

const fullConfig: VideoGenerateRequest = {
  // Test mode (no credits consumed, watermarked output)
  test: false,

  // Video title (for organization)
  title: "Product Demo Video",

  // Video dimensions
  dimension: {
    width: 1920,
    height: 1080,
  },

  // Video scenes/inputs
  video_inputs: [
    {
      // Avatar configuration
      character: {
        type: "avatar",
        avatar_id: "josh_lite3_20230714",
        avatar_style: "normal",
      },

      // Voice configuration
      voice: {
        type: "text",
        input_text: "Welcome to our product demonstration!",
        voice_id: "1bd001e7e50f421d891986aad5158bc8",
        speed: 1.0,
        pitch: 0,
      },

      // Background configuration
      background: {
        type: "color",
        value: "#FFFFFF",
      },
    },
  ],
};

5.2 多场景:一次提交一整支"分镜"

video_inputs 数组支持 1–50 个场景条目,每一条都是独立的一"幕",可分别指定头像运镜风格、台词与背景。这比多次生成后拼接更省事,也更容易控制节奏——尤其适合"开场 → 特性演示 → 收尾"式的口播结构:

const multiSceneConfig = {
  video_inputs: [
    // Scene 1: Introduction
    {
      character: {
        type: "avatar",
        avatar_id: "josh_lite3_20230714",
        avatar_style: "normal",
      },
      voice: {
        type: "text",
        input_text: "Hello! Today I'll show you three key features.",
        voice_id: "1bd001e7e50f421d891986aad5158bc8",
      },
      background: {
        type: "color",
        value: "#1a1a2e",
      },
    },
    // Scene 2: Feature 1
    {
      character: {
        type: "avatar",
        avatar_id: "josh_lite3_20230714",
        avatar_style: "closeUp",
      },
      voice: {
        type: "text",
        input_text: "First, let's look at our dashboard.",
        voice_id: "1bd001e7e50f421d891986aad5158bc8",
      },
      background: {
        type: "image",
        url: "https://example.com/dashboard-bg.jpg",
      },
    },
    // Scene 3: Conclusion
    {
      character: {
        type: "avatar",
        avatar_id: "josh_lite3_20230714",
        avatar_style: "normal",
      },
      voice: {
        type: "text",
        input_text: "Thanks for watching! Try it today.",
        voice_id: "1bd001e7e50f421d891986aad5158bc8",
      },
      background: {
        type: "color",
        value: "#1a1a2e",
      },
    },
  ],
  dimension: { width: 1920, height: 1080 },
};

值得注意的实践点:同一 avatar 在多场景间通过 avatar_style(如 normalcloseUp)切换景别,既能保持人物身份连续,又能制造画面的节奏变化——这正符合 avatar-video 技能默认工作流中"每场景一概念"的编排建议(参考 脚本撰写指南)。

六、两种角色类型与三种配音输入

6.1 角色类型

标准 Avatar(真人数字分身)

{
  character: {
    type: "avatar",
    avatar_id: "josh_lite3_20230714",
    avatar_style: "normal"
  }
}

Talking Photo(照片说话)——用一张静态人像照片生成会开口的 presenter:

{
  character: {
    type: "talking_photo",
    talking_photo_id: "your_talking_photo_id"
  }
}

talking_photo_id 需预先通过照片头像流程创建,参见 照片头像文档

6.2 配音类型:text / audio / silence

Text-to-Speech(最常用)——直接喂台词:

{
  voice: {
    type: "text",
    input_text: "Your script here",
    voice_id: "1bd001e7e50f421d891986aad5158bc8",
    speed: 1.0,  // 0.5 - 2.0
    pitch: 0     // -20 to 20
  }
}

Custom Audio(自定义音频)——配音已由外部工具(如仓库 skills 中 ElevenLabs / Fish Audio / Azure TTS 等本地音色管线)生成时,直接给音频 URL,HeyGen 负责做口型同步:

{
  voice: {
    type: "audio",
    audio_url: "https://example.com/your-audio.mp3"
  }
}

Silence(静默)——type="silence" 配合 duration,用于需要"人物不发声但保持画面/口型自然停顿"的场景。

七、完整工作流:提交 → 轮询 → 下载

HeyGen 的视频生成是异步的,POST 只返回 video_id,真正的成片需要轮询状态接口 GET /v2/videos/{video_id} 直到 status = "completed"。以下是一套完整的"生成→等待→取回 URL"代码:

async function createVideo(script: string, avatarId: string, voiceId: string) {
  // 1. Generate video
  console.log("Starting video generation...");
  const videoId = await generateVideo({
    video_inputs: [
      {
        character: {
          type: "avatar",
          avatar_id: avatarId,
          avatar_style: "normal",
        },
        voice: {
          type: "text",
          input_text: script,
          voice_id: voiceId,
        },
        background: {
          type: "color",
          value: "#FFFFFF",
        },
      },
    ],
    dimension: { width: 1920, height: 1080 },
  });

  console.log(`Video ID: ${videoId}`);

  // 2. Poll for completion
  console.log("Waiting for video completion...");
  const videoUrl = await waitForVideo(videoId);

  console.log(`Video ready: ${videoUrl}`);
  return videoUrl;
}

// Helper function for polling
async function waitForVideo(videoId: string): Promise<string> {
  const maxAttempts = 60;
  const pollInterval = 10000; // 10 seconds

  for (let i = 0; i < maxAttempts; i++) {
    const response = await fetch(
      `https://api.heygen.com/v2/videos/${videoId}`,
      { headers: { "X-Api-Key": process.env.HEYGEN_API_KEY! } }
    );

    const { data } = await response.json();

    if (data.status === "completed") {
      return data.video_url;
    } else if (data.status === "failed") {
      throw new Error(data.failure_message || "Video generation failed");
    }

    await new Promise((r) => setTimeout(r, pollInterval));
  }

  throw new Error("Video generation timed out");
}

状态接口的四态语义与超时策略在仓库参考文档 视频状态与轮询 中有完整展开:pending(排队)→ processing(生成中)→ completed(可取件)→ failed(失败,含 failure_code / failure_message)。经验值:单支视频通常 5–15 分钟,高峰期或长脚本可能超过 20 分钟。因此推荐:

  • 超时设 15–20 分钟(即 900,000–1,200,000 ms);
  • 演讲稿超过 2 分钟时预期 15 分钟以上;
  • 长视频优先"异步检查"而非长驻轮询——保存 video_id,稍后回来查状态。

八、错误处理与开发期加速

8.1 常见失败的分诊模式

async function generateVideoSafe(config: VideoGenerateRequest) {
  try {
    const videoId = await generateVideo(config);
    return { success: true, videoId };
  } catch (error) {
    // Common errors
    if (error.message.includes("quota")) {
      console.error("Insufficient credits");
    } else if (error.message.includes("avatar")) {
      console.error("Invalid avatar ID");
    } else if (error.message.includes("voice")) {
      console.error("Invalid voice ID");
    } else if (error.message.includes("script")) {
      console.error("Script too long or invalid");
    }

    return { success: false, error: error.message };
  }
}

8.2 Test Mode:免费试错开关

test: true 打开,就能以带水印、不消耗额度的方式验证整套配置是否合法、出片节奏是否满意——开发期应当默认开启,仅最终出片时关闭:

const config = {
  test: true, // Watermarked output, no credits consumed
  video_inputs: [...],
};

8.3 脚本长度与停顿控制

不同套餐对单场景台词长度有限制,规划脚本时应先按档位预估:

套餐档位 最大字符数
Free ~500
Creator ~1,500
Team ~3,000
Enterprise ~5,000+

想要控制口播节奏,可在台词中插入 SSML 风格的 <break> 停顿标签:

const script = "Welcome to our demo. <break time=\"1s\"/> Let me show you the features.";
  • 格式<break time="Xs"/>,其中 X 为秒数(如 1s1.5s0.5s);
  • 关键约束:标签前后必须留有空格word <break time="1s"/> word),直接粘连会导致标签不被识别;
  • 连续多个 <break> 会被自动合并为总时长的一次停顿;
  • 停顿节奏与情感化音色的更多规则见 配音与音色指南

九、生产级工作流:自动选用头像默认音色

直接硬编码 avatar_id / voice_id 只适合验证。生产环境中更稳的做法是:先列头像 → 取该头像的 default_voice_id(官方预匹配音色)→ 再生成,从而避免"男像配女声"之类的低级错误;若头像没有默认音色,再按性别人工配对(配音指南 给出了完整的配对策略与多语言示例)。

interface VideoGenerationResult {
  videoId: string;
  videoUrl: string;
  duration: number;
  avatarId: string;
  voiceId: string;
  avatarName: string;
}

async function generateAvatarVideo(
  script: string,
  options: {
    avatarId?: string; // Specific avatar, or will pick first available
    width?: number;
    height?: number;
  } = {}
): Promise<VideoGenerationResult> {
  const { width = 1920, height = 1080 } = options;
  let { avatarId } = options;

  // 1. List avatars if no specific one provided
  if (!avatarId) {
    console.log("Listing available avatars...");
    const listResponse = await fetch("https://api.heygen.com/v2/avatars", {
      headers: { "X-Api-Key": process.env.HEYGEN_API_KEY! },
    });
    const listData = await listResponse.json();

    if (!listData.data?.avatars?.length) {
      throw new Error("No avatars available");
    }
    avatarId = listData.data.avatars[0].avatar_id;
  }

  // 2. Get avatar details including default_voice_id
  console.log(`Getting details for avatar: ${avatarId}`);
  const detailsResponse = await fetch(
    `https://api.heygen.com/v2/avatar/${avatarId}/details`,
    { headers: { "X-Api-Key": process.env.HEYGEN_API_KEY! } }
  );
  const { data: avatar } = await detailsResponse.json();

  if (!avatar.default_voice_id) {
    throw new Error(`Avatar ${avatar.name} has no default voice - select voice manually`);
  }

  console.log(`Using avatar: ${avatar.name} with default voice: ${avatar.default_voice_id}`);

  // 3. Generate video using avatar's default voice
  const videoId = await generateVideo({
    video_inputs: [{
      character: {
        type: "avatar",
        avatar_id: avatar.id, // from details response
        avatar_style: "normal",
      },
      voice: {
        type: "text",
        input_text: script,
        voice_id: avatar.default_voice_id, // pre-matched default voice
        speed: 1.0,
      },
      background: {
        type: "color",
        value: "#1a1a2e",
      },
    }],
    dimension: { width, height },
  });

  console.log(`Video ID: ${videoId}`);

  // 3. Wait for completion (20 minute timeout - generation can take 15+ min)
  console.log("Waiting for video generation (typically 5-15 minutes, can be longer)...");
  const result = await waitForVideo(
    videoId,
    process.env.HEYGEN_API_KEY!,
    (status, elapsed) => {
      console.log(`  [${Math.round(elapsed / 1000)}s] ${status}`);
    },
    1200000 // 20 minute timeout for safety
  );

  return {
    videoId,
    videoUrl: result.video_url!,
    duration: result.duration!,
    avatarId: avatar.id,
    voiceId: avatar.default_voice_id,
    avatarName: avatar.name,
  };
}

// Usage - let it pick an avatar automatically
const result = await generateAvatarVideo(
  "Hello! Welcome to our product demonstration."
);
console.log(`Video ready: ${result.videoUrl}`);

// Or specify a known avatar_id
const result2 = await generateAvatarVideo(
  "Hello! Welcome to our product demonstration.",
  { avatarId: "josh_lite3_20230714" }
);

十、透明背景视频(WebM):何时用、怎么用

10.1 决策依据:别为不需要透明的地方付代价

不需要 WebM 的场景(请直接用 MP4):

  • 只需在头像上方叠加动效文字/图形;
  • 带纯色背景的画中画(PiP);
  • 标准主讲人出镜视频。

必须用 WebM 的场景

  • 头像叠加在屏幕录制上(Loom 风格);
  • 头像"漂浮"在视频背景之上;
  • 需要真实 alpha 通道做合成的场景。

端点注意:WebM 端点 /v1/video.webm 的请求结构与 /v2/video/generate 不同,且 WebM 仅支持 normalcloseUp 两种风格——circle 圆形风格不支持。想要圆形头像请在后处理阶段(Remotion / 视频编辑器)做圆形遮罩。

10.2 WebM 请求字段

字段 类型 必填 说明
avatar_pose_id string Avatar 姿势 ID(取自 avatar 详情)
avatar_style string "normal""closeUp"(不支持 circle)
input_text string ✓* 台词文本(不使用 input_audio 时必填)
voice_id string ✓* 音色 ID(与 input_text 搭配时必填)
input_audio string ✓* 音频 URL(不使用 input_text 时必填)
dimension object {width, height}(默认 1280×720)

二选一约束:必须提供 input_text + voice_id input_audio,两者不可同时提供。

10.3 curl 示例

curl -X POST "https://api.heygen.com/v1/video.webm" \
  -H "X-Api-Key: $HEYGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "avatar_pose_id": "josh_lite3_20230714",
    "avatar_style": "normal",
    "input_text": "Hello! This video has a transparent background.",
    "voice_id": "1bd001e7e50f421d891986aad5158bc8",
    "dimension": {
      "width": 1920,
      "height": 1080
    }
  }'

10.4 TypeScript 封装

interface WebMVideoRequest {
  avatar_pose_id: string;                      // Required
  avatar_style: "normal" | "closeUp";          // Required (no circle support)
  input_text?: string;                         // Required if not using input_audio
  voice_id?: string;                           // Required with input_text
  input_audio?: string;                        // Required if not using input_text
  dimension?: { width: number; height: number };
}

async function generateTransparentVideo(
  script: string,
  avatarPoseId: string,
  voiceId: string
): Promise<string> {
  const response = await fetch("https://api.heygen.com/v1/video.webm", {
    method: "POST",
    headers: {
      "X-Api-Key": process.env.HEYGEN_API_KEY!,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      avatar_pose_id: avatarPoseId,            // Required
      avatar_style: "normal",                  // Required: "normal" or "closeUp"
      input_text: script,                      // Required (with voice_id)
      voice_id: voiceId,                       // Required (with input_text)
      dimension: { width: 1920, height: 1080 },
    }),
  });

  const { data } = await response.json();
  return data.video_id;
}

10.5 MP4 vs WebM 速查

场景 格式 原因
头像上叠加动效文字 MP4 叠加层在头像之上,无需透明
标准主讲人视频 MP4 更简单、兼容性更好
Loom 风格(头像盖在屏幕录制上) WebM + normal/closeUp 需要透明,后期裁成圆形
头像浮于视频内容上 WebM 需要透出头像背后的内容

10.6 生产案例:Loom 风格叠加 + Remotion 圆形遮罩

先生成透明 WebM(此处选择 closeUp 近景,更接近真人主播窗效果):

// Generate avatar with transparent background
const videoId = await fetch("https://api.heygen.com/v1/video.webm", {
  method: "POST",
  headers: { "X-Api-Key": apiKey, "Content-Type": "application/json" },
  body: JSON.stringify({
    avatar_pose_id: avatarPoseId,              // Required
    avatar_style: "closeUp",                   // Required: "normal" or "closeUp" only
    input_text: script,                        // Required (with voice_id)
    voice_id: voiceId,                         // Required (with input_text)
    dimension: { width: 1920, height: 1080 },
  }),
}).then(r => r.json()).then(d => d.data.video_id);

再在 Remotion 合成里把它作为第二层 Video,用 CSS borderRadius: "50%" 圆角遮罩压成"悬浮圆窗":

import { Video, AbsoluteFill } from "remotion";

export const LoomStyleVideo: React.FC<{
  screenRecordingUrl: string;
  avatarWebmUrl: string;
}> = ({ screenRecordingUrl, avatarWebmUrl }) => {
  return (
    <AbsoluteFill>
      {/* Screen recording as base layer */}
      <Video src={screenRecordingUrl} style={{ width: "100%", height: "100%" }} />

      {/* Avatar with circular mask applied in CSS */}
      <Video
        src={avatarWebmUrl}
        style={{
          position: "absolute",
          bottom: 20,
          left: 20,
          width: 150,
          height: 150,
          borderRadius: "50%", // Circular mask
          overflow: "hidden",
          objectFit: "cover",
        }}
      />
    </AbsoluteFill>
  );
};

WebM 产物与 MP4 共用同一状态查询端点,轮询到 completedvideo_url 指向的将是 .webm 文件,可直接喂给上面的 <Video src>。若想在此基础上叠加字幕/文字层,参考 Remotion 集成字幕文字叠加;长任务不轮询而改用回调的,见 Webhooks

十一、最佳实践清单(可直接对照自检)

  1. 生成前预览头像——下载 preview_image_url 让用户看到形象后再花钱出片(参考 头像选择);
  2. 优先用头像的默认音色——多数 avatar 带官方预匹配的 default_voice_id,出片自然度最高;
  3. 兜底策略:人工按性别配对——无默认音色时保证 avatar 与 voice 的性别一致(配音指南);
  4. 先校验输入——生成前确认 avatar_idvoice_id 真实存在(可分别通过 /v2/avatars/v2/voices 拉取校验);
  5. 开发期开 test mode——不消耗额度、出片带水印,用于全流程联调;
  6. 预留充足的超时——建议 15–20 分钟,因为常规生成 10–15 分钟、长脚本更久;
  7. 长视频走异步模式——保存 video_id 稍后查状态,而不是长驻进程干等;
  8. 优雅处理错误——对 quota / avatar / voice / script 四类错误分别分诊;
  9. 监控进度——轮询时输出耗时与状态,便于向用户反馈进度;
  10. 精简台词——脚本保持简洁自然,利于控制长度与节奏;
  11. 按用途定画幅——YouTube 16:9、短视频 9:16、信息流 1:1,720p 草稿/1080p 出片(画幅与分辨率)。

十二、回到仓库:Avatar 生成在 OpenMontage 里的源码呼应

理解了上面这套 API 契约后,再看 OpenMontage 源码中两处 HeyGen 相关实现,能帮你把"外部 API"与"本仓库工具体系"对应起来:

其一是 API 侧的工具封装 tools/video/heygen_video.py。它把 HeyGen 作为云端视频生成聚合入口provider = "heygen"capability = "video_generation"),通过 tools/video/_shared.py 中的 HEYGEN_PROVIDERS 将 VEO 3.x、Sora、Kling、Runway、Seedance 等模型暴露为统一 provider_variant(如 veo_3_1sora_v2_prokling_pro),并声明了成本估算(estimate_quality_cost)、运行时长估算、重试策略与"无 GPU、纯云端"的资源画像(ResourceProfile(cpu_cores=1, ...))。注意:该工具面向的是 HeyGen 的文生视频/图生视频工作流text_to_video / image_to_video),与本文讲解的 Avatar 精确控片/v2/video/generate)是两个不同的能力面——前者聚合视频大模型,后者编排数字人出镜。

其二是技能侧的编排入口 .agents/skills/avatar-video/SKILL.md。它的默认工作流五步为:列头像(/v2/avatars)→(按需)列音色(/v2/voices)→ 写脚本 → POST /v2/video/generate → 轮询 /v2/videos/{video_id}。这正是本文全部知识点的落地编排;当仓库工具连了 mcp__heygen__* MCP 时,建议优先使用 MCP 工具完成状态查询、视频列表与删除(它们会自动处理鉴权与请求格式化),而 Avatar 生成与头像/音色列举按技能约定走直接 API 调用。

追溯说明:本文引用的 .agents/skills/heygen/references/video-generation.md 与 .agents/skills/avatar-video/references/video-generation.md 内容完全一致——前者所在的 heygen 技能已在 .agents/skills/heygen/SKILL.md 中标注弃用,avatar-video(精确控片)与 create-video(提示词出片)是仓库当前推荐的替代入口。查阅本文提到的头像、音色、状态等补充文档时,两份副本均可读,建议以 avatar-video 目录下的为主。

结语

/v2/video/generate 是 HeyGen Avatar 能力中最具"制片人思维"的一个端点:一次请求携带 1–50 个场景,逐场景指定人物、台词、音色与背景,配合 /v1/video.webm 的透明通道输出,几乎可以覆盖"精确口播 → 多景切换 → 叠加合成"的全部常规制片需求。掌握字段语义、轮询节奏、test mode 与默认音色策略之后,你便可以在 OpenMontage 的 Agent 工作流中把它当作一个高确定性的"数字人出镜组件"来调用——让 AI 编码助手真正替你完成从脚本到成片的最后一公里。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391