setTimeout功能是否足够准确以与音频定时同步?

时间:2015-01-15 20:00:12

标签: javascript html5 settimeout html5-audio

我想播放音乐(使用HTML5音频)并在特定时间显示一些图形元素(应与音频时序同步)。

使用JavaScript的window.setTimeout函数可以做到吗?

setTimeout(function() {
    requestAnimationFrame(function() {
        // display something
    });
}, 1400);

setTimeout(function() {
    requestAnimationFrame(function() {
        // display something else
    });
}, 2300);

或者,有没有更好的方法来做到这一点?

3 个答案:

答案 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%的延迟,

delay

来自this question

的图片

但是,在速度较慢的用户计算机上,效果可能会更明显,并且使用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回调在与其他所有内容相同的线程上运行,因此只要您没有其他任何运行占用主线程的时间太长,它就会准确无误。例如,如果你有一些其他的事件处理程序做了一些繁重的工作,这可能会延迟超时足以显示。