无法在 Safari 中恢复 AudioContext

问题描述 投票:0回答:3

我遇到了一个问题,当尝试在 Safari 中播放音频时,在

resume
上调用
AudioContext
永远无法解决。我在页面加载时创建一个
AudioContext
,因此它以暂停状态启动。

根据此 chromium 问题,如果浏览器的自动播放策略阻止,调用

resume
将无法解决。我有一个绑定到
<button>
的点击事件,如果上下文被挂起,它将恢复上下文。这适用于 Firefox 和 Chrome,也适用于 Safari 如果我更改了网站的自动播放设置。

以下是我通常如何恢复上下文:

await context.resume();

对于 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();
    });
}

但是,什么都没有改变:

Promise
永远不会解析,这意味着上下文状态没有改变。

我错过了什么吗?

safari web-audio-api
3个回答
6
投票

我终于成功在 Safari 上播放音频了。

“修复”相当简单:我必须在绑定到用于启动播放的元素的事件处理程序中调用

resume
。在我的场景中,我将 Redux 与 React 结合使用,因此将进行调度,并稍后在另一个组件中恢复上下文。我猜测 Safari 并没有将其视为对用户交互事件的直接响应,因此它将上下文保持在挂起状态。


6
投票

iOS 仅允许在 UI 事件处理程序的调用堆栈中运行时恢复 audioContext。在 Promise 中运行它会将调用移动到另一个调用堆栈。

此外,

audioContext.resume()
返回一个必须等待的承诺。

试试这个:

onPlayHandler() {
   alert("State before: " + this.audioContext.state);
   await this.audioContext.resume();
   alert("State after: " + this.audioContext.state);
}

-1
投票

我看到了类似但不完全相同的问题。当前我的 AudioContext 陷入“中断”状态,我无法使用 audioContext.resume() 恢复它。

有人知道如何在设置中断后恢复吗?

© www.soinside.com 2019 - 2024. All rights reserved.