AgentAi视频模型开发对接部署使用
·
一、整体方案设计思路
要制作一个基于 ComfyUI + Dify + Python Web + LangChain 的视频生成网站并部署到服务器,核心逻辑是:
- LangChain:处理用户文本输入,进行意图解析、文案生成、关键词提取(如视频主题/风格/时长);
- Dify:封装LangChain的能力,提供可视化的prompt管理、对话流程编排,简化业务逻辑开发;
- ComfyUI:作为视频生成的核心引擎(可对接AI绘画、视频剪辑、文生视频模型),通过API调用执行视频生成工作流;
- Python Web:搭建后端服务(如FastAPI),承接前端请求,串联Dify、LangChain、ComfyUI,同时处理文件存储、任务队列;
- 前端:简单的网页界面,供用户输入需求、查看生成进度、下载视频;
- 服务器部署:将各组件容器化(Docker),通过Docker Compose编排,保证环境一致性。
二、环境准备(服务器端)
1. 基础依赖安装
# 更新系统依赖
sudo apt update && sudo apt install -y docker docker-compose python3-pip git
# 启动Docker服务
sudo systemctl start docker && sudo systemctl enable docker
# 安装Python依赖
pip3 install fastapi uvicorn requests langchain dify-client python-multipart redis celery
2. 组件部署前置准备
- ComfyUI:提前部署并开启API服务(默认端口8188),配置好视频生成的工作流(如文生图→图生视频、文本直接生视频);
- Dify:参考Dify官方部署文档,用Docker Compose部署,创建应用并配置LangChain的插件;
- Redis:用于任务队列(Celery),存储视频生成任务状态。
三、核心代码实现
1. 后端服务(FastAPI):串联所有组件
from fastapi import FastAPI, UploadFile, File, BackgroundTasks
from fastapi.middleware.cors import CORSMiddleware
from dify_client import DifyClient
from langchain.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
import requests
import json
import uuid
import os
# 初始化FastAPI
app = FastAPI(title="视频生成网站后端")
# 跨域配置
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 生产环境替换为前端域名
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 配置各组件地址和密钥
COMFYUI_API_URL = "http://localhost:8188/prompt" # ComfyUI API地址
DIFY_API_KEY = "your_dify_api_key"
DIFY_API_URL = "http://localhost:8000/v1/completions" # Dify API地址
VIDEO_SAVE_DIR = "./generated_videos"
os.makedirs(VIDEO_SAVE_DIR, exist_ok=True)
# 初始化Dify客户端
dify_client = DifyClient(api_key=DIFY_API_KEY, base_url=DIFY_API_URL)
# 1. LangChain + Dify:处理用户输入,生成视频参数
def generate_video_params(user_prompt: str) -> dict:
"""
通过Dify调用LangChain,解析用户输入生成视频参数
:param user_prompt: 用户输入的视频需求(如"生成10秒的海边日落视频,风格治愈")
:return: 视频参数(主题、风格、时长、分辨率等)
"""
# LangChain提示词模板
prompt_template = PromptTemplate(
input_variables=["user_prompt"],
template="""解析用户需求,生成视频生成所需的参数,返回JSON格式:
要求:
1. 主题:简洁描述视频内容
2. 风格:如治愈、科技、卡通等
3. 时长:单位秒,整数
4. 分辨率:如1080p、720p
用户需求:{user_prompt}
"""
)
# 调用Dify API(Dify已集成LangChain和大模型)
response = dify_client.completions.create(
model="gpt-3.5-turbo", # Dify中配置的模型
prompt=prompt_template.format(user_prompt=user_prompt),
temperature=0.7
)
# 解析返回的参数
params = json.loads(response.choices[0].text.strip())
return params
# 2. 调用ComfyUI API生成视频
def generate_video_with_comfyui(params: dict, task_id: str) -> str:
"""
调用ComfyUI API执行视频生成工作流
:param params: 视频参数
:param task_id: 任务ID(用于命名视频文件)
:return: 生成的视频文件路径
"""
# ComfyUI工作流配置(需提前在ComfyUI中保存工作流,复制JSON)
comfyui_workflow = {
"prompt": {
"3": {"inputs": {"text": params["主题"]}}, # 文本输入节点
"5": {"inputs": {"style": params["风格"]}}, # 风格节点
"7": {"inputs": {"seconds": params["时长"]}}, # 时长节点
"9": {"inputs": {"resolution": params["分辨率"]}}, # 分辨率节点
"10": {"inputs": {"output_path": f"{VIDEO_SAVE_DIR}/{task_id}.mp4"}} # 输出路径节点
},
"client_id": "video_generator",
"extra": {"save_images": True}
}
# 调用ComfyUI API
response = requests.post(
COMFYUI_API_URL,
json=comfyui_workflow,
headers={"Content-Type": "application/json"}
)
if response.status_code == 200:
return f"{VIDEO_SAVE_DIR}/{task_id}.mp4"
else:
raise Exception(f"ComfyUI调用失败:{response.text}")
# 3. 前端接口:提交视频生成请求
@app.post("/api/generate-video")
async def generate_video(user_prompt: str, background_tasks: BackgroundTasks):
"""
接收用户视频生成请求,异步执行生成任务
"""
# 生成唯一任务ID
task_id = str(uuid.uuid4())
try:
# 步骤1:生成视频参数
params = generate_video_params(user_prompt)
# 步骤2:异步调用ComfyUI生成视频(避免前端等待)
background_tasks.add_task(generate_video_with_comfyui, params, task_id)
return {
"code": 200,
"msg": "视频生成任务已提交",
"data": {"task_id": task_id, "params": params}
}
except Exception as e:
return {"code": 500, "msg": f"任务提交失败:{str(e)}"}
# 4. 前端接口:查询任务状态/获取视频链接
@app.get("/api/task-status/{task_id}")
async def get_task_status(task_id: str):
"""
查询视频生成任务状态
"""
video_path = f"{VIDEO_SAVE_DIR}/{task_id}.mp4"
if os.path.exists(video_path):
return {
"code": 200,
"status": "completed",
"video_url": f"/videos/{task_id}.mp4" # 前端访问的视频URL
}
else:
return {"code": 200, "status": "processing", "msg": "视频生成中..."}
# 5. 静态文件服务:提供视频下载
@app.get("/videos/{filename}")
async def serve_video(filename: str):
from fastapi.responses import FileResponse
return FileResponse(f"{VIDEO_SAVE_DIR}/{filename}")
# 启动服务
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8080)
2. 简单前端页面(HTML+JS):用户交互
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>AI视频生成网站</title>
<style>
body { max-width: 800px; margin: 0 auto; padding: 20px; }
#prompt-input { width: 100%; height: 100px; margin-bottom: 10px; }
#generate-btn { padding: 10px 20px; background: #007bff; color: white; border: none; border-radius: 4px; }
#status { margin-top: 20px; color: #666; }
#video-container { margin-top: 20px; display: none; }
</style>
</head>
<body>
<h1>AI视频生成工具</h1>
<textarea id="prompt-input" placeholder="请输入视频需求(如:生成10秒的海边日落视频,风格治愈)"></textarea>
<button id="generate-btn">生成视频</button>
<div id="status"></div>
<div id="video-container">
<h3>生成的视频:</h3>
<video controls width="100%"></video>
</div>
<script>
const generateBtn = document.getElementById('generate-btn');
const statusDiv = document.getElementById('status');
const videoContainer = document.getElementById('video-container');
const videoElement = videoContainer.querySelector('video');
let taskId = null;
// 提交生成请求
generateBtn.addEventListener('click', async () => {
const prompt = document.getElementById('prompt-input').value.trim();
if (!prompt) {
alert('请输入视频需求!');
return;
}
statusDiv.textContent = '提交中...';
try {
const response = await fetch('http://localhost:8080/api/generate-video', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ user_prompt: prompt })
});
const data = await response.json();
if (data.code === 200) {
taskId = data.data.task_id;
statusDiv.textContent = '视频生成中,请等待...';
// 轮询查询任务状态
checkTaskStatus();
} else {
statusDiv.textContent = `失败:${data.msg}`;
}
} catch (e) {
statusDiv.textContent = `请求失败:${e.message}`;
}
});
// 轮询查询任务状态
async function checkTaskStatus() {
if (!taskId) return;
try {
const response = await fetch(`http://localhost:8080/api/task-status/${taskId}`);
const data = await response.json();
if (data.status === 'completed') {
statusDiv.textContent = '视频生成完成!';
videoElement.src = data.video_url;
videoContainer.style.display = 'block';
} else if (data.status === 'processing') {
statusDiv.textContent = '视频生成中(进度:未知,ComfyUI可扩展进度接口)...';
setTimeout(checkTaskStatus, 3000); // 每3秒查询一次
}
} catch (e) {
statusDiv.textContent = `查询失败:${e.message}`;
setTimeout(checkTaskStatus, 3000);
}
}
</script>
</body>
</html>
3. Docker Compose部署配置(服务器端)
创建docker-compose.yml文件,统一管理所有组件:
version: '3'
services:
# Redis:任务队列/状态存储
redis:
image: redis:latest
ports:
- "6379:6379"
volumes:
- redis_data:/data
restart: always
# ComfyUI:视频生成引擎
comfyui:
image: comfyui/comfyui:latest # 或自定义构建的镜像
ports:
- "8188:8188"
volumes:
- ./comfyui:/app
- ./generated_videos:/app/output
environment:
- PYTHONUNBUFFERED=1
restart: always
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu] # 需服务器有NVIDIA显卡,支持CUDA
# Dify:LLM流程编排
dify:
image: langgenius/dify-api:latest
ports:
- "8000:8000"
volumes:
- ./dify:/app
environment:
- DATABASE_URL=sqlite:///./dify.db
- REDIS_URL=redis://redis:6379/0
- OPENAI_API_KEY=your_openai_api_key # 若使用OpenAI模型
depends_on:
- redis
restart: always
# Python Web后端(FastAPI)
video-api:
build: ./ # 假设Dockerfile和代码在同一目录
ports:
- "8080:8080"
volumes:
- ./generated_videos:/app/generated_videos
environment:
- COMFYUI_API_URL=http://comfyui:8188/prompt
- DIFY_API_URL=http://dify:8000/v1/completions
- DIFY_API_KEY=your_dify_api_key
depends_on:
- redis
- comfyui
- dify
restart: always
# Nginx:前端静态文件服务+反向代理
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./frontend:/usr/share/nginx/html # 前端HTML文件放此目录
- ./nginx.conf:/etc/nginx/conf.d/default.conf
- ./generated_videos:/usr/share/nginx/html/videos
depends_on:
- video-api
restart: always
volumes:
redis_data:
创建Dockerfile(用于构建FastAPI后端镜像):
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "main.py"]
创建requirements.txt:
fastapi>=0.104.1
uvicorn>=0.24.0
requests>=2.31.0
dify-client>=0.3.0
langchain>=0.1.0
langchain-openai>=0.1.0
python-multipart>=0.0.6
redis>=5.0.1
celery>=5.3.4
创建nginx.conf(Nginx反向代理配置):
server {
listen 80;
server_name localhost;
# 前端静态文件
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
# 后端API反向代理
location /api {
proxy_pass http://video-api:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 视频文件访问
location /videos {
alias /usr/share/nginx/html/videos;
expires 7d; # 视频文件缓存7天
}
}
四、部署步骤(服务器端)
-
目录结构准备:
/video-generator/ ├── frontend/ # 前端HTML文件 │ └── index.html ├── comfyui/ # ComfyUI挂载目录(提前复制ComfyUI配置) ├── generated_videos/ # 视频存储目录 ├── main.py # FastAPI后端代码 ├── Dockerfile ├── requirements.txt ├── docker-compose.yml └── nginx.conf -
启动所有服务:
cd /video-generator docker-compose up -d # 后台启动所有服务 -
验证部署:
- 访问
http://服务器IP:可看到前端页面,输入视频需求提交; - 访问
http://服务器IP:8188:验证ComfyUI是否正常; - 访问
http://服务器IP:8000:验证Dify是否正常; - 查看日志:
docker-compose logs -f video-api(排查后端错误)。
- 访问
五、关键优化点
- 任务队列:若视频生成耗时久,用Celery替代BackgroundTasks,支持任务重试、进度追踪;
- 资源限制:ComfyUI视频生成耗GPU/CPU,在docker-compose中配置资源限制(如
mem_limit: 16g); - 缓存与清理:定期清理
generated_videos目录的旧视频,避免磁盘占满; - 权限控制:生产环境添加用户登录(如FastAPI-Users),限制视频生成次数;
- 进度反馈:扩展ComfyUI的API,返回视频生成进度(如帧生成百分比),前端实时展示。
总结
- 核心流程:前端输入 → FastAPI后端 → Dify+LangChain解析需求生成参数 → ComfyUI执行视频生成 → 前端查询进度/下载视频;
- 部署关键:通过Docker Compose统一编排ComfyUI、Dify、FastAPI、Nginx,保证环境一致性;
- 扩展方向:添加任务队列、GPU优化、用户权限、视频预览、多模型支持(如Stable Video Diffusion)。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)