import { useRef, useCallback, useState, useEffect } from 'react'; import { useEditorStore } from '../store/editorStore'; import { useVideoSync } from '../hooks/useVideoSync'; import { Play, Pause, SkipBack, SkipForward, Volume2 } from 'lucide-react'; export default function VideoPlayer() { const videoRef = useRef(null); const videoUrl = useEditorStore((s) => s.videoUrl); const isPlaying = useEditorStore((s) => s.isPlaying); const duration = useEditorStore((s) => s.duration); const { seekTo, togglePlay } = useVideoSync(videoRef); const [displayTime, setDisplayTime] = useState(0); useEffect(() => { const video = videoRef.current; if (!video) return; let raf = 0; const tick = () => { setDisplayTime(video.currentTime); raf = requestAnimationFrame(tick); }; raf = requestAnimationFrame(tick); return () => cancelAnimationFrame(raf); }, [videoUrl]); const formatTime = (seconds: number) => { const m = Math.floor(seconds / 60); const s = Math.floor(seconds % 60); return `${m}:${s.toString().padStart(2, '0')}`; }; const handleProgressClick = useCallback( (e: React.MouseEvent) => { const rect = e.currentTarget.getBoundingClientRect(); const ratio = (e.clientX - rect.left) / rect.width; seekTo(ratio * duration); }, [seekTo, duration], ); const skip = useCallback( (delta: number) => { const video = videoRef.current; if (!video) return; seekTo(Math.max(0, Math.min(duration, video.currentTime + delta))); }, [seekTo, duration], ); if (!videoUrl) { return (
No video loaded
); } return (
0 ? `${(displayTime / duration) * 100}%` : '0%' }} >
skip(-5)} title="Back 5s"> {isPlaying ? : } skip(5)} title="Forward 5s">
{formatTime(displayTime)} / {formatTime(duration)}
); } function ControlButton({ children, onClick, title, primary, }: { children: React.ReactNode; onClick: () => void; title: string; primary?: boolean; }) { return ( ); }