"use client"; import { useRef, useState, useEffect } from "react"; import { Play, Pause, Volume2, VolumeX, Maximize, AlertCircle } from "lucide-react"; interface ReelPlayerProps { src: string; className?: string; } export function ReelPlayer({ src, className = "" }: ReelPlayerProps) { const videoRef = useRef(null); const progressBarRef = useRef(null); const [isPlaying, setIsPlaying] = useState(false); const [isMuted, setIsMuted] = useState(false); const [currentTime, setCurrentTime] = useState(0); const [duration, setDuration] = useState(0); const [volume, setVolume] = useState(1); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const video = videoRef.current; if (!video) return; const handleLoadedMetadata = () => { setDuration(video.duration); }; const handleTimeUpdate = () => { setCurrentTime(video.currentTime); }; const handleEnded = () => { setIsPlaying(false); }; const handleError = (e: Event) => { setIsLoading(false); const videoEl = e.target as HTMLVideoElement; const errorCode = videoEl.error?.code; const errorMessage = videoEl.error?.message; let userMessage = "Failed to load video. "; switch (errorCode) { case 1: userMessage += "Video loading was aborted."; break; case 2: userMessage += "Network error occurred."; break; case 3: userMessage += "Video format not supported by your browser."; break; case 4: userMessage += "Video source not found."; break; default: userMessage += errorMessage || "Unknown error."; } setError(userMessage); console.error("Video error:", errorCode, errorMessage); }; const handleCanPlay = () => { console.log("Video canplay event fired"); setIsLoading(false); setError(null); }; const handleLoadedData = () => { console.log("Video loadeddata event fired"); setIsLoading(false); }; video.addEventListener("loadedmetadata", handleLoadedMetadata); video.addEventListener("timeupdate", handleTimeUpdate); video.addEventListener("ended", handleEnded); video.addEventListener("error", handleError); video.addEventListener("canplay", handleCanPlay); video.addEventListener("loadeddata", handleLoadedData); // Check if video is already loaded (in case events fired before listeners attached) if (video.readyState >= 3) { // HAVE_FUTURE_DATA or HAVE_ENOUGH_DATA console.log("Video already loaded, readyState:", video.readyState); setIsLoading(false); if (video.duration) { setDuration(video.duration); } } return () => { video.removeEventListener("loadedmetadata", handleLoadedMetadata); video.removeEventListener("timeupdate", handleTimeUpdate); video.removeEventListener("ended", handleEnded); video.removeEventListener("error", handleError); video.removeEventListener("canplay", handleCanPlay); video.removeEventListener("loadeddata", handleLoadedData); }; }, []); const togglePlay = async () => { const video = videoRef.current; if (!video || error) return; try { if (isPlaying) { video.pause(); setIsPlaying(false); } else { await video.play(); setIsPlaying(true); } } catch (err) { console.error("Play error:", err); setError("Unable to play video. " + (err as Error).message); setIsPlaying(false); } }; const toggleMute = () => { const video = videoRef.current; if (!video) return; video.muted = !isMuted; setIsMuted(!isMuted); }; const handleProgressClick = (e: React.MouseEvent) => { const video = videoRef.current; const progressBar = progressBarRef.current; if (!video || !progressBar) return; const rect = progressBar.getBoundingClientRect(); const clickX = e.clientX - rect.left; const percentage = clickX / rect.width; video.currentTime = percentage * video.duration; }; const toggleFullscreen = () => { const video = videoRef.current; if (!video) return; if (!document.fullscreenElement) { video.requestFullscreen(); } else { document.exitFullscreen(); } }; const formatTime = (seconds: number) => { const mins = Math.floor(seconds / 60); const secs = Math.floor(seconds % 60); return `${mins}:${secs.toString().padStart(2, "0")}`; }; const progress = duration > 0 ? (currentTime / duration) * 100 : 0; return (
{/* Video Element */} {/* Loading State */} {isLoading && !error && (
Loading video...
)} {/* Error State */} {error && (
{error}
Try refreshing the page or using a different browser.
)} {/* Custom Controls */} {!error && (
{/* Progress Bar */}
{/* Controls Row */}
{/* Play/Pause Button */} {/* Volume Button */} {/* Time Display */} {formatTime(currentTime)} / {formatTime(duration)}
{/* Fullscreen Button */}
)}
); }