diff --git a/client/src/components/video-modal.tsx b/client/src/components/video-modal.tsx index 30af466..cd3a0d9 100644 --- a/client/src/components/video-modal.tsx +++ b/client/src/components/video-modal.tsx @@ -3,6 +3,7 @@ import { X } from "lucide-react"; import { type Video } from "@shared/schema"; import { Button } from "@/components/ui/button"; import { apiRequest } from "@/lib/queryClient"; +import Hls from "hls.js"; interface VideoModalProps { video: Video | null; @@ -45,6 +46,7 @@ function formatDate(date: Date | string): string { export default function VideoModal({ video, isOpen, onClose }: VideoModalProps) { const videoRef = useRef(null); + const hlsRef = useRef(null); useEffect(() => { const handleEscape = (e: KeyboardEvent) => { @@ -66,6 +68,82 @@ export default function VideoModal({ video, isOpen, onClose }: VideoModalProps) }; }, [isOpen, onClose]); + // Initialize HLS when video is available + useEffect(() => { + if (isOpen && video && videoRef.current) { + const videoElement = videoRef.current; + + // Clean up previous HLS instance + if (hlsRef.current) { + hlsRef.current.destroy(); + hlsRef.current = null; + } + + const videoUrl = video.videoUrl; + console.log('Loading video:', videoUrl); + + // Check if the video URL is HLS (.m3u8) + if (videoUrl.includes('.m3u8')) { + if (Hls.isSupported()) { + // Use HLS.js for browsers that don't support HLS natively + const hls = new Hls({ + debug: true, + enableWorker: false, + lowLatencyMode: true, + backBufferLength: 90 + }); + + hls.loadSource(videoUrl); + hls.attachMedia(videoElement); + + hls.on(Hls.Events.MANIFEST_PARSED, () => { + console.log('HLS manifest loaded successfully'); + }); + + hls.on(Hls.Events.ERROR, (event, data) => { + console.error('HLS error:', data); + if (data.fatal) { + switch (data.type) { + case Hls.ErrorTypes.NETWORK_ERROR: + console.log('Network error, trying to recover...'); + hls.startLoad(); + break; + case Hls.ErrorTypes.MEDIA_ERROR: + console.log('Media error, trying to recover...'); + hls.recoverMediaError(); + break; + default: + console.log('Fatal error, destroying HLS instance...'); + hls.destroy(); + break; + } + } + }); + + hlsRef.current = hls; + } else if (videoElement.canPlayType('application/vnd.apple.mpegurl')) { + // For Safari that supports HLS natively + videoElement.src = videoUrl; + console.log('Using native HLS support'); + } else { + console.error('HLS is not supported in this browser'); + } + } else { + // For regular MP4 videos + videoElement.src = videoUrl; + console.log('Using native video support for MP4'); + } + } + + // Cleanup when modal closes + return () => { + if (hlsRef.current) { + hlsRef.current.destroy(); + hlsRef.current = null; + } + }; + }, [isOpen, video]); + const handleVideoPlay = async () => { if (video) { try { @@ -102,17 +180,28 @@ export default function VideoModal({ video, isOpen, onClose }: VideoModalProps)
- + {video.videoUrl.includes('iframe.mediadelivery.net') ? ( +