fix HLS streaming quality

This commit is contained in:
2025-07-30 08:06:24 -04:00
parent a722a404dc
commit 172b43fc8b

View File

@@ -54,45 +54,64 @@ export function Player() {
const lcStation = activeStation.toLowerCase(); const lcStation = activeStation.toLowerCase();
const streamUrl = `https://stream.codey.lol/hls/${lcStation}/${lcStation}.m3u8?t=${Date.now()}`; const streamUrl = `https://stream.codey.lol/hls/${lcStation}/${lcStation}.m3u8?t=${Date.now()}`;
// Cleanup existing stream
if (hlsRef.current) { if (hlsRef.current) {
hlsRef.current.destroy(); hlsRef.current.destroy();
hlsRef.current = null; hlsRef.current = null;
} }
if (audioRef.current.canPlayType("application/vnd.apple.mpegurl")) { const audio = audioRef.current;
// Native HLS support (Safari) if (!audio) return;
audioRef.current.src = streamUrl;
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()) { } else if (Hls.isSupported()) {
const hls = new Hls({ 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) => { hls.loadSource(streamUrl);
console.error("Playback failed:", e); 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 = () => { const togglePlayback = () => {
if (!audioRef.current) return; const audio = audioRef.current;
if (!audio) return;
if (isPlaying) { if (isPlaying) {
audioRef.current.pause(); audio.pause();
setIsPlaying(false); setIsPlaying(false);
} else { } else {
audioRef.current.play().then(() => setIsPlaying(true)); audio.play().then(() => setIsPlaying(true)).catch(console.error);
} }
}; };
useEffect(() => { useEffect(() => {
if (audioRef.current) { const audio = audioRef.current;
audioRef.current.pause(); if (audio) {
audioRef.current.src = ""; audio.pause();
audio.src = "";
setIsPlaying(false); setIsPlaying(false);
} }
@@ -101,6 +120,7 @@ export function Player() {
return () => { return () => {
if (hlsRef.current) { if (hlsRef.current) {
hlsRef.current.destroy(); hlsRef.current.destroy();
hlsRef.current = null;
} }
}; };
}, [activeStation]); }, [activeStation]);
@@ -196,9 +216,7 @@ export function Player() {
<div className="c-containter"> <div className="c-containter">
<div className="music-container mt-8"> <div className="music-container mt-8">
<section className="album-cover"> <section className="album-cover">
<div className="music-player__album" title="Album"> <div className="music-player__album" title="Album">{trackAlbum}</div>
{trackAlbum}
</div>
<img <img
src={coverArt} src={coverArt}
className="cover" className="cover"
@@ -215,7 +233,7 @@ export function Player() {
<div className="music-time"> <div className="music-time">
<p className="music-time__current">{formatTime(elapsed)}</p> <p className="music-time__current">{formatTime(elapsed)}</p>
<p className="music-time__last">{formatTime(duration - elapsed)}</p> <p className="music-time__last">{formatTime(remaining)}</p>
</div> </div>
<div className="w-full h-2 rounded bg-neutral-300 dark:bg-neutral-700 overflow-hidden"> <div className="w-full h-2 rounded bg-neutral-300 dark:bg-neutral-700 overflow-hidden">
@@ -228,7 +246,6 @@ export function Player() {
<div className="music-control"> <div className="music-control">
<div <div
className="music-control__play" className="music-control__play"
id="play"
onClick={togglePlayback} onClick={togglePlayback}
role="button" role="button"
tabIndex={0} tabIndex={0}