Genjutsu
用一段源视频和参考图生成新视频。
mode | 作用 |
|---|---|
motion_control | 动作迁移:参考图里的人物做出源视频中的动作 |
replace_object | 物体替换:把源视频中的某个物体换成参考图里的物体 |
创建任务
POST https://api.nanoapi.ai/v1/genjutsu读取源视频,从可用余额中冻结费用,返回 202 Accepted 和状态为 queued 的任务。视频在后台生成,通常需要 10–20 分钟,通过回调或 GET /v1/tasks/{id} 获取结果。任务不能取消。
读取源视频需要 1–3 秒,最长约 35 秒:客户端超时请设为 60 秒以上。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
model | string | 否 | 模型版本:genjutsu-1.0(默认,目前也只有这一个)。可用的版本见 GET /v1/products 的 models。建议显式传:以后发布新版本时,不传的仍然用 genjutsu-1.0。传了不存在的版本返回 400 invalid_request,param 为 "model" |
mode | string | 是 | motion_control 或 replace_object |
video_url | string | 是 | 源视频,见素材 |
image_urls | string[] | 是 | 1–10 张参考图,见素材 |
prompt | string | 否 | 最长 5000 字符 |
resolution | string | 否 | 480p、720p(默认)或 1080p,决定价格 |
num_outputs | integer | 否 | 目前只能是 1(默认) |
metadata | object | 否 | 自定义键值对,原样出现在任务和回调里:最多 16 个键,键 1–40 字符,值为字符串、最长 500 字符。放上你的订单号,之后方便找到任务 |
webhook_url | string | 否 | 任务成功或失败时通知该地址:https,最长 2048 字符。见回调 |
curl https://api.nanoapi.ai/v1/genjutsu \
-H "Authorization: Bearer $NANOAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "genjutsu-1.0",
"mode": "motion_control",
"image_urls": ["https://example.com/person.png"],
"video_url": "https://example.com/dance.mp4",
"resolution": "720p",
"metadata": { "order_id": "A1001" },
"webhook_url": "https://example.com/hooks/nanoapi"
}'返回(节选,各字段见任务对象):
{
"object": "task",
"id": "tk_01jb8z5q4w3e2r1t0y9u8i7o6p",
"product": "genjutsu",
"model": "genjutsu-1.0",
"status": "queued",
"billing": { "currency": "USD", "frozen": "4.095", "charged": "0.00", "refunded": "0.00", "billed_seconds": null },
"metadata": { "order_id": "A1001" },
"created_at": "2026-10-22T08:30:00Z"
}素材
所有素材都以公开的 http(s) 链接提交。不提供上传接口,请自行托管文件,例如放在你自己的对象存储中。链接最长 4096 字符,不能指向 localhost 或内网、回环、保留地址。
源视频(video_url) | 参考图(image_urls) | |
|---|---|---|
| 数量 | 1 个 | 1–10 张 |
| 格式 | 能直接下载的 mp4、mov、webm 或 mkv | 常见图片格式 |
| 时长 | 最长 30 秒;replace_object 为 4–30 秒 | – |
| 何时读取 | 创建任务时,用来计算价格 | 生成时 |
| 读不了时 | 请求直接返回 400(见错误),不创建任务、不冻结费用 | 任务失败,冻结金额全额退回 |
任务结束前所有链接都要保持可访问,有有效期的链接也不能提前过期。
价格
费用 = 源视频的计费秒数 × 所选分辨率的每秒单价| 分辨率 | 每秒单价 | 30 秒视频 |
|---|---|---|
| 480p | $0.117 | $3.51 |
| 720p | $0.273 | $8.19 |
| 1080p | $0.78 | $23.40 |
计费秒数:
- 时长:取视频画面和音轨里较长的那个,不是文件信息里显示的时长。编码带来的几十毫秒误差不算在内(画面正好 30 秒、文件信息显示 30.02 秒的视频可以提交)。
motion_control:四舍五入到整秒,不足 4 秒按 4 秒算。replace_object:向上取整到整秒。
例如 720p、15 秒的视频冻结 $4.095,成功后扣 $4.095。价格可能调整,请从 GET /v1/products 读取,不要写死在代码里。冻结和扣费的通用规则见计费规则。
想在提交前显示价格:在你这边读出视频时长,按上面的规则计算。这只是预估,以返回的 billing.frozen 为准。
错误
这个接口特有的错误。全部错误码和处理方式见错误。
| 状态码 | code | 何时出现 |
|---|---|---|
| 400 | invalid_media | 源视频读不了:链接打不开或已过期、不是公网地址,或不是支持的视频。details.reason 是具体原因 |
| 400 | video_too_long | 源视频超过 30 秒(details.video_duration) |
| 400 | video_too_short | replace_object 的源视频不到 4 秒 |
| 402 | insufficient_balance | 可用余额不够付这次的费用(details.required、details.available) |
| 429 | too_many_inflight_tasks | 排队中和运行中的任务已有 10 个(details.limit) |
| 503 | service_unavailable | 暂时无法计算价格,任务没有创建;按 Retry-After 等待后重试 |
以上错误都不会创建任务,也不会冻结费用。