首页 > 解决方案 > 即使在创建 onclick 时,Safari AudioContext 也会暂停

问题描述

我在使用 Safari(桌面和移动设备)创建 AudioContext 时遇到问题。似乎即使在用户交互时创建,它仍然被暂停。

我的代码:

<button onclick="test()">Test</button>
const test = () => {
    window.AudioContext = window.AudioContext || window.webkitAudioContext;
    audioContext = new AudioContext();
    console.log(audioContext.state); // Suspended
}

这应该是一个最低限度的工作示例,对吧?这里有什么问题?

标签: safarimobile-safariweb-audio-apiaudiocontextwebkitaudiocontext

解决方案


我认为 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
}

有趣的是,statechange如果您console.log在调用resume().

但是,您可以尝试使用另一种技巧来破解AudioContext. 只需创建一个简单的GainNode.

const test = () => {
    window.AudioContext = window.AudioContext || window.webkitAudioContext;
    audioContext = new AudioContext();
    audioContext.createGain();
    console.log(audioContext.state); // running
}

您还可以尝试标准化音频上下文,以使所有浏览器在这方面表现相同。


推荐阅读