【问题标题】:JS Audio API - Oscillator inside function doesn't play soundJS Audio API - 函数内部的振荡器不播放声音
【发布时间】:2018-05-04 20:46:51
【问题描述】:

使用 Opera 44.0,我正在摆弄音频 API 并尝试了一个简单的示例:

var ac = new AudioContext();
var osc = ac.createOscillator();

osc.connect(ac.destination);
osc.start();
osc.stop(2);

按预期工作,声音播放 2 秒然后停止。

然后我试着往上一点,在点击按钮时播放声音:

function play(){
  var osc = ac.createOscillator();
  osc.connect(ac.destination);
  osc.start();
  osc.stop(2);
}

var ac = new AudioContext();

var playBtn = document.querySelector("#play");
playBtn.addEventListener("click", play);

它不起作用。当我单击按钮时调用该函数(我在函数内部使用console.log() 检查),但没有播放声音。我尝试刷新页面,重新启动浏览器.. 没有。

经过一番研究,我发现在调用stop() 时振荡器被丢弃,所以我每次都必须创建一个新的振荡器。我发现的几乎所有示例都围绕着这个概念,这就是我在函数内部创建它的原因。但是没有任何错误,我无法弄清楚为什么它不起作用。

那么,问题出在哪里?

【问题讨论】:

    标签: javascript web-audio-api


    【解决方案1】:

    挖掘documentation,我设法解决了这个问题。

    最初,我假设传递给osc.stop(2) 的参数是以秒为单位的播放时间,类似于“播放 2 秒,然后停止”。 但这是不正确的:参数是“...振荡器应该停止的音频上下文时间”。

    通过在play() 函数中记录ac.currentTime,当我单击按钮时返回的值约为5。所以,发生的事情是通过将 2 传递给 osc.stop() 我告诉 osc 在上下文时间为 2 时停止,这已经过去了!

    解决方法很简单:

    function play(){
      var osc = ac.createOscillator();
      osc.connect(ac.destination);
      osc.start();
      //take into account the current time of the context
      osc.stop(ac.currentTime + 2);
    }
    

    智慧之言现在回荡在我的脑海中... R....T....F...M...

    【讨论】:

      猜你喜欢
      • 2021-03-29
      • 2019-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-14
      • 1970-01-01
      相关资源
      最近更新 更多