在过去几个月里,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
何时播放完毕?
答:由于 Web Audio API 不支持此功能,因此您目前必须使用 JavaScript 计时器。“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 将能够使用 Web Audio 的内部计时器(context.currentTime
属性)在特定时间回调。如需了解详情,请参阅此功能请求。
一般来说,最好在应用进入后台时停止播放。您可以使用 Page Visibility API 检测网页何时进入后台。
问题:如何使用 Web Audio API 更改音调?
答:更改源节点上的 playbackRate
。
问:我可以更改音调而不更改速度吗?
答:Web Audio API 可以在音频上下文中包含 PitchNode,但很难实现。这是因为音频社区中没有简单的音高移调算法。已知的技术会产生伪影,尤其是在音高移调幅度较大的情况下。有两种方法可以解决此问题:
- 时域算法,会导致重复的片段回声伪影。
- 频域技术,会导致混响音效伪影。
虽然没有用于执行这些技术的原生节点,但您可以使用 JavaScriptAudioNode
执行这些技术。您可以参考以下代码段入手。
问题:如何以我选择的采样率创建 AudioContext?
答:目前不支持这种做法,但我们正在研究中。请参阅此功能请求。
如果您还有其他问题,欢迎随时在 StackOverflow 上使用 web-audio 标签提问。