goldfire / howler.js

Javascript audio library for the modern web.
https://howlerjs.com
MIT License
23.87k stars 2.23k forks source link

Playback of static audio files waits until whole file loaded, ignores ranges on Firefox 115 with html5 #1672

Open bikubi opened 1 year ago

bikubi commented 1 year ago

The Problem

Playback of audio files over http waits until the whole file is loaded. Until Firefox114 it would start as soon as there is enough data buffered ("canplay"). Especially noticeable/annoying when you have to wait a minute for a 100MB+ MP3 to fully download. Tested on Linux an macOS 13.4.

Reproducible Example

https://howlerjs.com/assets/howler.js/examples/player/

Reproduction Steps

Play the first example file. It might be not noticeable with a regular connection; I had to use a throttling proxy. Playback doesn't start immediately (or after seconds of buffering), but only after the whole file is loaded.

Possible Solution

Done some digging, but nothing substantial yet.

Context

No response

Howler.js Version

v2.2.3

Affected Browser(s)/Versiuon(s)

Firefox 115

bikubi commented 1 year ago

Hacky workaround:

if (isFirefox) { // it wouldn't break chrome, but I haven't tested exhaustively
  window.Howler._canPlayEvent = 'canplay' // fixes the "wait for file complete downloaded"
}
var sound = new Howl({
  src: 'foo.mp3',
  preload: 'metadata' // prevents loading/caching the full file in background
})

Tested on macOS 13.4 and Linux.

Weirdly related to #1495, although I wasn't affected by that...
(hat tip to Manuel, if you're reading this!)

A proper fix would probably address Firefox's (presumed) changed events:

wbob commented 1 year ago

to see where the changed FF114->F115 behaviour originates from I was looking at canplay / canplaythrough logic (canplaythrough is 3s+ of buffered frames from the current position) and checked the sources revisions.

There, the 'Rewrite TimeUnit.h' patchset is a candidate that introduced regressions (this one). A current FF117 nightly from 2023-07-23 has a change that fixes the behaviour. I haven't fully understood how ChannelMediaDecoder::ComputePlaybackRate alleviates it though (Edit: betting on the logic in DownloadProgressed()).

This isn't a howler.js issue, though workarounds help until the bugfix finds its release in the upcoming FF116 on August 1st.