视频生成 API 接入教程
从零接入视频生成能力:鉴权、提交任务、轮询结果、渠道差异与常见问题
概述
本文档描述视频生成相关的 RESTful API 接口,包含提交视频生成任务和查询任务状态/结果两个核心接口。接口兼容 OpenAI Video API 规范,支持多种上游视频生成能力(如豆包 Seedance、可灵 Kling、即梦 Jimeng 等),通过模型名称自动路由至对应提供商。
视频生成为异步任务,提交后立即返回 task_id(响应体中的 id 字段),需通过查询接口轮询获取最终结果。
快速开始
前提条件
- 已获取有效的 API Key(
Authorization: Bearer sk-xxx)。 - 账户所在分组下已配置好目标模型对应的可用渠道(例如要用
doubao-seedance-*系列模型,需要先在渠道管理里配置好豆包 Seedance 渠道并保证模型在售)。
整体流程
1. POST /v1/videos → 提交任务,拿到响应中的 id(即 task_id)
2. GET /v1/videos/{id} → 每隔 2-5 秒轮询一次
status = "queued" → 继续等待
status = "in_progress" → 继续等待
status = "completed" → 下载视频(见下方「下载视频内容」)
status = "failed" → 查看 error.message查询任务请统一使用 GET /v1/videos/{task_id},本文档后续均以此为准。
一、提交视频生成任务
接口信息
| 项目 | 说明 |
|---|---|
| 路径 | /v1/videos(推荐,OpenAI 兼容) |
| 方法 | POST |
| Content-Type | application/json |
/v1/video/generations 是功能等价的旧路径,提交行为和返回结构与 /v1/videos 完全相同,可作为备选。
请求参数
基础参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
model | string | 是 | 模型名称。示例:doubao-seedance-2-0-260128、kling-v1、kling-v2-master、kling-v3、kling-v3-omni |
prompt | string | 是 | 文本提示词,描述期望生成的视频内容。支持自然语言详细描述 |
image | string | 否 | 单张输入图片的 URL 或 Base64 编码字符串。用于图生视频场景 |
images | string[] | 否 | 多张图片引用 URL 列表。用于多图参考场景(如首帧、尾帧),具体含义由所选渠道解释 |
duration | int | 否 | 视频时长(秒)。示例:5。Kling 取值范围 4~15 |
seconds | string | 否 | 视频时长的字符串形式,部分渠道(如 Sora)使用此字段代替 duration |
size | string | 否 | 输出尺寸/分辨率,格式因渠道而异,见下方「渠道差异:size 格式对照」 |
mode | string | 否 | 生成模式,目前仅 Kling 渠道读取。可选 std(默认,720P)/pro(1080P)/4k(4K,需模型支持,如 kling-v3/kling-v3-omni) |
input_reference | string | 否 | 参考图/视频。对通义万相(Ali)渠道会直接作为首帧图 URL;通用兼容路径下会被当作 images 的第一张使用 |
metadata | object | 否 | 渠道自定义扩展参数容器,部分渠道的专属参数须放在这里才会生效 |
videos、audios、video_urls、audio_urls 目前没有任何渠道会解析,作为顶层字段传入会被静默丢弃,不会报错,但上游收不到。如需传多个视频/音频参考,请使用下文「metadata.content:显式指定首尾帧与参考素材」的方式。
渠道差异:size 格式对照
| 渠道 | 期望格式 | 说明 |
|---|---|---|
| Kling | "1280x720" 等 宽x高 | 内部会换算成宽高比;无法识别的格式会静默回退为 1:1,不会报错 |
| Vidu | "1080p" 等分辨率档位 | 默认 1080p |
| 通义万相(Ali) | "1920*1080"(星号分隔) | 文生视频模型若缺少 * 分隔符会直接报错;也支持部分分辨率档位关键字 |
| Sora | "720x1280" 等 宽x高 | 原样透传,默认 "720x1280" |
| 豆包 Seedance | 不读取 size 字段 | 请改用 metadata.resolution + metadata.ratio(见下文) |
| 海螺 / Gemini·Vertex Veo | 各自独立解析规则 | 建议先用小额度测试确认实际生效效果 |
扩展参数(豆包 Seedance 专属)
这些参数需嵌套在 metadata 对象内传递,不能作为请求体顶层字段;顶层同名字段会被静默丢弃,不会生效,也不会报错。
参数名(metadata.xxx) | 类型 | 说明 |
|---|---|---|
ratio | string | 画面比例。示例:4:3、16:9、9:16、1:1 |
resolution | string | 输出分辨率。示例:720p、1080p |
watermark | bool | 是否添加水印。默认:false |
camera_fixed | bool | 是否固定镜头。默认:false |
generate_audio | bool | 是否自动生成音频。默认:false |
return_last_frame | bool | 是否返回尾帧图片。默认:false |
execution_expires_after | int | 任务最长执行时间(秒),超时自动终止。示例:172800 |
seed | int | 随机种子,用于结果复现 |
callback_url | string | 异步回调地址。任务完成后向此地址发送通知 |
tools | array | 上游工具配置,目前仅支持 [{"type": "..."}] 这种简单数组,不是自由格式对象 |
frames | int | 视频总帧数(不是帧率 fps) |
content | array | 显式指定首尾帧、参考图、参考视频、参考音频,见下方说明 |
fps(真实字段名是 frames,且语义是总帧数而非帧率)、n(生成数量,没有对应实现)、safety_identifier(视频任务链路中没有对应字段,仅 Chat Completions 接口相关)当前不生效,请不要依赖。
metadata.content:显式指定首尾帧与参考素材
如果只是简单图生视频,用顶层 images 数组即可。如果需要显式区分首帧/尾帧/参考图/参考视频/参考音频的角色,而不是依赖数组顺序隐式约定,可以在 metadata.content 里传入完整的内容数组,它会直接覆盖由 images 自动生成的内容:
{
"content": [
{ "type": "image_url", "image_url": { "url": "https://.../first.jpg" }, "role": "first_frame" },
{ "type": "image_url", "image_url": { "url": "https://.../last.jpg" }, "role": "last_frame" },
{ "type": "video_url", "video_url": { "url": "https://.../ref.mp4" }, "role": "reference_image" },
{ "type": "audio_url", "audio_url": { "url": "https://.../bgm.mp3" } }
]
}role 字段目前没有做任何校验,是原样透传的字符串,具体支持哪些取值请以 Seedance 官方文档为准,上表 role 取值仅供参考。无论 content 里是否包含 text 类型条目,最终都会被替换成顶层的 prompt 字段内容,文本提示词请始终通过 prompt 传递。
扩展参数(可灵 Kling v3 专属)
这些参数同样需嵌套在 metadata 对象内传递,不能作为请求体顶层字段;顶层同名字段会被静默丢弃,不会生效,也不会报错。
参数名(metadata.xxx) | 类型 | 说明 |
|---|---|---|
sound | bool | 是否生成原生配音(对白、音效、环境音)。默认:false。仅 kling-v3/kling-v3-omni 生效 |
kling_elements | array | 参考视频元素数组,用于跨镜头保持画面构图/主体一致性。每项形如 {"element_input_urls": ["https://..."]},参考片段建议 3-8 秒。仅 kling-v3-omni 生效 |
{
"model": "kling-v3-omni",
"prompt": "延续参考视频的运镜与构图,主角转身望向镜头",
"mode": "pro",
"duration": 5,
"metadata": {
"sound": true,
"kling_elements": [
{ "element_input_urls": ["https://your-bucket.example.com/assets/ref_clip.mp4"] }
]
}
}kling_elements 的取值范围、片段时长限制以官方文档为准;未传时按无参考视频计费/生成。
同时开启 sound: true 与 kling_elements 时,按下表"有参考视频"档计费,与是否有声无关。
计费参考(元/秒)
按输出时长(秒)计费,费率随分辨率(mode)、是否配音(sound)、是否使用参考视频(kling_elements)变化,仅供参考,以账户实际扣费为准:
kling-v3:
分辨率(mode) | 无声 | 有声 |
|---|---|---|
720p (std) | 0.6 | 0.9 |
1080p (pro) | 0.8 | 1.2 |
4K (4k) | 3.0 | 3.0 |
kling-v3-omni:
分辨率(mode) | 无参考视频 · 无声 | 无参考视频 · 有声 | 有参考视频 |
|---|---|---|---|
720p (std) | 0.6 | 0.8 | 0.9 |
1080p (pro) | 0.8 | 1.0 | 1.2 |
4K (4k) | 3.0 | 3.0 | 3.0 |
响应参数(提交成功后)
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 任务唯一标识 ID,用于后续查询 |
task_id | string | 与 id 相同,兼容旧版本调用方,计划废弃,请优先使用 id |
object | string | 固定值:"video" |
model | string | 使用的模型名称 |
status | string | 初始状态:queued(排队中) |
created_at | int64 | 创建时间戳(Unix 秒) |
metadata | object | 附加元数据(提交阶段通常为空) |
请求示例
1. 基础文生视频
{
"model": "kling-v1",
"prompt": "一只猫在花园里弹钢琴,阳光明媚",
"duration": 5,
"size": "1280x720"
}2. 图生视频
{
"model": "kling-v2-master",
"image": "https://example.com/input.jpg",
"prompt": "让图片动起来,镜头缓慢推进",
"duration": 5
}3. 首尾帧 + 参考视频/音频(豆包 Seedance 2.0)
{
"model": "doubao-seedance-2-0-260128",
"prompt": "第一人称视角果茶宣传广告:首帧为图片1,你的手摘下一颗带晨露的红苹果;随后将苹果块投入雪克杯摇晃;最后举杯展示,尾帧定格为图片2。全程使用参考视频的运镜方式,使用参考音频作为背景音乐。",
"duration": 8,
"metadata": {
"ratio": "4:3",
"resolution": "720p",
"watermark": false,
"camera_fixed": false,
"generate_audio": false,
"return_last_frame": false,
"execution_expires_after": 172800,
"content": [
{ "type": "image_url", "image_url": { "url": "https://your-bucket.example.com/assets/r2v_tea_pic1.jpg" }, "role": "first_frame" },
{ "type": "image_url", "image_url": { "url": "https://your-bucket.example.com/assets/r2v_tea_pic2.jpg" }, "role": "last_frame" },
{ "type": "video_url", "video_url": { "url": "https://your-bucket.example.com/assets/r2v_tea_video1.mp4" }, "role": "reference_image" },
{ "type": "audio_url", "audio_url": { "url": "https://your-bucket.example.com/assets/r2v_tea_audio1.mp3" } }
]
}
}该示例依赖 Seedance 2.0 的多参考素材能力,请先确认账户下 doubao-seedance-2-0-260128 模型渠道可用,并以 Seedance 官方文档确认 role 取值和素材数量限制。
4. 有声 + 参考视频(可灵 Kling v3 Omni)
{
"model": "kling-v3-omni",
"prompt": "延续参考视频的运镜与构图,主角转身望向镜头,配合环境音效",
"mode": "pro",
"duration": 5,
"metadata": {
"sound": true,
"kling_elements": [
{ "element_input_urls": ["https://your-bucket.example.com/assets/ref_clip.mp4"] }
]
}
}该示例依赖 kling-v3-omni 的参考视频能力,请先确认账户下该模型渠道可用;mode 为 4k 时出片为 4K 分辨率,费率也最高(3.0 元/秒),详见上方"计费参考"表。
cURL 示例
文生视频:
curl -X POST "{BASE_URL}/v1/videos" \
-H "Authorization: Bearer sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"model": "kling-v1",
"prompt": "一只猫在花园里弹钢琴,阳光明媚",
"duration": 5,
"size": "1280x720"
}'图生视频:
curl -X POST "{BASE_URL}/v1/videos" \
-H "Authorization: Bearer sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"model": "kling-v2-master",
"image": "https://example.com/input.jpg",
"prompt": "让图片动起来,镜头缓慢推进",
"duration": 5
}'二、查询视频任务状态与结果
接口信息
| 项目 | 说明 |
|---|---|
| 路径 | /v1/videos/{task_id} |
| 方法 | GET |
| Content-Type | application/json |
请求参数
| 参数名 | 类型 | 位置 | 必填 | 说明 |
|---|---|---|---|---|
task_id | string | Path | 是 | 提交接口返回的 id 字段值 |
响应参数
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 任务唯一标识 |
task_id | string | 与 id 相同,计划废弃 |
object | string | 固定值:"video" |
model | string | 使用的模型名称 |
status | string | 任务状态,取值见下方状态表 |
progress | int | 进度百分比(0-100) |
created_at | int64 | 创建时间戳(Unix 秒) |
completed_at | int64 | 完成时间戳(Unix 秒),任务结束(成功/失败)后返回 |
error | object | 错误信息(仅 failed 状态) |
error.message | string | 错误描述 |
error.code | string | 错误码 |
metadata | object | 结果元数据 |
metadata.url | string | 生成视频的下载 URL(completed 时返回) |
expires_at、size、seconds(除 Kling 外)、remixed_from_video_id 属于响应结构中预留的字段,目前大多数渠道不会填充具体值,请不要在业务逻辑中强依赖它们,实际以 metadata.url 是否存在来判断视频是否可下载。
任务状态说明
| 状态值 | 含义 |
|---|---|
queued | 任务已提交,排队等待处理 |
in_progress | 任务正在处理中 |
completed | 任务处理成功,视频已生成完毕 |
failed | 任务处理失败 |
响应示例
排队中
{
"id": "task_abc123def456",
"object": "video",
"model": "doubao-seedance-2-0-260128",
"status": "queued",
"progress": 0,
"created_at": 1748227200
}处理中
{
"id": "task_abc123def456",
"object": "video",
"model": "doubao-seedance-2-0-260128",
"status": "in_progress",
"progress": 50,
"created_at": 1748227200
}已完成
{
"id": "task_abc123def456",
"object": "video",
"model": "doubao-seedance-2-0-260128",
"status": "completed",
"progress": 100,
"created_at": 1748227200,
"completed_at": 1748227250,
"metadata": {
"url": "https://cdn.example.com/videos/task_abc123def456/content"
}
}失败
{
"id": "task_abc123def456",
"object": "video",
"model": "doubao-seedance-2-0-260128",
"status": "failed",
"progress": 100,
"created_at": 1748227200,
"completed_at": 1748227210,
"error": {
"message": "task failed",
"code": "failed"
}
}cURL 示例
curl -X GET "{BASE_URL}/v1/videos/task_abc123def456" \
-H "Authorization: Bearer sk-your-api-key"备选:/v1/video/generations/{task_id}(内部任务管理格式)
如果确实需要 quota、channel_id、platform、username 等内部管理字段,可以调用 GET /v1/video/generations/{task_id},但返回结构与上面完全不同,是一层通用任务信封:
{
"code": "success",
"message": "",
"data": {
"id": 123,
"task_id": "task_abc123def456",
"platform": "doubao",
"status": "...",
"progress": "50%",
"result_url": "https://cdn.example.com/videos/task_abc123def456/content",
"submit_time": 1748227200,
"finish_time": 1748227250,
"channel_id": 1,
"quota": 1000,
"...": "..."
}
}注意两点差异:progress 是字符串(如 "50%"),下载地址字段是 result_url 而不是 metadata.url。除非明确需要这些内部字段,否则请统一使用 /v1/videos/{task_id},避免两套结构混用导致解析出错。
三、下载视频内容
接口信息
| 项目 | 说明 |
|---|---|
| 路径 | /v1/videos/{task_id}/content |
| 方法 | GET |
任务状态必须已经是 completed 才能下载,否则返回 400。
渠道下载差异
metadata.url 是否能直接下载取决于渠道:
| 渠道 | metadata.url 能否直接下载 | 说明 |
|---|---|---|
| 豆包 Seedance、可灵 Kling 等大多数渠道 | 可以 | 上游直接返回公网可访问的视频地址 |
| Sora / OpenAI | 通常不行 | 上游内容接口需要 Authorization: Bearer 鉴权,直接访问会被拒绝 |
| Gemini、Vertex Veo | 通常不行 | 上游需要 x-goog-api-key 等专属鉴权头 |
对于需要额外鉴权的渠道,请统一改用 GET /v1/videos/{task_id}/content:网关会自动补上对应上游所需的鉴权头并把视频内容流式转发回来,客户端只需要带自己的 API Key 即可,无需关心上游细节。这个接口对所有渠道都通用,建议作为默认的下载方式。
cURL 示例
curl -X GET "{BASE_URL}/v1/videos/task_abc123def456/content" \
-H "Authorization: Bearer sk-your-api-key" \
--output video.mp4响应为视频二进制流(Content-Type 由上游决定,通常为 video/mp4),并带有 Cache-Control: public, max-age=86400。
四、渠道差异速查
| 渠道 | 模型示例 | 关键差异 |
|---|---|---|
| 豆包 Seedance | doubao-seedance-1-0-pro-250528、doubao-seedance-1-0-lite-t2v、doubao-seedance-1-0-lite-i2v、doubao-seedance-1-5-pro-251215、doubao-seedance-2-0-260128 | 不读取 size;扩展参数必须放在 metadata 内;多参考素材需用 metadata.content |
| 可灵 Kling | kling-v1、kling-v2-master、kling-v3、kling-v3-omni | 支持 mode(std/pro/4k,分别对应 720P/1080P/4K);size 用 宽x高 格式;kling-v3 起支持 metadata.sound(原生配音),kling-v3-omni 额外支持 metadata.kling_elements(参考视频) |
| 通义万相(Ali) | 视具体渠道配置 | size 用 宽*高(星号分隔);input_reference 直接作为首帧图 URL |
| Sora | 视具体渠道配置 | size 用 宽x高,默认 720x1280 |
具体某个模型支持哪些能力,最终以账户下实际配置的渠道和上游供应商文档为准;上表仅覆盖已在代码中确认的差异点。
五、典型调用流程与最佳实践
┌─────────────────────────────────────────────────────────┐
│ 1. POST /v1/videos │
│ → 提交任务,获得响应中的 id 字段(即 task_id) │
│ │
│ 2. GET /v1/videos/{task_id}(轮询) │
│ → 每隔 2-5 秒查询一次,直到 status 变为 completed │
│ ← status = "queued" → 继续等待 │
│ ← status = "in_progress" → 继续等待 │
│ ← status = "completed" → 下载视频(见第三节) │
│ ← status = "failed" → 查看 error.message │
└─────────────────────────────────────────────────────────┘- 轮询间隔:建议 2-5 秒/次,避免过于频繁请求。
- 超时处理:可通过
metadata.execution_expires_after(豆包 Seedance)设置任务超时时间(秒),超时后上游自动终止任务。 - 下载方式:Sora/Gemini/Vertex Veo 渠道请使用
GET /v1/videos/{task_id}/content下载(见第三节),其余渠道可直接用metadata.url。 - 视频有效期:下载 URL 有有效期限制,请在任务完成后及时下载并转存。
六、错误码说明
| HTTP 状态码 | 含义 |
|---|---|
200 | 请求成功 |
400 | 请求参数错误(如缺少必填参数、参数格式不正确) |
401 | 未认证(缺少 Authorization 头或 API Key 无效) |
403 | 无权限(API Key 无权访问该接口或模型) |
500 | 服务器内部错误 |
502 | 上游服务异常(网关错误,上游模型不可用或超时) |
七、注意事项
- 模型路由:系统根据
model字段自动路由到对应上游提供商,请确保填写的模型名称在账户/分组下已配置好可用渠道。 - 媒体文件 URL:传入的图片、视频、音频 URL 需要为公网可访问地址,建议使用对象存储(如 OSS/S3)托管,避免使用会过期或需要鉴权的临时链接。
- 扩展参数透传:
ratio、resolution、watermark等豆包 Seedance 专属参数,以及sound、kling_elements等可灵 Kling 专属参数,均须嵌套在metadata对象内传递,顶层同名字段会被静默丢弃、不会生效。 - 多参考素材:
videos、audios、video_urls、audio_urls顶层字段当前不被任何渠道解析,需要传多个视频/音频参考时请使用metadata.content数组。 - 查询接口:请统一使用
GET /v1/videos/{task_id};GET /v1/video/generations/{task_id}返回结构不同,仅用于需要内部管理字段的场景。 - 下载视频:Sora、Gemini、Vertex Veo 渠道的
metadata.url需要上游专属鉴权,无法直接下载,请改用GET /v1/videos/{task_id}/content。 - 异步模式:视频生成为异步任务,提交后立即返回
task_id,需通过查询接口轮询获取最终结果。