From 3b513ba9e86af227a9d6f26d65d7b5de29994f6a Mon Sep 17 00:00:00 2001 From: sebastjanartic <45803536-sebastjanartic@users.noreply.replit.com> Date: Fri, 26 Sep 2025 06:24:11 +0000 Subject: [PATCH] Improve live stream playback and error handling in the video player Implement more robust HLS.js integration with detailed logging and specific error handling for live video playback. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 45a1dcfc-f8a2-475a-a6b9-96fbb841dc27 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/60d372ff-2c10-46c7-b01b-10c3435136b0/45a1dcfc-f8a2-475a-a6b9-96fbb841dc27/u8V0MoO --- .replit | 4 ++ client/src/pages/LivePage.tsx | 129 +++++++++++++++++++++++++++------- 2 files changed, 107 insertions(+), 26 deletions(-) diff --git a/.replit b/.replit index 77a16c9..69e9900 100644 --- a/.replit +++ b/.replit @@ -15,6 +15,10 @@ run = ["npm", "run", "start"] localPort = 5000 externalPort = 80 +[[ports]] +localPort = 33401 +externalPort = 3001 + [[ports]] localPort = 35637 externalPort = 3000 diff --git a/client/src/pages/LivePage.tsx b/client/src/pages/LivePage.tsx index e17343c..5379659 100644 --- a/client/src/pages/LivePage.tsx +++ b/client/src/pages/LivePage.tsx @@ -49,63 +49,110 @@ export default function LivePage() { useEffect(() => { const initializePlayer = async () => { - if (!videoRef.current) return; + console.log('πŸ”΄ LivePage: Starting to initialize player...'); + + if (!videoRef.current) { + console.error('🚨 Video ref not available!'); + return; + } + + console.log('πŸ”΄ Video element found, continuing...'); try { - // Load HLS.js + // Load HLS.js if not already loaded + console.log('πŸ”΄ Checking if HLS.js is loaded...'); if (!window.Hls) { + console.log('πŸ”΄ Loading HLS.js script...'); const script = document.createElement('script'); - script.src = 'https://cdn.jsdelivr.net/npm/hls.js@latest'; + script.src = 'https://cdn.jsdelivr.net/npm/hls.js@1.5.8'; script.async = true; document.head.appendChild(script); await new Promise((resolve, reject) => { - script.onload = resolve; - script.onerror = reject; + script.onload = () => { + console.log('βœ… HLS.js script loaded successfully'); + resolve(null); + }; + script.onerror = (e) => { + console.error('❌ Failed to load HLS.js script:', e); + reject(e); + }; }); + } else { + console.log('βœ… HLS.js already available'); } const video = videoRef.current; + console.log('πŸ”΄ Stream URL:', streamUrl); if (window.Hls && window.Hls.isSupported()) { - console.log('πŸ”΄ Initializing HLS.js for live stream'); + console.log('πŸ”΄ HLS.js is supported, initializing...'); const hls = new window.Hls({ + debug: true, enableWorker: false, lowLatencyMode: true, - backBufferLength: 90 + backBufferLength: 90, + maxBufferLength: 30, + maxMaxBufferLength: 600, + maxBufferSize: 60 * 1000 * 1000, + maxBufferHole: 0.5 }); + console.log('πŸ”΄ Loading source:', streamUrl); hls.loadSource(streamUrl); hls.attachMedia(video); hls.on(window.Hls.Events.MEDIA_ATTACHED, () => { - console.log('πŸ”΄ HLS media attached'); + console.log('βœ… HLS media attached successfully'); }); - hls.on(window.Hls.Events.MANIFEST_PARSED, () => { - console.log('πŸ”΄ HLS manifest parsed, starting playback'); + hls.on(window.Hls.Events.MANIFEST_PARSED, (event: any, data: any) => { + console.log('βœ… HLS manifest parsed successfully:', data); + console.log('Available levels:', data.levels); setIsLoading(false); + // Try auto-play - video.play().catch((e) => { - console.log('Auto-play blocked:', e); - setError('Kliknite play za zagon stream-a'); + video.play().then(() => { + console.log('βœ… Auto-play started successfully'); + }).catch((e) => { + console.log('⚠️ Auto-play blocked, user interaction required:', e); + setError('Kliknite play za zagon streama'); }); }); + hls.on(window.Hls.Events.LEVEL_LOADED, (event: any, data: any) => { + console.log('πŸ“Š Level loaded:', data); + }); + + hls.on(window.Hls.Events.FRAG_LOADED, (event: any, data: any) => { + console.log('πŸ“¦ Fragment loaded:', data.frag.url); + }); + hls.on(window.Hls.Events.ERROR, (event: any, data: any) => { - console.error('🚨 HLS Error:', event, data); + console.error('🚨 HLS Error occurred:', { + type: data.type, + details: data.details, + fatal: data.fatal, + error: data.error, + event, + data + }); + if (data.fatal) { switch (data.type) { case window.Hls.ErrorTypes.NETWORK_ERROR: - setError('Napaka pri povezavi s streamom'); + console.log('πŸ”„ Network error, attempting recovery...'); + setError('Napaka pri povezavi s streamom - poskuΕ‘am znova...'); hls.startLoad(); break; case window.Hls.ErrorTypes.MEDIA_ERROR: - setError('Napaka pri predvajanju videa'); + console.log('πŸ”„ Media error, attempting recovery...'); + setError('Napaka pri predvajanju - poskuΕ‘am znova...'); hls.recoverMediaError(); break; default: - setError('Neznana napaka pri streamingu'); + console.error('πŸ’₯ Fatal error, cannot recover:', data); + setError(`Napaka pri streamingu: ${data.details}`); break; } } @@ -115,25 +162,33 @@ export default function LivePage() { } else if (video.canPlayType('application/vnd.apple.mpegurl')) { // Native HLS support (Safari) - console.log('πŸ”΄ Using native HLS support'); + console.log('🍎 Using native HLS support (Safari)'); video.src = streamUrl; + video.addEventListener('loadedmetadata', () => { - console.log('πŸ”΄ Native HLS loaded'); + console.log('βœ… Native HLS metadata loaded'); setIsLoading(false); }); + + video.addEventListener('error', (e) => { + console.error('❌ Native video error:', e); + setError('Napaka pri nalaganju streama'); + }); + } else { - setError('HLS not supported in this browser'); + console.error('❌ HLS not supported in this browser'); + setError('HLS ni podprt v tem brskalniku'); setIsLoading(false); } - // Video event listeners + // Add comprehensive video event listeners video.addEventListener('play', () => { - console.log('πŸ”΄ Live stream playing'); + console.log('▢️ Video started playing'); setIsPlaying(true); }); video.addEventListener('pause', () => { - console.log('⏸️ Live stream paused'); + console.log('⏸️ Video paused'); setIsPlaying(false); }); @@ -142,17 +197,39 @@ export default function LivePage() { setIsMuted(video.muted); }); + video.addEventListener('loadstart', () => { + console.log('πŸ”„ Video load started'); + }); + + video.addEventListener('loadeddata', () => { + console.log('πŸ“Š Video data loaded'); + }); + + video.addEventListener('canplay', () => { + console.log('βœ… Video can start playing'); + }); + + video.addEventListener('error', (e) => { + console.error('❌ Video element error:', e); + setError('Napaka video elementa'); + }); + } catch (error) { - console.error('Failed to initialize live stream:', error); - setError('Napaka pri nalaganju stream-a'); + console.error('πŸ’₯ Failed to initialize live stream player:', error); + setError('Napaka pri inicializaciji playerja'); setIsLoading(false); } }; - initializePlayer(); + // Add a small delay to ensure DOM is ready + const timer = setTimeout(() => { + initializePlayer(); + }, 100); return () => { + clearTimeout(timer); if (hlsRef.current) { + console.log('🧹 Destroying HLS instance'); hlsRef.current.destroy(); } };