experiment(web): drop separate preload <audio> element (single-element like Navidrome)

Navidrome's player (react-jinke fork) uses one persistent <audio> element and
does not flicker the OS media tile, so the source-swap itself isn't the cause.
Our one structural difference was a second buffering <audio> (_preAudio) for
preload. A second media element seems to make Chromium hand the OS media
session over on skip → Windows tile flicker. This drops it; we rely on the main
element's preload="auto" + browser HTTP cache. Cover art is still prewarmed.

Trade-off: next-track start may be marginally slower. Easy to revert if it
doesn't fix the flicker.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Opus 4.8 committed 2026-06-26 18:01:38 +02:00
1 parent bed007258a
commit f252586398
1 file changed
+5 -8
+5 -8
View File
@@ -293,14 +293,11 @@ function _preloadNext() {
const ni = _nextIdx();
if(ni < 0) return;
const next = S.queue[ni];
if(!next || _preId === next.id) return;
_preId = next.id;
_preUrl = streamUrl(next.id);
// Real Audio preload — actually buffers the stream so canplay fires instantly
if(_preAudio) { _preAudio.src = ''; _preAudio = null; }
_preAudio = new Audio();
_preAudio.preload = 'auto';
_preAudio.src = _preUrl;
if(!next) return;
// (b) EXPERIMENT — no separate preload <audio> element. Navidrome's player keeps a single
// element only; a second buffering media element appears to make Chromium flip the OS media
// session on skip (Windows tile flicker). We rely on the main element's preload="auto" + the
// browser HTTP cache instead, and just warm the next cover art. Easy to revert if it doesn't help.
if(next.coverArt) {
[256, 512, 1024].forEach(size => {
const img = new Image();