搜索

搜索 HiAPI 模型、工具和资源。

返回博客
教程4 分钟阅读

HeyGen Avatar V API 怎么用?选形象到下载成片

台词与音频两条路径,附形象声音查值、cURL、响应结构、有限轮询和视频/SRT下载。

HiAPI 编辑部HeyGen Avatar V数字人视频API 接入

HeyGen Avatar V 选一个预置数字人,输入台词或音频,就能生成口型同步视频。HiAPI 按输出时长收费,每秒 $0.15,10 秒视频 $1.50。

HeyGen Avatar V 已在 HiAPI 上线,打开模型页先选形象和声音,再接 API。下面这条商务讲解就是已有成片:

Brandon Office Sitting Front、Dexter - Professional;16:9,成片 1280×720、约 8 秒。原请求为1080p,本页为720p网页版本。

Hi, I'm Daniel. Send me your quarterly numbers, and I'll walk your team through what changed and what to do next.

用这个提示词生成 → 台词已填好;手选上面的形象、声音、1080p 和 16:9,输出选 MP4。

在线怎么试?

  1. 打开预填链接,保留这句短台词。
  2. 选择形象和声音;这些参数需要手选,链接只带入台词。
  3. 设置画幅、分辨率和格式,首次可用上面的组合。
  4. 生成后试听配音、检查口型,下载成片,再换成自己的文案。

记下这次试用的形象、声音和画幅,批量生成时沿用,只换台词,出镜人和声音就能保持一致。

V 从预置形象中选择出镜人;要让自己的照片出镜,选 Avatar IV。

所有分辨率都按实际输出秒数收费,失败全额退款;完整费用见 价格与预算表。

API 要准备什么?

在控制台创建 API key。请求中明确写 model、必填的 input.avatar,再从 prompt 与 audio_url 中选一个。形象和声音用文档卡片的英文请求值,中文名只用于辨认。

台词直接读出,镜头指令别放进 prompt。音频驱动传可访问的 HTTP(S) 地址,并移除 prompt 和 voice。无需传 duration,时长由台词朗读或音频决定。

手里有什么传哪些驱动字段
要读出的台词avatar + prompt;voice 可选
已录好的声音avatar + audio_url;省略 prompt 和 voice

形象查值:参数文档 → 数字人形象,展开全部后搜索并复制英文「请求值」;声音同样在 预置声音 查找。英文页对应 Request value,不要把中文展示名放入请求。

**音频驱动最小完整请求:**把占位地址换成自己的公开可访问音频 URL。省略的画幅、分辨率和格式使用文档默认值;音频最长600秒、最大32 MiB。

{
  "model": "heygen-avatar-v",
  "input": {
    "avatar": "Brandon Office Sitting Front",
    "audio_url": "https://example.com/your-recording.mp3"
  }
}

用 cURL 创建和查询任务

把 Key 占位符换成自己的值;这个请求沿用商务案例参数:

export HIAPI_API_KEY="sk-YOUR_KEY"
curl --fail-with-body --connect-timeout 10 --max-time 60 \
  -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "heygen-avatar-v",
    "input": {
      "avatar": "Brandon Office Sitting Front",
      "prompt": "Hi, I\u0027m Daniel. Send me your quarterly numbers, and I\u0027ll walk your team through what changed and what to do next.",
      "voice": "Dexter - Professional",
      "aspect_ratio": "16:9",
      "resolution": "1080p",
      "caption": false,
      "output_format": "mp4"
    }
  }'

检查 HTTP 状态与 JSON 的 code,成功创建后保存 data.taskId。随后只查询同一个任务:

TASK_ID="REPLACE_WITH_data.taskId"
curl --fail-with-body --connect-timeout 10 --max-time 60 \
  "https://api.hiapi.ai/v1/tasks/$TASK_ID" \
  -H "Authorization: Bearer $HIAPI_API_KEY"

queued、handling、archiving 表示处理中;终态是 success 或 fail。成功后按 data.output[].type 找 video,启用字幕时再找 caption。读取产物 url,按 expireAt 及时下载。

**响应结构示例:**第一段为创建成功,第二段为启用字幕后的成功查询;任务 ID、URL 和过期时间都是示意值;expireAt 是数字,单位为 Unix 秒。POST 超时或响应丢失时,先查任务记录,禁止盲目再次 POST;有 ID 就继续 GET。

{
  "code": 200,
  "data": {"taskId": "TASK_ID_FROM_CREATE"}
}
{
  "code": 200,
  "data": {
    "taskId": "TASK_ID_FROM_CREATE",
    "status": "success",
    "output": [
      {"type": "video", "url": "https://example.com/result.mp4", "expireAt": 4070908800},
      {"type": "caption", "url": "https://example.com/result.srt", "expireAt": 4070908800}
    ]
  }
}

Python:创建、有限轮询、下载

先安装 requests,在环境变量 HIAPI_API_KEY 中设置 Key。代码只提交一次,轮询最多 30 分钟;超时保留任务 ID 继续查询。

import os
import time
from pathlib import Path
import requests

API = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}"}
payload = {
    "model": "heygen-avatar-v",
    "input": {
        "avatar": "Brandon Office Sitting Front",
        "prompt": "Hi, I'm Daniel. Send me your quarterly numbers, and I'll walk your team through what changed and what to do next.",
        "voice": "Dexter - Professional",
        "aspect_ratio": "16:9",
        "resolution": "1080p",
        "caption": False,
        "output_format": "mp4",
    },
}

def api_request(method, url, **kwargs):
    advice = (
        "Submission state may be unknown; check task history before another POST."
        if method == "POST"
        else f"Continue GET with the saved task ID: {url.rsplit('/', 1)[-1]}."
    )
    try:
        response = requests.request(
            method, url, headers=HEADERS, timeout=(10, 30), **kwargs
        )
    except requests.RequestException:
        raise RuntimeError(f"Network error. {advice}") from None
    if not response.ok:
        raise RuntimeError(f"HTTP {response.status_code}. {advice}")
    try:
        body = response.json()
    except ValueError:
        raise RuntimeError(f"Response is not JSON. {advice}") from None
    if not isinstance(body, dict):
        raise RuntimeError(f"Unexpected response shape. {advice}")
    if body.get("code") != 200 or not isinstance(body.get("data"), dict):
        raise RuntimeError(f"API error: code={body.get('code')}. {advice}")
    return body["data"]

# Submit once. No automatic POST retries.
created = api_request("POST", API, json=payload)
task_id = created.get("taskId")
if not isinstance(task_id, str) or not task_id:
    raise RuntimeError("Missing taskId; check task history before resubmitting.")
print("taskId:", task_id)  # Keep this ID to resume GET queries.
deadline = time.monotonic() + 1800
while time.monotonic() < deadline:
    data = api_request("GET", f"{API}/{task_id}")
    status = data.get("status")
    if status == "fail":
        raise RuntimeError(f"Task failed: {task_id}; inspect its task record.")
    if status == "success":
        break
    if status not in ("queued", "handling", "archiving"):
        raise RuntimeError(f"Unexpected task status: {status}")
    time.sleep(8)
else:
    raise TimeoutError(f"Polling timed out; continue GET for taskId={task_id}.")

raw_outputs = data.get("output")
if not isinstance(raw_outputs, list):
    raise RuntimeError(f"Missing output list; inspect taskId={task_id}.")
outputs = {
    item["type"]: item
    for item in raw_outputs
    if isinstance(item, dict) and item.get("type") in ("video", "caption")
}
if "video" not in outputs:
    raise RuntimeError("Successful task has no video artifact.")
for kind, artifact in outputs.items():
    if not isinstance(artifact.get("url"), str) or not artifact["url"]:
        raise RuntimeError(f"Missing {kind} URL; inspect taskId={task_id}.")
    suffix = payload["input"]["output_format"] if kind == "video" else "srt"
    target = Path(f"avatar-v.{suffix}")
    # Artifact downloads do not need the API Authorization header.
    with requests.get(artifact["url"], stream=True, timeout=(10, 120)) as response:
        response.raise_for_status()
        with target.open("wb") as file:
            for chunk in response.iter_content(chunk_size=1024 * 1024):
                if chunk:
                    file.write(chunk)
    print("saved:", target)

哪些参数需要显式设置?

字段规则与默认值
avatar必填,英文形象请求值
prompt / audio_url二选一;台词最多 5,000 字符,音频最长 600 秒、最大 32 MiB
voice台词路径可选,默认 Warm Pro Narrator
resolution默认 720p,可选 1080p、小写 4k
aspect_ratio默认 16:9;另有 9:16、4:5、5:4、1:1、auto
fit默认 cover,可选 contain
caption默认 false;true 返回独立 SRT
output_format默认 mp4,可选 webm
remove_background默认 false;透明用途选 true 配合 webm,先用短片检查所选形象
background对象;type 为 color 或 image,value 填十六进制颜色或 HTTP(S) 图片 URL

分辨率和画幅是两个参数:横版讲解用 16:9,竖屏口播用 9:16,都在请求里写明。下载后看一眼文件实际尺寸。透明 WebM 先确认所选形象的去背景效果,再导入剪辑软件。

字幕不烧进画面,要在播放器或剪辑软件里叠加。下面的竖屏案例设了 caption=true,返回独立 SRT;视频 1080×1920、6.52 秒,请求为1080p、9:16。独立 SRT 字幕 可在剪辑时导入。

New drop just landed: our travel mug keeps coffee hot for twelve hours. Swipe up and grab yours today!

用这个提示词生成 → 台词已填好;手选 Riley Casual Front、Charming Charles - Friendly、9:16 和 1080p,开启字幕,输出选 MP4。

上线前检查哪四项?

  1. 验证输入:形象、驱动方式、英文请求值和长度限制。
  2. 保存任务 ID:查询失败或超时后用同一个 ID 继续 GET。
  3. 找齐产物:成功后按 type 找 video,开启字幕时找 caption。
  4. 下载检查:确认实际尺寸、声音和字幕文件,再交付。

常见问题怎么处理?

  • **输入校验有问题:**检查 avatar、二选一驱动字段、英文请求值、台词与音频上限;分辨率写 4k,删除 duration。
  • **POST 超时:**先查任务记录;已有 taskId 就继续 GET,每次 POST 都创建新任务。
  • **任务 fail:**查看任务记录里的错误原因,修改相应输入后再提交。
  • **下载链接过期:**成功后及时保存产物;字幕从 type=caption 读取。

服务端可在 input 同级加 "callback": {"url": "https://yourapp.com/webhook", "when": "final"},接收终态任务对象,并用 GET 补偿查询。

价格细节见秒单价和预算表,换形象参考两个案例,完整取值见API 参数文档。

用这个提示词生成 → 台词已填好;手选商务形象和声音、1080p、16:9、MP4,先生成一句,再接入完整脚本。

现在就用 HiAPI 生成

选一个模型,输入你的提示词,直接查看生成结果。

HiAPI Blog

相关文章

HiAPI

现在就用 HiAPI 生成

开始生成