m36 中的网络音频变化

Chris Wilson
Chris Wilson

Web Audio 变更

Google 非常重视标准。我们致力于构建标准定义的 Web 平台。一段时间以来,Web Audio API 的 webkit 前缀实现(尤其是 webkitAudioContext 对象)以及我们继续支持的 Web Audio 的某些已废弃部分,一直是 Web Audio 的一个小缺陷。

我们原本计划在 Chrome 36 中移除对带前缀的 webkitAudioContext 的支持,因为我们已开始支持不带前缀的 AudioContext 对象。事实证明,这比预期更麻烦,因此 Chrome 36 同时支持带前缀和不带前缀的 API。不过,即使在重新引入的 webkitAudioContext 中,也移除了 createGainNode 和 createJavaScriptNode 等一些旧版方法和属性。简而言之,在 Chrome 36 中,webkitAudioContext 和 AudioContext 是彼此的别名;这两个对象在功能上没有区别。

我们将在 Chrome 36 之后(可能在几个版本中)完全移除对此前缀的支持。当变更即将生效时,我们会在此处发布通知。我们会继续与作者联系,帮助他们修正 Web Audio 应用。

为什么我们要这样做,而不是恢复到之前的实现?原因之一是我们不愿过于向后兼容;我们已移除这些 API,而这种重名的附带好处是,应用可以在 Firefox 上正常运行,Firefox 在去年秋季首次发布的 Web Audio 支持中从未支持带前缀的 AudioContext 对象(这也是正确的做法!)。

本更新的其余部分提供了有关如何修复因这项变更而导致代码中可能出现的问题的指南。解决这些问题的好处在于,您的代码很可能也会在 Firefox 中正常运行!(我一直认为我的 Vocoder 应用因 Firefox 的实现而损坏,但事实证明是其中一个问题导致的!)

如果您只想快速上手,不妨查看猴子补丁 (我为使用旧版 Web Audio 代码编写的应用编写的库)。由于该库会适当地为对象和方法添加别名,因此有助于您在最短的时间内快速上手。事实上,库列出的补丁是了解发生了哪些变化的绝佳指南。

首先

window.webkitAudioContext 的任何引用都应改为对 window.AudioContext 的引用。通常,只需执行以下简单操作即可解决此问题:

window.AudioContext = window.AudioContext || window.webkitAudioContext;

如果您的应用响应的内容类似于“很抱歉,您的浏览器不支持 Web Audio。请使用 Chrome 或 Safari。”,则很可能在明确寻找 webkitAudioContext。开发者太差劲了!您可能已经支持 Firefox 数月了!

但我们还移除了一些更细微的代码,其中一些可能不太明显。

  • .type 属性(现在是字符串)的 BiquadFilter 枚举类型常量不再显示在 BiquadFilterNode 对象上,并且我们不支持在 .type 属性上使用这些常量。因此,您不再使用 .LOWPASS(或 0),而是将其设置为“lowpass”。
  • 此外,Oscillator.type 属性现在也同样是字符串枚举类型,不再是 .SAWTOOTH
  • PannerNode.type 现在也是一种字符串枚举类型。
  • PannerNode.distanceModel 现在也是一种字符串枚举类型。
  • createGainNode 已重命名为 createGain
  • createDelayNode 已重命名为 createDelay
  • createJavaScriptNode 已重命名为 createScriptProcessor
  • AudioBufferSourceNode.noteOn() 现已被 start() 所取代
  • AudioBufferSourceNode.noteGrainOn() 现已被 start() 所取代
  • 已将 AudioBufferSourceNode.noteOff() 重命名为 stop()
  • 已将 OscillatorNode.noteOn() 重命名为 start()
  • 已将 OscillatorNode.noteOff() 重命名为 stop()
  • 已将 AudioParam.setTargetValueAtTime() 重命名为 setTargetAtTime()
  • AudioContext.createWaveTable()OscillatorNode.setWaveTable() 现已重命名为 createPeriodicWave() andsetPeriodicWave()`。
  • 移除了 AudioBufferSourceNode.looping,取而代之的是 .loop
  • 用于同步解码已编码音频数据的 Blob 的 AudioContext.createBuffer(ArrayBuffer, boolean) 已被移除。同步调用需要很长时间才能完成,这是一种不良的编码做法;请改用异步 decodeAudioData 调用。这项更改比较具有挑战性,因为您需要实际更改逻辑流程,但这是一种更妥善的做法。Mozilla 的 Ehsan Angkari 在关于转换为标准 Web Audio 的博文中提供了一个很好的示例,介绍了如何执行此操作。

其中许多更改(例如重命名 createGainNode 和移除 createBuffer 中的同步解码)显然会在开发者工具控制台中显示为错误,但有些更改(例如以下用法)则不会:

MULTI_LINE_CODE_PLACEHOLDER_1

将完全不会显示,并静默失败(myFilterNode.BANDPASS 现在会解析为未定义,而尝试将 .type 设置为未定义将完全不会产生任何效果。顺便提一下,正是这个原因导致了声码器失败。)同样,只需将 filter.type 分配给一个数字即可正常运行:

myFilterNode.type = 2;

不过,现在您需要使用字符串枚举:

myFilterNode.type = bandpass;

因此,您可能需要使用 grep 在代码中查找以下字词:

  • webkitAudioContext
  • .LOWPASS
  • .HIGHPASS
  • .BANDPASS
  • .LOWSHELF
  • .HIGHSHELF
  • .PEAKING
  • .NOTCH
  • .ALLPASS
  • .SINE
  • .SQUARE
  • .SAWTOOTH
  • .TRIANGLE
  • .noteOn
  • .noteGrainOn
  • .noteOff
  • .setWaveTable
  • .createWaveTable
  • .looping
  • .EQUALPOWER
  • .HRTF
  • .LINEAR
  • .INVERSE
  • .EXPONENTIAL
  • createGainNode
  • createDelayNode
  • .type(是的,这会产生大量误报,但这是捕获上述最后一个示例的唯一方法!)

再次提醒一下,如果您很着急,想快速上手,只需获取我的 monkeypatch webkitAudioContext 库的副本,并将其添加到您的应用中即可。祝您音频黑客攻击愉快!