Changeset 421046c in Klonkt for CHANGELOG.md


Ignore:
Timestamp:
07/02/2026 01:21:34 PM (2 months ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
d039264
Parents:
a369029
Message:

fix(audio): gapless MSE playback - background auto-advance survives on Android

Root cause of "next track plays 1 second, then pauses and the media
notification closes" on backgrounded mobile Chrome/PWA: every track
change did pause() + audio.src=<new blob> + load() + play(), which the
browser treats as a NEW playback session - and Chrome's background media
policy pauses new sessions started in the background. Only a CONTINUING
session may keep playing.

The player now has two engines:

  • MSE chain (Chrome/Firefox/Android): one MediaSource + one 'audio/mpeg' SourceBuffer (every track is uniform transcoder mp3). The next track's bytes are appended into the same buffer, so the whole queue is one continuous playback session; auto-advance is just the timeline flowing past a segment boundary - no pause/src/load/play at all. Track chrome, per-track time display, seek, lock-screen position state and session save/restore all work in track coordinates via a segment table. Played data is pruned (~2 tracks buffered), ID3 tags are stripped between appends, QuotaExceeded evicts and retries.
  • Blob fallback (iOS Safari - no MSE; or runtime MSE failure): the previous per-track objectURL behaviour, now fed from shared byte fetches. An audio error while the MSE chain is active permanently falls back to blobs for the session and retries the same track.

Manual actions (play/next/prev/queue click/restore) start a fresh chain -
those happen in the foreground where a new session is allowed.

Verified in-browser (desktop Chrome, two 8s test tones): auto-advance
crosses the boundary with ZERO pause/play events (old engine: one pair
per track), per-track time display correct, manual next resets the
chain, in-track seek works, queue wrap-around is gapless, no console
errors.

  • src/assets/js/audio-player.js - the two-engine pipeline (fetchTrackBytes, MSE chain: chainStart/appendSegment/ensureNextAppended/pruneBuffer/ maybeCrossBoundary/displayTimes; applyBlobBytes fallback; updateTrackChrome extraction; MediaSession positionState)
  • src/views/shell.ejs - cache-buster v31 -> v32
  • CHANGELOG(.nl/.de).md - user-facing entry under Unreleased (3 languages)

Co-Authored-By: Claude <noreply@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • CHANGELOG.md

    ra369029 r421046c  
    55
    66## [Unreleased]
     7
     8### Fixed
     9- **Music keeps playing in the background on Android.** When a track ended while
     10  your phone was locked or the app was in the background, the next track would
     11  start and stop again after a second. The player now feeds the whole queue as
     12  one continuous stream, so auto-advancing to the next track no longer counts
     13  as "new" playback that the browser is allowed to pause.
    714
    815## [1.3.0] — 2026-07-02
Note: See TracChangeset for help on using the changeset viewer.