视频生成模型 API 接入实操:即梦 Seedance 2.0 / 可灵 / 通义万相统一调用

即梦 Seedance 2.0、可灵 Kling、通义万相 Wan 2.5 这类视频生成模型,官方接口各有各的参数命名和鉴权方式,但调用形态高度一致:都是提交任务 → 拿 task_id → 轮询结果的异步模型。本文给出三家 API 的接入步骤、参数对照表与一份可运行的统一调用封装,并说明如何用 OpenAI 兼容端点把它们收敛到一处管理。视频生成类接口的接入与计费可参考 🚀 某中转平台 API 聚合模型站。


一、为什么视频生成 API 值得单独讲

文本模型是「请求即返回」,视频模型不是。一条 5 秒 1080p 视频的生成耗时通常在几十秒到几分钟,任何一次同步调用都会把 HTTP 连接拖死。这带来三个和文本 API 完全不同的工程问题:

  • 必须异步:所有主流视频生成 API 都采用「创建任务 + 轮询/回调」,没有例外。
  • 参数维度多:文本模型只有 prompt 和 max_tokens,视频模型多了分辨率、宽高比、时长、帧率、运动强度、首尾帧、镜头控制等一整组参数。
  • 失败率高且贵:视频任务排队、超时、额度不足是常态,而一次失败的成本远高于一次文本请求,重试策略必须单独设计。

也正因为参数杂、各家命名不统一,把多家视频模型收敛到一个兼容端点的收益比文本模型更大——你只需要维护一套轮询逻辑和一套错误处理。


二、三家主流视频 API 的参数对照

能力即梦Seedance 2.0可灵 Kling通义万相 Wan 2.5
文生视频支持支持支持
图生视频支持(首帧)支持(首帧 + 尾帧)支持
分辨率480p / 720p / 1080p720p / 1080p480p / 720p / 1080p
时长5s / 10s5s / 10s5s(部分档位 10s)
宽高比16:9 / 9:16 / 1:116:9 / 9:16 / 1:116:9 / 9:16 / 1:1
运动控制镜头运动参数Motion Control(轨迹/运镜)基础运镜
返回形态task_id 轮询task_id 轮询task_id 轮询
鉴权API KeyAPI Key(部分需签名)API Key

各家参数命名与可选值迭代很快,以上为接入形态层面的对照,具体字段名请以官方最新文档为准。

可以看到三家的差异主要在能力上限(谁能控运镜、谁能给首尾帧),而不是调用范式。这就给统一封装留出了空间。


三、异步任务模型的标准流程

无论哪家,流程都是这四步:

1. POST /v1/video/generations  →  提交任务,立即返回 task_id
2. GET  /v1/video/tasks/{id}   →  查询状态:queued / running / succeeded / failed
3. 轮询直到终态( succeeded 或 failed )
4. 从响应里取 video_url,下载并转存( URL 通常有有效期 )

关键点:第 1 步返回不等于生成完成。很多初接的人在这里踩坑,拿到 task_id 就去取 URL,结果拿到空值。


四、统一调用封装(Python)

下面这段代码把「提交 → 轮询 → 取结果」封装成一个函数,用 OpenAI 兼容端点做统一入口,切换模型只改 model 参数。

import os, time, requests

BASE_URL = os.getenv("VIDEO_BASE_URL", "https://easy88ai.com/v1")
API_KEY  = os.getenv("VIDEO_API_KEY")

HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}

def create_video_task(prompt: str, model: str, **kwargs) -> str:
    """提交视频生成任务,返回 task_id"""
    payload = {
        "model": model,
        "prompt": prompt,
        "resolution": kwargs.get("resolution", "1080p"),
        "aspect_ratio": kwargs.get("aspect_ratio", "16:9"),
        "duration": kwargs.get("duration", 5),
    }
    # 各家扩展参数(首尾帧、运镜等)按需透传
    payload.update(kwargs.get("extra", {}))

    r = requests.post(f"{BASE_URL}/video/generations",
                      headers=HEADERS, json=payload, timeout=30)
    r.raise_for_status()
    return r.json()["task_id"]


def wait_for_video(task_id: str,
                   interval: int = 10,
                   timeout: int = 900) -> dict:
    """轮询任务直到终态,返回完整结果"""
    deadline = time.time() + timeout
    while time.time() < deadline:
        r = requests.get(f"{BASE_URL}/video/tasks/{task_id}",
                         headers=HEADERS, timeout=30)
        r.raise_for_status()
        data = r.json()
        status = data.get("status")

        if status == "succeeded":
            return data
        if status == "failed":
            raise RuntimeError(f"生成失败:{data.get('error')}")

        time.sleep(interval)

    raise TimeoutError(f"任务 {task_id} 超过 {timeout}s 未出结果")


if __name__ == "__main__":
    tid = create_video_task(
        prompt="雨后的青石板路,镜头缓慢推进,水洼倒映着暖黄路灯",
        model="seedance-2.0",          # 换成 kling / wan-2.5 即可切换模型
        duration=5,
        resolution="1080p",
    )
    print("task_id:", tid)

    result = wait_for_video(tid)
    print("video_url:", result["video_url"])

三个细节值得注意:

  1. wait_for_video 里用固定间隔 + 总超时而不是无限轮询。固定间隔实现简单,但如果想更优雅,可以改成指数退避(首次 5s,逐步加到 30s 封顶),减少无效请求。
  2. video_url 一般有有效期(常见 24 小时)。拿到后要立刻转存到自己的对象存储,别直接把厂商 URL 存进业务数据库。
  3. extra 字段用来透传各家独有参数(比如可灵的轨迹控制、即梦的镜头运动),这样主逻辑不用为每家写分支。

五、踩坑清单

1. 轮询太密被限流 视频任务本来就要跑几十秒,5 秒一次轮询纯属浪费。建议起步 10 秒,超过 60 秒还没完成再放慢到 20–30 秒。

2. 忽略了排队态 queuedrunning 是两回事。高峰期 queued 可能持续几分钟,如果你的超时设成 60 秒,会误判成失败。

3. 重试导致重复扣费 提交任务这一步如果超时,你并不知道服务端到底建没建任务。不要用同一个请求体盲目重试,应该先用 prompt + 时间窗口 去查一次任务列表确认,否则容易生成两条一样的视频、扣两次钱。

4. 参数组合不被支持 不是所有 分辨率 × 时长 × 宽高比 组合都合法,比如某些档位只支持 5 秒。非法组合有的厂商在提交时就报 400,有的要到任务执行阶段才失败。接入前建议把常用组合跑一遍摸底。

5. 中文 prompt 的编码 部分厂商对 prompt 长度和字符有校验,长中文描述先做截断和清洗,避免提交时直接 400。


六、统一端点带来的实际收益

把多家视频模型收敛到一个兼容地址后,业务侧的变化是:

  • 一套轮询逻辑:不用为每个厂商写一套状态机。
  • 一个 Key 管多家:密钥轮换、额度监控集中在一处。
  • 失败可降级:某家排队过长或失败时,换个 model 参数就能切到备用模型,业务代码零改动。
  • 成本可横向对比:同样的调用量,不同模型的实际消耗能放在一起看,方便选型。

对刚起步的团队,建议先用兼容端点把流程跑通,等业务量上来、对某个模型形成强依赖后,再考虑是否直连官方。


七、小结

视频生成 API 的接入难点不在「怎么发请求」,而在异步状态管理、失败重试和参数兼容这三件事上。先把提交-轮询-转存的骨架搭稳,再把各家差异收敛到 extra 透传字段里,后面加新模型就只是加一个模型名而已。

本文代码示例基于 OpenAI 兼容调用形态编写,不同服务商在字段命名上会有差异,请以实际接入文档的「模型名与参数」章节为准。

0
0
0
0
评论
未登录
暂无评论