Seedance 2.0 视频生成 API 怎么调:快速上手(2026)
Seedance 2.0 API 快速上手:一把 ofox key,POST /v1/videos,轮询到 completed,读 unsigned_urls[0]。Python + Node 代码,价格 $0.07/s 起。
Seedance 2.0 是 ByteDance 的文生视频与图生视频模型,而调用它最快的方式是走 ofox:一把 API key、美元计费、一个异步 REST 端点。你向 POST https://api.ofox.io/v1/videos 发一个 model ID 加一段 prompt,拿回一个 polling_url,轮询到状态变成 completed,再从 unsigned_urls[0] 读出片段。不用为每家厂商单开账号,也不用装单独的 SDK。本文剩下的部分就是一份能跑通的快速上手:鉴权、Python 和 Node 各一个文生视频调用、异步生命周期、图像与参考输入,以及一段片段实际要花多少钱。
| 端点 | POST https://api.ofox.io/v1/videos(异步) |
| 鉴权 | 一把 ofox Bearer key |
| 模型 ID | bytedance/seedance-2.0、-fast、-mini |
| 首个片段耗时 | 约 5 分钟 |
| 取回结果 | 轮询 GET /v1/videos/{id},读 unsigned_urls[0] |
你需要准备什么
三样东西,如果你已经用 ofox 做过 chat 或图像调用,那其中两样你早就有了。
- 一把 ofox API key。 base URL 是
https://api.ofox.io/v1,鉴权用标准的Authorization: Bearer头。你做 OpenAI 兼容的 chat 和图像请求用的那把 key,同样能提交视频任务,所以不用另开账号,也不用装厂商 SDK。 - 端点。 一切都走
POST /v1/videos和GET /v1/videos/{id}。整个操作面就这么大。 - 一个 model ID。
bytedance/seedance-2.0是旗舰档:文生视频、图生视频、视频生视频、同步音轨、4 到 15 秒的片段、最高 4K。bytedance/seedance-2.0-fast和bytedance/seedance-2.0-mini是更便宜的档位,两者都封顶 720p。
把 key 设一次:
export OFOX_API_KEY="sk-..."
你的第一个请求:文生视频
视频生成不像 chat completion 那样是个阻塞调用。片段需要渲染时间,所以 POST /v1/videos 会立刻返回一个 202 Accepted 和一个 polling_url,你轮询那个 URL 直到任务进入终态。模式由你发送的字段推断:没有图像字段就是文生视频。
下面是一次完整的 Python 往返。它提交任务,以合理的节奏轮询,再从 unsigned_urls[0] 取出片段。
import os, time, requests
BASE = "https://api.ofox.io/v1"
HEAD = {"Authorization": f"Bearer {os.environ['OFOX_API_KEY']}"}
TERMINAL = {"completed", "failed", "cancelled", "expired"}
job = requests.post(f"{BASE}/videos", headers=HEAD, json={
"model": "bytedance/seedance-2.0",
"prompt": "A red kayak cuts through morning fog on a still lake, slow dolly forward.",
"duration": 8,
"resolution": "1080p",
"aspect_ratio": "16:9",
})
job.raise_for_status() # 202 Accepted
task_url = job.json()["polling_url"]
while True:
task = requests.get(task_url, headers=HEAD).json()
if task["status"] in TERMINAL: # 命中全部四个终态都要跳出
break
time.sleep(2) # 每 1-2s 轮询一次,别用死循环猛打
if task["status"] == "completed":
print("clip:", task["unsigned_urls"][0]) # 没有 output_url 字段
print("billed:", task["usage"]["video_cost"], "USD",
"for", task["usage"]["video_seconds"], "s")
else:
print("job ended as:", task["status"])
用 Node 的 fetch 是同样的结构:
const BASE = "https://api.ofox.io/v1";
const HEAD = {
Authorization: `Bearer ${process.env.OFOX_API_KEY}`,
"Content-Type": "application/json",
};
const TERMINAL = ["completed", "failed", "cancelled", "expired"];
const job = await fetch(`${BASE}/videos`, {
method: "POST",
headers: HEAD,
body: JSON.stringify({
model: "bytedance/seedance-2.0",
prompt: "A red kayak cuts through morning fog on a still lake, slow dolly forward.",
duration: 8,
resolution: "1080p",
aspect_ratio: "16:9",
}),
});
const { polling_url } = await job.json(); // 202 Accepted
let task;
do {
await new Promise((r) => setTimeout(r, 2000)); // 每 1-2s 轮询一次
task = await (await fetch(polling_url, { headers: HEAD })).json();
} while (!TERMINAL.includes(task.status));
if (task.status === "completed") {
console.log("clip:", task.unsigned_urls[0]); // 不是 output_url
console.log("billed:", task.usage.video_cost, "USD");
}
有两件事会绊倒第一次调用的人。第一是去取 resp["output_url"]——它并不存在,在 Python 里返回 None、在 Node 里返回 undefined。片段在 unsigned_urls[0] 里。第二是只检查 completed 的轮询循环。一个以 failed 或 expired 收尾的任务永远不会置为 completed,所以忽略其他终态的循环会一直空转。四个终态都要跳出。
处理异步生命周期
一个 Seedance 任务会走过一组固定的状态。三个是过渡态,四个是终态。没有 processing 这个状态,所以别去检查它。
| 状态 | 阶段 | 该做什么 |
|---|---|---|
pending | 已受理,尚未排队 | 每 1-2s 继续轮询 |
queued | 已排队待渲染 | 每 1-2s 继续轮询 |
in_progress | 渲染中 | 每 1-2s 继续轮询 |
completed | 完成,已附 URL | 从 unsigned_urls[0] 下载 |
failed | 生成出错 | 读错误,重试或回退 |
cancelled | 你取消了它 | 停止轮询 |
expired | 任务过期 | 重新提交 |
轮询节奏很重要。GET /v1/videos/{id} 不要快于每秒一次;大约每一到两秒是最佳区间。在死循环里猛打只会浪费配额,也不会让结果更早出来,因为片段无论如何都在上游渲染。
结果 URL 有保质期,所以把 completed 当作下载的信号。unsigned_urls 在任务结束后约 24 小时过期。mirror_urls 是持久的,但每个签名链接仍带自己的 TTL。实操上:当状态翻到 completed,立刻把 unsigned_urls[0] 拉进你自己的存储桶(S3、R2、GCS),而不是把 API URL 存下来之后再发给客户端。
生产环境通常应该用 webhook,而不是一个轮询线程。创建时传一个 callback_url,任务进入终态时 ofox 会 POST 一个 HMAC 签名的负载过来。这个地址必须是公开 HTTPS;私有、回环或其他不可达的主机会在提交时被拒,返回 400 invalid_callback_url。轮询和 webhook 并不互斥,所以常见做法是 happy path 用 webhook,再加一个慢速轮询兜底。
需要提前停掉一个任务?DELETE /v1/videos/{id} 会取消它,任务随后落到 cancelled。
图生视频与参考图
想让一张静图动起来,或用参考帧引导生成,你都不用换端点。同一个 POST /v1/videos,同样的轮询。请求模式由你带上哪些字段推断。
- 不带图像字段 就是文生视频,也就是上面那个调用。
frame_images就是图生视频。传一个 URL 作为单个起始帧,或传首帧和尾帧让模型在两者之间做插值。input_references就是参考引导生成,你提供一些图像来锚定身份、风格或某个产品的外观。
从起始帧做图生视频:
job = requests.post(f"{BASE}/videos", headers=HEAD, json={
"model": "bytedance/seedance-2.0",
"prompt": "The logo tilts up and catches a rim light, subtle rotation.",
"frame_images": ["https://your-cdn.com/first-frame.png"],
"duration": 8,
"resolution": "1080p",
"aspect_ratio": "16:9",
})
后续一切都相同:202、一个 polling_url、同一组状态,以及在 unsigned_urls[0] 里的片段。三档都会生成音轨,所以在 prompt 里点名你想要的声音,否则你就得接受模型自己推断出来的结果。
定价:按分辨率,不是固定档价
这是大家最容易算错的数字。目录里 Seedance 2.0 旁边那个 $0.07/s 起 是 480p 的底价,不是一个固定费率。价格随你请求的分辨率上涨,所以一段片段的真实成本,是你所在分辨率的每秒费率乘以片段时长。下面是旗舰文生视频的费率表:
| 分辨率 | bytedance/seedance-2.0(文生视频) |
|---|---|
| 480p | $0.07/s |
| 720p | $0.16/s |
| 1080p | $0.34/s |
| 4K | $1.37/s |
计费按输出秒数,completed 响应会在 usage.video_cost 里告诉你确切的费用。所以一段 8 秒 1080p 片段是 8 x $0.34 = $2.72,同一段片段在 4K 下是 8 x $1.37 = $10.96。视频生视频在每个分辨率上都比文生视频每秒略贵一点,模型页里有完整说明。
更便宜的档位用分辨率换成本,两者都封顶 720p:bytedance/seedance-2.0-fast 是 480p $0.06/s、720p $0.13/s,而 bytedance/seedance-2.0-mini 是 480p $0.04/s、720p $0.08/s。如果你的输出大多落在一个反正会降采样到 720p 的 feed 上,那 Mini 的 $0.08/s 是三档里最低的 720p 费率。
因为三档共用同一个端点,只在 model 字符串上不同,你可以把草稿路由到 Mini,把旗舰留给母版。要看完整的正面对比,包括 Fast 相对 Mini 的溢价什么时候值得,读 Seedance 2.0 三档对比;要看完整的分辨率分级矩阵,看 Seedance 2.0 模型页。
一把 key,所有视频模型
这份快速上手之所以短,是因为 ofox 把整个视频栈收敛成了一套鉴权和一套 schema。你已经掌握了这个套路:提交到 /v1/videos,轮询,下载。换模型只是改个字符串。
用你手上已有的 key 在 Seedance 2.0 上生成视频。 开始使用 ofox 视频 API:一把 key、美元计费、只为你渲染的秒数付费,无需为每家厂商单独注册。
如果 Seedance 对某段片段不合适,同一个端点也能触及目录里的其余模型。阿里的 Wan 最短从 2 秒起步,而 Seedance 的下限是 4 秒;Seedance 2.0 与 Wan 对比 讲了这笔取舍。确切的请求和响应字段,包括每一个可选参数,都在 ofox 视频 API 参考文档 里。
FAQ
Seedance 2.0 API 怎么调?
向 POST https://api.ofox.io/v1/videos 发一个 Bearer ofox key,加一个包含 model、prompt、duration、resolution、aspect_ratio 的 JSON body。它返回 202 和一个 polling_url。每 1-2 秒轮询一次 GET /v1/videos/{id},直到 status 变成 completed,再从 unsigned_urls[0] 读出片段。
为什么我读 output_url 时视频 URL 是空的?
因为根本没有 output_url 字段。片段在 unsigned_urls 里(一个数组,所以用 unsigned_urls[0]),或者在 mirror_urls 里。读 resp["output_url"] 每次都返回 None。
Seedance 2.0 的结果 URL 能有效多久?
unsigned_urls 在完成后约 24 小时过期。mirror_urls 是持久的,但每个签名链接都带自己的 TTL。状态一变成 completed 就把文件下载下来。
Seedance 2.0 API 要多少钱? 按输出秒数、按分辨率计费,不是固定费率。旗舰文生视频是 480p $0.07/s、720p $0.16/s、1080p $0.34/s、4K $1.37/s。一段 8 秒 1080p 片段是 $2.72。
Seedance 2.0 能从一张图片生成视频吗?
能。传 frame_images 做图生视频,或传 input_references 做参考引导生成。模式由字段推断;不带图像就是文生视频。
Seedance 2.0 最便宜的模型是哪个?
bytedance/seedance-2.0-mini,480p $0.04/s、720p $0.08/s。它封顶 720p,-fast 也一样。只有旗舰能到 1080p 和 4K。
