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
This commit is contained in:
parent
c5342f8164
commit
3b513ba9e8
4
.replit
4
.replit
@ -15,6 +15,10 @@ run = ["npm", "run", "start"]
|
|||||||
localPort = 5000
|
localPort = 5000
|
||||||
externalPort = 80
|
externalPort = 80
|
||||||
|
|
||||||
|
[[ports]]
|
||||||
|
localPort = 33401
|
||||||
|
externalPort = 3001
|
||||||
|
|
||||||
[[ports]]
|
[[ports]]
|
||||||
localPort = 35637
|
localPort = 35637
|
||||||
externalPort = 3000
|
externalPort = 3000
|
||||||
|
|||||||
@ -49,63 +49,110 @@ export default function LivePage() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const initializePlayer = async () => {
|
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 {
|
try {
|
||||||
// Load HLS.js
|
// Load HLS.js if not already loaded
|
||||||
|
console.log('🔴 Checking if HLS.js is loaded...');
|
||||||
if (!window.Hls) {
|
if (!window.Hls) {
|
||||||
|
console.log('🔴 Loading HLS.js script...');
|
||||||
const script = document.createElement('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;
|
script.async = true;
|
||||||
document.head.appendChild(script);
|
document.head.appendChild(script);
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
script.onload = resolve;
|
script.onload = () => {
|
||||||
script.onerror = reject;
|
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;
|
const video = videoRef.current;
|
||||||
|
console.log('🔴 Stream URL:', streamUrl);
|
||||||
|
|
||||||
if (window.Hls && window.Hls.isSupported()) {
|
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({
|
const hls = new window.Hls({
|
||||||
|
debug: true,
|
||||||
enableWorker: false,
|
enableWorker: false,
|
||||||
lowLatencyMode: true,
|
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.loadSource(streamUrl);
|
||||||
hls.attachMedia(video);
|
hls.attachMedia(video);
|
||||||
|
|
||||||
hls.on(window.Hls.Events.MEDIA_ATTACHED, () => {
|
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, () => {
|
hls.on(window.Hls.Events.MANIFEST_PARSED, (event: any, data: any) => {
|
||||||
console.log('🔴 HLS manifest parsed, starting playback');
|
console.log('✅ HLS manifest parsed successfully:', data);
|
||||||
|
console.log('Available levels:', data.levels);
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
|
|
||||||
// Try auto-play
|
// Try auto-play
|
||||||
video.play().catch((e) => {
|
video.play().then(() => {
|
||||||
console.log('Auto-play blocked:', e);
|
console.log('✅ Auto-play started successfully');
|
||||||
setError('Kliknite play za zagon stream-a');
|
}).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) => {
|
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) {
|
if (data.fatal) {
|
||||||
switch (data.type) {
|
switch (data.type) {
|
||||||
case window.Hls.ErrorTypes.NETWORK_ERROR:
|
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();
|
hls.startLoad();
|
||||||
break;
|
break;
|
||||||
case window.Hls.ErrorTypes.MEDIA_ERROR:
|
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();
|
hls.recoverMediaError();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
setError('Neznana napaka pri streamingu');
|
console.error('💥 Fatal error, cannot recover:', data);
|
||||||
|
setError(`Napaka pri streamingu: ${data.details}`);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,25 +162,33 @@ export default function LivePage() {
|
|||||||
|
|
||||||
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
|
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
|
||||||
// Native HLS support (Safari)
|
// Native HLS support (Safari)
|
||||||
console.log('🔴 Using native HLS support');
|
console.log('🍎 Using native HLS support (Safari)');
|
||||||
video.src = streamUrl;
|
video.src = streamUrl;
|
||||||
|
|
||||||
video.addEventListener('loadedmetadata', () => {
|
video.addEventListener('loadedmetadata', () => {
|
||||||
console.log('🔴 Native HLS loaded');
|
console.log('✅ Native HLS metadata loaded');
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
video.addEventListener('error', (e) => {
|
||||||
|
console.error('❌ Native video error:', e);
|
||||||
|
setError('Napaka pri nalaganju streama');
|
||||||
|
});
|
||||||
|
|
||||||
} else {
|
} 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);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Video event listeners
|
// Add comprehensive video event listeners
|
||||||
video.addEventListener('play', () => {
|
video.addEventListener('play', () => {
|
||||||
console.log('🔴 Live stream playing');
|
console.log('▶️ Video started playing');
|
||||||
setIsPlaying(true);
|
setIsPlaying(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
video.addEventListener('pause', () => {
|
video.addEventListener('pause', () => {
|
||||||
console.log('⏸️ Live stream paused');
|
console.log('⏸️ Video paused');
|
||||||
setIsPlaying(false);
|
setIsPlaying(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -142,17 +197,39 @@ export default function LivePage() {
|
|||||||
setIsMuted(video.muted);
|
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) {
|
} catch (error) {
|
||||||
console.error('Failed to initialize live stream:', error);
|
console.error('💥 Failed to initialize live stream player:', error);
|
||||||
setError('Napaka pri nalaganju stream-a');
|
setError('Napaka pri inicializaciji playerja');
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
initializePlayer();
|
// Add a small delay to ensure DOM is ready
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
initializePlayer();
|
||||||
|
}, 100);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
clearTimeout(timer);
|
||||||
if (hlsRef.current) {
|
if (hlsRef.current) {
|
||||||
|
console.log('🧹 Destroying HLS instance');
|
||||||
hlsRef.current.destroy();
|
hlsRef.current.destroy();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user