过去几个月里,WebKit Web Audio API 已成为极具吸引力的 Web 游戏和音频应用平台。随着开发者对它越来越熟悉,我听到类似的问题反复出现。此快速更新旨在解答一些常见问题,让您在使用 Web Audio API 时获得更加愉悦的体验。
问:帮忙,我没法发出声音!
答:如果您是 Web Audio API 新用户,可以看看入门教程或 Eric 根据用户互动播放音频的食谱。
问:我应该有多少个音频上下文?
答:通常,您应为每个网页添加一个 AudioContext
,并且单个音频上下文可以支持多个连接到该上下文的节点。虽然您可以在一个页面上添加多个 AudioContext,但这可能导致性能下降。
问:我有一个 AudioBufferSourceNode,我刚刚使用 noteOn()
播放过,我想再播放一遍,但 noteOn()
什么都不会用!我需要帮助!
答:源节点播放完毕后,便无法再播放更多内容。如需再次回放底层缓冲区,您应创建一个新的 AudioBufferSourceNode
并调用 noteOn()
。
虽然重新创建源节点可能会让人觉得效率低下,但源节点已针对此模式进行了大量优化。此外,如果您保留了 AudioBuffer 的句柄,则无需向相应资产另外提出请求即可再次播放相同的声音。如果您发现自己需要重复这种模式,请使用 playSound(buffer)
等简单的辅助函数封装播放。
问:播放声音时,为什么每次都需要创建新的来源节点?
答:此架构的理念是将音频资产与播放状态分离开来。按唱片机类比,缓冲区就类似于唱片和播放头的来源。由于许多应用涉及同时播放同一缓冲区的多个版本,因此该模式至关重要。
问:如何处理来自 audio
和 video
标记的声音?
答:MediaElementAudioSourceNode
仍在开发中!如果可用,其工作原理大致如下(向通过音频标记播放的样本添加滤镜效果):
<audio src="sounds/sample.wav" controls>
var audioElement = document.querySelector('audio');
var mediaSourceNode = context.createMediaElementSource(audioElement);
mediaSourceNode.connect(filter);
filter.connect(context.destination);
此功能在此 crbug 中进行跟踪。请注意,在此设置中,无需调用 mediaSourceNode.noteOn()
,音频标记用于控制播放。
问:什么时候才能收到麦克风的声音?
答:此过程中的音频输入部分将使用 getUserMedia
作为 WebRTC 的一部分实现,并可在 Web Audio API 中作为特殊源节点使用。它可与 createMediaElementSource
结合使用。
问:如何查看 AudioSourceNode
何时结束?
答:目前您必须使用 JavaScript 计时器,因为 Web Audio API 不支持此功能。Web Audio API 使用入门教程中的以下代码段就是实际操作中的代码段:
// Assume source and buffer are previously defined.
source.noteOn(0);
var timer = setTimeout(function() {
console.log('playback finished');
}, buffer.duration * 1000);
有一个待解决的 bug,可以使 Web Audio API 实现更准确的回调。
问:加载声音会导致整个界面线程锁定,我的界面变得无响应。救命啊!**
答:使用 decodeAudioData
API 进行异步加载,以免阻塞主线程。请参阅此示例。
问:可以使用 Web Audio API 来处理比实时更快的声音吗?
答:是的,我们正在制定解决方案。请继续关注我们的行动!
问:我开发了一个很棒的 Web Audio API 应用,但是每当它运行的标签页在后台运行时,听起来都会很奇怪!
答:这可能是因为您使用的是 setTimeouts
;如果网页在后台运行,其行为方式会有所不同。将来,Web Audio API 将能够使用网络音频的内部计时器(context.currentTime
属性)在特定时间进行回调。如需了解详情,请参阅此功能请求。
一般而言,最好在应用转入后台时停止播放。您可以使用 Page Visibility API 检测网页何时转到后台。
问:如何使用 Web Audio API 更改声音的音高?
答:更改源节点上的 playbackRate
。
问:可以在不改变速度的情况下改变音调吗?
答:Web Audio API 在音频上下文中可以有一个 PitchNode,但这很难实现。这是因为音频社区中没有简单直接的音高转换算法。已知技术会产生伪影,尤其是在音调偏移较大的情况下。可以通过两种方法解决此问题:
- 时域算法,会导致重复片段回显伪影。
- 产生混响声音伪像的频域技术。
虽然没有用于执行这些方法的原生节点,但您可以使用 JavaScriptAudioNode
来完成。您可以参考此代码段。
问:如何以我选择的采样率创建 AudioContext?
答:我们目前还不支持这项功能,但我们正在努力解决此问题。请参阅此功能请求。
如果您还有其他问题,请随时在 StackOverflow 上使用 web-audio 标记进行提问。