feat: 集成 AI 视频生成功能到 MixVideo V2
🎬 主要功能: - ✅ 完整的 AI 视频生成模块 (Python) - ✅ 图片转视频 API 集成 (字节跳动 Seedance) - ✅ 云存储支持 (腾讯云 COS) - ✅ 单张图片和批量处理模式 - ✅ 现代化 React 界面组件 - ✅ Tauri 桥接通信 🛠️ 技术实现: - Python 模块:VideoGenerator, CloudStorage, APIClient - Rust 命令:generate_ai_video, batch_generate_ai_videos - React 组件:AIVideoGenerator, AIVideoPage - 状态管理:useAIVideoStore (Zustand) - 路由集成:/ai-video 页面 �� 新增文件: - python_core/ai_video/ - AI 视频生成核心模块 - src/components/AIVideoGenerator.tsx - 主要 UI 组件 - src/pages/AIVideoPage.tsx - AI 视频生成页面 - src/stores/useAIVideoStore.ts - 状态管理 🎯 功能特性: - 支持 Lite (720p) 和 Pro (1080p) 模型 - 可配置视频时长 (5秒/10秒) - 实时进度跟踪和任务管理 - 批量处理多张图片 - 云存储自动上传下载 - 错误处理和重试机制 🔗 界面集成: - 侧边栏导航添加 'AI 视频' 入口 - 首页快速操作卡片 - 完整的用户引导和帮助文档 这是从原始 Tkinter GUI 到现代 Web 应用的完整迁移!
This commit is contained in:
@@ -1,4 +1,24 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct AIVideoRequest {
|
||||
pub image_path: String,
|
||||
pub prompt: String,
|
||||
pub duration: String,
|
||||
pub model_type: String,
|
||||
pub output_path: Option<String>,
|
||||
pub timeout: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct BatchAIVideoRequest {
|
||||
pub image_folder: String,
|
||||
pub prompts: Vec<String>,
|
||||
pub output_folder: String,
|
||||
pub duration: String,
|
||||
pub model_type: String,
|
||||
pub timeout: Option<u32>,
|
||||
}
|
||||
use std::process::Command;
|
||||
use tauri::State;
|
||||
|
||||
@@ -165,3 +185,61 @@ pub async fn load_project(project_path: String) -> Result<ProjectInfo, String> {
|
||||
Err(format!("Python script error: {}", error))
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn generate_ai_video(request: AIVideoRequest) -> Result<String, String> {
|
||||
let mut args = vec![
|
||||
"python_core/ai_video/video_generator.py".to_string(),
|
||||
"--action".to_string(),
|
||||
"single".to_string(),
|
||||
"--image".to_string(),
|
||||
request.image_path,
|
||||
"--prompt".to_string(),
|
||||
request.prompt,
|
||||
"--duration".to_string(),
|
||||
request.duration,
|
||||
"--model".to_string(),
|
||||
request.model_type,
|
||||
];
|
||||
|
||||
if let Some(output_path) = request.output_path {
|
||||
args.push("--output".to_string());
|
||||
args.push(output_path);
|
||||
}
|
||||
|
||||
if let Some(timeout) = request.timeout {
|
||||
args.push("--timeout".to_string());
|
||||
args.push(timeout.to_string());
|
||||
}
|
||||
|
||||
execute_python_command(&args).await
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn batch_generate_ai_videos(request: BatchAIVideoRequest) -> Result<String, String> {
|
||||
let prompts_json = serde_json::to_string(&request.prompts)
|
||||
.map_err(|e| format!("Failed to serialize prompts: {}", e))?;
|
||||
|
||||
let mut args = vec![
|
||||
"python_core/ai_video/video_generator.py".to_string(),
|
||||
"--action".to_string(),
|
||||
"batch".to_string(),
|
||||
"--folder".to_string(),
|
||||
request.image_folder,
|
||||
"--prompts".to_string(),
|
||||
prompts_json,
|
||||
"--output".to_string(),
|
||||
request.output_folder,
|
||||
"--duration".to_string(),
|
||||
request.duration,
|
||||
"--model".to_string(),
|
||||
request.model_type,
|
||||
];
|
||||
|
||||
if let Some(timeout) = request.timeout {
|
||||
args.push("--timeout".to_string());
|
||||
args.push(timeout.to_string());
|
||||
}
|
||||
|
||||
execute_python_command(&args).await
|
||||
}
|
||||
|
||||
@@ -24,7 +24,9 @@ pub fn run() {
|
||||
commands::analyze_audio,
|
||||
commands::get_project_info,
|
||||
commands::save_project,
|
||||
commands::load_project
|
||||
commands::load_project,
|
||||
commands::generate_ai_video,
|
||||
commands::batch_generate_ai_videos
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
|
||||
Reference in New Issue
Block a user