Skip to content

图生视频 — Wan2.2 I2V

网关地址: https://ai.ospreyai.cn(公网) 模型: wan2.2_i2v_high_noise_14B + wan2.2_i2v_low_noise_14B(4步加速 LightX2V LoRA) 无需后端 Bearer Token

概述

使用 Wan2.2 I2V + LightX2V 4步加速 工作流,仅需 4 步采样即可生成约 5 秒视频。任务异步执行:提交工作流 → 轮询状态 → 下载结果。任务状态查询、结果下载等通用接口见 任务管理

前置条件: 需先通过 /api/v1/upload 上传输入图片。

bash
export GW="https://ai.ospreyai.cn"
export API_KEY="sk-your-api-key"

接口清单

用途方法路径
上传输入图片POST/api/v1/upload
提交视频任务POST/api/v1/ai/video/generate
查询任务状态GET/api/v1/ai/tasks/{prompt_id}
下载结果文件GET/api/v1/ai/image/view/
查询队列GET/api/v1/ai/queue

提交任务后异步生成,需轮询 tasks/{prompt_id} 直到 status.completed=true,再下载。视频输出在任务状态 outputsimages 字段(文件名 .mp4,同节点 animated 标记为视频),下载时需带 subfolder=video

提交视频生成任务

POST /api/v1/ai/video/generate
Content-Type: application/json
Authorization: Bearer sk-xxx

1. 上传图片

bash
curl -H "Authorization: Bearer $API_KEY" -X POST "$GW/api/v1/upload" \
  -F "image=@/path/to/input.png" \
  -F "overwrite=true"
# 返回: {"name": "input.png", "subfolder": "", "type": "input"}

2. 提交视频工作流

bash
curl -H "Authorization: Bearer $API_KEY" -X POST "$GW/api/v1/ai/video/generate" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": {
      "84": {"inputs": {"clip_name": "umt5_xxl_fp8_e4m3fn_scaled.safetensors", "type": "wan", "device": "default"}, "class_type": "CLIPLoader"},
      "85": {"inputs": {"add_noise": "disable", "noise_seed": 0, "steps": 4, "cfg": 1, "sampler_name": "euler", "scheduler": "simple", "start_at_step": 2, "end_at_step": 4, "return_with_leftover_noise": "disable", "model": ["103", 0], "positive": ["98", 0], "negative": ["98", 1], "latent_image": ["86", 0]}, "class_type": "KSamplerAdvanced"},
      "86": {"inputs": {"add_noise": "enable", "noise_seed": 42, "steps": 4, "cfg": 1, "sampler_name": "euler", "scheduler": "simple", "start_at_step": 0, "end_at_step": 2, "return_with_leftover_noise": "enable", "model": ["104", 0], "positive": ["98", 0], "negative": ["98", 1], "latent_image": ["98", 2]}, "class_type": "KSamplerAdvanced"},
      "87": {"inputs": {"samples": ["85", 0], "vae": ["90", 0]}, "class_type": "VAEDecode"},
      "89": {"inputs": {"text": "色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸变的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走", "clip": ["84", 0]}, "class_type": "CLIPTextEncode"},
      "90": {"inputs": {"vae_name": "wan_2.1_vae.safetensors"}, "class_type": "VAELoader"},
      "93": {"inputs": {"text": "A bird spreading its wings and flying away", "clip": ["84", 0]}, "class_type": "CLIPTextEncode"},
      "94": {"inputs": {"fps": 16, "images": ["87", 0]}, "class_type": "CreateVideo"},
      "95": {"inputs": {"unet_name": "wan2.2_i2v_high_noise_14B_fp8_scaled.safetensors", "weight_dtype": "default"}, "class_type": "UNETLoader"},
      "96": {"inputs": {"unet_name": "wan2.2_i2v_low_noise_14B_fp8_scaled.safetensors", "weight_dtype": "default"}, "class_type": "UNETLoader"},
      "97": {"inputs": {"image": "input.png"}, "class_type": "LoadImage"},
      "98": {"inputs": {"width": 640, "height": 640, "length": 81, "batch_size": 1, "positive": ["93", 0], "negative": ["89", 0], "vae": ["90", 0], "start_image": ["97", 0]}, "class_type": "WanImageToVideo"},
      "101": {"inputs": {"lora_name": "wan2.2_i2v_lightx2v_4steps_lora_v1_high_noise.safetensors", "strength_model": 1.0, "model": ["95", 0]}, "class_type": "LoraLoaderModelOnly"},
      "102": {"inputs": {"lora_name": "wan2.2_i2v_lightx2v_4steps_lora_v1_low_noise.safetensors", "strength_model": 1.0, "model": ["96", 0]}, "class_type": "LoraLoaderModelOnly"},
      "103": {"inputs": {"shift": 5.0, "model": ["102", 0]}, "class_type": "ModelSamplingSD3"},
      "104": {"inputs": {"shift": 5.0, "model": ["101", 0]}, "class_type": "ModelSamplingSD3"},
      "108": {"inputs": {"filename_prefix": "video/my_video", "format": "auto", "codec": "auto", "video-preview": "", "video": ["94", 0]}, "class_type": "SaveVideo"}
    }
  }'

响应:

json
{"prompt_id": "03464627-3b48-43fe-91b9-ca7c779ba618", "number": 130, "node_errors": {}}

关键节点参数

节点字段说明推荐值
97image输入图片文件名(需先上传)上传返回的 name
93text正向提示词(英文动作描述)
98width / height视频尺寸640 × 640
98length视频帧数(81帧≈5秒@16fps)81
86noise_seed随机种子任意整数
108filename_prefix输出文件名前缀"video/xxx"

提示词技巧

  • 英文动作描述优先:A bird spreading its wings and flying away
  • 动作 + 主体 + 场景:A girl walking through a rainy street, holding an umbrella
  • 描述要体现动态,避免静态描述(如 a beautiful girl 不如 a beautiful girl dancing

下载结果

视频输出在任务状态 outputsimages 字段(文件名是 .mp4),同节点有 animated 布尔列表标记是视频。

bash
# 注意 subfolder=video 必须带上
curl -H "Authorization: Bearer $API_KEY" \
  "$GW/api/v1/ai/image/view/?filename=my_video_00001_.mp4&type=output&subfolder=video" \
  -o result.mp4

输出: MP4 视频,640×640, 81帧, 16fps, 约5秒。

Python 调用示例

python
import json, time, urllib.request

GW = "https://ai.ospreyai.cn"
API_KEY = "sk-your-api-key"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}

# 1. 上传图片(参考「任务管理」页上传示例)

# 2. 提交工作流
nodes = {
    "84": {"inputs": {"clip_name": "umt5_xxl_fp8_e4m3fn_scaled.safetensors", "type": "wan", "device": "default"}, "class_type": "CLIPLoader"},
    # ...其余节点同上 curl 示例...
}
nodes["93"]["inputs"]["text"] = "A bird spreading its wings and flying away"
nodes["97"]["inputs"]["image"] = "input.png"
nodes["86"]["inputs"]["noise_seed"] = 42  # 避免缓存

req = urllib.request.Request(
    f"{GW}/api/v1/ai/video/generate",
    data=json.dumps({"prompt": nodes}).encode(),
    headers=HEADERS, method="POST",
)
prompt_id = json.loads(urllib.request.urlopen(req, timeout=30).read())["prompt_id"]

# 3. 轮询
while True:
    r = urllib.request.Request(f"{GW}/api/v1/ai/tasks/{prompt_id}", headers=HEADERS)
    task = json.loads(urllib.request.urlopen(r, timeout=15).read())[prompt_id]
    if task["status"].get("completed"):
        break
    time.sleep(5)

# 4. 下载(视频在 outputs 的 images 字段,文件名 .mp4,subfolder=video)
for out in task["outputs"].values():
    for g in out.get("images", []):
        if not g["filename"].endswith(".mp4"):
            continue
        url = f"{GW}/api/v1/ai/image/view/?filename={g['filename']}&type=output&subfolder={g.get('subfolder','')}"
        req = urllib.request.Request(url, headers=HEADERS)
        open(g["filename"], "wb").write(urllib.request.urlopen(req, timeout=120).read())

常见问题

问题现象可能原因解决方案
401 UnauthorizedAPI Key 错误/未传检查 Authorization: Bearer sk-xxx
500 on generate工作流 JSON 格式错{"prompt": {...}},节点连接用 ["id", slot]
任务 success 但 outputs 为空命中 ComfyUI 缓存(execution_cached提交时换个随机 noise_seed
下载 404没带 subfolder=video视频在 output 的 video/ 子目录,URL 必须带 subfolder=video
outputs 里找不到视频找错字段视频在 outputs[].images(文件名 .mp4 + animated 标记),不是 gifs

详细文档见 ComfyUI 视频生成 Skill

AI API Gateway Documentation