You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 6da782d
Browse filesBrowse the repository at this point in the historyBrowse files
Abort a blocked play()'s downloads; unload fixes (5.0.0-alpha.2) (#32)
* Unload tracks that leave the preload window
Moving a track out of the window now aborts its download, drops a decode
in progress and releases its decoded buffer, instead of only cancelling
an unfinished fetch. Late fetch/decode results from an unloaded load are
ignored.
* Bump to 5.0.0-alpha.1
* Abort a blocked play()'s downloads
When the browser refused HTML5 play() (autoplay policy, NotAllowedError),
gapless reported onPlayBlocked and the queue paused, but the track stayed
in the html5 state with both downloads running: the Web Audio HEAD and
GET started alongside play(), and the element, switched to preload=auto,
kept buffering. Nothing cancelled them; unload() refuses the current
track, and the element is internal. A page whose autoplay was blocked
downloaded the whole first track anyway.
A blocked play() now sends PLAY_BLOCKED to the track before onPlayBlocked
runs. From html5 it returns to idle, as if play() had never been called:
isPlaying cleared, progress loop stopped, the element released (source
dropped and reattached with preload=none, which aborts its fetch without
an error event), and a Web Audio load still in flight aborted, with any
decode that finishes later dropped (the same bookkeeping as unload()).
The seek target is kept, so the next play() resumes where it would have.
The next play() starts both loads fresh.
The queue's existing PAUSE then reaches an idle track, which ignores it,
so the app sees a stopped queue inside its onPlayBlocked callback.
* Bump to 5.0.0-alpha.2
* Report HTML5 again when an unloaded track replays
Nothing set playbackType back to HTML5. Before tracks could be unloaded
that didn't matter: a track that had played on Web Audio kept its
buffer, so it replayed on Web Audio. Now unload() can release that
buffer, and replaying the track goes through HTML5 with playbackType
still WEBAUDIO, which the queue reads in two places:
- _preloadAhead's bandwidth guard (defer preloading while the current
track is on HTML5 and still loading) didn't apply, so the next track
downloaded alongside the current track's fresh fetch, delaying its
crossover;
- _cancelScheduledGapless skipped cancelling the HTML5 gain mute.
The html5 state now sets playbackType to HTML5 on entry: it's HTML5
playback by definition, and both transitions into it get it.
Reported by Codex review on #32.
* Release a finished source node when unloading its track
unload() nulled audioBuffer, but a track that ended naturally on Web
Audio still held its source node: WEBAUDIO_ENDED goes to idle without
stopping it, and DEACTIVATE in idle doesn't either. The node's buffer is
the decoded audio, so in ordinary sequential playback every finished
track kept its decoded audio (hundreds of MB for a long track) after the
queue unloaded it for leaving the preload window.
unload() now also releases the source node through _stopSourceNode()
(onended cleared, disconnected, dropped). unload() never runs on a
playing or scheduled track, so the node it finds is a finished one.
Reported by Codex review on #32.
0 commit comments