From db7a515ee4c74fd6645f2ccc3344bfac6dbeb780 Mon Sep 17 00:00:00 2001 From: Honey Date: Thu, 4 Jun 2026 11:13:45 +0200 Subject: [PATCH] fix: stop ExoPlayer shuffle conflict causing end-of-queue desync When reaching the last shuffled song, the UI changed but audio kept playing the same song. Root cause: ExoPlayer still had its own shuffle mode on (set in onReady), so its auto-advance and _nsBridge('next') picked random indices that conflicted with the pre-shuffled JS array. - setShuffleMode always false: we own the playback order via pre-shuffled JS array, ExoPlayer must advance sequentially through it - Remove _nsBridge('next') fallback: never let ExoPlayer decide the next song autonomously. End of queue with no repeat = let ExoPlayer stop. Co-Authored-By: Claude Sonnet 4.6 --- src/player.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/player.js b/src/player.js index ee06f71..0b19a69 100644 --- a/src/player.js +++ b/src/player.js @@ -130,8 +130,10 @@ window.NSPlayer = { } catch (e) {} } // Always sync shuffle/repeat settings. + // setShuffleMode is always false — we pre-shuffle the JS array ourselves and + // traverse sequentially, so ExoPlayer's internal shuffle must stay off. _nsBridge('setRepeatMode', S.repeat === false ? 'off' : S.repeat); - _nsBridge('setShuffleMode', S.shuffle); + _nsBridge('setShuffleMode', false); }, // Play/pause/buffer state changed. @@ -714,10 +716,7 @@ export function nextSong() { // Explicit index prevents desync when JS and native queue pointers diverge. _nsBridge('seekToIndex', ni, 0); _nsBridge('play'); - } else { - // Shuffle mode: native picks the shuffled-next item; onTrackChanged will confirm the index. - _nsBridge('next'); - } + // else: ni = -1 means end of queue with no repeat — let ExoPlayer stop naturally. if (S.radioMode && S.queue.length - S.qIdx < 5) fillRadioQueue(); return; }