I need to catch the exact moment when HTML5 audio starts producing sound.
It turns out not so simple as it seems.
You might expect audio starts playing when onplay
or onplaying
event is fired? No way. At least in WebKit family, it seems to be no browser event that fires exactly at this point of time. In Chrome, Safari and Firefox onplay
and onplaying
events are just faking their behaviour by simply firing together with oncanplay
!
I've prepared a simple test to prove that fact. It demonstrates that audio actually starts playing after some reasonable time (over 100ms - 400ms) when all the events had already been fired.
You can notice this by your ears and ears if you look at console log. In the log I output currentTime
every 15ms. It seems to reflect the actual audio state correctly, and it starts changing 10-40 polls after any event has been fired. So the audio is still freezed after play
is fired.
Test code looks like this:
var audioEl = new Audio('http://www.w3schools.com/tags/horse.ogg');
audioEl.oncanplay = function () {
console.log('oncanplay');
audioEl.currentTime = 1;
console.log('ready state is: ' + audioEl.readyState);
audioEl.play();
}
audioEl.oncanplay = function () {
console.log('oncanplay again');
}
audioEl.onplay = function() {
console.log('onplay -----------------');
}
audioEl.onplaying = function() {
console.log('onplaying ----------------');
}
setInterval(function () {
console.log(audioEl.currentTime);
}, 15);
JsFiddle
I critically need to know the exact moment when the audio starts playing for precise synchronisation with visual animations.
Of course, I can find this moment roughly using quick polling. This is very bad for performance in real-time app, especially on mobile.
I'm asking if anyone knows any better solution for this. HTML audio implementation looks to be still so poor in 2014 :(