'use client'; import React, { useRef, useEffect, useState } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Edit3, Play, Pause, Volume2, VolumeX, Maximize, Minimize } from 'lucide-react'; import { ProgressiveReveal, presets } from '@/components/ui/progressive-reveal'; import { GlassIconButton } from '@/components/ui/glass-icon-button'; import { ScriptRenderer } from '@/components/script-renderer/ScriptRenderer'; import { mockScriptData } from '@/components/script-renderer/mock'; interface MediaViewerProps { currentStep: string; currentSketchIndex: number; taskSketch: any[]; taskVideos: any[]; isVideoPlaying: boolean; isPlaying: boolean; showControls: boolean; isGeneratingSketch: boolean; isGeneratingVideo: boolean; onControlsChange: (show: boolean) => void; onEditModalOpen: (tab: string) => void; onToggleVideoPlay: () => void; onTogglePlay: () => void; final?: any; } export function MediaViewer({ currentStep, currentSketchIndex, taskSketch, taskVideos, isVideoPlaying, isPlaying, showControls, isGeneratingSketch, isGeneratingVideo, onControlsChange, onEditModalOpen, onToggleVideoPlay, onTogglePlay, final }: MediaViewerProps) { const mainVideoRef = useRef(null); const finalVideoRef = useRef(null); // 音量控制状态 const [isMuted, setIsMuted] = useState(false); const [volume, setVolume] = useState(0.8); // 最终视频控制状态 const [isFinalVideoPlaying, setIsFinalVideoPlaying] = useState(true); const [isFullscreen, setIsFullscreen] = useState(false); const [finalVideoReady, setFinalVideoReady] = useState(false); const [userHasInteracted, setUserHasInteracted] = useState(false); // 音量控制函数 const toggleMute = () => { setUserHasInteracted(true); setIsMuted(!isMuted); if (mainVideoRef.current) { mainVideoRef.current.muted = !isMuted; } if (finalVideoRef.current) { finalVideoRef.current.muted = !isMuted; } }; const handleVolumeChange = (newVolume: number) => { setUserHasInteracted(true); setVolume(newVolume); if (mainVideoRef.current) { mainVideoRef.current.volume = newVolume; } if (finalVideoRef.current) { finalVideoRef.current.volume = newVolume; } }; // 应用音量设置到视频元素 const applyVolumeSettings = (videoElement: HTMLVideoElement) => { if (videoElement) { videoElement.volume = volume; videoElement.muted = isMuted; } }; useEffect(() => { if (finalVideoRef.current && finalVideoReady) { if (isFinalVideoPlaying) { finalVideoRef.current.play().catch(error => { console.log('最终视频自动播放被阻止:', error); // 如果自动播放被阻止,将状态设置为暂停 setIsFinalVideoPlaying(false); }); } else { finalVideoRef.current.pause(); } } }, [isFinalVideoPlaying, finalVideoReady]); // 最终视频播放控制 const toggleFinalVideoPlay = () => { setUserHasInteracted(true); setIsFinalVideoPlaying(!isFinalVideoPlaying); }; // 处理最终视频加载完成 const handleFinalVideoLoaded = () => { if (finalVideoRef.current) { setFinalVideoReady(true); applyVolumeSettings(finalVideoRef.current); // 如果当前状态是应该播放的,尝试播放 if (isFinalVideoPlaying) { finalVideoRef.current.play().catch(error => { console.log('最终视频自动播放被阻止:', error); setIsFinalVideoPlaying(false); }); } } }; // 处理视频点击 - 首次交互时尝试播放 const handleVideoClick = () => { if (!userHasInteracted && finalVideoRef.current && finalVideoReady) { setUserHasInteracted(true); if (isFinalVideoPlaying) { finalVideoRef.current.play().catch(error => { console.log('视频播放失败:', error); }); } } }; // 包装编辑按钮点击事件 const handleEditClick = (tab: string) => { setUserHasInteracted(true); onEditModalOpen(tab); }; // 全屏控制 const toggleFullscreen = () => { setUserHasInteracted(true); if (!document.fullscreenElement) { // 进入全屏 if (finalVideoRef.current) { finalVideoRef.current.requestFullscreen?.() || (finalVideoRef.current as any).webkitRequestFullscreen?.() || (finalVideoRef.current as any).msRequestFullscreen?.(); setIsFullscreen(true); } } else { // 退出全屏 document.exitFullscreen?.() || (document as any).webkitExitFullscreen?.() || (document as any).msExitFullscreen?.(); setIsFullscreen(false); } }; // 视频播放控制 useEffect(() => { if (mainVideoRef.current) { applyVolumeSettings(mainVideoRef.current); if (isVideoPlaying) { mainVideoRef.current.play().catch(error => { console.log('视频播放失败:', error); }); } else { mainVideoRef.current.pause(); } } }, [isVideoPlaying]); // 当切换视频时重置视频播放 useEffect(() => { if (mainVideoRef.current) { applyVolumeSettings(mainVideoRef.current); mainVideoRef.current.currentTime = 0; if (isVideoPlaying) { mainVideoRef.current.play().catch(error => { console.log('视频播放失败:', error); }); } } }, [currentSketchIndex]); // 音量设置变化时应用到所有视频 useEffect(() => { if (mainVideoRef.current) { applyVolumeSettings(mainVideoRef.current); } if (finalVideoRef.current) { applyVolumeSettings(finalVideoRef.current); } }, [volume, isMuted]); // 监听全屏状态变化 useEffect(() => { const handleFullscreenChange = () => { setIsFullscreen(!!document.fullscreenElement); }; document.addEventListener('fullscreenchange', handleFullscreenChange); document.addEventListener('webkitfullscreenchange', handleFullscreenChange); document.addEventListener('msfullscreenchange', handleFullscreenChange); return () => { document.removeEventListener('fullscreenchange', handleFullscreenChange); document.removeEventListener('webkitfullscreenchange', handleFullscreenChange); document.removeEventListener('msfullscreenchange', handleFullscreenChange); }; }, []); // 组件卸载时清理视频状态 useEffect(() => { return () => { // 清理最终视频状态 setFinalVideoReady(false); if (finalVideoRef.current) { finalVideoRef.current.pause(); } }; }, []); // 渲染音量控制组件 const renderVolumeControls = () => (
{/* 静音按钮 */} {/* 音量滑块 - 一直显示 */}
handleVolumeChange(parseFloat(e.target.value))} className="w-16 h-1 bg-white/20 rounded-lg appearance-none cursor-pointer [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-white [&::-webkit-slider-thumb]:cursor-pointer [&::-webkit-slider-thumb]:shadow-lg [&::-moz-range-thumb]:w-3 [&::-moz-range-thumb]:h-3 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-white [&::-moz-range-thumb]:cursor-pointer [&::-moz-range-thumb]:border-none [&::-moz-range-thumb]:shadow-lg" style={{ background: `linear-gradient(to right, white 0%, white ${volume * 100}%, rgba(255,255,255,0.2) ${volume * 100}%, rgba(255,255,255,0.2) 100%)` }} />
{Math.round(volume * 100)}%
); // 渲染最终成片 const renderFinalVideo = (currentStep: string) => { // 使用真实的final数据,如果没有则使用默认值 const finalVideo = final || { url: 'https://cdn.qikongjian.com/videos/1750389908_37d4fffa-8516-43a3-a423-fc0274f40e8a_text_to_video_0.mp4' }; return (
onControlsChange(true)} onMouseLeave={() => onControlsChange(false)} >
{/* 背景模糊的视频 */} {/* 最终成片视频 */} {/* 操作按钮组 */} {showControls && ( handleEditClick('4')} /> )} {/* 视频信息浮层 */}
{currentStep === '6' ? 'Final product' : 'Trailer Video'}
{/* 底部控制区域 */} {/* 播放/暂停按钮 */} {/* 播放时的发光效果 */} {isFinalVideoPlaying && ( )} {/* 音量控制 */} {renderVolumeControls()} {/* 全屏按钮 */} {/* 完成标记 */} Task completed
); }; // 渲染视频内容 const renderVideoContent = () => { const currentSketch = taskSketch[currentSketchIndex]; const defaultBgColors = ['RGB(45, 50, 70)', 'RGB(75, 80, 100)', 'RGB(105, 110, 130)']; const bgColors = currentSketch?.bg_rgb || defaultBgColors; return (
onControlsChange(true)} onMouseLeave={() => onControlsChange(false)} > {/* 只在生成过程中或没有视频时使用ProgressiveReveal */} {(isGeneratingVideo || !taskVideos[currentSketchIndex]) ? ( taskVideos[currentSketchIndex] ? (
{/* 背景模糊的图片 */}
background
{/* 视频 */}
) : (
{`Sketch
) ) : ( /* 生成完成后直接显示视频,不使用ProgressiveReveal */
{/* 视频 修复播放没有声音 */}
)} {/* 操作按钮组 */} {showControls && ( handleEditClick('3')} /> )} {/* 底部控制区域 */} { taskVideos[currentSketchIndex] && ( {/* 播放按钮 */} {/* 播放时的发光效果 */} {isVideoPlaying && ( )} {/* 音量控制 */} {renderVolumeControls()} )}
); }; // 渲染分镜草图 const renderSketchContent = () => { const currentSketch = taskSketch[currentSketchIndex]; const defaultBgColors = ['RGB(45, 50, 70)', 'RGB(75, 80, 100)', 'RGB(105, 110, 130)']; const bgColors = currentSketch?.bg_rgb || defaultBgColors; return (
onControlsChange(true)} onMouseLeave={() => onControlsChange(false)} > {/* 只在生成过程中或没有分镜图片时使用ProgressiveReveal */} {(isGeneratingSketch || !currentSketch) ? ( currentSketch ? ( {`Sketch ) : (
{/* 动态渐变背景 */} {/* 动态光效 */}
) ) : ( /* 生成完成后直接显示图片,不使用ProgressiveReveal */ {`NG-Sketch )} {/* 操作按钮组 */} {showControls && ( handleEditClick('2')} /> )} {/* 底部播放按钮 */} {/* 播放时的发光效果 */} {isPlaying && ( )}
); }; // 渲染剧本 const renderScriptContent = () => { return (
); }; // 根据当前步骤渲染对应内容 if (Number(currentStep) === 6 || Number(currentStep) === 5.5) { return renderFinalVideo(currentStep); } if (Number(currentStep) > 2 && Number(currentStep) < 6) { return renderVideoContent(); } if (Number(currentStep) === 0) { return renderScriptContent(); } return renderSketchContent(); }