跳到主要内容
置顶公告算力就位,只等你来 | 国芯词元 RTX 5090 裸金属正式上线

视频生成接口

全部文档视频生成

用接口生成视频。视频生成是异步任务:提交后马上拿到任务 ID,生成通常需要几分钟,之后查询任务取得视频。请求与任务对象沿用火山方舟(Seedance)视频生成接口的字段。

不写代码时,可以在控制台的 视频生成 页提交任务、查看进度、播放与下载视频;用你的 API 密钥提交的任务也列在那里。

准备工作

  • API 密钥:在控制台的 API 密钥 页新建,把下文的 sk-... 换成你的密钥。
  • 接入地址:https://api.gxcy.com/v1,与 OpenAI 接口相同。
  • 模型:控制台的 模型 页中类型为“视频生成”的模型,下文以 MiniMax-H3 为例。

接口一览

方法与路径 用途
POST /v1/videos 提交任务
GET /v1/videos/{id} 查询一个任务
GET /v1/videos 列出任务,或按 ID 批量查询
DELETE /v1/videos/{id} 取消排队中的任务,或删除已结束的任务
GET /v1/videos/{id}/content 下载视频
POST /v1/assets 上传参考图片
GET /v1/models/〔模型名称〕 查询模型支持的参数

请求头带上 Authorization: Bearer <密钥>。任务只有提交它的 API 密钥查得到。

提交任务

curl https://api.gxcy.com/v1/videos \
  -H "Authorization: Bearer sk-..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "MiniMax-H3",
    "content": [
      {"type": "text", "text": "一只橘猫在窗台上伸懒腰,阳光从窗外照进来"}
    ],
    "duration": 5,
    "resolution": "720p",
    "ratio": "16:9"
  }'

返回任务对象,status 为 queued,记下 id 用来查询:

{
  "id": "vid_01JB8Y3N5Q8V7K2M4X6Z9C1D3F",
  "model": "MiniMax-H3",
  "status": "queued",
  "created_at": 1793091790,
  "updated_at": 1793091790,
  "usage": null
}

请求参数

参数 类型 必填 说明
model string 是 模型名称
content array 是 提示词与参考图片,见下文
duration integer 否 时长(秒);-1 由模型决定
resolution string 否 分辨率,如 480p、720p、1080p
ratio string 否 画面比例,如 16:9、9:16、1:1;adaptive 跟随首帧图片
generate_audio boolean 否 是否生成声音
seed integer 否 随机种子:相同的种子与参数生成相近的画面
return_last_frame boolean 否 同时返回最后一帧的图片
callback_url string 否 任务结束时回调的地址,见下文“回调”
metadata object 否 你自己的键值,原样返回;最多 16 个键,值是不超过 512 字的字符串
  • 除 model 与 content 外,各模型支持的参数与取值不同。模型不支持时返回 400 unsupported_parameter,任务不会提交,也不收费。
  • 不给的参数用模型的默认值,实际使用的值见任务对象里的同名字段。
  • 一个任务只生成一条视频,输出为 MP4。

查询模型支持哪些参数:

curl https://api.gxcy.com/v1/models/MiniMax-H3 \
  -H "Authorization: Bearer sk-..."

返回的 video_capabilities 列出可用的分辨率(resolutions)、比例(ratios)、时长范围(duration)与默认值,以及是否支持首帧(first_frame)、尾帧(last_frame)、声音(generate_audio)、随机种子(seed)。没有列出的就是不支持。

提示词与参考图片

content 是一个数组,按顺序放入:

type 写法 说明
text {"type": "text", "text": "…"} 提示词
image_url {"type": "image_url", "role": "first_frame", "image_url": {"url": "…"}} 参考图片;role 为 first_frame(首帧)、last_frame(尾帧)或 reference_image(参考图)
  • 图片地址可以是 https:// 链接、data URI(data:image/png;base64,…),或上传后的素材 ID(asset_…,见下文“上传参考图片”)。
  • 首帧、尾帧各最多一张。能不能同时给首尾帧与参考图、各给几张,由模型决定。
  • 整个请求体不超过 64 MB,大图片请上传后用素材 ID 引用。

避免重复提交

提交超时、不知道是否成功时,带同一个 Idempotency-Key 请求头重试即可:24 小时内同一个键、同样的请求只建一个任务,返回已有的任务,不重复计费。同一个键用于不同的请求时返回 409 idempotency_key_reused。

curl https://api.gxcy.com/v1/videos \
  -H "Authorization: Bearer sk-..." \
  -H "Idempotency-Key: order-1024" \
  ...

查询结果

curl https://api.gxcy.com/v1/videos/vid_01JB8Y3N5Q8V7K2M4X6Z9C1D3F \
  -H "Authorization: Bearer sk-..."

status 的取值:

status 含义 已结束
queued 排队中 否
running 生成中;progress 为 0–100 的进度,没有进度时为 null 否
succeeded 已完成,可以下载 是
failed 失败,原因见 error 是
cancelled 已取消 是
expired 超过 48 小时仍未完成 是

遇到不认识的 status 时当作还没结束,继续查询。

完成的任务:

{
  "id": "vid_01JB8Y3N5Q8V7K2M4X6Z9C1D3F",
  "model": "MiniMax-H3",
  "status": "succeeded",
  "content": {
    "video_url": "https://api.gxcy.com/v1/videos/vid_01JB8Y3N5Q8V7K2M4X6Z9C1D3F/content?expires=1793095390&sig=…"
  },
  "usage": {"items": {"units.video_seconds.720p": 5}, "source": "reported"},
  "duration": 5,
  "resolution": "720p",
  "ratio": "16:9",
  "created_at": 1793091790,
  "started_at": 1793091802,
  "completed_at": 1793092090,
  "expires_at": 1793696590,
  "error": null
}
  • content.video_url 是下载链接,自带签名,不需要 API 密钥,可以直接放进 <video> 标签或交给播放器。链接 1 小时内有效,每次查询任务都会换新,过期后重新查询即可。
  • expires_at 之后视频不能再下载,请在此之前保存。
  • 时间都是 Unix 秒。
  • 请求了 return_last_frame 时,content.last_frame_url 是最后一帧图片的下载链接。

用 Python 提交并等待完成:

import time

import requests

base = "https://api.gxcy.com/v1"
headers = {"Authorization": "Bearer sk-..."}

task = requests.post(f"{base}/videos", headers=headers, json={
    "model": "MiniMax-H3",
    "content": [{"type": "text", "text": "一只橘猫在窗台上伸懒腰"}],
}).json()

while task["status"] not in ("succeeded", "failed", "cancelled", "expired"):
    time.sleep(10)
    task = requests.get(f"{base}/videos/{task['id']}", headers=headers).json()

if task["status"] == "succeeded":
    video = requests.get(task["content"]["video_url"])
    with open("video.mp4", "wb") as f:
        f.write(video.content)
else:
    print(task["status"], task["error"])

查询间隔建议 10 秒左右;任务多时用回调代替轮询。

列出与批量查询

  • 批量查询:GET /v1/videos?ids=vid_a,vid_b,最多 100 个。返回 data 按请求的顺序排列,查不到的放在 missing。
  • 列出:GET /v1/videos?status=succeeded&limit=20,按提交时间从新到旧。status 可以写多个,以逗号分隔;另可以按 model、created_after、created_before(Unix 秒)筛选。has_more 为 true 时,带上 after=〔这一页最后一个任务的 id〕 取下一页。

回调

提交时带上 callback_url,任务结束时平台向这个地址发一次 POST 请求,不必轮询:

{
  "id": "evt_01JB8Y…",
  "type": "video.succeeded",
  "created_at": 1793092091,
  "data": {"id": "vid_01JB8Y3N5Q8V7K2M4X6Z9C1D3F", "status": "succeeded", "...": "…"}
}
  • type 为 video.succeeded、video.failed、video.cancelled 或 video.expired;data 是完整的任务对象。
  • 地址只能是 https://,不能是内网地址,不跟随重定向。
  • 接收方返回 2xx 即为成功;10 秒内没有成功响应时,按 1 分钟、5 分钟、30 分钟、2 小时、6 小时重试。同一个事件可能收到不止一次,请按请求头 webhook-id 去重。
  • 回调只是通知,任务的状态以查询结果为准。

回调按 Standard Webhooks 签名。签名密钥在控制台的 API 密钥 页查看:在密钥一行的操作菜单中选“回调签名密钥”,每个 API 密钥各有一个,以 whsec_ 开头。校验签名:

import base64
import hashlib
import hmac


def verify(secret: str, headers: dict, body: bytes) -> bool:
    key = base64.b64decode(secret.removeprefix("whsec_"))
    signed = f"{headers['webhook-id']}.{headers['webhook-timestamp']}.".encode() + body
    expected = base64.b64encode(hmac.new(key, signed, hashlib.sha256).digest()).decode()
    return any(
        hmac.compare_digest(expected, s.split(",", 1)[1])
        for s in headers["webhook-signature"].split()
        if s.startswith("v1,")
    )
  • body 用收到的原始字节,不要先解析再序列化。
  • 也可以直接用 Standard Webhooks 的官方库(pip install standardwebhooks 等)校验。
  • 轮换签名密钥后旧密钥立即失效,之后的回调都用新密钥签名。

上传参考图片

大图片、或者要在多个任务里复用的图片,先上传成素材,再在 content 里用素材 ID 引用:

# 申请上传:给出文件类型与大小(字节)
curl https://api.gxcy.com/v1/assets \
  -H "Authorization: Bearer sk-..." \
  -H "Content-Type: application/json" \
  -d '{"content_type": "image/png", "size": 482133}'

# 返回 {"id": "asset_…", "status": "pending", "upload_url": "…", "expires_at": …}
# 把文件直接 PUT 到 upload_url,不需要 API 密钥
curl -X PUT "〔upload_url〕" -H "Content-Type: image/png" --data-binary @cat.png

上传后在 content 里写 {"type": "image_url", "role": "first_frame", "image_url": {"url": "asset_…"}}。素材只有上传它的 API 密钥可以引用;GET /v1/assets/{id} 查看状态,DELETE /v1/assets/{id} 删除。平台没有开放上传时这个接口返回 501,请改用图片链接。

取消与删除

DELETE /v1/videos/{id}:

  • 排队中的任务:取消,返回任务对象,status 变为 cancelled。
  • 生成中的任务:大多数模型不能取消,返回 409 cannot_cancel,任务照常生成并计费。
  • 已结束的任务:删除,之后查询返回 404,视频一并删除;已经产生的费用不变。

用火山方舟或 MiniMax 的接口接入

已经按火山方舟(Seedance)或 MiniMax 的视频接口写好的程序,只改接入地址与密钥即可,请求与响应仍按原来的格式:

接口 接入地址 路径
火山方舟 https://api.gxcy.com/byteplus/api/v3 提交 POST /contents/generations/tasks;查询、删除 GET、DELETE /contents/generations/tasks/{id};列表 GET /contents/generations/tasks
MiniMax https://api.gxcy.com/minimax 提交 POST /v2/video_generation;查询 GET /v2/query/video_generation/{task_id}
  • model 填平台的模型名称。同一个模型可以用上面任意一种接口调用,与 /v1/videos 的任务互通:任务 ID 都是平台的 vid_…,可以用任意一种接口查询。
  • 视频的下载链接是平台的链接,MiniMax 格式的查询结果中在 task.content.url。
  • MiniMax 的分辨率写大写(768P),水印写 aigc_watermark。
  • MiniMax 的视频再生成、提示词增强与海螺旧模型的接口暂不支持,返回 501。
  • ComfyUI 自带的视频节点也经这两种接口接入。

用火山方舟的 Python SDK:

from volcenginesdkarkruntime import Ark

client = Ark(base_url="https://api.gxcy.com/byteplus/api/v3", api_key="sk-...")
task = client.content_generation.tasks.create(
    model="MiniMax-H3",
    content=[{"type": "text", "text": "一只橘猫在窗台上伸懒腰"}],
)
print(client.content_generation.tasks.get(task_id=task.id).status)

用 MiniMax 的接口:

curl https://api.gxcy.com/minimax/v2/video_generation \
  -H "Authorization: Bearer sk-..." \
  -H "Content-Type: application/json" \
  -d '{"model": "MiniMax-H3", "content": [{"type": "text", "text": "一只橘猫在窗台上伸懒腰"}], "resolution": "768P", "duration": 5}'

# 返回 {"task_id": "vid_…"}
curl https://api.gxcy.com/minimax/v2/query/video_generation/vid_01JB8Y3N5Q8V7K2M4X6Z9C1D3F \
  -H "Authorization: Bearer sk-..."

计费

  • 单价见控制台的 模型 页,视频按生成的秒数计价,不同分辨率的单价可能不同。
  • 提交本身不计费。任务结束时按任务对象的 usage.items 计费,与账单一致;usage.items 为空的任务不收费,排队中取消的任务通常不收费。
  • 先抵扣订阅与赠送额度,不够的部分从余额扣除。余额或额度不足时提交会被拒绝。
  • 用量在控制台的 用量统计 页查看。

错误

出错时返回 {"error": {"code": "…", "message": "…", "param": "…"}},param 是出错的参数名。

HTTP code 说明
400 invalid_request 请求体不是合法的 JSON、类型错误或取值超出范围
400 unknown_parameter 出现了未定义的参数
400 unsupported_parameter 这个模型不支持该参数或取值
400 content_policy_violation 提示词或图片未通过审核
401 invalid_api_key API 密钥无效
404 model_not_found、task_not_found、asset_not_found 模型、任务或素材不存在
409 idempotency_key_reused、cannot_cancel、task_not_succeeded 见上文
410 output_expired 视频已过保留期
429 rate_limited 请求过于频繁,稍后重试
503 no_healthy_upstream 暂时没有可用的模型服务,稍后重试

任务失败时 status 为 failed,error.code 说明原因:content_policy_violation(未通过审核)、invalid_input(参考图片无法使用)、generation_failed(生成失败)、upstream_rejected(任务未被受理)。