视频生成
异步任务模型的完整流程——提交任务、轮询状态、取回视频,覆盖统一接口与 Kling、即梦官方格式路由。
视频生成是异步任务模型:提交请求只拿回 task_id,需要轮询任务状态,完成后再取视频内容。
不要期望提交接口同步返回视频。
端点总览
| 方法 | 路径 | 说明 |
|---|---|---|
POST | /v1/video/generations | 提交任务(统一格式) |
GET | /v1/video/generations/{task_id} | 查询任务(统一格式响应) |
POST | /v1/videos | 提交任务(OpenAI Sora 兼容格式) |
GET | /v1/videos/{task_id} | 查询任务(OpenAI 视频格式响应) |
GET | /v1/videos/{task_id}/content | 取回视频文件内容 |
POST | /v1/videos/{video_id}/remix | 基于已有视频二次创作(Sora 兼容) |
POST | /kling/v1/videos/text2video | 可灵官方格式:文生视频 |
POST | /kling/v1/videos/image2video | 可灵官方格式:图生视频 |
GET | /kling/v1/videos/text2video/{task_id} | 可灵官方格式:查询 |
GET | /kling/v1/videos/image2video/{task_id} | 可灵官方格式:查询 |
POST | /jimeng/?Action=...&Version=2022-08-31 | 即梦官方格式:提交与查询合一 |
统一格式与 Sora 兼容格式提交的是同一种任务,task_id 通用:
用 /v1/video/generations 提交的任务也可以用 /v1/videos/{task_id} 查询,反之亦然。
第一步:提交任务
/v1/video/generations通用参数
modelstring必填视频模型 ID,如 kling-v2-master、jimeng-video-3.0-pro、sora-2、veo-3.1-generate-preview
promptstring文本提示词。模型无 media Schema 时必填;配置了 Schema 时以 input_schema.required 为准
imagestring单图输入(URL 或 Base64),用于图生视频/首帧
imagesstring[]多图输入(首尾帧、参考图等,语义随厂商而异)
durationinteger视频时长(秒),默认值与可选值随模型而异
sizestring尺寸或分辨率,如 1280x720、720P、1080P,格式随厂商而异
modestring生成模式,可灵专用:std(标准)/ pro(高品质)
默认值: stdsecondsstringSora 兼容参数:时长(秒)
input_referencestringSora 兼容参数:输入参考图
metadataobject各 adaptor 从 metadata 读取自己已实现的字段——下文对照表之外的字段不保证下发,因为请求体会被反序列化进各厂商的强类型结构,未知键直接丢弃。只有已配置 Schema 的模型才透传 input_schema 声明的 arguments
duration/size 等通用字段不会自动转换成厂商字段名(例如不会把 duration 改名为 seconds),
各适配器只按自己的规则取通用字段;其余厂商参数放 metadata,但这不是通用的原样透传:
各适配器会把 metadata 反序列化进自己的类型结构,只有下文对照表中的字段会下发,未知键被丢弃。
受 Schema 约束的透传只适用于已配置 media Schema 的模型(见媒体工具 Schema)。提交响应
提交成功的关键产出是任务标识。各厂商的提交响应骨架不同:
多数厂商返回 OpenAI 视频对象(含 id 与 task_id),Vertex 只返回 {"task_id": "..."},
Sora 透传上游原始对象(通常只有 id)。读取时统一用 id ?? task_id 兜底:
{
"id": "task_9f8e7d6c5b4a",
"task_id": "task_9f8e7d6c5b4a",
"object": "video",
"model": "kling-v2-master",
"status": "",
"progress": 0,
"created_at": 1753700000
}
- 拿到任务标识后,一切进展都以轮询为准,不要解析提交响应里的
status - 提交响应的其余字段(
model、created_at等)随厂商而异,以实际返回为准
提交即预扣费。配额不足的提交会被直接拒绝(HTTP 403 quota_not_enough)。
任务失败时的退款规则见下文「失败与重试」。
第二步:轮询任务状态
/v1/video/generations/{task_id} 返回大写内部枚举
(SUBMITTED / IN_PROGRESS / SUCCESS / FAILURE 等),OpenAI 视频格式 /v1/videos/{task_id}
返回小写枚举(queued / in_progress / completed / failed)。
在同一条链路里混用两种判断(例如用统一格式查询却比对 completed)会让状态机永远等不到终态。
选定一种格式后全链路保持一致。两套查询路径返回不同的响应结构与状态枚举,混用是接视频接口最常见的错误。
统一格式查询
/v1/video/generations/{task_id}status 取值为 queued / processing / succeeded / failed,
而非下表的内部枚举),按下表比对 SUCCESS 会永远等不到。Veo 任务请统一用
/v1/videos/{task_id} 查询,以 completed / failed 判定终态。响应包裹在 data 中,状态为内部任务枚举:
{
"code": "success",
"message": "",
"data": {
"task_id": "task_9f8e7d6c5b4a",
"action": "generate",
"status": "IN_PROGRESS",
"fail_reason": "",
"submit_time": 1753700000,
"start_time": 1753700005,
"finish_time": 0,
"progress": "30%",
"data": { ... }
}
}
data 内字段全部固定返回(不存在缺省省略的情况):
task_idstring任务 ID
actionstring任务动作,如 generate、textGenerate
statusstring内部状态枚举,见下表
fail_reasonstring双语义字段:失败时是失败原因;成功时被复用为视频地址(历史设计,注意按 status 区分解读)
submit_time / start_time / finish_timeint64提交 / 开始 / 完成时间戳,未发生时为 0
progressstring带百分号的字符串(如 "30%"),粒度较粗,仅作展示
dataobject上游最近一次响应原文(内联 base64 等大字段会被服务端脱敏截断),结构随厂商而异
status 值 | 含义 |
|---|---|
NOT_START | 已创建,尚未提交上游 |
SUBMITTED | 已提交上游,等待受理 |
QUEUED | 上游排队中 |
IN_PROGRESS | 生成中 |
SUCCESS | 生成成功(终态) |
FAILURE | 生成失败(终态),原因见 fail_reason |
UNKNOWN | 状态未知 |
任务状态是如何更新的
理解状态流有助于设计轮询节奏:
- 提交后任务落库,初始状态
NOT_START - 后台同步器每约 15 秒扫描未完成任务,逐个回源查询上游,把厂商私有状态映射为内部枚举落库
- Gemini / Vertex(Veo)渠道除外——它们在你的查询请求到达时实时回源刷新,其余厂商都以最近一轮后台同步为准
progress是展示用的粗粒度值:终态为100%,进行中的取值随厂商覆盖规则而不同, 不要把它当精确进度条,更不要用它判断完成
因此轮询间隔小于 15 秒对大多数厂商不会看到更新的数据。
OpenAI 视频格式查询
/v1/videos/{task_id}响应为 OpenAI 视频对象,状态为小写枚举:
{
"id": "task_9f8e7d6c5b4a",
"object": "video",
"model": "kling-v2-master",
"status": "completed",
"progress": 100,
"created_at": 1753700000,
"completed_at": 1753700120,
"metadata": {
"url": "https://cdn.example.com/video.mp4"
}
}
status 值 | 对应内部状态 | 含义 |
|---|---|---|
queued | SUBMITTED / QUEUED | 排队中 |
in_progress | IN_PROGRESS | 生成中 |
completed | SUCCESS | 完成,视频地址在 metadata.url |
failed | FAILURE | 失败,原因在 error.message |
unknown | 其他(含 NOT_START、UNKNOWN) | 状态未知 |
字段完备度随上游厂商不同,带 omitempty 的字段不满足条件时整个键不会出现:
| 字段 | 返回条件 |
|---|---|
id、object、status、progress、created_at | 恒定返回 |
model | 键恒定存在,但部分厂商(可灵、即梦、Vidu)值为空字符串 |
task_id | 仅部分厂商返回(豆包;Sora 透传的上游响应若含此键也会带出) |
completed_at | 任务记录有更新时间时返回;可灵取上游时间,可能缺失 |
metadata.url | 完成后的视频地址。可灵/Vidu 仅在上游返回地址时出现;即梦/豆包/万相恒定出现(未完成时可能是空字符串);Gemini 不出现(必须走 /content 下载);Vertex 当前实现不提供产物地址(见下方「取回视频内容」的限制说明) |
seconds | 仅可灵(取上游时长)与 Sora 透传 |
size、expires_at、remixed_from_video_id | 仅 Sora 透传的上游响应可能包含 |
error | 失败时出现(可选,部分厂商某些失败场景不返回,如海螺在上游业务码成功但任务失败时无此键),结构为 { "message": "...", "code": "..." },读取用 error?.message 兜底。各家填充见下 |
Sora 渠道特殊:该格式的查询响应直接透传上游原始 JSON,字段以 OpenAI 官方视频对象为准。
失败时的响应
任务进入 FAILURE / failed 后:
- 统一格式:
data.status为FAILURE,data.fail_reason为失败原因(上游原始错误信息透传),data.progress为"100%" - OpenAI 格式:
status为failed,error.message/error.code承载原因。各家填充来源不同:
| 厂商 | error.message 来源 | error.code 来源 |
|---|---|---|
| 可灵 | 上游 message | 上游数字错误码的字符串形式 |
| 即梦 | 上游 message | 上游业务码(成功为 10000) |
| 海螺 | 上游 StatusMsg | 上游 StatusCode |
| 豆包 | 固定 "task failed"(上游不返回详情) | 固定 "failed" |
| 万相 | 上游 message | 上游 code |
| Vidu | 上游 errcode | 上游 errcode |
| Sora | 上游原始错误对象透传 | 同左 |
任务经后台同步首次进入失败终态时,平台自动退还预扣额度(同一任务只退一次)。
第三步:取回视频内容
/v1/videos/{task_id}/content直接返回视频文件流(附带上游的 Content-Type 等响应头,缓存 24 小时)。适用于两类场景:
- 模型不暴露公开 CDN 地址(Sora、Gemini 接入的 Veo),必须经此接口下载
- 希望隐藏上游地址、统一从积木域名下载
若 metadata.url 是可公开访问的 CDN 地址,也可以直接下载该地址(注意时效)。
任务未完成时调用返回 400;任务不存在返回 404。
/content 也无法下载。经 Gemini 原生 API 接入的 Veo 不受影响。轮询建议
| 项目 | 建议值 |
|---|---|
| 轮询间隔 | 10–15 秒。后台同步器约 15 秒刷新一次(Veo 除外,查询时实时回源),更短的间隔看不到新数据 |
| 总超时 | 建议 10–15 分钟,超时后标记本地失败并允许人工重查 |
| 退避策略 | 连续多次 in_progress 后可将间隔拉长到 30 秒 |
| 完成判断 | 只认终态:completed/SUCCESS、failed/FAILURE,不要用进度百分比判断 |
# 提交(任务标识用 id ?? task_id 兜底提取)
TASK_ID=$(curl -s https://api.jimu.chat/v1/video/generations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $JIMU_API_KEY" \
-d '{"model":"kling-v2-master","prompt":"一只猫在草地上奔跑","duration":5,"size":"1280x720"}' \
| python -c "import sys,json;d=json.load(sys.stdin);print(d.get('id') or d.get('task_id'))")
# 轮询(每 10 秒一次)
while true; do
STATUS=$(curl -s "https://api.jimu.chat/v1/videos/$TASK_ID" \
-H "Authorization: Bearer $JIMU_API_KEY" \
| python -c "import sys,json;print(json.load(sys.stdin)['status'])")
echo "status=$STATUS"
[ "$STATUS" = "completed" ] || [ "$STATUS" = "failed" ] && break
sleep 10
done
# 下载
curl -L "https://api.jimu.chat/v1/videos/$TASK_ID/content" \
-H "Authorization: Bearer $JIMU_API_KEY" -o video.mp4
失败与重试
- 提交阶段失败(4xx/5xx):5xx 与 429 网关会自动换渠道重试;400 为请求本身问题,修复参数后再提交
- 任务状态
failed/FAILURE:读取error.message或fail_reason定位原因。内容审核、提示词违规类失败不要原样重试 - 重试新任务:失败的任务不能直接「重放」,需用相同参数重新提交一个新任务
- 查询不存在的任务:两条查询路径对不存在的
task_id均返回 HTTP 400(不是 404); 下载接口/content返回 404。task_id只能由提交它的令牌查询,确认没跨令牌或拼写错误
{
"code": "task_not_exist",
"message": "task_not_exist",
"data": null
}
厂商参数对照
通用字段之外,厂商特有参数全部放 metadata 透传。下表按厂商列出:
可灵 Kling(kling-v1 / kling-v1-6 / kling-v2-master)
| metadata 参数 | 类型 | 说明 |
|---|---|---|
negative_prompt | string | 反向提示词 |
image_tail | string | 尾帧图片 URL |
cfg_scale | float | 引导系数,默认 0.5 |
aspect_ratio | string | 1:1 / 16:9 / 9:16;未提供时由 size 推断 |
camera_control | object | 镜头控制:type + config{horizontal,vertical,pan,tilt,roll,zoom} |
static_mask / dynamic_masks | string / array | 静态/动态遮罩 |
通用字段映射:mode→mode(默认 std),duration→秒数字符串(默认 5),image→首帧。
即梦 Jimeng(jimeng-video-*、jimeng_vgfm_t2v_l20)
| metadata 参数 | 类型 | 说明 |
|---|---|---|
aspect_ratio | string | 宽高比 |
seed | int | 随机种子 |
frames | int | 帧数 |
参考图不走 metadata:图生视频/参考图使用顶层 image(单张)或 images(多张,URL 或 Base64)。
海螺 MiniMax/Hailuo(MiniMax-Hailuo-*、T2V-01*、I2V-01*、S2V-01)
| metadata 参数 | 类型 | 说明 |
|---|---|---|
resolution | string | 512P / 720P / 768P / 1080P(可选范围随模型而异) |
prompt_optimizer | bool | 提示词自动优化 |
fast_pretreatment | bool | 快速预处理 |
first_frame_image / last_frame_image | string | 首帧/尾帧图片 URL |
subject_reference | array | 主体参考(仅 S2V-01),type 固定 character |
aigc_watermark | bool | AI 水印 |
时长组合:Hailuo-2.3 系列支持 6s/10s;T2V-01、I2V-01、S2V-01 固定 6s。
豆包 Seedance(doubao-seedance-*)
| metadata 参数 | 类型 | 说明 |
|---|---|---|
content | array | 多模态内容,元素 type 为 text / image_url / video,可带 role: reference_image/first_frame/last_frame |
resolution / ratio | string | 分辨率 / 宽高比 |
frames / seed | int | 帧数 / 随机种子 |
generate_audio | bool | 生成配音 |
camera_fixed / watermark | bool | 固定镜头 / 水印 |
万相 Wan(wan2.x、wanx2.1-*)
万相的上游请求是 { "input": {...}, "parameters": {...} } 结构,metadata 按同样两层组织:
| metadata 参数 | 类型 | 说明 |
|---|---|---|
input.negative_prompt | string | 反向提示词 |
input.first_frame_url / input.last_frame_url | string | 首帧/尾帧图片 |
input.audio_url | string | 配音音频 URL(wan2.5) |
input.template | string | 视频特效模板 |
parameters.resolution | string | 480P / 720P / 1080P |
parameters.size | string | 精确尺寸,用 * 分隔,如 1920*1080、1280*720、832*480 |
parameters.prompt_extend | bool | 提示词智能改写,默认 true |
parameters.watermark / parameters.audio | bool | 水印 / 音频(wan2.5) |
parameters.seed | int | 随机种子 |
Gemini Veo(veo-3.x-*)
以下参数对应 Gemini 原生 API 的 Veo 模型;经 Vertex AI 接入时参数集不同
(storageUri、sampleCount 等),以实际接入方式的上游文档为准:
| metadata 参数 | 类型 | 说明 |
|---|---|---|
aspectRatio | string | 16:9 / 9:16 |
durationSeconds | number | 4 / 6 / 8 秒 |
negativePrompt | string | 反向提示词 |
personGeneration | string | allow_all / allow_adult |
resolution | string | 分辨率 |
Veo 查询时网关会实时回源刷新状态;产物取回方式见「取回视频内容」(Vertex 接入当前受限)。
Vidu(viduq1 / viduq2 / vidu1.5 / vidu2.0)
| metadata 参数 | 类型 | 说明 |
|---|---|---|
resolution | string | 默认 1080p |
movement_amplitude | string | auto / small / medium / large |
bgm | bool | 背景音乐 |
seed | int | 随机种子 |
images 数量决定模式:1 张=图生视频,2 张=首尾帧,3 张及以上=参考图生视频(仅 viduq2)。
Sora(sora-2 / sora-2-pro)
使用 OpenAI 原生字段:seconds(时长)、size、input_reference(参考图),
支持 multipart/form-data 上传。建议直接用 /v1/videos 系列路径。
视频二次创作(remix)
/v1/videos/{video_id}/remix基于一个已完成的 Sora 视频任务做二次创作。{video_id} 填原任务的 id。
promptstring必填二创指令(如何修改原视频),为空返回 400
返回与提交任务相同的任务标识结构,用 id ?? task_id 读取后按正常流程轮询。
官方格式兼容路由
这两组路由兼容厂商官方的请求体格式——如果你已经在用可灵或即梦的官方请求结构,
把请求地址换成积木、鉴权换成积木令牌即可,请求体不用改。
注意:响应不是厂商官方结构——提交返回任务标识,查询返回积木统一任务结构
({"code":"success","data":{...}}),客户端需按本文前述的任务结构解析,
不能把官方 SDK 的响应模型直接对上。
可灵官方格式
POST /kling/v1/videos/text2video
POST /kling/v1/videos/image2video
GET /kling/v1/videos/text2video/{task_id}
GET /kling/v1/videos/image2video/{task_id}
请求体与可灵官方一致(model_name、prompt、image、negative_prompt、aspect_ratio、
camera_control 等),鉴权头换成积木令牌即可,不需要可灵的 JWT 密钥对。
curl https://api.jimu.chat/kling/v1/videos/text2video \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $JIMU_API_KEY" \
-d '{
"model_name": "kling-v2-master",
"prompt": "一只猫在草地上奔跑",
"duration": "5",
"aspect_ratio": "16:9",
"mode": "pro"
}'
即梦官方格式
POST /jimeng/?Action=CVSync2AsyncSubmitTask&Version=2022-08-31 # 提交
POST /jimeng/?Action=CVSync2AsyncGetResult&Version=2022-08-31 # 查询
请求体与火山引擎即梦官方一致:提交时带 req_key(模型)、prompt 等;
查询时带 req_key 与 task_id。无需火山 AK/SK 签名,用积木令牌。
# 提交
curl "https://api.jimu.chat/jimeng/?Action=CVSync2AsyncSubmitTask&Version=2022-08-31" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $JIMU_API_KEY" \
-d '{"req_key":"jimeng_vgfm_t2v_l20","prompt":"一只猫在草地上奔跑"}'
# 查询
curl "https://api.jimu.chat/jimeng/?Action=CVSync2AsyncGetResult&Version=2022-08-31" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $JIMU_API_KEY" \
-d '{"req_key":"jimeng_vgfm_t2v_l20","task_id":"task_xxx"}'