Skip to content

ComfyUI LTX-2 文生视频 API 调用手册

本手册说明如何通过公网网关调用 LTX-2 19B 模型做文生视频。 网关通用说明(鉴权、限流、错误码)见 AI API Gateway — API 调用手册

网关地址: https://ai.ospreyai.cn(公网) 模型: ltx-2-19b-dev-fp8.safetensors + ltx-2-19b-distilled-lora-384.safetensors(加速) 无需后端 Bearer Token


一、概述

LTX-2 19B 是 Lightricks 的视频生成模型。本工作流采用两阶段采样管线:先用低分辨率(输出尺寸的 1/2)快速打底 20 步,再空间放大 2× 精修 4 步,输出带空音轨的 mp4 静音视频。

  • 网关地址:https://ai.ospreyai.cn
  • 鉴权:Authorization: Bearer sk-xxx(网关 new-api 的 key)
  • 模型:ltx-2-19b-dev-fp8.safetensors + ltx-2-19b-distilled-lora-384.safetensors(加速)
bash
export GW="https://ai.ospreyai.cn"
export API_KEY="sk-your-api-key"

二、接口清单

用途方法路径
提交视频任务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,再下载。


三、提交视频生成任务

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

请求体为 ComfyUI 工作流 JSON,prompt 字段内为节点定义(连接用 ["node_id", slot] 格式)。

bash
curl -H "Authorization: Bearer $API_KEY" -X POST "$GW/api/v1/ai/video/generate" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": {
      "75": {"inputs": {"filename_prefix": "video/LTX-2", "format": "mp4", "codec": "auto", "video": ["122", 0]}, "class_type": "SaveVideo"},
      "98": {"inputs": {"steps": 20, "max_shift": 2.05, "base_shift": 0.95, "stretch": true, "terminal": 0.1, "latent": ["109", 0]}, "class_type": "LTXVScheduler"},
      "99": {"inputs": {"text_encoder": "gemma_3_12B_it_fp4_mixed.safetensors", "ckpt_name": "ltx-2-19b-dev-fp8.safetensors", "device": "default"}, "class_type": "LTXAVTextEncoderLoader"},
      "100": {"inputs": {"sigmas": "0.909375, 0.725, 0.421875, 0.0"}, "class_type": "ManualSigmas"},
      "101": {"inputs": {"model_name": "ltx-2-spatial-upscaler-x2-1.0.safetensors"}, "class_type": "LatentUpscaleModelLoader"},
      "102": {"inputs": {"positive": ["107", 0], "negative": ["107", 1], "latent": ["116", 0]}, "class_type": "LTXVCropGuides"},
      "103": {"inputs": {"cfg": 1, "model": ["132", 0], "positive": ["102", 0], "negative": ["102", 1]}, "class_type": "CFGGuider"},
      "104": {"inputs": {"upscale_method": "lanczos", "scale_by": 0.5, "image": ["111", 0]}, "class_type": "ImageScaleBy"},
      "105": {"inputs": {"image": ["104", 0]}, "class_type": "GetImageSize"},
      "106": {"inputs": {"frames_number": ["112", 0], "frame_rate": ["130", 0], "batch_size": 1, "audio_vae": ["123", 0]}, "class_type": "LTXVEmptyLatentAudio"},
      "107": {"inputs": {"frame_rate": ["129", 0], "positive": ["121", 0], "negative": ["110", 0]}, "class_type": "LTXVConditioning"},
      "108": {"inputs": {"width": ["105", 0], "height": ["105", 1], "length": ["112", 0], "batch_size": 1}, "class_type": "EmptyLTXVLatentVideo"},
      "109": {"inputs": {"video_latent": ["108", 0], "audio_latent": ["106", 0]}, "class_type": "LTXVConcatAVLatent"},
      "110": {"inputs": {"text": "blurry, low quality, still frame, frames, watermark, overlay, titles, has blurbox, has subtitles", "clip": ["99", 0]}, "class_type": "CLIPTextEncode"},
      "111": {"inputs": {"width": 1280, "height": 720, "batch_size": 1, "color": 0}, "class_type": "EmptyImage"},
      "112": {"inputs": {"value": 121}, "class_type": "PrimitiveInt"},
      "113": {"inputs": {"noise": ["115", 0], "guider": ["128", 0], "sampler": ["135", 0], "sigmas": ["98", 0], "latent_image": ["109", 0]}, "class_type": "SamplerCustomAdvanced"},
      "114": {"inputs": {"noise_seed": 0}, "class_type": "RandomNoise"},
      "115": {"inputs": {"noise_seed": 12345}, "class_type": "RandomNoise"},
      "116": {"inputs": {"av_latent": ["113", 0]}, "class_type": "LTXVSeparateAVLatent"},
      "117": {"inputs": {"video_latent": ["118", 0], "audio_latent": ["116", 1]}, "class_type": "LTXVConcatAVLatent"},
      "118": {"inputs": {"samples": ["102", 2], "upscale_model": ["101", 0], "vae": ["138", 2]}, "class_type": "LTXVLatentUpsampler"},
      "119": {"inputs": {"noise": ["114", 0], "guider": ["103", 0], "sampler": ["136", 0], "sigmas": ["100", 0], "latent_image": ["117", 0]}, "class_type": "SamplerCustomAdvanced"},
      "121": {"inputs": {"text": "A cheerful girl puppet singing in the rain, close-up, soft lighting, photorealistic", "clip": ["99", 0]}, "class_type": "CLIPTextEncode"},
      "122": {"inputs": {"fps": ["129", 0], "images": ["126", 0], "audio": ["127", 0]}, "class_type": "CreateVideo"},
      "123": {"inputs": {"ckpt_name": "ltx-2-19b-dev-fp8.safetensors"}, "class_type": "LTXVAudioVAELoader"},
      "124": {"inputs": {"av_latent": ["119", 1]}, "class_type": "LTXVSeparateAVLatent"},
      "126": {"inputs": {"tile_size": 512, "overlap": 64, "temporal_size": 4096, "temporal_overlap": 8, "samples": ["124", 0], "vae": ["138", 2]}, "class_type": "VAEDecodeTiled"},
      "127": {"inputs": {"samples": ["124", 1], "audio_vae": ["123", 0]}, "class_type": "LTXVAudioVAEDecode"},
      "128": {"inputs": {"cfg": 4, "model": ["138", 0], "positive": ["107", 0], "negative": ["107", 1]}, "class_type": "CFGGuider"},
      "129": {"inputs": {"value": 24}, "class_type": "PrimitiveFloat"},
      "130": {"inputs": {"value": 24}, "class_type": "PrimitiveInt"},
      "132": {"inputs": {"lora_name": "ltx-2-19b-distilled-lora-384.safetensors", "strength_model": 1, "model": ["138", 0]}, "class_type": "LoraLoaderModelOnly"},
      "135": {"inputs": {"sampler_name": "euler_ancestral"}, "class_type": "KSamplerSelect"},
      "136": {"inputs": {"sampler_name": "euler_ancestral"}, "class_type": "KSamplerSelect"},
      "138": {"inputs": {"ckpt_name": "ltx-2-19b-dev-fp8.safetensors"}, "class_type": "CheckpointLoaderSimple"}
    },
    "extra_data": {}
  }'

响应:

json
{"prompt_id": "5af01c46-eeba-4978-9bbd-71d763c770d4", "number": 6, "node_errors": {}}

完整工作流节点说明

节点 IDclass_type作用
121CLIPTextEncode正向提示词(英文动作描述)
110CLIPTextEncode负向提示词(内置:模糊/低质/静态/水印等)
111EmptyImage输出尺寸(如 1280×720),低清阶段会 ×0.5
112PrimitiveInt帧数(默认 121,24fps≈5s)
129 / 130PrimitiveFloat / PrimitiveInt帧率(两处必须同步,默认 24)
115RandomNoise低清阶段随机种子
99LTXAVTextEncoderLoader加载 Gemma-3 文本/音频编码器
138CheckpointLoaderSimple主模型 ltx-2-19b-dev-fp8.safetensors
132LoraLoaderModelOnly加速 LoRA ltx-2-19b-distilled-lora-384(strength=1)
98LTXVScheduler低清调度器(steps=20)
113SamplerCustomAdvanced低清采样(20 步)
118LTXVLatentUpsampler空间放大 ×2(用 ltx-2-spatial-upscaler-x2-1.0
100ManualSigmas精修 sigma 序列(4 步)
119SamplerCustomAdvanced精修采样(4 步)
126VAEDecodeTiled视频解码(tile_size=512)
127LTXVAudioVAEDecode空音轨解码
122CreateVideo合成视频(fps 来自 129)
75SaveVideo输出前缀(默认 video/LTX-2,mp4)

关键参数

节点字段说明推荐值
121text正向提示词(英文)
111width / height输出分辨率(需被 32 整除)1280 × 720
112value帧数121(≈5s@24fps)
129 / 130value帧率(两处同步)24
115noise_seed随机种子任意整数
75filename_prefix输出文件名前缀(可含子目录)video/LTX-2

提示词技巧

  • 英文优先(文本编码器基于 Gemma-3)
  • 动作 + 镜头 + 光影 + 质感四要素:
    A close-up of a cheerful girl puppet, singing with joy,
    rain falls gently around her, the camera holds steady,
    rain sparkles against the soft lighting.
  • 运镜:camera dolly out / slow pan / close-up

两阶段参数含义

阶段节点步数分辨率
低清打底98 + 11320 步(LTXVScheduler)输出 ×0.5
精修100 + 1194 步(ManualSigmas)输出全尺寸

四、查询任务状态

GET /api/v1/ai/tasks/{prompt_id}
Authorization: Bearer sk-xxx
bash
curl -H "Authorization: Bearer $API_KEY" "$GW/api/v1/ai/tasks/5af01c46-eeba-4978-9bbd-71d763c770d4"

进行中:

json
{
  "5af01c46-...": {
    "outputs": {},
    "status": { "status_str": "success", "completed": false }
  }
}

已完成:

json
{
  "5af01c46-...": {
    "status": { "status_str": "success", "completed": true },
    "outputs": {
      "75": {
        "images": [
          { "filename": "LTX-2_00001_.mp4", "subfolder": "video", "type": "output" }
        ],
        "animated": [true]
      }
    }
  }
}

视频输出在 outputsimages 字段(文件名是 .mp4),同节点有 animated 布尔列表标记是动图/视频——不是 gifs 字段。

缓存坑:若提交的工作流与某次历史完全相同(尤其 seed 相同),ComfyUI 会命中 execution_cached 直接返回缓存结果,此时 outputs 可能为。提交时给个随机 seed 可避免。


五、下载结果

GET /api/v1/ai/image/view/?filename={filename}&type={type}&subfolder={subfolder}
Authorization: Bearer sk-xxx

参数值来自任务状态响应的 outputs[].images[]

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

输出: MP4 静音视频,1280×720, 121帧, 24fps, 约5秒(实测约 30s 出片,mp4 约 3MB)。


六、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"}

# 工作流节点定义(完整见上文 curl 示例)
nodes = {
    "75": {"inputs": {"filename_prefix": "video/LTX-2", "format": "mp4", "codec": "auto", "video": ["122", 0]}, "class_type": "SaveVideo"},
    # ...其余节点...
}

# 参数化
nodes["121"]["inputs"]["text"] = "A cheerful girl puppet singing in the rain"
nodes["112"]["inputs"]["value"] = 121          # 帧数
nodes["129"]["inputs"]["value"] = 24.0         # fps (float)
nodes["130"]["inputs"]["value"] = 24           # fps (int)
nodes["111"]["inputs"]["width"] = 1280
nodes["111"]["inputs"]["height"] = 720
nodes["115"]["inputs"]["noise_seed"] = 12345   # 种子,避免缓存命中
nodes["75"]["inputs"]["filename_prefix"] = "video/LTX-2"

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

# 轮询
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)

# 下载(视频在 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())

封装脚本(如有)

技能目录提供封装脚本 comfyui-ltx2-text-to-video/scripts/text_to_video.py,自动完成提交 → 轮询 → 下载(实测通过,1280×720 / 121 帧 / 24fps,约 30s 出片,mp4 约 3MB):

bash
# 默认 5 秒 1280×720 视频到当前目录
python comfyui-ltx2-text-to-video/scripts/text_to_video.py \
  --prompt "A cheerful girl puppet singing in the rain"

# 自定义参数
python comfyui-ltx2-text-to-video/scripts/text_to_video.py \
  --prompt "A bird spreading its wings and flying away" \
  --length 97 --fps 24 --seed 42 \
  --output_prefix video/my_clip --output my_clip.mp4

脚本参数:

参数说明默认
--prompt英文正向提示词(必须)
--negative负向提示词工作流内置
--length帧数121
--fps帧率24
--width / --height输出分辨率1280 × 720
--seed随机种子时间戳随机(避免命中缓存)
--output_prefix输出前缀(可含子目录)video/LTX-2
--output本地保存路径当前目录/服务端名
--timeout轮询超时秒数600

脚本原理:读取同目录 workflow.json,按命令行参数替换正/负提示词、帧数、帧率、分辨率、种子、输出前缀,提交后轮询,从 outputs[].images 中按 .mp4 扩展名取视频并下载。未指定 seed 时自动用时间戳随机,避免 ComfyUI 缓存命中导致 outputs 为空。改 ComfyUI 画布后导出新 JSON 覆盖 workflow.json 即可同步。


七、常见问题

问题现象可能原因解决方案
401 UnauthorizedAPI Key 错误/未传检查 Authorization: Bearer sk-xxx
500 on generate工作流 JSON 格式错{"prompt": {...}, "extra_data": {}},节点连接用 ["id", slot]
node_errors 非空分辨率不被 32 整除 / 模型缺失宽高对齐到 32 的倍数;看 node_errors 详情
任务 success 但 outputs 为空命中 ComfyUI 缓存(execution_cached提交时换个随机 seed,避免工作流完全相同
轮询一直不完成排队或首帧加载慢首次约 30s 加载;增大 --timeout,用 prompt_id 手动重查
下载 404没带 subfolder=video视频在 output 的 video/ 子目录,URL 必须带 subfolder=video
outputs 里找不到视频找错字段视频在 outputs[].images(文件名 .mp4 + animated 标记),不是 gifs
视频无声工作流设计为空音轨本工作流输出静音视频;需带真实音频用 LTX 2.3 图音生视频

更新日志

版本日期更新内容
v0.1.12026.07.24修正:视频输出在 outputs[].images 字段(非 gifs);补充缓存命中导致 outputs 为空的说明;脚本未指定 seed 时自动随机;实测通过
v0.1.02026.07.24初始版本:LTX-2 19B 文生视频,两阶段管线,输出静音 mp4

AI API Gateway Documentation