'use client'; import React, { useState, useRef, useEffect } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Upload, Library, Play, Pause, RefreshCw, Music2, Volume2 } from 'lucide-react'; import { cn } from '@/public/lib/utils'; import { GlassIconButton } from './glass-icon-button'; import { ReplaceMusicModal } from './replace-music-modal'; interface Music { url: string; script: string; name?: string; duration?: string; totalDuration?: string; isLooped?: boolean; } interface MusicTabContentProps { currentSketchIndex: number; } export function MusicTabContent({ currentSketchIndex, }: MusicTabContentProps) { const music = { url: '', script: '', name: '', duration: '', totalDuration: '', isLooped: true, } const [isReplaceModalOpen, setIsReplaceModalOpen] = useState(false); const [activeMethod, setActiveMethod] = useState('upload'); const [isPlaying, setIsPlaying] = useState(false); const [progress, setProgress] = useState(0); const [volume, setVolume] = useState(75); const [isLooped, setIsLooped] = useState(music?.isLooped ?? true); const [fadeIn, setFadeIn] = useState('0s'); const [fadeOut, setFadeOut] = useState('3s'); const [trimFrom, setTrimFrom] = useState('00 : 00'); const [trimTo, setTrimTo] = useState(music?.duration?.split(' : ').slice(0, 2).join(' : ') || '01 : 35'); const audioRef = useRef(null); useEffect(() => { if (music) { setIsLooped(music.isLooped ?? true); if (music.duration) { const durationParts = music.duration.split(' : '); if (durationParts.length >= 2) { setTrimTo(`${durationParts[0]} : ${durationParts[1]}`); } } } }, [music]); if (!music || !music.url) { return (

No music data

); } const handleTimeUpdate = () => { if (audioRef.current) { const progress = (audioRef.current.currentTime / audioRef.current.duration) * 100; setProgress(progress); } }; const togglePlay = () => { if (audioRef.current) { if (isPlaying) { audioRef.current.pause(); } else { audioRef.current.play(); } setIsPlaying(!isPlaying); } }; const handleProgressClick = (e: React.MouseEvent) => { if (audioRef.current) { const rect = e.currentTarget.getBoundingClientRect(); const x = e.clientX - rect.left; const percentage = (x / rect.width) * 100; const time = (percentage / 100) * audioRef.current.duration; audioRef.current.currentTime = time; setProgress(percentage); } }; const handleVolumeChange = (e: React.ChangeEvent) => { const newVolume = parseInt(e.target.value); setVolume(newVolume); if (audioRef.current) { audioRef.current.volume = newVolume / 100; } }; return (

{music.name || music.script || 'Background music'}

Replace music

setIsReplaceModalOpen(true)} whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }} > Upload music setIsReplaceModalOpen(true)} whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }} > Music library
setIsLooped(!isLooped)} layout >
from setTrimFrom(e.target.value)} className="w-20 px-2 py-1 bg-white/5 border border-white/10 rounded text-center focus:outline-none focus:border-blue-500" />
to setTrimTo(e.target.value)} className="w-20 px-2 py-1 bg-white/5 border border-white/10 rounded text-center focus:outline-none focus:border-blue-500" />
Fade in: setFadeIn(e.target.value)} className="w-full px-2 py-1 bg-white/5 border border-white/10 rounded text-center focus:outline-none focus:border-blue-500" />
Fade out: setFadeOut(e.target.value)} className="w-full px-2 py-1 bg-white/5 border border-white/10 rounded text-center focus:outline-none focus:border-blue-500" />
{volume}%
{isPlaying ? ( ) : ( )}
{audioRef.current ? ( `${Math.floor(audioRef.current.currentTime)}s / ${Math.floor(audioRef.current.duration)}s` ) : '0:00 / 0:00'}
setIsReplaceModalOpen(false)} onMusicSelect={(music) => { console.log('Selected music:', music); setIsReplaceModalOpen(false); // TODO: 处理音乐选择逻辑 }} />
); }