防止多个 AudioContexts

Ada*_*ale 3 html javascript web-audio-api

我遵循了一种使用 Webaudio 将声音附加到对象的模式。它运行良好,但是如果我在页面上生成多个项目并附加此脚本,我会得到一个 console.log,表明我已经超过了每页可用的最大音频上下文数。

我的理解是该行声明了audioContext附加到窗口的 AudioContext,而不是声明一个新的。我如何询问窗口是否已经有一个 AudioContext 并简单地将音频节点添加到它的图形中?

var that = this
  , audioContext = window.AudioContext || window.webkitAudioContext;

if (!audioContext) {
  console.warn("Web Audio API not supported in this browser.");
  return;
}

this.context = new audioContext();
Run Code Online (Sandbox Code Playgroud)

Kev*_*nis 7

我不完全确定我理解你的问题。是否有理由不能只在脚本顶部创建单个音频上下文,然后让其余代码引用它?

无论如何,为了提供答案,您可以执行以下操作:

var getContext = function() {
  var ac = null;
  if ( !window.AudioContext && !window.webkitAudioContext ) {
    console.warn('Web Audio API not supported in this browser');
  } else {
    ac = new ( window.AudioContext || window.webkitAudioContext )();
  }
  return function() {
    return ac;
  };
}();
Run Code Online (Sandbox Code Playgroud)

然后,每次需要上下文时,只需调用此函数:

var ctx = getContext(),
  osc = ctx.createOscillator();
osc.connect(ctx.destination);
Run Code Online (Sandbox Code Playgroud)

  • 基本思想是它使用了一个闭包。本质上,外部函数会立即执行(注意最后的括号?那些调用它的)并为您创建音频上下文。它还返回一个新函数,它只返回音频上下文。所以,你基本上是在说“`getContext` 等于调用这个外部函数的结果”。由于外部函数的返回值是另一个函数,这就是你得到的。闭包一开始可能有点难以让你理解(它们是为我准备的)——但是谷歌搜索应该会让你走上正轨。 (4认同)