tutorial6 分钟阅读

MiniMax Hailuo 2.3 API 集成:用视频接口生成复杂人体运动

面向开发者的 ToAPIs MiniMax Hailuo 2.3 视频 API 指南:人体运动提示词写法、当前 6/10 秒与 768P/1080P 请求约定,以及 cURL/Python 示例。

ToAPIs Engineering & Evaluation Team
TL;DR - 核心要点
  • 文生视频与首帧图生视频使用目录字符串 MiniMax-Hailuo-2.3;MiniMax-Hailuo-2.3-Fast 仅支持图生视频。
  • 当前约定允许 6 或 10 秒,分辨率 768P 或 1080P;1080P 只支持 6 秒,提示词上限为 2,000 个字符。
  • 文档中的运镜指令如 [Push in] 写在提示词文本里,不是独立字段。Hailuo 2.3 没有尾帧输入。
  • 请持久化任务 id,轮询 GET /v1/videos/generations/{id},并确认当前账户定价,不要沿用未经核实的每秒单价。

MiniMax Hailuo 2.3 API 集成:用视频接口生成复杂人体运动

目标模型: MiniMax-Hailuo-2.3
推理端点: https://api.toapis.com/v1/videos/generations
相关阅读: MiniMax H3 API 指南 · H3 运镜提示词 · 自动化 R2V 流水线


1. 核心摘要与性能速览 (TL;DR)

  • 任务:在 ToAPIs 的视频生成端点上提交文生视频,或带首帧的图生视频,用来制作角色与人体运动镜头。
  • 约定:MiniMax-Hailuo-2.3 接受整数时长 6 或 10 秒,分辨率 768P 或 1080P。1080P 只支持 6 秒。当前 API 参考将提示词上限写为 2,000 个字符。
  • 模型 ID:文生视频与图生视频使用目录字符串 MiniMax-Hailuo-2.3。MiniMax-Hailuo-2.3-Fast 仅支持图生视频,且必须提供首帧 URL。这两个 ID 都不能与 minimax-h3 互换。
  • 运镜用语:ToAPIs 的 Hailuo 2.3 参考文档列出了 [Push in]、[Pan left, Pedestal up] 这类括号指令。下表是当前文档中的词汇,硬编码前请再对一次线上文档。
  • 协议:Bearer REST。从提交响应里取出任务 id,在截止时间内轮询 GET /v1/videos/generations/{task_id}(或 GET /v1/tasks/{task_id})。客户端超时并不等于上游任务已经失败。

2. 复杂人体运动的提示词写法

ToAPIs 公开目录把 MiniMax Hailuo 2.3 描述为面向角色运动、表情与风格的视频模型,适合表现性叙事和角色短片。这是产品定位,不是“肢体绝不变形”的独立测评。正式上线前,请用清晰的动作语言写提示词,并人工复核取样。

一条好用的人体运动提示词,会先写清身体力学,再写风格:谁在动、哪条肢体先动、重心如何转移、动作如何起势和收势。对比时长或分辨率时,先稳住这一段核心描述,以免把措辞变化误当成模型差异。

ToAPIs Hailuo 2.3 API 参考将下列运镜指令写在提示词里,而不是单独的请求字段。前端请求约定仍然把 prompt 当作文本校验。同一对括号里最多组合 3 条指令表示同时运动,或在句子里按顺序写出先后运镜。

类别文档中的指令
横摇[Pan left]、[Pan right]
俯仰[Tilt up]、[Tilt down]
推 / 拉[Push in]、[Pull out]
升降[Pedestal up]、[Pedestal down]
横移[Truck left]、[Truck right]
变焦[Zoom in]、[Zoom out]
其他[Shake]、[Tracking shot]、[Static shot]

抽象的首帧姿态节点图进入 ToAPIs 网关并分出多路运动取样

图 1:把静止姿态当作首帧输入,在提示词里写随后的动作,再通过 ToAPIs 网关提交一次生成请求。

一条方便测试的压缩模板:

text
SUBJECT and PRIMARY ACTION (lead limb, weight shift, follow-through), ENVIRONMENT, [CAMERA], STYLE NOTES

示例:A contemporary dancer in a black practice leotard plants the left foot, then uncoils a slow 360-degree turn with the right arm leading and the torso stacked over the standing leg, warehouse skylight, [Tracking shot], photorealistic, no morphing limbs.

图生视频时,在 image_urls 里放一个可公开访问的首帧 URL。图片是起始帧,提示词描述随后的运动。当前文档中的图片限制是:JPG、JPEG、PNG 或 WebP;小于 20 MB;短边大于 300 px;宽高比介于 2:5 与 5:2 之间。不要在 image_urls 里传 base64,本地文件请先上传。

MiniMax-Hailuo-2.3-Fast 不接受文生视频,必须提供首帧 URL。Hailuo 2.3 没有文档化的尾帧字段;首尾帧过渡属于 MiniMax-Hailuo-02,不是这个 ID。不要把 H3 的 ratio 或 reference_videos 等字段直接套到 Hailuo 2.3 请求上。

Playground 选项可能会显示小写的 768p / 1080p,当前 API 示例使用 768P 和 1080P。批量自动化前,先确认你的账户实际接受哪一种写法。把同样的运镜措辞拿到 MiniMax H3 上也可以作为提示词文本,但时长、分辨率和媒体模式约定不同,换 ID 前请重读那篇指南。


3. 生产级实现:cURL 与 Python

步骤 1:用 cURL 提交

bash
curl -X POST "https://api.toapis.com/v1/videos/generations" \
  -H "Authorization: Bearer $TOAPIS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "MiniMax-Hailuo-2.3",
    "prompt": "A contemporary dancer in a black practice leotard plants the left foot, then uncoils a slow 360-degree turn with the right arm leading and the torso stacked over the standing leg, warehouse skylight, [Tracking shot], photorealistic, no morphing limbs",
    "duration": 6,
    "resolution": "768P"
  }'

步骤 2:Python 辅助函数与轮询

官方文档当前写的是公开源站 https://toapis.com(中国大陆请使用 https://toapis.cn)。本系列其他指南使用 https://api.toapis.com。选定一个基址并保持一致。下面的示例遵循文档中的任务查询路径以及 completed / failed 状态;上线前请对照你账户的 API 参考,确认 id、result.data[0].url 和响应包络。

python
import os
import time
import requests

API_KEY = os.environ["TOAPIS_API_KEY"]
BASE = "https://api.toapis.com"
ENDPOINT = f"{BASE}/v1/videos/generations"
HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}


def dispatch_motion_clip(
    prompt: str,
    duration: int = 6,
    resolution: str = "768P",
    image_url: str | None = None,
    model: str = "MiniMax-Hailuo-2.3",
) -> str:
    if resolution == "1080P" and duration != 6:
        raise ValueError("1080P currently supports a 6-second duration only")
    payload = {
        "model": model,
        "prompt": prompt,
        "duration": duration,
        "resolution": resolution,
        "metadata": {"prompt_optimizer": True, "aigc_watermark": False},
    }
    if image_url:
        payload["image_urls"] = [image_url]
    elif model == "MiniMax-Hailuo-2.3-Fast":
        raise ValueError("MiniMax-Hailuo-2.3-Fast requires a first-frame image_urls value")
    res = requests.post(ENDPOINT, headers=HEADERS, json=payload, timeout=30)
    res.raise_for_status()
    data = res.json()
    task_id = data.get("id") or data.get("task_id")
    if not task_id:
        raise RuntimeError(f"Unexpected submission envelope: {data}")
    return task_id


def poll_task(task_id: str, deadline_s: int = 300) -> str:
    poll_url = f"{BASE}/v1/videos/generations/{task_id}"
    interval = 5.0
    start = time.time()
    while time.time() - start < deadline_s:
        time.sleep(interval)
        poll = requests.get(poll_url, headers=HEADERS, timeout=15)
        if poll.status_code == 429:
            retry_after = poll.headers.get("Retry-After")
            time.sleep(float(retry_after) if retry_after else min(interval * 2, 30))
            continue
        poll.raise_for_status()
        data = poll.json()
        status = data.get("status")
        if status == "completed":
            return data["result"]["data"][0]["url"]
        if status == "failed":
            raise RuntimeError(f"Generation failed: {data.get('error')}")
        interval = min(interval * 1.5, 10.0)
    raise TimeoutError(f"Task {task_id} exceeded {deadline_s}s; check status before retrying")


if __name__ == "__main__":
    prompt = (
        "A contemporary dancer in a black practice leotard plants the left foot, "
        "then uncoils a slow 360-degree turn with the right arm leading and the "
        "torso stacked over the standing leg, warehouse skylight, [Tracking shot], "
        "photorealistic, no morphing limbs"
    )
    task_id = dispatch_motion_clip(prompt)
    print("Task:", task_id)
    print("Video:", poll_task(task_id))

把提示词模板版本和任务记录放在一起,这样才能分清是模型变了还是措辞变了。若要做首帧任务,给 dispatch_motion_clip 传入 image_url=。Fast SKU 必须提供该参数。

Hailuo 2.3 的基础时长是 6 或 10 秒。不要把 1080P 和 duration: 10 一起发送。若你需要连续的 4–15 秒时长、参考媒体或尾帧输入,那是另一套约定,请看 H3 API 指南 和 R2V 流水线教程。


4. 错误处理与状态码对照

下表只是排查起点,并不保证与 ToAPIs 的精确错误码一一对应。HTTP 查询成功后,仍然要读取任务 status。

HTTP 状态常见类别建议操作
400字段非法、组合不受支持,或媒体模式冲突核对精确模型 ID,确认时长只能是 6 或 10,1080P 只能搭配 6 秒,Fast 任务必须带 image_urls。不要在 Hailuo 2.3 上发送尾帧字段
401缺少或无效的 API 密钥在 ToAPIs 控制台轮换密钥,并确认 Authorization 头
429速率或并发限制如有 Retry-After 就按其等待;加抖动退避;只在安全时重试
5xx 或网络超时网关或上游暂时异常重新提交前先查任务状态;使用有上限的重试策略

WaitTime=min⁡(MaxWait,BaseInterval×2attempt)+Uniform(0,1)\text{WaitTime} = \min(\text{MaxWait}, \text{BaseInterval} \times 2^{\text{attempt}}) + \text{Uniform}(0, 1)


5. 定价与 FinOps ROI

Estimated cost=successful billable jobs×current account rate for that model, duration, and resolution\text{Estimated cost} = \text{successful billable jobs} \times \text{current account rate for that model, duration, and resolution}

  • 不要沿用策划稿里的单价。 按秒或按条计费、计费单位,以及对失败任务的处理,都会随模型、分辨率、时长、线路和账户变化。ToAPIs 定价页上的官方厂商参考行仅供展示,未必等于你账户的实际扣费。预测镜头成本前,请查阅当前目录和你的账户报价。
  • Fast 是另一个 SKU,不是同一 ID 上的免费加速开关。文档写明 MiniMax-Hailuo-2.3-Fast 仅支持图生视频,请单独确认它的账户价格。
  • 把花费控制在提示词层:先用 768P 和 6 秒打样,保留带版本的模板,一次只改一个变量;客户端超时后,先查任务状态再决定是否重提。
  • 厂商直签合同常带年框、席位和预付门槛。ToAPIs 计费通常是按量付费,请以账户当前条款为准。

6. 常见问题

结构化问答见文章 frontmatter 中的 FAQ。摘要:请求里的模型字符串是 MiniMax-Hailuo-2.3,不是连字符形式的页面 slug,也不是 H3 的 ID;1080P 仅支持 6 秒;Fast 必须提供首帧 URL,且不支持文生视频;文档中的运镜指令写在提示词里,不是独立字段;Hailuo 2.3 没有尾帧输入。


7. 行动清单

  • 在 ToAPIs 开发者门户 创建密钥。
  • 用 MiniMax-Hailuo-2.3、resolution: "768P" 和 6 秒时长冒烟测试上面的 cURL。
  • 确认账户接受的是 768P 还是 768p,并对 GET /v1/videos/generations/{id} 做有截止时间的轮询。
  • 接下来:若需要另一套时长或媒体约定,阅读 H3 运镜指南;并在 Hailuo 2.3 模型指南 查看当前目录状态。

本文提到的模型与接口

MiniMaxVIDEO

minimax-hailuo-2.3

当前费率:38.8 credits /request
MiniMaxVIDEO

minimax-hailuo-2.3-fast

当前费率:27.2 credits /request
MiniMaxVIDEO

minimax-h3

当前费率:20.8 credits /second

相关技术文章

tutorial3 分钟阅读

Seedance 2.0 Mini API 评测:低成本高吞吐视频生成

面向开发者的 Seedance 2.0 Mini 评测:约 16–20 秒出片、原生 720p/24fps,以及 $0.012/秒的高并发社媒与广告流水线成本结构。

TO
ToAPIs 研发评测组
#Seedance 2.0 Mini