listen together, in tune.
A playback-robustness release — background listening on iOS is now solid.
Fixed
- Background auto-advance rebuilt — track advancement and prefetch now live in a plain module cursor (
window.__lsAdv), mutated synchronously inside theendedhandler. React state is frozen in a backgrounded iOS tab, so the old React-driven advance died after one hop. - The real culprit of silent background playback:
preload='auto'— the audio element eagerly downloaded the whole file the momentsrcwas set, and iOS cuts that network off in the background. Nowpreload='none': the address is set instantly, bytes load onplay(), which iOS allows. - "Advances but pauses" — a track finishing naturally fires a
pauseevent that used to knock the just-advanced next track back into pause. Now guarded (internal-load window +endedcheck). - Personal FM keeps flowing — the module cursor stays in sync when FM batches extend the queue, and switching from FM to a playlist properly escapes the FM queue kind.
- Updates actually reach installed PWAs —
index.htmland the web manifest are served withno-cache.
Upgrade: git pull and restart the service — no schema or config changes.