如何准确地将<audio>播放与Web音频时间轴的开始同步

时间:2018-08-30 18:42:41

标签: javascript web-audio

我正在尝试做到这一点,以便当用户单击按钮时,会播放音频文件(通过<audio>),但是使用Web Audio的linearRampToValueAtTime方法会淡入。

整个过程从在上下文时间轴上设置增益值开始:

if (fadeIn) {
  console.log('0 gain at', currentTime);
  console.log('fade to 1 by', currentTime + fadeIn);
  this.trackGain.gain.setValueAtTime(0, currentTime);
  this.trackGain.gain.linearRampToValueAtTime(1, currentTime + fadeIn);
} else {
  this.trackGain.gain.setValueAtTime(1, currentTime);
}

然后完成:

await this.$refs.audio.play();
await this.audioCtx.resume();
// currentTime must be set after play starts, for Safari
this.$refs.audio.currentTime = this.trackList[0].startTime;

当我在Chrome中触发此过程时,数字看起来不错:

enter image description here

它们并不完美(轨道增益从0开始),但是足够接近。但是,在Safari中,音频开始播放之前的这种延迟要严重得多。上下文时间线有足够的时间开始播放音频元素之前的时间。

enter image description here

如您所见,上下文时间轴运行了一段时间,跟踪增益从0.31开始而不是0。

完整代码如下:https://codesandbox.io/s/ykjkoj3yvv

我可能在这里做错了吗?我是在做乱序的事情吗?我该怎么解决?

侧面说明:在Firefox中,trackGain.gain.value始终为1。好像是个错误。

1 个答案:

答案 0 :(得分:0)

我的猜测是,在await()节之后更新currentTime之前,Safari以某种方式进入了“ this.trackGain.gain.setValueAtTime(0,currentTime)”-因为存在与setLinearRampAtTime()一致的不连续跳转呼叫以过去的时间值触发。 setValue / setLinear调用看起来好像在t = 0.60和t = 0.62之间触发(尝试将console.log添加到set部分进行测试)。

这与数学是一致的-值与在t = 0时将其初始点设置为0,在t = 2时将其设置为value = 1的斜坡大致一致。