Reframe Video
视频改画幅:改成新的画面比例并补画新增的区域,可以带参考图,按源视频计价。
Reframe Video(产品 reframe_video)把视频改成新的画面比例,补画新画面里多出来的区域,可以带最多 2 张参考图引导补画的内容。一个任务出 1 段视频,按源视频的时长和分辨率计价。
创建任务
https://api.nanoapi.ai/v1/tasks用所有模型共用的创建任务接口,model 传 "reframe-video"。接口通常不到 1 秒返回,几秒内在后台读取源视频、冻结费用;任务结束后获取结果。
请求头
| 请求头 | 必填 | 说明 |
|---|---|---|
Authorization | 是 | Bearer <API Key>,见鉴权 |
Content-Type | 是 | application/json |
Idempotency-Key | 否 | 每个新任务一个唯一字符串,建议用 UUID(1–255 个字符),见防止重复创建 |
请求体
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
model | string | 是 | reframe-video |
video_url | string | 是 | 源视频,4–60 秒,见素材 |
aspect_ratio | string | 是 | 新的画面比例:16:9、9:16、4:3、3:4、1:1 或 21:9 |
image_urls | string[] | 否 | 参考图,最多 2 张,引导新增区域补画的内容。只有 15 秒以内的源视频能带,见素材 |
webhook_url | string | 否 | 任务成功或失败时通知该地址:https,最长 2048 字符,不能指向内网、回环或保留地址。见回调 |
把一段 15 秒以内的视频改成 9:16,带一张参考图引导新增的区域:
curl https://api.nanoapi.ai/v1/tasks \
-H "Authorization: Bearer $NANOAPI_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 4f6a8c2e-0b3d-4d9f-9a7e-2c5b1f8d6e30" \
-d '{
"model": "reframe-video",
"video_url": "https://example.com/clip.mp4",
"aspect_ratio": "9:16",
"image_urls": ["https://example.com/background.jpg"]
}'响应:200 OK。data 是刚创建的任务,只有下面这几个字段,各字段的含义见创建任务的返回。保存 data.id,用它获取结果。创建后几秒内才冻结费用,任务可能在这时失败(例如源视频超过 15 秒却带了 image_urls),以查询或回调的结果为准。
{
"code": 200,
"message": "success",
"data": {
"object": "task",
"id": "tk_01jbm7f9h2k5m8p1t4w7z0d3e6",
"model": "reframe-video",
"status": "queued",
"error": null,
"created_at": "2026-11-03T08:30:00Z"
}
}获取结果
实测从创建到结束 5–10 分钟,10 秒的视频约 7 分钟,生成服务忙时会更慢。任务结束(成功或失败)后用下面任一方式拿结果:
- 回调(生产环境推荐):创建时传了
webhook_url,任务结束时会把完整的任务推送一次,见回调。 - 轮询:用
data.id调用GET /v1/tasks/{task_id},间隔 15 秒以上,直到status为succeeded或failed;多个任务用列出任务的ids一次查询。
上面的请求成功后(省略了其他字段):
{
"status": "succeeded",
"input": {
"video_url": "https://example.com/clip.mp4",
"aspect_ratio": "9:16",
"image_urls": ["https://example.com/background.jpg"]
},
"num_outputs": 1,
"outputs": [
{
"index": 0,
"type": "video",
"url": "https://cdn.nanoapi.ai/h/tk_01jbm7f9h2k5m8p1t4w7z0d3e6_1_1793694600.mp4",
"preview_url": "https://cdn.nanoapi.ai/h/tk_01jbm7f9h2k5m8p1t4w7z0d3e6_1_1793694600_compressed.mp4"
}
],
"billing": {
"currency": "USD",
"frozen": "…", // 按源视频算出的价格,见价格
"charged": "…", // 一样,偶尔略少
"refunded": "0.00",
"billed_seconds": null
}
}| 字段 | Reframe Video |
|---|---|
outputs | 1 项 |
outputs[0].type | video |
outputs[0].url | 改好画幅的视频,mp4,用于下载。分辨率跟随源视频(480p / 720p / 1080p),不能指定;短边超过 1080 的源视频会先缩到 1080 |
outputs[0].preview_url | 无声的压缩版 mp4(h264),宽最多 600,用于展示。生成不了预览时为 null |
billing.billed_seconds | 一直是 null:费用按源视频计算,见价格 |
input | 你传的参数;image_urls 传了才有 |
失败时冻结的钱全额退回,原因在 data.error.type,见错误。完整的字段见任务对象。
素材
所有素材都以公开的 http(s) 链接提交。不提供上传接口,请自行托管文件。链接最长 4096 字符,必须能直接下载,不能指向 localhost 或内网、回环、保留地址。
源视频(video_url) | 参考图(image_urls) | |
|---|---|---|
| 数量 | 1 | 0–2 张(GET /v1/products 的 limits.max_reference_images) |
| 时长 | 4–60 秒(limits.min_source_video_seconds / limits.max_source_video_seconds);带 image_urls 时最长 15 秒(limits.max_source_video_seconds_with_images) | – |
| 有问题时 | 创建后几秒内读取:读不了(包括读不出时长、宽高)时任务失败(invalid_media);不在 4–60 秒时失败(video_too_short / video_too_long);超过 15 秒却带了 image_urls 时失败(invalid_request)。都不冻结费用 | 生成时才读取(算价格只读源视频):下载不了或读不了时任务失败(invalid_media),冻结的钱全额退回。创建后几秒内就失败的,是在冻结之前发现的,billing.frozen 一直是 "0.00" |
任务结束前所有链接都要保持可访问,有有效期的链接也不能提前过期。
价格
费用 = 每次的固定费用 + 每秒单价(按源视频的分辨率)× 源视频秒数正在读取当前价格…
- 秒数:源视频的时长,四舍五入到整秒。
- 每秒单价:按源视频的分辨率档位,480p、720p 或 1080p,由生成服务读取源视频时确定。例如 640×360 的视频按 480p 计费,短边超过 1080 的按 1080p。
aspect_ratio和参考图不影响价格。 - 创建后几秒内读取源视频、算出价格再冻结。成功后扣冻结的金额,偶尔略少(少数视频在生成时会被重新处理,例如手机剪辑留下的隐藏帧、重新编码),不会更多;失败全额退回。冻结和扣费的通用规则见计费。
billing.billed_seconds一直是null。
例:上面请求的源视频如果是 10 秒的 720p,费用是每次的固定费用 + 10 × 720p 的每秒单价。
想在提交前显示价格:自己读出视频的时长和分辨率,用 GET /v1/products 返回的当前单价计算:reframe_video 产品的 prices 每种源视频分辨率一行,每次的固定费用在 base_price。价格会调整,不要写死。算出来的是预估(分辨率档位要读取源视频时才确定),实际费用以查询任务返回的 billing.frozen 为准(创建后几秒内冻结)。
错误
这个模型特有的错误和失败原因。创建任务的全部错误见创建任务 → 错误,全部失败原因见失败原因。
创建请求出错:请求返回 HTTP 错误,任务不会创建。param 是对应的参数名。
| 状态码 | error.type | 何时出现 | 怎么处理 |
|---|---|---|---|
400 | invalid_request | 没传 video_url 或 aspect_ratio(Field required,param 是缺的那个) | 两个都要传 |
400 | invalid_request | aspect_ratio 不是上面列出的值(Input should be '16:9', '9:16', '4:3', '3:4', '1:1' or '21:9' for reframe-video),image_urls 超过 2 张(param 为 "image_urls"),链接不是公开的 http(s) 链接或者超过 4096 字符,或者 num_outputs 不是 1 | 按 param 改正 |
400 | invalid_request | 传了这个模型没有的参数,例如 prompt(Extra inputs are not permitted) | 去掉这个参数 |
创建接口的其他错误(401、402、429 等)见创建任务 → 错误。
任务失败:创建请求成功(200),任务之后变成 failed。这种情况没有 HTTP 状态码,原因在任务的 error.type,通过查询任务或回调拿到。
error.type | 何时出现 | 怎么处理 |
|---|---|---|
invalid_media | 源视频读不了(包括读不出时长、宽高)。创建后几秒内出现,不冻结费用 | 换成能公开直接下载的视频链接,重新创建 |
invalid_media | 参考图下载不了(A reference image could not be downloaded. Make sure every link in image_urls is publicly downloadable.)或读不了(A reference image could not be read. It may be corrupted or in an unsupported format.)。一般在生成时才发现,这时已经冻结过费用,全额退回(charged 为 "0.00",refunded 等于 frozen);创建后几秒内就失败的不冻结费用 | 按 error.message 换掉那张图,重新创建 |
video_too_short / video_too_long | 源视频不到 4 秒或超过 60 秒(The video duration must be between 4 and 60 seconds.)。创建后几秒内出现,不冻结费用 | 换一段 4–60 秒的视频,重新创建 |
invalid_request | 源视频超过 15 秒,却带了 image_urls(image_urls is only allowed when the source video is at most 15 seconds long.)。创建后几秒内出现,不冻结费用 | 去掉 image_urls,或者把视频裁到 15 秒以内 |
insufficient_balance | 可用余额不够按源视频算出的费用。创建后几秒内出现,不冻结费用 | 充值后重新创建 |
spend_limit_exceeded | 加上这个任务的费用会超出 Key 的消费限额。创建后几秒内出现,不冻结费用 | 在控制台 → API Keys 调高限额,或者等限额重置后重新创建 |
content_policy | 视频或参考图不符合内容政策 | 原样重新提交还会失败,请更换素材 |
generation_failed | 生成失败 | 稍后重新创建 |
queue_timeout / internal_error | 排队超过 30 分钟未开始 / 内部错误 | 稍后重新创建 |
所有失败的任务都已全额退回冻结金额,billing.charged 为 "0.00"。程序判断请用 error.type:括号里的 message 用于展示,措辞可能调整,见每种原因的 message。