diff --git a/components/pages/work-flow/media-viewer.tsx b/components/pages/work-flow/media-viewer.tsx index 6c7f6c9..3263086 100644 --- a/components/pages/work-flow/media-viewer.tsx +++ b/components/pages/work-flow/media-viewer.tsx @@ -1,8 +1,8 @@ 'use client'; -import React, { useRef, useEffect } from 'react'; +import React, { useRef, useEffect, useState } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; -import { Edit3, Play, Pause } from 'lucide-react'; +import { Edit3, Play, Pause, Volume2, VolumeX } from 'lucide-react'; import { ProgressiveReveal, presets } from '@/components/ui/progressive-reveal'; import { GlassIconButton } from '@/components/ui/glass-icon-button'; @@ -40,10 +40,45 @@ export function MediaViewer({ final }: MediaViewerProps) { const mainVideoRef = useRef(null); + const finalVideoRef = useRef(null); + + // 音量控制状态 + const [isMuted, setIsMuted] = useState(false); + const [volume, setVolume] = useState(0.8); + + // 音量控制函数 + const toggleMute = () => { + setIsMuted(!isMuted); + if (mainVideoRef.current) { + mainVideoRef.current.muted = !isMuted; + } + if (finalVideoRef.current) { + finalVideoRef.current.muted = !isMuted; + } + }; + + const handleVolumeChange = (newVolume: number) => { + 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 (mainVideoRef.current) { + applyVolumeSettings(mainVideoRef.current); if (isVideoPlaying) { mainVideoRef.current.play().catch(error => { console.log('视频播放失败:', error); @@ -57,6 +92,7 @@ export function MediaViewer({ // 当切换视频时重置视频播放 useEffect(() => { if (mainVideoRef.current) { + applyVolumeSettings(mainVideoRef.current); mainVideoRef.current.currentTime = 0; if (isVideoPlaying) { mainVideoRef.current.play().catch(error => { @@ -66,6 +102,56 @@ export function MediaViewer({ } }, [currentSketchIndex]); + // 音量设置变化时应用到所有视频 + useEffect(() => { + if (mainVideoRef.current) { + applyVolumeSettings(mainVideoRef.current); + } + if (finalVideoRef.current) { + applyVolumeSettings(finalVideoRef.current); + } + }, [volume, isMuted]); + + // 渲染音量控制组件 + 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 = () => { // 使用真实的final数据,如果没有则使用默认值 @@ -108,12 +194,14 @@ export function MediaViewer({ className="relative z-10" >