当我想知道使用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[]
变量值,而不是之前。
非常感谢您提前。我真的很感激任何帮助。
答案 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