我正在使用Safari(桌面和移动设备(创建AudioContext的麻烦。似乎即使在用户交互时创建也仍然被暂停。
我的代码:
<button onclick="test()">Test</button>
const test = () => {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
audioContext = new AudioContext();
console.log(audioContext.state); // Suspended
}
这应该是一个最小的工作示例,对吗?这里怎么了?
我认为Safari实际上在这种情况下(至少部分(行为正确。网络音频规范说...
新创建的AudioContext将始终以暂停状态开始,每当状态更改为其他状态时,状态变更事件将被解雇。
https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-onstatechange
不幸的是,Safari不会自行过渡到running
状态。您必须明确要求这样做。
audioContext.resume();
audioContext.onstatechange = () => console.log(audioContext.state);
statechange
事件几乎应该立即发射。如果您在单击处理程序中执行此操作。
上面的功能将看起来像这样:
const test = () => {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
audioContext = new AudioContext();
console.log(audioContext.state); //suspended
audioContext.resume();
audioContext.onstatechange = () => console.log(audioContext.state); // running
}
有趣的是,如果您在致电resume()
之前保留console.log
语句,Safari仅发射statechange
事件。
但是,您可以尝试踢AudioContext
的另一个黑客。只需创建一个简单的GainNode
。
const test = () => {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
audioContext = new AudioContext();
audioContext.createGain();
console.log(audioContext.state); // running
}
您还可以尝试标准化的audio-context尝试,这使得所有浏览器在这方面的行为相同。