Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/442.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 播放音频文件时的Web音频API和实时当前时间_Javascript_Html_Web Audio Api - Fatal编程技术网

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

Javascript 播放音频文件时的Web音频API和实时当前时间,javascript,html,web-audio-api,Javascript,Html,Web Audio Api,当我想知道使用Web音频API播放文件的当前时间时,我遇到了问题。我的代码很好地播放了文件,并且当短文件加载速度很快时,getCurrentTime()函数返回的当前时间足够准确 但是当我尝试加载大文件时,有时getCurrentTime()函数返回的当前时间是准确的,有时则不准确。有时,在等待(例如)20秒以听到文件播放后,当它开始播放时,它会说当前时间约为20秒(这不是真的,因为它只是播放文件的开头)。任何音频格式(OGG、MP3、WAV…)都会发生这种情况,但有时也会发生 我使用的是速度较

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

但是当我尝试加载大文件时,有时
getCurrentTime()
函数返回的当前时间是准确的,有时则不准确。有时,在等待(例如)20秒以听到文件播放后,当它开始播放时,它会说当前时间约为20秒(这不是真的,因为它只是播放文件的开头)。任何音频格式(OGG、MP3、WAV…)都会发生这种情况,但有时也会发生

我使用的是速度较慢的系统(Asus EEE PC 901,采用Intel Atom 1.60 Ghz,2 GB RAM,采用Windows XP Home Edition和SP3)和Firefox 41.0.1

我不确定,但似乎
source.start()
方法开始播放声音的时间太晚了,因此调用该方法后的行(我在其中设置
startTime
变量的值)不是真正的开始时间

以下是代码(简化):

var上下文、缓冲区、开始时间、源;
var=true;
函数加载(文件,startAt)
{
//这里创建AudioContext,通过XHR(AJAX)加载文件并获取缓冲区,一切正常。
//当它通过XHR(AJAX)获取缓冲区并且一切正常时,它立即调用play(startAt)函数。
//注:正常情况下,startAt为0。
}
功能播放(startAt)
{
source=context.createBufferSource();//以前创建的上下文。
source.buffer=buffer;//以前从XHR(AJAX)获得的缓冲区。
//创建一个增益节点,以便以后能够设置卷:
var gainNode=context.createGain();
source.connect(gainNode);
连接(context.destination);
//播放声音:
source.loop=false;
source.start(startAt,0,buffer.duration-3);//我不想要最后3秒。
//存储开始时间(对暂停/恢复有用):
startTime=context.currentTime-startAt;//在这里我存储了startTime,但可能文件还没有开始播放(应该是startTime=context.currentTime吗?)。
停止=错误;
}
函数停止()
{
源。停止(0);
停止=真;
}
函数getCurrentTime()
{
返回(已停止)?0:context.currentTime-startTime;
}
如何准确地检测
source.start()
方法何时开始播放文件?因此,我可以在那一刻设置
startTime
变量值,而不是在此之前


事先非常感谢。非常感谢您的帮助。

context.currentTime
从您创建context对象的那一秒开始计算。这意味着如果加载音频需要20秒,
context.currentTime==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;
从MDN(),关于
start()
函数的第一个参数:

(可选)

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

您的代码没有明显的问题(尽管没有调用
play()
):如果调用
play(0)
play(context.currentTime+someDelayInSeconds)
start()
应按预期运行。不幸的是,这里的问题是AudioBufferSource不适用于大文件。同样来自AudioBuffer()的MDN文档:

这些类型的对象设计用于保存小的音频片段,通常小于45秒

我怀疑对于大事件来说,“声音立即开始播放”的假设并不适用(我也经历过,虽然20秒似乎太多了…)。不幸的是,目前还没有办法在WebAudio中获得AudioBufferSource的确切开始时间


如果您没有任何真正的理由用AudioBufferSource加载这个大文件,我建议您使用MediaElementSourceNode():从链接文档的示例中可以看到,它允许您将一个简单的HTML5
Audio
元素插入AudioContext。然后您可以对元素本身进行所有常规控制,即您还可以访问
audioElement.currentTime
属性,该属性告诉您当前播放时间(在本例中是文件本身,这是您所需要的)。此外,您不必在内存中处理文件的加载,只要有可用的数据,就可以开始播放。

非常感谢您的回复。但在我的代码中,我观察到以下几点:我调用load()函数(它创建AudioConNext)加载文件后,我等待5分钟调用play方法。根据您所说的,现在的当前时间应该是5分钟或更长。但播放开始时显示的当前时间是零,这是正确的,这正是我想要的。如果AudioContext创建时间超过5分钟,为什么会发生这种情况?抱歉,我不能编辑我上面的评论。请注意,每次我调用play方法时,我都会计算startTime,因为我已经考虑了当前执行“startTime=context.currentTime-startAt;”的时间。