diff --git a/src/components/AudioPlayer.jsx b/src/components/AudioPlayer.jsx index bc1d964..4acc8f9 100644 --- a/src/components/AudioPlayer.jsx +++ b/src/components/AudioPlayer.jsx @@ -54,45 +54,64 @@ export function Player() { const lcStation = activeStation.toLowerCase(); const streamUrl = `https://stream.codey.lol/hls/${lcStation}/${lcStation}.m3u8?t=${Date.now()}`; + // Cleanup existing stream if (hlsRef.current) { hlsRef.current.destroy(); hlsRef.current = null; } - if (audioRef.current.canPlayType("application/vnd.apple.mpegurl")) { - // Native HLS support (Safari) - audioRef.current.src = streamUrl; + const audio = audioRef.current; + if (!audio) return; + + if (audio.canPlayType("application/vnd.apple.mpegurl")) { + // Native support (Safari) + audio.src = streamUrl; + audio.play().then(() => setIsPlaying(true)).catch(console.error); } else if (Hls.isSupported()) { const hls = new Hls({ - maxBufferLength: 60, + maxBufferLength: 30, + maxMaxBufferLength: 60, + abrEwmaFastLive: 2.0, + abrEwmaSlowLive: 6.0, + abrBandWidthFactor: 0.95, // Bias toward higher quality + autoStartLoad: true, + startLevel: -1, // adaptive start }); - hls.loadSource(streamUrl); - hls.attachMedia(audioRef.current); - hlsRef.current = hls; - } else { - console.error("HLS is not supported in this browser."); - } - audioRef.current.play().then(() => setIsPlaying(true)).catch((e) => { - console.error("Playback failed:", e); - }); + hls.loadSource(streamUrl); + hls.attachMedia(audio); + + hls.on(Hls.Events.ERROR, (_, data) => { + if (data.fatal) { + console.error("HLS fatal error:", data); + hls.destroy(); + } + }); + + hlsRef.current = hls; + audio.play().then(() => setIsPlaying(true)).catch(console.error); + } else { + console.error("HLS not supported"); + } }; const togglePlayback = () => { - if (!audioRef.current) return; + const audio = audioRef.current; + if (!audio) return; if (isPlaying) { - audioRef.current.pause(); + audio.pause(); setIsPlaying(false); } else { - audioRef.current.play().then(() => setIsPlaying(true)); + audio.play().then(() => setIsPlaying(true)).catch(console.error); } }; useEffect(() => { - if (audioRef.current) { - audioRef.current.pause(); - audioRef.current.src = ""; + const audio = audioRef.current; + if (audio) { + audio.pause(); + audio.src = ""; setIsPlaying(false); } @@ -101,6 +120,7 @@ export function Player() { return () => { if (hlsRef.current) { hlsRef.current.destroy(); + hlsRef.current = null; } }; }, [activeStation]); @@ -196,9 +216,7 @@ export function Player() {
{formatTime(elapsed)}
-{formatTime(duration - elapsed)}
+{formatTime(remaining)}