Seedance 2.5 首尾帧实测:尾帧误差 5.4,2.0 Mini 是 35.9
把首尾两张图一起发给 Seedance 2.5,它真的落在你指定的尾帧上:480p 尾帧误差 5.4,2.0 Mini 是 35.9。传 aspect_ratio 会直接 400,480p 按 $0.11/秒计费。
Seedance 2.5 把尾帧当成目的地,而不是提示。 给它一个镜头的首尾两端,它会真的落在你要的那一端 —— 这正是 2.0 Mini 做不到的事。
接口: POST /v1/videos -> 202 + polling_url
字段: frame_images[],每个元素带 frame_type first_frame / last_frame
画幅规则: 2.5 的帧任务传 aspect_ratio 直接 400。不传,或者传 adaptive。
2.0 一样吗:不一样。2.0-mini 接受 frame_images + aspect_ratio。
尾帧误差(0-255 平均绝对差,越小越接近):
Seedance 2.5 720p 2.0
Seedance 2.5 480p 5.4
Seedance 2.0 Mini 35.9
两张无关图片 39.0(天花板)
计费: 480p $0.11/秒,720p $0.24/秒,走文生视频那一行
实测: 2026-08-24,每种配置一段 5 秒片
最后更新 2026-08-24。下面每个数字都来自当天通过 ofox 发出的 POST /v1/videos。视频模型路由会变,把校验表抄进自己代码之前,请重跑一遍那四个错误用例。
首帧和尾帧怎么传
frame_images 里两个元素,各自打上 frame_type。 没有模式开关,接口从请求体推断这是图生视频。
import base64, json, requests
def data_uri(path):
return "data:image/jpeg;base64," + base64.b64encode(open(path, "rb").read()).decode()
body = {
"model": "bytedance/seedance-2.5",
"prompt": "The woman stops walking on the rain-slicked street, turns toward the "
"camera, and the shot pushes in to her face. Hand-painted 2D animation style.",
"duration": 5,
"resolution": "480p",
# 这里故意不传 aspect_ratio,原因见下一节
"frame_images": [
{"type": "image_url", "image_url": {"url": data_uri("wide.jpg")}, "frame_type": "first_frame"},
{"type": "image_url", "image_url": {"url": data_uri("close.jpg")}, "frame_type": "last_frame"},
],
}
r = requests.post("https://api.ofox.io/v1/videos", json=body,
headers={"Authorization": "Bearer YOUR_OFOX_API_KEY"})
print(r.status_code, r.json()) # 202 {'id': ..., 'status': 'queued', 'polling_url': ...}
data URI 是通的,这件事比听上去重要:你不用先搭一个公网图床,就能把首尾帧功能测完。之后轮询 polling_url 到终态即可,而轮询本身有一堆坑,写循环之前值得先读一遍。
prompt 在这里仍然干活。它不是夹在两张固定图片中间的装饰品:它决定中间这段发生什么,以及要用掉几个运镜。
它真的会落在尾帧上吗
会,而且和 2.0 Mini 的差距一点也不微妙。 同样两张图、同样 prompt、同样时长、同一天。

为了给它一个数字,我们从每段片子里取出第 0 帧和最后一帧,把帧和源图都缩到 256x144,然后算每通道平均绝对差(0-255 量纲)。数值越小越接近。
| 运行 | 首帧误差 | 尾帧误差 | 计费 |
|---|---|---|---|
| Seedance 2.5,720p | 1.8 | 2.0 | $1.20 |
| Seedance 2.5,1080p | 1.8 | 3.1 | $2.40 |
| Seedance 2.5,480p | 3.0 | 5.4 | $0.55 |
| Seedance 2.0 Mini,480p | 9.5 | 35.9 | $0.10 |
| Seedance 2.0 Mini,480p,不传 ratio | 9.6 | 37.1 | $0.10 |
| 参照:两张无关图片 | 38.6 | 39.0 | 不适用 |
先看最后一行。两张毫无关系的图片,分数大约是 39。Mini 的尾帧是 35.9,也就是说它自己挑了个地方结束:雨天的色调还在,人物换了,取景也换了。首帧则是另一回事,两个模型都抓得很牢 —— 这和我们在 2.0 上看到的老行为一致:首帧被尊重,尾帧会飘。
在此基础上建东西之前有两条提醒。每种配置只跑了一次,不是分布,所以请把排序当作结论,把小数点当作单个样本。另外这个差异指标是刻意粗糙的:一个构图正确但早了两帧的结尾也会被它扣分。而这种粗糙恰恰让 35.9 更有说服力 —— 这么钝的指标都能测出接近「无关」的数值,说明差得是真的远。
为什么 2.5 的帧任务传 aspect_ratio 会 400
因为画幅是从首帧图片推导出来的,所以传它是错误,而不是冗余。
POST /v1/videos {model: bytedance/seedance-2.5, resolution: 480p,
aspect_ratio: "16:9", frame_images: [first, last]}
400 invalid_request
"The parameter ratio specified in the request is not valid. For first-frame or
first-last-frame generation, the output ratio follows the first-frame image."
容易踩的地方在于:我们的首帧图正好是 1280x720,传的 16:9 完全正确,照样被拒。API 不是在拿你的值和图片比对,它是在这个模式下根本不接受这个值。
由此推出三件事,全部是实测而非推断:
| 请求 | 结果 |
|---|---|
2.5 + frame_images + aspect_ratio: "16:9" | 400,ratio not valid |
2.5 + frame_images + aspect_ratio: "adaptive" | 202,输出 854x480 |
2.5 + frame_images,不传该字段 | 202,720p 下输出 1280x720 |
2.5 纯文生视频 + aspect_ratio: "16:9",无帧 | 202 |
2.0 Mini + frame_images + aspect_ratio: "16:9" | 202,输出 864x496 |
所以这个限制专属于 2.5 的帧类任务。它不是关于视频生成的规则,不是关于整个模型的规则,也不是网关加的规则。在 Seedance 2.0 上跑了几个月的代码,会在有人把模型 ID 改成 2.5 的那天开始返回 400,而错误信息谈论的是一个没人动过的参数。
字节自己是写清楚了的。Seedance 2.5 提示词指南把任务分成锁定和非锁定两类,把「编辑、首尾帧、续写」放进锁定组,并说明锁定意味着「输出视频的画幅,有时还包括时长,是被锁死的」。同一页还有一句正好解释了我们的 2.0 结果:「Seedance 2.0 不作这个区分。」
frame_images 的校验还会拒绝什么
四种形状,全部在请求发往上游之前拦下。 每个都在一秒左右返回,不花钱。
| 你发的东西 | HTTP | 信息 |
|---|---|---|
两个元素都是 first_frame | 400 | frame_images: at most one first_frame and one last_frame |
只有 last_frame | 400 | frame_images: last_frame requires a first_frame |
frame_type: "start_frame" | 400 | frame_images[0]: frame_type must be first_frame or last_frame |
frame_images 和 input_references 同时出现 | 400 | frame_images and input_references are mutually exclusive |
注意第三条里带了下标路径。当你在循环里批量生成请求体时,frame_images[0] 直接告诉你该看哪个元素 —— 这比多数视频 API 给的多。

五个拒绝全部是对 Seedance 2.5 的真实调用。底部的 ffprobe 那段是三段成功跑出来的片子,1080p 的编码变化就在那里。
第二条规则最值得围着它做设计:没有「只给尾帧」这个模式,所以想让片子结束在某张已知图片上的产线,必须同时决定它从哪开始。如果你只在乎结尾,就先生成一张说得通的开场静帧,然后两张一起传。
图生视频一段片子到底多少钱
按对应分辨率的文生视频那一行计费。 模型页按分辨率和模式列价,没有图生视频这一行,所以很自然会担心自己落到「其他组合」的 $0.568/秒 上。不会。
| 分辨率 | 模型页文生视频价 | 我们 5 秒帧任务实际计费 | 折算 |
|---|---|---|---|
| 480p | $0.11/秒 | $0.55 | $0.11/秒 |
| 720p | $0.24/秒 | $1.20 | $0.24/秒 |
| 1080p | $0.48/秒 | $2.40 | $0.48/秒 |
三个分辨率,三次精确吻合。文件分别是 854x480、1280x720、1920x1080,都是 24 fps,带 32 kHz 的 AAC 音轨。时长落在 5.04 秒而不是正好 5 秒,所以计费请读 usage.video_seconds,不要用自己的算术。
作为对比,同样的请求在 bytedance/seedance-2.0-mini 的 480p 上计费 $0.10。这也是 Mini 仍然适合走量的原因:便宜五倍半,而且在没人盯着尾帧的活儿上,这个差距无所谓。反过来说,在这个任务上,差距是看得见的。
Seedance 2.5 支持哪些分辨率
问价格表,别问文字描述。 模型页当前的文字摘要写着 480p 或 720p,而同一页的价格表列出了文生视频和视频生视频的 1080p 行,我们的 1080p 首尾帧任务也真的跑完了。
| 来源 | 说法 |
|---|---|
| 模型页文字 | 480p 或 720p,默认 720p |
| 模型页价格表 | 有 480p / 720p / 1080p 三行,1080p 文生视频 $0.48/秒 |
| 真实 API,1080p 首尾帧 | 接受,176.2 秒完成,计费 $2.40 |
一个资费档刚开放的那几周,这种自相矛盾很常见,而分辨率字段恰好是最便宜的验证对象:发一个请求,看状态码。被拒是即时的,而且免费。
1080p 上还有一件页面上没写的事:文件回来是 HEVC,而 480p 和 720p 的输出是 H.264。如果你要用流复制拼接,或者直接丢给浏览器播,混编码的一批素材会咬人。按文件查编码,别按模型猜。
时长是两代之间变化的另一个轴:2.5 支持 4 到 30 秒,2.0 那条线到 15 秒为止。而 30 秒的片子在 prompt 里大概需要十个动作节拍,否则模型会把一个瞬间抻满十秒。这个节奏问题我们在 2.5 提示词指南里写过,剩下的能力差异在 2.5 与 2.0 的对比里。
怎么不开两个控制台就比较两个视频模型
这篇文章里的对比只需要一件麻烦事:拿同一个请求体去打 seedance-2.5 和 seedance-2.0-mini,其他什么都不改。两个模型 ID,一把 key,一种接口形状。原生对接的话,那是两个厂商控制台、两个余额、两套请求 schema —— 到这一步,多数人就改成「拿一个模型和自己对另一个模型的印象比一比」,然后管它叫评测。
这里的两个模型都答在同一个 POST /v1/videos 上,因为视频接口与模型无关;两次运行之间的差异就只有 model 字段。我们用的是 ofox 的视频接口,任何能在不同厂商之间保持请求形状稳定的网关都能干同样的活。信任一次跨模型对比之前要检查的点是:网关有没有在中途把字段规范化掉。如果 aspect_ratio 在 2.5 和 2.0 上表现完全一致,那才是异味。它没有一致,这正是字段原样送达每个模型的证据。
参考资料
常见问题
- 怎么给 Seedance 2.5 传首帧和尾帧?
- 在 POST /v1/videos 的 frame_images 数组里放两个元素,每个元素带 image_url 和 frame_type(first_frame 或 last_frame)。模式由请求体推断,没有 mode 参数要设。图片可以是公网 URL,也可以是 data URI —— base64 data URI 是通的,省掉了为测试搭图床这一步。
- Seedance 2.5 真的会落在你给的尾帧上吗?
- 会,而且很接近。我们把输出的最后一帧和请求的尾帧做对比,480p 的平均绝对像素误差是 5.4,720p 是 2.0(0-255 量纲)。同样的请求在 Seedance 2.0 Mini 上是 35.9,而两张毫不相干的图片的基线是 39.0。在 Mini 上尾帧是建议,在 2.5 上尾帧是目标。
- 为什么 Seedance 2.5 的首尾帧任务传 aspect_ratio 会 400?
- 因为输出画幅取自首帧图片,所以这个字段是被拒绝而不是被忽略。错误信息写着:首帧或首尾帧生成时,输出画幅跟随首帧图片。即使你传的比例和图片完全一致也照样报错。要么不传 aspect_ratio,要么传 adaptive。
- Seedance 2.0 也有这个限制吗?
- 没有。完全相同的请求体(frame_images 加 aspect_ratio 16:9)在 bytedance/seedance-2.0-mini 上被接受,返回了 864x496 的片子。这个限制属于 2.5 的锁定任务类型,不是「带帧生成」的通用规则 —— 所以在 2.0 上跑了几个月的代码,会在有人把模型 ID 改成 2.5 的那天开始 400。
- 可以只传尾帧吗?
- 不行,会返回 400:last_frame requires a first_frame。也不能传两个首帧,那是 400:at most one first_frame and one last_frame。这两条都在请求发往上游之前校验,所以不花钱,大约一秒就返回。
- Seedance 2.5 的图生视频怎么计费?
- 按对应分辨率的文生视频档计费,不是「其他组合」那一行。我们的 5 秒 480p 任务计费 $0.55,720p 计费 $1.20,正好等于模型页上的 $0.11/秒 和 $0.24/秒。失败任务 usage 为 null,不计费。
- Seedance 2.5 支持 1080p 吗?
- 模型页的价格表里文生视频和视频生视频都有 1080p 行,我们的 1080p 首尾帧任务也跑完了:176.2 秒,计费 $2.40,正好是 $0.48/秒 的文生视频价。但同一个页面的文字描述仍然写着 480p 或 720p。以价格表和一次真实请求为准。
- 输出带声音吗?
- 默认带。我们拉回来的每一段片子都有 32 kHz 的 AAC 音轨,视频是 24 fps 的 H.264。如果你后面要拼接,这点很重要:音频参数也必须一致,否则 ffmpeg concat 的流复制会拒绝工作。


