Upscale Video
把视频放大到 1080p、2k 或 4k,有两种放大服务可选,按源视频计价。
Upscale Video(产品 upscale_video)把视频放大到 1080p、2k 或 4k,保留音轨。有 bytedance、topaz 两种放大服务,参数和计费方式不同。一个任务出 1 段视频,按源视频计价。
创建任务
https://api.nanoapi.ai/v1/tasks用所有模型共用的创建任务接口,model 传 "upscale-video"。接口通常不到 1 秒返回,几秒内在后台读取源视频、冻结费用;任务结束后获取结果。
请求头
| 请求头 | 必填 | 说明 |
|---|---|---|
Authorization | 是 | Bearer <API Key>,见鉴权 |
Content-Type | 是 | application/json |
Idempotency-Key | 否 | 每个新任务一个唯一字符串,建议用 UUID(1–255 个字符),见防止重复创建 |
请求体
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
model | string | 是 | upscale-video |
video_url | string | 是 | 要放大的视频,最长 180 秒,见素材 |
provider | string | 是 | 放大服务:bytedance 或 topaz。两者的参数和计费方式不同 |
resolution | string | 是 | bytedance:1080p、2k 或 4k。topaz:1080p 或 4k。决定价格 |
fps | integer | bytedance 必填 | 输出帧率:24、30 或 60。影响价格:60 翻倍。只有 bytedance 有,topaz 传了返回 400 |
preset | string | bytedance 必填 | 按视频内容选:common(通用)、aigc(AI 生成的视频)、short_series(短剧)、ugc(用户拍摄的视频)或 old_film(老片)。不影响价格。只有 bytedance 有,topaz 传了返回 400 |
webhook_url | string | 否 | 任务成功或失败时通知该地址:https,最长 2048 字符,不能指向内网、回环或保留地址。见回调 |
用 bytedance 放大到 1080p、24 帧:
curl https://api.nanoapi.ai/v1/tasks \
-H "Authorization: Bearer $NANOAPI_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 9b4d2f7a-6e1c-4c8b-a3f5-8d0e6b2a9c47" \
-d '{
"model": "upscale-video",
"video_url": "https://example.com/clip.mp4",
"provider": "bytedance",
"resolution": "1080p",
"fps": 24,
"preset": "common"
}'用 topaz 放大到 4k(不传 fps、preset),请求体是:
{
"model": "upscale-video",
"video_url": "https://example.com/clip.mp4",
"provider": "topaz",
"resolution": "4k"
}响应:200 OK。data 是刚创建的任务,只有下面这几个字段,各字段的含义见创建任务的返回。保存 data.id,用它获取结果。创建后几秒内才冻结费用,任务可能在这时失败(例如源视频读不了),以查询或回调的结果为准。
{
"code": 200,
"message": "success",
"data": {
"object": "task",
"id": "tk_01jbm6e8g1j4k7n0s3v6y9c2d5",
"model": "upscale-video",
"status": "queued",
"error": null,
"created_at": "2026-11-03T08:30:00Z"
}
}获取结果
实测从创建到结束的耗时:10 秒的视频放大到 1080p,topaz 约 2 分钟,bytedance 约 2.5 分钟;长视频会久得多,生成服务忙时也会更慢。任务结束(成功或失败)后用下面任一方式拿结果:
- 回调(生产环境推荐):创建时传了
webhook_url,任务结束时会把完整的任务推送一次,见回调。 - 轮询:用
data.id调用GET /v1/tasks/{task_id},间隔 15 秒以上,直到status为succeeded或failed;多个任务用列出任务的ids一次查询。
上面 bytedance 的请求成功后(省略了其他字段):
{
"status": "succeeded",
"input": {
"video_url": "https://example.com/clip.mp4",
"provider": "bytedance",
"resolution": "1080p",
"fps": 24,
"preset": "common"
},
"num_outputs": 1,
"outputs": [
{
"index": 0,
"type": "video",
"url": "https://cdn.nanoapi.ai/h/tk_01jbm6e8g1j4k7n0s3v6y9c2d5_1_1793694600.mp4",
"preview_url": "https://cdn.nanoapi.ai/h/tk_01jbm6e8g1j4k7n0s3v6y9c2d5_1_1793694600_compressed.mp4"
}
],
"billing": {
"currency": "USD",
"frozen": "…", // 按源视频算出的价格,见价格
"charged": "…", // 一样,偶尔略少
"refunded": "0.00",
"billed_seconds": null
}
}| 字段 | Upscale Video |
|---|---|
outputs | 1 项 |
outputs[0].type | video |
outputs[0].url | 放大后的视频,带音轨,用于下载。bytedance:h264 的 mp4。topaz:HEVC(h265),部分浏览器不能直接播放,网页里请用 preview_url 播放 |
outputs[0].preview_url | 无声的压缩版 mp4(h264),宽最多 600,用于展示。生成不了预览时为 null |
billing.billed_seconds | 一直是 null:费用按源视频计算,见价格 |
input | 你传的参数 |
失败时冻结的钱全额退回,原因在 data.error.type,见错误。完整的字段见任务对象。
素材
视频以公开的 http(s) 链接放在 video_url 里提交。不提供上传接口,请自行托管文件。链接最长 4096 字符,必须能直接下载,不能指向 localhost 或内网、回环、保留地址。
源视频(video_url) | |
|---|---|
| 时长 | 最长 180 秒(GET /v1/products 的 limits.max_source_video_seconds) |
| 有问题时 | 创建后几秒内读取:读不了时任务失败(invalid_media),超过 180 秒时任务失败(video_too_long),不冻结费用 |
任务结束前链接要保持可访问,有有效期的链接也不能提前过期。
实测过的时长
180 秒以内的也不保证都能成功。下面是实测成功过的范围,超出的可能失败,冻结的钱全额退回(invalid_media、video_too_long、invalid_request 或 generation_failed):
provider | 1080p | 2k | 4k |
|---|---|---|---|
bytedance | 10 秒以内 | 未测 | 3 秒以内 |
topaz | 30 秒以内 | – | 10 秒以内 |
价格
bytedance:费用 = 每秒单价(按分辨率和 fps)× 源视频时长
topaz: 费用 = 每次的固定费用 + ceil(源视频帧数 × 每帧单价 ÷ 取整步长) × 取整步长正在读取当前价格…
bytedance:源视频画面(视频轨)的时长,不取整。fps为60时每秒单价翻倍;preset不影响价格。topaz:源视频的帧数,平台读取视频后才知道。按帧计算的部分向上取整到price_step(GET /v1/products里topaz那几行的字段)的整数倍。请用整数微美元(金额 × 1,000,000)计算,不要用浮点数:浮点除法可能比整数多出一点点(JavaScript 里0.07 / 0.01是7.000000000000001),向上取整时就多算一档。- 创建后几秒内读取源视频、算出价格再冻结。成功后扣冻结的金额,偶尔略少(少数视频在生成时会被重新处理,例如手机剪辑留下的隐藏帧、重新编码),不会更多;失败全额退回。冻结和扣费的通用规则见计费。
billing.billed_seconds一直是null。
例:10 秒的视频用 bytedance 放大到 1080p、24 帧(上面第一个请求),费用是 10 × 1080p、24 帧的每秒单价。10 秒、24 帧(240 帧)的视频用 topaz 放大到 4k,费用是 4k 每次的固定费用 + 240 × 4k 的每帧单价,按帧计算的部分向上取整到 price_step 的整数倍。
想在提交前显示价格:自己读出视频的时长(topaz 的帧数按时长 × 帧率估算),用 GET /v1/products 返回的当前单价计算:upscale_video 产品的 prices 按 provider、resolution、fps 每种一行;topaz 那几行的 billing_unit 是 frame,每次的固定费用在 base_price,取整步长在 price_step。价格会调整,不要写死。算出来的是预估,实际费用以查询任务返回的 billing.frozen 为准(创建后几秒内冻结)。
错误
这个模型特有的错误和失败原因。创建任务的全部错误见创建任务 → 错误,全部失败原因见失败原因。
创建请求出错:请求返回 HTTP 错误,任务不会创建。param 是对应的参数名。
| 状态码 | error.type | 何时出现 | 怎么处理 |
|---|---|---|---|
400 | invalid_request | 没传 video_url、provider 或 resolution(Field required),或者 bytedance 没传 fps、preset(fps is required for provider bytedance)。param 是缺的那个 | 必填参数都要传,见创建任务 |
400 | invalid_request | topaz 传了 fps 或 preset(fps is only allowed for provider bytedance) | 去掉这个参数 |
400 | invalid_request | provider 不是 bytedance / topaz,resolution 不是这个 provider 支持的值(Input should be '1080p' or '4k' for provider topaz),fps、preset 不是上面列出的值,video_url 不是公开的 http(s) 链接或者超过 4096 字符,或者 num_outputs 不是 1 | 改成允许的值 |
400 | invalid_request | 传了这个模型没有的参数,例如 prompt(Extra inputs are not permitted) | 去掉这个参数 |
创建接口的其他错误(401、402、429 等)见创建任务 → 错误。
任务失败:创建请求成功(200),任务之后变成 failed。这种情况没有 HTTP 状态码,原因在任务的 error.type,通过查询任务或回调拿到。
error.type | 何时出现 | 怎么处理 |
|---|---|---|
invalid_media | 源视频读不了:链接打不开或已过期、不是公网地址,或者不是视频。创建后几秒内出现,不冻结费用。也可能是生成服务返回的,这时已经冻结过费用,全额退回 | 换成能公开直接下载的视频链接,重新创建 |
video_too_long | 源视频超过 180 秒(The video duration must be at most 180 seconds.):创建后几秒内出现,不冻结费用。或者生成服务不接受这么长的视频(The video is too long for this model. Use a shorter video.):这时已经冻结过费用,全额退回 | 换一段短一些的视频,见实测过的时长 |
insufficient_balance | 可用余额不够按源视频算出的费用。创建后几秒内出现,不冻结费用 | 充值后重新创建 |
spend_limit_exceeded | 加上这个任务的费用会超出 Key 的消费限额。创建后几秒内出现,不冻结费用 | 在控制台 → API Keys 调高限额,或者等限额重置后重新创建 |
invalid_request | 生成服务不接受这段视频和这组参数,例如视频超出了实测过的时长。这时已经冻结过费用,全额退回 | 换一段短一些的视频,或者降低 resolution |
content_policy | 视频不符合内容政策 | 原样重新提交还会失败,请换一段视频 |
generation_failed | 生成失败 | 稍后重新创建,或者换一段短一些的视频 |
queue_timeout / internal_error | 排队超过 30 分钟未开始 / 内部错误 | 稍后重新创建 |
所有失败的任务都已全额退回冻结金额,billing.charged 为 "0.00"。程序判断请用 error.type:括号里的 message 用于展示,措辞可能调整,见每种原因的 message。