允许在 safari 上使用 audio.play() 进行聊天应用

And*_*dré 3 javascript safari macos ios html5-audio

由于 Apple 禁用了HTMLMedia?Element?.play() 在没有用户交互的情况下通过javascript自动播放音频的功能,我不确定当用户在页面加载后与 DOM 交互之前收到聊天消息时应该如何播放声音。

socket.on("receive message", data => {
  const receiveSound = new Audio("1.mp3");
  messages.push(data);
  receiveSound.play();
});
Run Code Online (Sandbox Code Playgroud)

我尝试在mousemove事件中播放音频元素。我还尝试click()通过 React ref 上的元素伪造 a以最初激活它。两种解决方案都不起作用。

如果有消息进来,有没有办法自动播放音频元素?这一定是可能的,因为 YouTube 可以在没有交互的情况下自动播放视频。

每次尝试播放音频时,都会出现此错误:

Unhandled Rejection (NotAllowedError): The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.
Run Code Online (Sandbox Code Playgroud)

小智 8

有一种方法可以让 Safari 播放声音,而不必在站点设置中允许它播放。

根据webkit 文档,它明确指出用户需要交互来播放音频/视频,在这种情况下是通过点击,但他没有说在你播放了一些音频之后他让你播放任何其他音频然后没有任何问题。考虑到这一点,您可以例如在您的index.html位置上运行一些脚本,它将在没有任何音量的情况下播放您的通知音频,然后您可以毫无问题地再次运行它,如下例所示:

function unlockAudio() {
    const sound = new Audio('path/to/your/sound/notification.mp3');

    sound.play();
    sound.pause();
    sound.currentTime = 0;

    document.body.removeEventListener('click', unlockAudio)
    document.body.removeEventListener('touchstart', unlockAudio)
}

document.body.addEventListener('click', unlockAudio);
document.body.addEventListener('touchstart', unlockAudio);
Run Code Online (Sandbox Code Playgroud)

要在此解决方法后运行您的代码,只需这样做:

function soundNotification() {
    const sound = new Audio('path/to/your/sound/notification.mp3');

    const promise = sound.play();

    if (promise !== undefined) {
        promise.then(() => {}).catch(error => console.error);
    }
}
Run Code Online (Sandbox Code Playgroud)

请记住,上面的示例只是为了向您展示替代方案,有多种方法可以解决此问题,请记住,您需要先播放一些声音...