fix HLS streaming quality
This commit is contained in:
@@ -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() {
|
||||
<div className="c-containter">
|
||||
<div className="music-container mt-8">
|
||||
<section className="album-cover">
|
||||
<div className="music-player__album" title="Album">
|
||||
{trackAlbum}
|
||||
</div>
|
||||
<div className="music-player__album" title="Album">{trackAlbum}</div>
|
||||
<img
|
||||
src={coverArt}
|
||||
className="cover"
|
||||
@@ -215,7 +233,7 @@ export function Player() {
|
||||
|
||||
<div className="music-time">
|
||||
<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 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__play"
|
||||
id="play"
|
||||
onClick={togglePlayback}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
|
Reference in New Issue
Block a user