视频
视频要渲染几分钟,所以它是一个任务:先创建,再轮询到完成,然后下载文件。所有视频模型都这样用,调用的都是同样三个接口:
| 步骤 | 调用 | 返回 |
|---|---|---|
| 创建 | POST /v1/videos | 任务,带有 id,status 为 queued |
| 轮询 | GET /v1/videos/{video_id} | 任务当前的 status;状态为 completed 后带有 content_url |
| 下载 | GET /v1/videos/{video_id}/content | MP4 文件 |
下面的示例是一个真实的文件,发布前我们都会实际运行一遍。它根据提示生成一段 4 秒的视频:
# Video generation is a job: submit it, poll until it is done, then download the file.
# Videos take minutes to render, so never wait on the first request.
import os
import time
import requests
BASE = os.getenv("OCEANTOKEN_BASE_URL", "https://api.oceantoken.ai/v1")
HEADERS = {"Authorization": f"Bearer {os.environ['OCEANTOKEN_API_KEY']}"}
job = requests.post(
f"{BASE}/videos",
headers=HEADERS,
json={
"model": "bytedance/seedance-1-5-pro",
"prompt": "A paper boat drifting down a rain gutter, close up, soft light",
"seconds": "4",
},
timeout=60,
)
if not job.ok:
# The error body says why (see Errors in the docs), e.g. insufficient_credits.
raise SystemExit(f"{job.status_code}: {job.text}")
video_id = job.json()["id"]
print("submitted", video_id)
while True:
status = requests.get(f"{BASE}/videos/{video_id}", headers=HEADERS, timeout=60).json()
if status["status"] not in ("queued", "in_progress"):
break # completed, or failed with an error code and message
time.sleep(10)
if status["status"] != "completed":
raise SystemExit(f"video failed: {status.get('error')}")
content = requests.get(f"{BASE}/videos/{video_id}/content", headers=HEADERS, timeout=120)
content.raise_for_status()
with open(f"{video_id}.mp4", "wb") as f:
f.write(content.content)
print("saved", f"{video_id}.mp4", len(content.content), "bytes")
请求
| 字段 | 作用 |
|---|---|
model | 视频模型的 ID,例如 bytedance/seedance-2.0。 |
prompt | 视频里发生什么。 |
duration | 时长,单位为整秒,比如 5。也接受 seconds,数字或字符串均可。不填时,大多数模型生成 5 秒。 |
resolution | 480p、720p 或 1080p,以模型提供的为准。分辨率越低越快、越便宜。有的模型只出一种分辨率,传别的会被拒绝:kwaivgi/kling-v3.0-pro 只出 1080p,kwaivgi/kling-v3.0-std 只出 720p。 |
aspect_ratio | 16:9、9:16、1:1、4:3、3:4 或 21:9,以模型提供的为准。选项里有 adaptive 的模型(Seedance 2.0、2.0 Fast、2.0 Mini、2.5 等)也接受它:画面跟随首帧的比例。见画面比例。 |
size | 代替 resolution 和 aspect_ratio:宽 x 高,比如 1280x720。会采用模型提供的最接近的尺寸。 |
generate_audio | true 生成带声音的视频(适用于能生成声音的模型);false 生成无声视频。 |
frame_images | 首帧和尾帧,用于图生视频。 |
input_references | 参考图片、视频或音频,用于参考生视频。 |
omni_reference_task_type | bytedance/seedance-2.0、-2.0-fast、-2.0-mini 和 bytedance/seedance-2.5,带参考素材时使用:reference、edit、extend 或 auto(2.5 默认 reference)。见续写或编辑视频。 |
每个模型接受的时长、分辨率和输入各不相同。模型不接受的取值会在运行和扣费之前以 400 invalid_request 被拒绝,消息里会写明它接受什么,例如 duration must be 4 or 8 seconds for this model。想事先查看,见查询模型支持的选项。
有些可选字段(例如 adaptive 和 omni_reference_task_type)不是每个请求都用得上。用不上时请求不会被拒绝:视频照常生成,只是不带这个字段,创建任务的响应头 x-oceantoken-dropped-params 会列出它,例如 aspect_ratio。
图生视频
提供首帧;模型支持的话,再提供尾帧。每张图片可以是公开的 https:// URL,也可以是 data URL:
{
"model": "bytedance/seedance-2.0",
"prompt": "纸船漂出画面,镜头保持不动",
"duration": 5,
"resolution": "720p",
"frame_images": [
{"type": "image_url", "frame_type": "first_frame", "image_url": {"url": "https://example.com/start.png"}},
{"type": "image_url", "frame_type": "last_frame", "image_url": {"url": "https://example.com/end.png"}}
]
}
也可以用更短的写法:"first_frame": "https://..." 和 "last_frame": "https://...";或者用 OpenAI 的 input_reference 指定首帧,可以是 URL,也可以是 multipart 请求里上传的文件。
画面比例
在 bytedance/seedance-2.0、bytedance/seedance-2.0-fast、bytedance/seedance-2.0-mini 和 bytedance/seedance-2.5 上,带首帧时不传 aspect_ratio,画面会跟随首帧的比例:竖版首帧出竖版视频。传 "aspect_ratio": "adaptive" 效果相同,选项里有 adaptive 的模型都可以这样传。
想要固定的比例,就直接传,例如 "aspect_ratio": "9:16"。例外是 bytedance/seedance-2.5:带首帧或尾帧时,画面总是保持帧图的比例,传了别的 aspect_ratio 会被忽略(列在 x-oceantoken-dropped-params 里)。
参考生视频
支持参考素材的模型(Seedance 2.0 及更新的版本等)会根据你提供的图片来生成视频,部分模型还能参考视频和音频:一个角色、一件商品、一种运镜、一段配乐。
{
"model": "bytedance/seedance-2.0",
"prompt": "第一张图里的女人走过视频里的集市,配合音乐的节奏",
"duration": 8,
"input_references": [
{"type": "image_url", "image_url": {"url": "https://example.com/character.png"}},
{"type": "video_url", "video_url": {"url": "https://example.com/market.mp4"}},
{"type": "audio_url", "audio_url": {"url": "https://example.com/theme.mp3"}}
]
}
每种素材最多能放几个,写在模型的选项里(referenceLimits)。超过上限会以 400 被拒绝,例如 kwaivgi/kling-v3.0-std takes at most 6 reference images; 7 were sent. 模型用不上的参考素材同样以 400 被拒绝,绝不会不声不响地丢掉。-upscaled 系列的 Seedance 模型只接受参考图片(1 到 9 张),不接受首尾帧。
你发送的素材: 公开的 URL 或 data URL,每个最大 25 MB;整个请求最大 10 MB,所以视频和大图请用 URL 发送。模型无法获取的 URL 会让任务以 invalid_request 失败。
续写或编辑视频
提供一段参考视频,在提示词里说明要怎么处理它。
bytedance/seedance-2.0、bytedance/seedance-2.0-fast、bytedance/seedance-2.0-mini 和 bytedance/seedance-2.5 都支持 omni_reference_task_type,用来说明带参考素材的请求要做什么:reference 根据参考素材生成新视频,edit 编辑参考视频,extend 续写参考视频,auto 由模型根据提示词判断。
- Seedance 2.0、2.0 Fast 和 2.0 Mini:模型同时看提示词,提示词里也要写清楚,例如
edit配「编辑视频:改成下雪的冬天」,extend配「接着视频1结尾继续生成」。不传时由模型根据提示词判断。新视频的长度就是你要的时长,不会把原片拼接进去。 - Seedance 2.5:不指定时,带参考素材的请求按
reference处理。要从视频结尾严格往下延长,请用"omni_reference_task_type": "extend"。
不带参考素材,或者请求落在用不上这个字段的线路上时,omni_reference_task_type 会被忽略,并列在 x-oceantoken-dropped-params 里。
任务
{
"id": "video_9Ck2...",
"object": "video",
"status": "completed",
"model": "bytedance/seedance-2.0",
"seconds": "5",
"size": "1280x720",
"created_at": 1792000000,
"completed_at": 1792000095,
"content_url": "https://...",
"error": null
}
status依次为queued→in_progress→completed或failed。每 10 到 20 秒轮询一次;一段视频通常需要几分钟。content_url在任务completed后出现,有效期 24 小时;请在这段时间内下载,从它下载或从GET /v1/videos/{video_id}/content下载都可以。error:failed的任务带有code和message:
code | 发生了什么 | 怎么办 |
|---|---|---|
content_filtered | 提示、参考素材或生成结果被内容审核拒绝。 | 修改提示或素材。 |
invalid_request | 模型拒绝了参数,或读不了某个参考素材。 | 检查每个 URL 都公开可访问,取值都在模型的选项之内。 |
rate_limited | 模型繁忙。 | 一分钟后重新提交。 |
timeout | 任务没能按时完成。 | 重新提交。 |
temporarily_unavailable | 模型暂时无法接收任务。 | 稍后重新提交,或换一个模型。 |
generation_failed | 其他原因。 | 重新提交;如果一直失败,带上任务 id 联系我们。 |
如果弄丢了 ID,GET /v1/videos 会按从新到旧列出你的任务(limit 最大 100,after 填上一页最后一个 id)。控制台的生成记录里也能看到。
查询模型支持的选项
模型接受的时长、分辨率、画面比例、声音和输入:
curl "https://api.oceantoken.ai/oceantoken/video/model-spec?model=bytedance/seedance-2.0" \
-H "Authorization: Bearer $OCEANTOKEN_API_KEY"
返回内容的 spec 里有 duration(min、max、default)、resolutions、aspectRatios(能跟随首帧的模型会列出 adaptive)、generateAudio、modes(t2v 文生视频,i2v 首帧,flf2v 首尾帧,r2v 参考素材)、referenceLimits,bytedance/seedance-2.5 还有 omniReferenceTaskTypes。
费用与重试
- 任务创建时按预估费用预占你的余额,完成后按实际费用扣费。
failed的任务不扣费,预占的金额会释放。如果可用余额不够预估费用,创建请求会以400被拒绝,不会启动任务。 - 一段视频的费用取决于时长、分辨率和是否有声音,见计费方式以及 oceantoken.ai 上各模型的页面。控制台的 日志 显示每个任务的扣费。
- 创建时发送
Idempotency-Key。 网络超时后重试,会返回已经创建的任务,而不是再启动(并扣费)第二个(错误)。 - 任务由一个通道接收后,会在该通道上一直运行到结束,见重试与自动故障转移 → 视频任务。