Is there an event I can listen for, a value I can inspect, or a set of things I can combine, to know when the media has finished loading?
Some background:
My web-based music player plays audio using an html5 Audio
object. I would like to pre-load the next track (into a different, hidden Audio
object) before the first has finished playing, but after the first track has finished loading.
I want to do this because the backend, which serves the media, has to transcode on the fly and this is slow to start, causing a multi-second gap between tracks. The backend is also slow to transcode so ideally we don't want multiple songs transcoding simultaneously -- it's not ok to start the transcode of track 2 immediately after we start loading track 1.
This question is perhaps similar (if a bit unclear what is being asked) but none of the answers work for my use case.
What I've tried:
Listen for
canplaythrough
event. This happens as soon as it's predicted that the song can play all the way through, but if we then start the second song transcoding and uploading, it slows the progress of the first one, the prediction fails and playback stalls.Check periodically for the player's
networkState
. This goes toNETWORK_IDLE
when the song has finished loading, but it also happens long before this if there is network latency or if the player builds up enough of a buffer etc. In testing I found it to happen often within the first few seconds of playing the first song -- much too early for my purpose.Listen for
dataloaded
event -- but this means it has loaded some data, not all of it.Check the player's
duration
, hoping that this might only be set when the song had loaded. It's not, it's set long before on Firefox (and updates as more data is loaded), and apparently never(!) on Chrome.Check the player's
readyState
. This gives essentially the same information ascanplay
andcanplaythrough
.
My current almost-good-enough solution:
I listen for "suspend" events. In the handler, I check whether the audio has started playing (currentTime > 0
) and, if so, assume it's a good time to start pre-loading the next track. I haven't tested it all that much but it seems like it might work. Still interested in a better solution!