m36 中的网络音频变化

克里斯·威尔逊
Chris Wilson

网络音频更改

Google 一向秉持标准,我们的使命是打造以标准定义的网络平台。一段时间以来存在的一个小缺点是,带有 webkit 前缀的 Web Audio API 实现(尤其是 webkitAudioContext 对象),以及我们继续支持的一些已废弃的网络音频部分。

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

在 Chrome 36 之后,我们可能会在几个版本中完全停止对该前缀的支持。变更即将生效时,我们会在此处发布通知,同时会继续与相关作者联系,以修复其 Web Audio 应用。

我们为什么要这样做,而不是恢复到之前的实现?在一定程度上,我们一直不愿意回过头来;我们已经移除了这些 API,不过,对于这种混叠的一个有利的副作用是,应用程序可以在 Firefox 中正常运行,而 Firefox 从不支持带前缀的 AudioContext 对象(这也完全正确!)于去年秋季发布。

本更新的其余部分将提供指导,帮助您修复可能因这项变更而在代码中损坏的问题。解决这些问题最棒的一点是,您的代码很有可能也能在 Firefox 中正常运行!(我曾经以为,我的 Vocoder 应用会因为 Firefox 的实现而损坏,但事实证明,这确实是一个问题!)

如果您只想上手运行,不妨了解一下我为编写了旧版 Web Audio 代码的应用编写的 monkey-patch 。该库可帮助您在最短的时间内启动并运行,因为它会适当地为对象和方法添加别名。事实上,库列出的补丁可以很好地指导更改的内容。

首要任务

window.webkitAudioContext 的任何引用都应改为对 window.AudioContext。通常,此问题已通过一个简单的解决:

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

如果您的应用返回类似“很抱歉,您的浏览器不支持网络音频。请使用 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)。需要很长时间才能完成的同步调用是一种糟糕的编码做法;请改用异步 de AudioData 调用。这是更具挑战性的更改之一 - 您需要实际更改逻辑流程 - 但是一种更好的做法。Mozilla 的 Ehsan Angkari 在有关转换为标准网络音频的博文中编写了一个很好的示例,说明如何进行此操作。

其中许多错误(例如 createGrowNode 的重命名以及 createBuffer 中移除同步解码)显然会在开发者工具控制台中显示为错误;不过,也有一些其他问题,例如如下用法:

MULTI_LINE_CODE_PLACEHOLDER_1

根本不会显示,并且会静默失败(myFilterNode.BANDPASS 将解析为未定义,并且尝试将 .type 设置为 undefined 的操作将完全无法产生任何效果。顺便说一下,这也是导致声码器崩溃的原因。)同样,只需将 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(没错,这会有很多假正例,但这是捕获上述最后一个示例的唯一方法!)

再强调一次,如果您着急,并且想要上手使用,只需获取 my monkeypatch webkitAudioContext 库的副本,然后将其添加到您的应用中即可。祝您音频入侵愉快!