当前位置: 首页 > news >正文

ComfyUI部署Wan2.2,开放API,文生视频与图生视频

通义万象2.2开源了,5B模型具有文生视频和图生视频的能力。这里介绍通过ComfyUI部署wan2.2并开放API,通过url返回生成的视频。环境配置,api的worlflow配置文件获取,ComfyUI启动,配置url路径参考这里。

文生视频

这里直接给出API启动脚本:

from fastapi import FastAPI, HTTPException, Header
from fastapi import FastAPI, HTTPException, Header
from pydantic import BaseModel
import requests
import copy
import json
import os
import urllib.parse
import time
import base64API_KEY = "12345"# ---------------- 配置 ----------------
COMFYUI_API_URL = "http://127.0.0.1:8188"  # ComfyUI API 地址
WORKFLOW_FILE = "text_to_video_wan22_5B_API.json"      # 固定 workflow 文件
OUTPUT_DIR = "output_videos"
POLL_INTERVAL = 2  # 秒STATIC_DIR = "/var/www/static"  # 存储视频的目录
SERVER_BASE_URL = "http://server_ip:9001"  # 对外访问的服务器地址os.makedirs(OUTPUT_DIR, exist_ok=True)
os.makedirs(STATIC_DIR, exist_ok=True)# ---------------- 读取 workflow ----------------
with open(WORKFLOW_FILE, "r", encoding="utf-8") as f:base_workflow = json.load(f)# ---------------- 请求体定义 ----------------
class GenerateVideoRequest(BaseModel):positive: strnegative: str = ""height: int = 704width: int = 1280length: int = 121  # 视频帧数fps: int = 24# ---------------- FastAPI 实例 ----------------
app = FastAPI(title="ComfyUI Video API Server")# ---------------- 生成接口 ----------------
@app.post("/generate_video")
def generate_video(req: GenerateVideoRequest, x_api_key: str = Header(None)):if x_api_key != API_KEY:raise HTTPException(status_code=401, detail="Invalid API Key")workflow = copy.deepcopy(base_workflow)# 修改 workflow 中的输入参数workflow["6"]["inputs"]["text"] = req.positiveworkflow["7"]["inputs"]["text"] = req.negativeworkflow["55"]["inputs"]["width"] = req.widthworkflow["55"]["inputs"]["height"] = req.heightworkflow["55"]["inputs"]["length"] = req.lengthworkflow["47"]["inputs"]["fps"] = req.fps  # 保存 WEBMworkflow["28"]["inputs"]["fps"] = float(req.fps)  # 保存 WEBP 动图# 提交任务resp = requests.post(f"{COMFYUI_API_URL}/prompt", json={"prompt": workflow})resp.raise_for_status()prompt_id = resp.json()["prompt_id"]public_urls = []while True:history = requests.get(f"{COMFYUI_API_URL}/history/{prompt_id}").json()if prompt_id in history:outputs = history[prompt_id].get("outputs", {})for node_id, output_data in outputs.items():if "images" in output_data:  # 视频也会走这里for file in output_data["images"]:filename = file["filename"]subfolder = file.get("subfolder", "")filetype = file.get("type", "output")  # webm / webp / pngfile_url = (f"{COMFYUI_API_URL}/view"f"?filename={urllib.parse.quote(filename)}"f"&subfolder={urllib.parse.quote(subfolder)}"f"&type={urllib.parse.quote(filetype)}")file_data = requests.get(file_url).contentsave_path = os.path.join(STATIC_DIR, filename)with open(save_path, "wb") as f:f.write(file_data)public_url = f"{SERVER_BASE_URL}/static/{filename}"public_urls.append(public_url)if public_urls:breaktime.sleep(POLL_INTERVAL)return {"prompt_id": prompt_id, "video_urls": public_urls}

将上面的脚本保存为serve_fastapi.py,其中COMFYUI_API_URL是启动的ComfyUI服务,WORKFLOW_FILE是保存的workflow配置文件。使用下面的命令启动API:

uvicorn serve_fastapi:app --host 0.0.0.0 --port 9002

这里给出python访问api的脚本:

import requests
import base64
from PIL import Image
from io import BytesIOheaders = {"x-api-key": "12345"}
resp = requests.post("http://server_ip:9002/generate_video",headers=headers,json={"positive": "Two anthropomorphic cats in comfy boxing gear and bright gloves fight intensely on a spotlighted stage.","negative": "色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走","height": 512,"width": 768,"length": 73, # 帧数,帧率固定为24 fps}
)
print(resp.json())

api会返回可访问的生成视频的url。

图生视频

直接给出api启动脚本,与上面不同的就是图生视频需要多传如一个图像,这里以url的形式传入:

from fastapi import FastAPI, HTTPException, Header
from pydantic import BaseModel
import requests
import copy
import json
import os
import urllib.parse
import time
import base64
import tempfileAPI_KEY = "12345"# ---------------- 配置 ----------------
COMFYUI_API_URL = "http://127.0.0.1:8188"  # ComfyUI API 地址
WORKFLOW_FILE = "image_to_video_wan22_5B_api.json"  # 你准备好的图生视频 workflow
OUTPUT_DIR = "output_videos"
POLL_INTERVAL = 2  # 秒STATIC_DIR = "/var/www/static"  # 存储视频的目录
SERVER_BASE_URL = "http://server_ip:9001"  # 对外访问的服务器地址os.makedirs(OUTPUT_DIR, exist_ok=True)
os.makedirs(STATIC_DIR, exist_ok=True)# ---------------- 读取 workflow ----------------
with open(WORKFLOW_FILE, "r", encoding="utf-8") as f:base_workflow = json.load(f)# ---------------- 请求体定义 ----------------
class GenerateVideoRequest(BaseModel):image_url: str                     # 输入图像 URLpositive: str = ""                 # 可选的正向 promptnegative: str = ""                 # 可选的负向 promptheight: int = 704width: int = 1280length: int = 121                  # 视频帧数fps: int = 24# ---------------- FastAPI 实例 ----------------
app = FastAPI(title="ComfyUI Image-to-Video API Server")# ---------------- 生成接口 ----------------
@app.post("/generate_video_i2v")
def generate_video(req: GenerateVideoRequest, x_api_key: str = Header(None)):if x_api_key != API_KEY:raise HTTPException(status_code=401, detail="Invalid API Key")workflow = copy.deepcopy(base_workflow)# ----------- 下载输入图像到临时目录,并传给 ComfyUI -----------resp = requests.get(req.image_url)if resp.status_code != 200:raise HTTPException(status_code=400, detail="Failed to download input image")tmp_path = os.path.join(STATIC_DIR, "input_image.png")with open(tmp_path, "wb") as f:f.write(resp.content)# 替换 workflow 的图像节点 (假设节点 id 是 "57")workflow["57"]["inputs"]["image"] = tmp_path# 修改其他输入if "6" in workflow:  # 正向 prompt 节点workflow["6"]["inputs"]["text"] = req.positiveif "7" in workflow:  # 负向 prompt 节点workflow["7"]["inputs"]["text"] = req.negativeif "55" in workflow:workflow["55"]["inputs"]["width"] = req.widthworkflow["55"]["inputs"]["height"] = req.heightworkflow["55"]["inputs"]["length"] = req.lengthif "47" in workflow:workflow["47"]["inputs"]["fps"] = req.fps  # 保存 WEBMif "28" in workflow:workflow["28"]["inputs"]["fps"] = float(req.fps)  # 保存 WEBP 动图# 提交任务resp = requests.post(f"{COMFYUI_API_URL}/prompt", json={"prompt": workflow})resp.raise_for_status()prompt_id = resp.json()["prompt_id"]public_urls = []while True:history = requests.get(f"{COMFYUI_API_URL}/history/{prompt_id}").json()if prompt_id in history:outputs = history[prompt_id].get("outputs", {})for node_id, output_data in outputs.items():if "images" in output_data:  # 视频也会走这里for file in output_data["images"]:filename = file["filename"]subfolder = file.get("subfolder", "")filetype = file.get("type", "output")file_url = (f"{COMFYUI_API_URL}/view"f"?filename={urllib.parse.quote(filename)}"f"&subfolder={urllib.parse.quote(subfolder)}"f"&type={urllib.parse.quote(filetype)}")file_data = requests.get(file_url).contentsave_path = os.path.join(STATIC_DIR, filename)with open(save_path, "wb") as f:f.write(file_data)public_url = f"{SERVER_BASE_URL}/static/{filename}"public_urls.append(public_url)if public_urls:breaktime.sleep(POLL_INTERVAL)return {"prompt_id": prompt_id, "video_urls": public_urls}

将上面的脚本保存为serve_fastapi_i2v.py,其中COMFYUI_API_URL是启动的ComfyUI服务,WORKFLOW_FILE是保存的workflow配置文件。使用下面的命令启动API:

uvicorn serve_fastapi:app --host 0.0.0.0 --port 9003

这里给出python调用api的示例:

import requestsheaders = {"x-api-key": "12345"}
resp = requests.post("http://127.0.0.1:9003/generate_video_i2v",headers=headers,json={"image_url": "https://comfyanonymous.github.io/ComfyUI_examples/chroma/fennec_girl_hug.png","positive": "a cute anime girl with fennec ears and a fluffy tail walking in a beautiful field","negative": "色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走","height": 704,"width": 1280,"length": 141, # 帧数,帧率固定为24 fps}
)
print(resp.json())

图生视频的图像用url进行传入,如果是图像就在服务器上,可以直接使用路径,如果图像在本地主机,可以传到某个可访问的云服务上,开放url。api会返回生成视频的url。

http://www.dtcms.com/a/339111.html

相关文章:

  • 基于Python的宠物服务管理系统 Python+Django+Vue.js
  • 农村污水处理行业物联网解决方案
  • Vue3 el-table实现 将子表字段动态显示在主表行尾
  • GaussDB 中 alter default privileges 的使用示例
  • 鱼骨图图片制作全指南:使用工具推荐 + 行业案例
  • Python实战:SEO优化自动化工具开发指南
  • 大数据毕业设计选题推荐:护肤品店铺运营数据可视化分析系统详解
  • Android面试指南(三)
  • 在Excel和WPS表格中为多个数字同时加上相同的数值
  • 从接口自动化测试框架设计到开发(三)主流程封装、返回数据写入excel
  • 【iOS】内存管理
  • 如何在 Ubuntu Linux 上安装 RPM 软件包
  • 在 Windows 上使用 Kind 创建本地 Kubernetes 集群并集成Traefik 进行负载均衡
  • 2025年8月16日(星期六):雨骑古莲村游记
  • [优选算法专题二——找到字符串中所有字母异位词]
  • 网络间的通用语言TCP/IP-网络中的通用规则4
  • Java网络编程:TCP与UDP通信实现及网络编程基础
  • C语言—指针(针对小白版)
  • 算法学习day19----博弈论模型--取石子游戏(Python)
  • 懒加载机制实现子模块按需动态导入
  • 全平台轻量浏览器推荐|支持Win/macOS/Linux,极速加载+隐私保护+扩展插件,告别广告与数据追踪!
  • RT-Thread Nano移植到STM32心得(基于GCC、HAL库)
  • Mac下载AOSP源代码
  • UE小:交叉编译linux的坑
  • 【集合框架HashSet底层原理】
  • IDEA:设置彩色输出
  • DataAnalytics之Tool:Metabase的简介、安装和使用方法、案例应用之详细攻略
  • 项目一系列-第5章 前后端快速开发
  • 虚拟环境安装了fastapi但是使用时报错:ModuleNotFoundError: No module named ‘fastapi‘
  • C++利用CerateProcess创建WPF进程并通过命名管道通讯