Implement quality fallback on playback error (fix for Firefox blob/DASH issues)

This commit is contained in:
Julien Maille 2026-01-29 22:07:20 +01:00
parent 6ec7ecb5ea
commit 60d53cf87b
2 changed files with 46 additions and 1 deletions

View file

@ -113,10 +113,54 @@ export function initializePlayerEvents(player, audioPlayer, scrobbler, ui) {
player.updateMediaSessionPositionState();
});
audioPlayer.addEventListener('error', (e) => {
audioPlayer.addEventListener('error', async (e) => {
console.error('Audio playback error:', e);
playPauseBtn.innerHTML = SVG_PLAY;
const currentQuality = player.quality;
// Check if we can fallback to a lower quality
if (
player.currentTrack &&
currentQuality === 'HI_RES_LOSSLESS' &&
!player.currentTrack.isLocal &&
!player.currentTrack.isTracker &&
!player.isFallbackRetry
) {
console.warn('Playback failed, attempting fallback to LOSSLESS quality...');
player.isFallbackRetry = true; // Set flag to prevent infinite loops
try {
// Force getTrack to fetch new URL for LOSSLESS
const trackId = player.currentTrack.id;
// Fetch new stream URL
const newStreamUrl = await player.api.getStreamUrl(trackId, 'LOSSLESS');
if (newStreamUrl) {
// Reset player state for standard playback (non-DASH if possible)
if (player.dashInitialized) {
player.dashPlayer.reset();
player.dashInitialized = false;
}
audioPlayer.src = newStreamUrl;
audioPlayer.load();
await audioPlayer.play();
// Reset flag after successful start
setTimeout(() => {
player.isFallbackRetry = false;
}, 5000);
return; // Successfully handled
}
} catch (fallbackError) {
console.error('Fallback failed:', fallbackError);
}
}
player.isFallbackRetry = false;
// Skip to next track on error to prevent queue stalling
if (player.currentTrack) {
console.warn('Skipping to next track due to playback error');

View file

@ -26,6 +26,7 @@ export class Player {
this.currentTrack = null;
this.currentRgValues = null;
this.userVolume = parseFloat(localStorage.getItem('volume') || '0.7');
this.isFallbackRetry = false;
// Sleep timer properties
this.sleepTimer = null;