在过去几个月中,WebKit Web Audio API 已成为 Web 上游戏和音频应用的一个极具吸引力的平台。随着开发者逐渐熟悉 Gemini,我听到类似的问题反复出现。此快速更新旨在解答一些更常见的问题,让您在使用 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 将能够使用 Web Audio 的内部计时器(context.currentTime 属性)在特定时间进行回调。如需了解详情,请参阅此功能请求。
一般来说,当应用进入后台时,最好停止播放。您可以使用 Page Visibility API 检测网页何时转到后台。
问:如何使用 Web Audio API 更改声音的音调?
答:更改源节点上的 playbackRate。
问:我可以更改音调而不更改速度吗?
答:Web Audio API 可以在音频上下文中包含 PitchNode,但实现起来比较困难。这是因为音频社区中没有直接的音高转换算法。已知技术会产生伪影,尤其是在音高变化较大的情况下。解决此问题的方法有两种:
- 时域算法,会导致出现重复的片段回声伪影。
- 频域技术,会导致混响声音伪影。
虽然没有用于执行这些技术的原生节点,但您可以使用 JavaScriptAudioNode 来实现。此代码段可作为起点。
问:如何以我选择的采样率创建 AudioContext?
答:目前不支持此功能,但我们正在研究。请参阅此功能请求。
如果您还有其他问题,欢迎在 StackOverflow 上使用 web-audio 标签提问。