我想播放音乐(使用HTML5音频)并在特定时间显示一些图形元素(应与音频时序同步)。
使用JavaScript的window.setTimeout
函数可以做到吗?
setTimeout(function() {
requestAnimationFrame(function() {
// display something
});
}, 1400);
setTimeout(function() {
requestAnimationFrame(function() {
// display something else
});
}, 2300);
或者,有没有更好的方法来做到这一点?
答案 0 :(得分:3)
“足够准确”是主观的,但总的来说,没有。您不知道音频何时完成下载并开始播放,或者它是否会在没有缓冲或被用户暂停的情况下播放。
相反,您可以使用timeupdate
事件和currentTime
属性将事件正确地同步到时间轴。
var exampleElement = document.getElementById('example');
var lastTime = 0;
exampleElement.addEventListener('timeupdate', function(e) {
var nowTime = this.currentTime;
//Check if just passed the 1.4 second time mark.
if (nowTime > 1.4 && lastTime < 1.4) {
//Add a message to the debug element.
var logElement = document.getElementById('log');
logElement.textContent += 'Do something at 1.4 seconds\n';
}
lastTime = nowTime;
});
<audio id="example" controls="controls" autoplay="autoplay">
<source src="http://media.w3.org/2010/07/bunny/04-Death_Becomes_Fur.mp4" type='audio/mp4'>
<source src="http://media.w3.org/2010/07/bunny/04-Death_Becomes_Fur.oga" type='audio/ogg; codecs=vorbis'>
</audio>
<pre id="log"></pre><!--debug element-->
答案 1 :(得分:3)
setTimeout
通常只在给定的延迟后执行,并且当浏览器的线程清除时。
所以不,它并不完全准确,但我认为,为了您的目的,它将足够接近,通常不到0.2%的延迟,
的图片
但是,在速度较慢的用户计算机上,效果可能会更明显,并且使用setTimeout isn't recommended。
相反,您可以使用timeupdate
事件和currentTime
属性来更准确地匹配音频,
var audio = document.querySelector('audio#my-audio');
audio.addEventListener('timeupdate', function(){
switch (this.currentTime){
case 1:
//stuff
break;
/* etc. */
}
}
currentTime
使用秒数来计算,所以你必须使用不那么精确的节拍器,但准确性在那里。
答案 2 :(得分:0)
如果您能够在音频启动的同一实例中启动超时,那么它就足够准确了。例如,屏幕频率为60 Hz,直到下一帧有16 ms,所以它实际上并不准确。
根据您显示的内容,即使是几帧也可以接受。例如,考虑动画电影以12 Hz的速率更新(电影胶片以24 Hz运行,动画每隔一帧更新一次)。
但请注意,timout回调在与其他所有内容相同的线程上运行,因此只要您没有其他任何运行占用主线程的时间太长,它就会准确无误。例如,如果你有一些其他的事件处理程序做了一些繁重的工作,这可能会延迟超时足以显示。