Rag*_*eth 7 safari web-audio-api
我遇到了一个问题,当尝试在 Safari 中播放音频时,调用永远无法解决resume
。AudioContext
我正在创建一个AudioContext
页面加载,因此它以暂停状态启动。
根据此 chromium 问题,resume
如果浏览器的自动播放策略阻止,调用将无法解决。我有一个绑定到 a 的点击事件<button>
,如果它被挂起,它将恢复上下文。这适用于 Firefox 和 Chrome,并且如果我更改网站的自动播放设置,也将适用于 Safari。
以下是我通常如何恢复上下文:
await context.resume();
Run Code Online (Sandbox Code Playgroud)
对于 Safari,我尝试在不等待承诺解决的情况下调用resume,而是注册一个回调onstatechange
,然后将其包装在Promise
:
if (window.webkitAudioContext) {
await new Promise((accept, reject) => {
this.context.onstatechange = async () => {
if ((await this.context.state) === "playing") {
accept();
} else {
reject();
}
};
this.context.resume();
});
}
Run Code Online (Sandbox Code Playgroud)
然而,什么都没有改变:Promise
永远不会解决,这意味着上下文状态没有改变。
我错过了什么吗?
我终于成功在 Safari 上播放音频了。
“修复”相当简单:我必须resume
在绑定到用于启动播放的元素的事件处理程序中进行调用。在我的场景中,我将 Redux 与 React 结合使用,因此将进行调度,并稍后在另一个组件中恢复上下文。我猜测 Safari 并没有将其视为对用户交互事件的直接响应,因此它将上下文保持在挂起状态。
iOS 仅允许在 UI 事件处理程序的调用堆栈中运行时恢复 audioContext。在 Promise 中运行它会将调用移动到另一个调用堆栈。
此外,audioContext.resume()
还返回一个必须等待的承诺。
尝试这个:
onPlayHandler() {
alert("State before: " + this.audioContext.state);
await this.audioContext.resume();
alert("State after: " + this.audioContext.state);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4303 次 |
最近记录: |