Files
bookhoard/web/src
John O'Keefe 79ce5ab89d feat(web): multi-track audiobook player — per-track src switching, global-seconds position
The audio reader pointed <audio src> at ONE file — correct for m4b but
impossible for folder-of-tracks and zip books (the element holds a
single source). The player now generalizes to a track list built from
the /chapters manifest: single-file books are exactly one track whose
url is the whole file (zero behavior change — same element, same URL
flow), multi-file books swap src at track boundaries.

Mapping helpers (exported, unit-testable): trackIndexFor resolves a
global position to the owning track, localOffsetFor/globalSecondsFor
convert between global seconds — the coordinate system of chapters,
bookmarks and audio_offset_seconds — and (track, local offset). Every
consumer keeps global semantics: scrubber, skip ±N, bookmark saves,
?loc=audio: deep links and progress pushes are byte-identical payloads
server-side; the server contract does not move.

Mechanics: setActiveTrack swaps src and queues the position for
loadedmetadata (setting currentTime before the new metadata loads
resets it); ended advances to the next track and keeps playing;
timeupdate reports globalPosition(); playbackRate/volume re-apply
after swaps; src is deferred until the manifest loads (data-file-url
is a directory/zip root for multi-file books, not playable) with the
catch branch falling back to it for offline single-file starts.
2026-10-19 07:54:45 -04:00
..