From 0d16ea28a84e9c67949ab31928c933403ef95f97 Mon Sep 17 00:00:00 2001 From: Julien Maille Date: Sat, 21 Feb 2026 01:12:54 +0100 Subject: [PATCH] Avoid skipping tracks when autoplay is blocked --- js/player.js | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/js/player.js b/js/player.js index a094d17..8056a50 100644 --- a/js/player.js +++ b/js/player.js @@ -36,6 +36,7 @@ export class Player { this.currentRgValues = null; this.userVolume = parseFloat(localStorage.getItem('volume') || '0.7'); this.isFallbackRetry = false; + this.autoplayBlocked = false; // Sleep timer properties this.sleepTimer = null; @@ -69,6 +70,10 @@ export class Player { } audioContextManager.resume(); } + if (document.visibilityState === 'visible' && this.autoplayBlocked) { + this.autoplayBlocked = false; + this.audio.play().catch(() => {}); + } }); } @@ -459,7 +464,8 @@ export class Player { if (startTime > 0) { this.audio.currentTime = startTime; } - await this.audio.play(); + const played = await this.safePlay(); + if (!played) return; } else if (track.isLocal && track.file) { if (this.dashInitialized) { this.dashPlayer.reset(); // Ensure dash is off @@ -498,7 +504,8 @@ export class Player { if (startTime > 0) { this.audio.currentTime = startTime; } - await this.audio.play(); + const played = await this.safePlay(); + if (!played) return; } else { const isQobuz = String(track.id).startsWith('q:'); @@ -585,12 +592,17 @@ export class Player { if (startTime > 0) { this.audio.currentTime = startTime; } - await this.audio.play(); + const played = await this.safePlay(); + if (!played) return; } } this.preloadNextTracks(); } catch (error) { + if (error && (error.name === 'NotAllowedError' || error.name === 'AbortError')) { + this.autoplayBlocked = true; + return; + } console.error(`Could not play track: ${trackTitle}`, error); // Skip to next track on unexpected error if (recursiveCount < currentQueue.length) { @@ -684,7 +696,7 @@ export class Player { } if (this.audio.paused) { - this.audio.play().catch((e) => { + this.safePlay().catch((e) => { if (e.name === 'NotAllowedError' || e.name === 'AbortError') return; console.error('Play failed, reloading track:', e); if (this.currentTrack) { @@ -964,6 +976,20 @@ export class Player { } } + async safePlay() { + try { + await this.audio.play(); + this.autoplayBlocked = false; + return true; + } catch (error) { + if (error && (error.name === 'NotAllowedError' || error.name === 'AbortError')) { + this.autoplayBlocked = true; + return false; + } + throw error; + } + } + // Sleep Timer Methods setSleepTimer(minutes) { this.clearSleepTimer(); // Clear any existing timer