Avoid skipping tracks when autoplay is blocked

This commit is contained in:
Julien Maille 2026-02-21 01:12:54 +01:00
parent d84b30bc84
commit 0d16ea28a8

View file

@ -36,6 +36,7 @@ export class Player {
this.currentRgValues = null; this.currentRgValues = null;
this.userVolume = parseFloat(localStorage.getItem('volume') || '0.7'); this.userVolume = parseFloat(localStorage.getItem('volume') || '0.7');
this.isFallbackRetry = false; this.isFallbackRetry = false;
this.autoplayBlocked = false;
// Sleep timer properties // Sleep timer properties
this.sleepTimer = null; this.sleepTimer = null;
@ -69,6 +70,10 @@ export class Player {
} }
audioContextManager.resume(); 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) { if (startTime > 0) {
this.audio.currentTime = startTime; this.audio.currentTime = startTime;
} }
await this.audio.play(); const played = await this.safePlay();
if (!played) return;
} else if (track.isLocal && track.file) { } else if (track.isLocal && track.file) {
if (this.dashInitialized) { if (this.dashInitialized) {
this.dashPlayer.reset(); // Ensure dash is off this.dashPlayer.reset(); // Ensure dash is off
@ -498,7 +504,8 @@ export class Player {
if (startTime > 0) { if (startTime > 0) {
this.audio.currentTime = startTime; this.audio.currentTime = startTime;
} }
await this.audio.play(); const played = await this.safePlay();
if (!played) return;
} else { } else {
const isQobuz = String(track.id).startsWith('q:'); const isQobuz = String(track.id).startsWith('q:');
@ -585,12 +592,17 @@ export class Player {
if (startTime > 0) { if (startTime > 0) {
this.audio.currentTime = startTime; this.audio.currentTime = startTime;
} }
await this.audio.play(); const played = await this.safePlay();
if (!played) return;
} }
} }
this.preloadNextTracks(); this.preloadNextTracks();
} catch (error) { } catch (error) {
if (error && (error.name === 'NotAllowedError' || error.name === 'AbortError')) {
this.autoplayBlocked = true;
return;
}
console.error(`Could not play track: ${trackTitle}`, error); console.error(`Could not play track: ${trackTitle}`, error);
// Skip to next track on unexpected error // Skip to next track on unexpected error
if (recursiveCount < currentQueue.length) { if (recursiveCount < currentQueue.length) {
@ -684,7 +696,7 @@ export class Player {
} }
if (this.audio.paused) { if (this.audio.paused) {
this.audio.play().catch((e) => { this.safePlay().catch((e) => {
if (e.name === 'NotAllowedError' || e.name === 'AbortError') return; if (e.name === 'NotAllowedError' || e.name === 'AbortError') return;
console.error('Play failed, reloading track:', e); console.error('Play failed, reloading track:', e);
if (this.currentTrack) { 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 // Sleep Timer Methods
setSleepTimer(minutes) { setSleepTimer(minutes) {
this.clearSleepTimer(); // Clear any existing timer this.clearSleepTimer(); // Clear any existing timer