Web Audio API和播放音频文件时的实际当前时间

时间:2015-10-08 04:27:56

标签: javascript html5 web-audio

当我想知道使用Web Audio API播放文件的当前时间时,我遇到了问题。我的代码很好地播放文件,getCurrentTime()函数返回的当前时间对于加载速度快的短文件来说足够准确。

但是当我尝试加载大文件时,有时source.start()函数返回的当前时间是准确的,有时则不然。有时,等待20秒后听到文件播放,当它开始播放时,它表示当前时间约为20秒(这不是真的,因为它只是播放文件的开头)。它适用于任何音频格式(OGG,MP3,WAV ......),但有时只是。

我正在使用一个慢速系统(华硕EEE PC 901,Intel Atom 1.60 Ghz,2 GB RAM,Windows XP Home Edition和SP3)和Firefox 41.0.1。

我不确定,但似乎startTime方法开始播放声音太晚了,所以调用该方法之后的行,我设置var context, buffer, startTime, source; var stopped = true; function load(file, startAt) { //Here creates the AudioContext and loads the file through XHR (AJAX) and gets the buffer. All works fine. //When it gots the buffer through XHR (AJAX) and all is fine, it calls play(startAt) function immediately. //Note: normally, startAt is 0. } function play(startAt) { source = context.createBufferSource(); //Context created before. source.buffer = buffer; //Buffer got before from XHR (AJAX). //Creates a gain node to be able to set the volume later: var gainNode = context.createGain(); source.connect(gainNode); gainNode.connect(context.destination); //Plays the sound: source.loop = false; source.start(startAt, 0, buffer.duration - 3); //I don't want the last 3 seconds. //Stores the start time (useful for pause/resume): startTime = context.currentTime - startAt; //Here I store the startTime but maybe the file has still not begun to play (should it be just startTime = context.currentTime?). stopped = false; } function stop() { source.stop(0); stopped = true; } function getCurrentTime() { return (stopped) ? 0 : context.currentTime - startTime; } 变量的值,是不是真正的开始时间。

这是代码(简化):

source.start()

如何检测startTime方法何时开始播放文件?所以我可以在那一刻设置int main(int argc, char * argv[]变量值,而不是之前。

非常感谢您提前。我真的很感激任何帮助。

2 个答案:

答案 0 :(得分:2)

来自MDN(https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start),关于start()函数的第一个参数:

  

when(可选)

     

声音应开始播放的时间(以秒为单位),与AudioContext使用的时间坐标系相同。 如果小于(AudioContext.currentTime,或者如果它为0,则声音立即开始播放。默认值为0.。

您的代码没有明显的问题(虽然没有调用play()的示例):如果您致电play(0)play(context.currentTime + someDelayInSeconds)start()应该表现为预期。不幸的是,问题是AudioBufferSource不适用于大文件。再次来自AudioBuffer的MDN文档(https://developer.mozilla.org/en-US/docs/Web/API/AudioBuffer):

  

这些类型的对象旨在保存小型音频片段,通常小于45秒。

我怀疑,对于“声音立即开始播放”的假设(我也经历过它,虽然20秒似乎太过分了......)。遗憾的是,无法在WebAudio中获得AudioBufferSource的确切开始时间。

如果您没有任何真正的理由使用AudioBufferSource加载此大文件,我建议您使用 MediaElementSourceNode https://developer.mozilla.org/en-US/docs/Web/API/MediaElementAudioSourceNode):正如您在示例中所看到的那样链接文档,它允许您将简单的HTML5 Audio元素插入AudioContext。然后,您可以对元素本身进行所有常规控制,即您还可以访问audioElement.currentTime属性,该属性会告诉您当前的播出时间(在本例中是文件本身,这是您需要的)。此外,您不必处理内存中的文件加载,并且可以在某些数据可用时立即开始播放。

答案 1 :(得分:1)

context.currentTime == 20开始计算你创建上下文对象的第二个。这意味着如果加载音频需要20秒,var context; //Create your context here var audioLoadStart = new Date(); //Do audio load var audioLoadOffset = (new Date() - audioLoadStart) / 1000; currentTime = context.currentTime - audioLoadOffset - startTime;

要考虑此延迟,您可以设置一个简单的计时器,从创建上下文的时间到音频加载完成的时间。

friend