'use client'; import React, { useRef, useEffect, useState, SetStateAction, useMemo } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Edit3, Play, Pause, Volume2, VolumeX, Maximize, Minimize, Loader2, X, Scissors, RotateCcw, MessageCircleMore, Download, ArrowDownWideNarrow, PictureInPicture2, PenTool } from 'lucide-react'; import { showDownloadOptionsModal } from './download-options-modal'; 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'; import { Skeleton } from '@/components/ui/skeleton'; import ScriptLoading from './script-loading'; import { TaskObject } from '@/api/DTO/movieEdit'; import { Button, Tooltip } from 'antd'; import { downloadVideo, downloadAllVideos, getFirstFrame } from '@/utils/tools'; import { post } from '@/api/request'; import { VideoEditOverlay } from './video-edit/VideoEditOverlay'; import { EditPoint as EditPointType } from './video-edit/types'; import { isVideoModificationEnabled } from '@/lib/server-config'; import { useSearchParams } from 'next/navigation'; import RenderLoading from './RenderLoading'; interface MediaViewerProps { taskObject: TaskObject; scriptData: any; currentSketchIndex: number; isVideoPlaying: boolean; selectedView?: 'final' | 'video' | null; onEditModalOpen: (tab: string) => void; onToggleVideoPlay: () => void; setIsPauseWorkFlow: (isPause: boolean) => void; setAnyAttribute: any; isPauseWorkFlow: boolean; applyScript: any; mode: string; onOpenChat?: () => void; setVideoPreview?: (url: string, id: string) => void; showGotoCutButton?: boolean; onGotoCut: () => void; isSmartChatBoxOpen: boolean; onRetryVideo?: (video_id: string) => void; enableVideoEdit?: boolean; onVideoEditDescriptionSubmit?: (editPoint: EditPointType, description: string) => void; projectId?: string; aspectRatio: string; placeholderWidth: string; } export const MediaViewer = React.memo(function MediaViewer({ taskObject, scriptData, currentSketchIndex, isVideoPlaying, selectedView, onEditModalOpen, onToggleVideoPlay, setIsPauseWorkFlow, setAnyAttribute, isPauseWorkFlow, applyScript, mode, onOpenChat, setVideoPreview, showGotoCutButton, onGotoCut, isSmartChatBoxOpen, onRetryVideo, enableVideoEdit = true, onVideoEditDescriptionSubmit, projectId, aspectRatio, placeholderWidth }: MediaViewerProps) { const mainVideoRef = useRef(null); const finalVideoRef = useRef(null); const videoContentRef = useRef(null); // 音量控制状态 const [isMuted, setIsMuted] = useState(false); const [volume, setVolume] = useState(0.8); const [duration, setDuration] = useState(0); const [currentTime, setCurrentTime] = useState(0); // 最终视频控制状态 const [isFinalVideoPlaying, setIsFinalVideoPlaying] = useState(true); const [isFullscreen, setIsFullscreen] = useState(false); const [finalVideoReady, setFinalVideoReady] = useState(false); const [userHasInteracted, setUserHasInteracted] = useState(false); const [toosBtnRight, setToodsBtnRight] = useState('1rem'); const [isLoadingDownloadBtn, setIsLoadingDownloadBtn] = useState(false); const [isLoadingDownloadAllVideosBtn, setIsLoadingDownloadAllVideosBtn] = useState(false); const [isVideoEditMode, setIsVideoEditMode] = useState(false); // 控制钢笔图标显示的状态 - 参考谷歌登录按钮的实现 const [showVideoModification, setShowVideoModification] = useState(false); const searchParams = useSearchParams(); const episodeId = searchParams.get('episodeId') || ''; useEffect(() => { if (isSmartChatBoxOpen) { const videoContentWidth = videoContentRef.current?.clientWidth ?? 0; const right = (window.innerWidth * 0.25) - ((window.innerWidth - videoContentWidth) / 2) + 32; setToodsBtnRight(right + 'px'); } else { setToodsBtnRight('1rem'); } }, [isSmartChatBoxOpen]) // 检查视频修改功能是否启用 - 参考谷歌登录按钮的实现 useEffect(() => { const checkVideoModificationStatus = async () => { try { console.log('🔍 MediaViewer:开始检查视频修改功能状态...'); const enabled = await isVideoModificationEnabled(); console.log('📋 MediaViewer:视频修改功能启用状态:', enabled); setShowVideoModification(enabled); console.log('📋 MediaViewer:设置showVideoModification状态为:', enabled); } catch (error) { console.error("❌ MediaViewer:Failed to check video modification status:", error); setShowVideoModification(false); // 出错时默认不显示 } }; checkVideoModificationStatus(); }, []); // 只在组件挂载时执行一次 // 调试:监控钢笔图标显示状态 useEffect(() => { console.log('🔧 MediaViewer状态更新:', { enableVideoEdit, showVideoModification, shouldShowPenIcon: enableVideoEdit && showVideoModification }); }, [enableVideoEdit, showVideoModification]); // 音量控制函数 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); try { setDuration(Number.isFinite(finalVideoRef.current.duration) ? finalVideoRef.current.duration : 0); } catch {} // 如果当前状态是应该播放的,尝试播放 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); }); } } }; // 使用 useMemo 缓存最终视频元素,避免重复创建和请求 const memoizedFinalVideoElement = useMemo(() => { console.log('final', taskObject.final); if (!taskObject.final?.url) return null; return (