我需要抓住HTML5音频开始产生声音的确切时刻。
事实证明并非如此简单。
您可能希望在onplay
或onplaying
事件被触发时播放音频?没门。至少在WebKit系列中,似乎没有浏览器事件在这个时间点完全触发。在Chrome中,Safari和Firefox onplay
和onplaying
事件只是通过与oncanplay
一起解雇来伪装他们的行为!
我准备了一个简单的测试来证明这个事实。它表明,当所有事件都已被触发后,音频实际上会在一段合理的时间(超过100毫秒 - 400毫秒)后开始播放。
如果您查看控制台日志,您可以通过耳朵和耳朵注意到这一点。在日志中,我每15ms输出currentTime
。它似乎正确地反映了实际的音频状态,并且在任何事件被触发后它开始改变10-40个民意调查。因此,在play
被触发后,音频仍然会被冻结。
测试代码如下所示:
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);
我非常需要知道音频开始播放的确切时刻,以便与视觉动画进行精确同步。
当然,我可以粗略地使用快速轮询找到这个时刻。这对于实时应用程序的性能非常不利,特别是在移动设备上。
我在问是否有人知道更好的解决方案。 2014年HTML音频实现看起来仍然很差:(
答案 0 :(得分:3)
正如@justin所说,你可以听取playing
事件,以获得媒体开始实际播放的(或多或少)精确时刻。但是,我一直看到对媒体事件的一些支持,readyState
一般even in latest Chrome。
无论这些事件是否有效,我建议不要将setInterval
用于动画(或者就其他任何事情而言)。相反,使用requestAnimationFrame
,它会更频繁地触发,并且应该与浏览器和视频卡的重绘同步。并且您可以在每个帧上轮询currentTime
值以计算您应该在动画中的位置。表现应该不是问题;您的案例完全 requestAnimationFrame
的设计目的。
function update() {
var currentTime = audioEl.currentTime;
// update your animation here
requestAnimationFrame(update);
}
update();
当您遇到此问题时,请勿在{{1}}或currentTime
事件触发后将readyState > 0
设置为5。如果您尝试在浏览器加载足够的视频文件之前设置loadedmetadata
以了解持续时间,则会引发错误。但是你可以随时打电话给currentTime
;它不必等待play()
。
答案 1 :(得分:-1)
尝试使用canplaythrough。可能会有所帮助,最好还是确保你的音频可以一路走到尽头......
audioEl.oncanplay = function () {
console.log('ready state is: ' + audioEl.readyState);
audioEl.play();
}