import React, { useState, useRef } from 'react' import { Upload, Play, Settings, Folder, FileText, Clock, Cpu, Trash2, Download } from 'lucide-react' import { useAIVideoStore, useAIVideoJobs, useAIVideoProcessing, useAIVideoSettings } from '../stores/useAIVideoStore' interface AIVideoGeneratorProps { className?: string } const AIVideoGenerator: React.FC = ({ className = '' }) => { const fileInputRef = useRef(null) const folderInputRef = useRef(null) // State const [mode, setMode] = useState<'single' | 'batch'>('single') const [selectedImage, setSelectedImage] = useState('') const [selectedFolder, setSelectedFolder] = useState('') const [customPrompt, setCustomPrompt] = useState('') const [outputFolder, setOutputFolder] = useState('') const [duration, setDuration] = useState('5') const [modelType, setModelType] = useState('lite') // Store const { generateSingleVideo, batchGenerateVideos, removeJob, clearCompletedJobs, setDefaultDuration, setDefaultModelType } = useAIVideoStore() const jobs = useAIVideoJobs() const isProcessing = useAIVideoProcessing() const { defaultPrompts, defaultDuration, defaultModelType } = useAIVideoSettings() // Initialize settings React.useEffect(() => { setDuration(defaultDuration) setModelType(defaultModelType) }, [defaultDuration, defaultModelType]) // Handle file selection const handleImageSelect = () => { fileInputRef.current?.click() } const handleImageChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0] if (file) { setSelectedImage(file.path || file.name) } } const handleFolderSelect = () => { folderInputRef.current?.click() } const handleFolderChange = (e: React.ChangeEvent) => { const files = e.target.files if (files && files.length > 0) { // Get the directory path from the first file const firstFile = files[0] const path = firstFile.webkitRelativePath || firstFile.name const folderPath = path.split('/')[0] setSelectedFolder(folderPath) } } // Handle generation const handleGenerate = async () => { try { if (mode === 'single') { if (!selectedImage || !customPrompt) { alert('请选择图片文件并输入提示词') return } await generateSingleVideo({ image_path: selectedImage, prompt: customPrompt, duration, model_type: modelType, output_path: outputFolder || undefined, timeout: 300 }) } else { if (!selectedFolder || !outputFolder) { alert('请选择图片文件夹和输出目录') return } const prompts = customPrompt ? customPrompt.split('\n').filter(p => p.trim()) : defaultPrompts await batchGenerateVideos({ image_folder: selectedFolder, prompts, output_folder: outputFolder, duration, model_type: modelType, timeout: 300 }) } } catch (error) { console.error('Generation failed:', error) alert(`生成失败: ${error instanceof Error ? error.message : '未知错误'}`) } } // Format time const formatTime = (timestamp: number): string => { return new Date(timestamp).toLocaleTimeString() } // Format duration const formatDuration = (start: number, end?: number): string => { if (!end) return '进行中...' const duration = Math.round((end - start) / 1000) return `${duration}秒` } return (
{/* Header */}

AI 视频生成

{/* Mode Selection */}
{/* Input Section */}
{mode === 'single' ? (
{selectedImage || '未选择文件'}
) : ( <>
{selectedFolder || '未选择文件夹'}
setOutputFolder(e.target.value)} placeholder="输入保存目录路径" className="input w-full" />
)} {/* Prompt Input */}