参考
生成视频
视频模型与聊天补全不同。生成是异步的:你提交一个任务,拿回一个任务 id,然后轮询结果。目前唯一的视频模型是 doubao-seedance-2-0-pro(火山引擎方舟上的字节跳动 Seedance 2.0 Pro)。
1. 端点
| 方法 | 路径 | 用途 |
|---|---|---|
POST | https://chinzy.com/v1/videos/tasks | 提交一个生成任务。立即返回 { "id": "cgt-..." }。 |
GET | https://chinzy.com/v1/videos/tasks/{taskId} | 轮询任务状态。原样返回上游负载。 |
两个端点都使用你在聊天补全中使用的同一个 Authorization: Bearer tsk_... 头。如果你还没有密钥,参见使用你的 API 密钥。
任务生命周期。 状态在
queued → running → succeeded(或 failed、cancelled、expired)之间流转。一段 4 秒 720p 片段的典型渲染时间为 60–180 秒。2. 提交任务
curl
curl https://chinzy.com/v1/videos/tasks \
-H "Authorization: Bearer $TOKEN_RELAY_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "doubao-seedance-2-0-pro",
"content": [
{"type": "text", "text": "a calm sunset over rolling hills --rs 720p --dur 4"}
],
"ratio": "16:9"
}'请求字段
| 字段 | 类型 | 说明 |
|---|---|---|
model | string | 必填。使用 doubao-seedance-2-0-pro。(其他视频别名上线后会出现在这里。) |
content | array | 必填。每一项都是一个带类型的块:text、image_url、video_url 或 audio_url。接受内联 base64 data URL。 |
ratio | string | 宽高比:16:9、9:16、4:3、3:4、21:9、1:1 或 adaptive。 |
resolution | string | 480p、720p、1080p 或 2K。你也可以在提示词中以 --rs 1080p 的形式内联传入。 |
duration | number | 4–15 秒。内联形式:--dur 5。 |
generate_audio | boolean | 是否在视频之外渲染一条音轨。 |
seed | number | 可选的可复现性种子。 |
3. 轮询至完成
# poll-loop.sh
TASK_ID="cgt-..."
while true; do
RESP=$(curl -s "https://chinzy.com/v1/videos/tasks/$TASK_ID" \
-H "Authorization: Bearer $TOKEN_RELAY_KEY")
STATUS=$(echo "$RESP" | jq -r .status)
echo "[\$(date +%T)] $STATUS"
case "$STATUS" in
succeeded)
echo "$RESP" | jq -r .content.video_url
break
;;
failed|cancelled|expired)
echo "$RESP" | jq -r .error
exit 1
;;
esac
sleep 10
donePython
import os, time, requests
BASE = "https://chinzy.com/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['TOKEN_RELAY_KEY']}"}
def submit(prompt: str, *, ratio="16:9", resolution="720p", duration=4):
r = requests.post(f"{BASE}/videos/tasks", headers=HEADERS, json={
"model": "doubao-seedance-2-0-pro",
"content": [{"type": "text", "text": prompt}],
"ratio": ratio, "resolution": resolution, "duration": duration,
})
r.raise_for_status()
return r.json()["id"]
def wait(task_id: str, *, timeout=600, interval=10):
deadline = time.time() + timeout
while time.time() < deadline:
r = requests.get(f"{BASE}/videos/tasks/{task_id}", headers=HEADERS)
r.raise_for_status()
body = r.json()
if body["status"] == "succeeded":
return body["content"]["video_url"]
if body["status"] in ("failed", "cancelled", "expired"):
raise RuntimeError(body.get("error") or body["status"])
time.sleep(interval)
raise TimeoutError(task_id)
task_id = submit("a calm sunset over rolling hills")
url = wait(task_id)
print(url)Node.js
const BASE = 'https://chinzy.com/v1';
const headers = { Authorization: `Bearer ${process.env.TOKEN_RELAY_KEY}` };
async function submit(prompt) {
const r = await fetch(`${BASE}/videos/tasks`, {
method: 'POST',
headers: { ...headers, 'Content-Type': 'application/json' },
body: JSON.stringify({
model: 'doubao-seedance-2-0-pro',
content: [{ type: 'text', text: prompt }],
ratio: '16:9',
resolution: '720p',
duration: 4,
}),
});
if (!r.ok) throw new Error(await r.text());
return (await r.json()).id;
}
async function wait(taskId, { interval = 10_000, timeoutMs = 600_000 } = {}) {
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
const r = await fetch(`${BASE}/videos/tasks/${taskId}`, { headers });
if (!r.ok) throw new Error(await r.text());
const body = await r.json();
if (body.status === 'succeeded') return body.content.video_url;
if (['failed', 'cancelled', 'expired'].includes(body.status)) {
throw new Error(body.error?.message ?? body.status);
}
await new Promise((res) => setTimeout(res, interval));
}
throw new Error('timeout');
}
const taskId = await submit('a calm sunset over rolling hills');
console.log(await wait(taskId));4. 视频 URL
在 succeeded 时,响应包含 content.video_url ——一个指向字节跳动对象存储的直链 MP4。关于它有两点需要知道:
- 它在 24 小时后过期。在该窗口内下载或转存该文件。不要长期保存这个签名 URL 本身。
- 它绕过中转。下载是客户端到火山引擎的直连;我们从不看到这些字节,因此获取结果不产生任何中转带宽或钱包扣费。
5. 价格与计量
视频按 token 计费,方式与聊天模型相同。token 数会报告在 succeeded 响应的 usage.total_tokens 字段中。粗略来说,一段 4 秒 720p 片段约为 87,000 token(按当前转售汇率约 $0.08)。1080p 和更长的片段大致线性扩展。
结算发生在第一次观察到 succeeded 的轮询时刻。后续轮询免费——中转会幂等地跳过对已结算任务的重复扣费。
6. 所有权与访问
一个任务绑定到创建它的 API 密钥。视频 URL 仅可由同一个密钥取回,期限为 7 天。7 天后任务本身会从上游历史中失效,中转返回 404;在那之前下载好你需要的一切。
7. 常见错误
| 状态码 | 含义 | 解决 |
|---|---|---|
400 | Body 缺少 model 或 content,或其中之一格式错误。 | 确认 content 是一个由带类型块组成的非空数组。 |
403 (在 GET 时) | 你在轮询一个由不同 API 密钥创建的任务。 | 使用创建该任务的同一个密钥。如果你轮换了密钥,请重新提交任务。 |
404 | 中转不认识该任务 id(拼写错误、7 天后过期,或针对不同部署创建)。 | 重新提交;核对该 id 与创建时返回的一致。 |
503 | 火山引擎方舟后端不可用,或该部署未配置 DOUBAO_API_KEY。 | 退避后重试;若持续,检查你的状态页。 |
在本文档中发现遗漏或错误?提交一个 issue 或联系管理员。