当前位置: 首页 > 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.lryc.cn/news/625467.html

相关文章:

  • Diamond开发经验(1)
  • Unity进阶--C#补充知识点--【C#各版本的新功能新语法】C#1~4与C#5
  • 【科研绘图系列】R语言绘制多组火山图
  • 腾讯混元3D系列开源模型:从工业级到移动端的本地部署
  • Java:枚举的使用
  • arcgis-空间矫正工具(将下发数据A的信息放置原始数据B的原始信息并放置到成果数据C中,主要按下发数据A的范围)
  • Android-ContentProvider的跨应用通信学习总结
  • IPD流程执行检查表
  • Java高级面试实战:Spring Boot微服务与Redis缓存整合案例解析
  • 我的SSM框架自学3
  • 《C++进阶之STL》【二叉搜索树】
  • Vulkan笔记(七)---图像视图
  • Mac(七)右键新建文件的救世主 iRightMouse
  • 前沿技术借鉴研讨-2025.8.19 (信号提取、信号拆分、胎心诊断)
  • C++---为什么迭代器常用auto类型?
  • Flink on Native K8S安装部署
  • Typescript入门-对象讲解
  • C/C++ 常见笔试题与陷阱详解
  • 电脑出现‘无法启动此程序,因为计算机中丢失dll’要怎么办?2025最新的解决方法分析
  • vue3+element-plus 输入框el-input设置背景颜色和字体颜色,样式效果等同于不可编辑的效果
  • 微软行业案例:英格兰足球超级联赛(Premier League)
  • Flask 路由详解:构建灵活的 URL 映射系统
  • Flutter AlwaysScrollableScrollPhysics详解
  • Windows 平板/电脑 上使用 DHCPSRV 搭建 DHCP 服务器
  • 后台管理系统-8-vue3之首页count数据的渲染
  • Flink Stream API - 源码二开详细实现
  • Python爬虫第一课:爬取HTML静态网页小说章节
  • 【教程】在 VMware Windows 虚拟机中使用 WinPE 进行离线密码重置或取证操作
  • CT Micro’s New HV Photo-MOSFET Relay Optocouplers
  • github 上传代码步骤