如何在 JavaScript 没有严格限制的情况下播放音频?

How to play audio without strict limitations on JavaScript?

我正在制作一个由裸 JavaScript 代码组成的游戏,我想在 JavaScript 中处理音频。 具体来说,我想让页面在单击某些 div 元素时以及在 JavaScript 代码中使用某些功能时开始播放音乐。

我知道 HTML5 的音频标签有一个限制,即与 Audio 元素关联的音乐文件在用户不单击音频元素的播放按钮的情况下无法播放,所以我不能这样做:

const audio = document.createElement("audio");
audio.src = "url of source";
audio.play(); 
//Uncaught (in promise) DOMException: play() failed because 
//the user didn't interact with the document first. 
//https://developers.google.com/web/updates/2017/09/autoplay-policy-changes

Chrome's autoplay policies are simple:

Muted autoplay is always allowed. Autoplay with sound is allowed if: User has interacted with the domain (click, tap, etc.). On desktop, the user's Media Engagement Index threshold has been crossed, meaning the user has previously played video with sound. The user has added the site to their home screen on mobile or installed the PWA on desktop. Top frames can delegate autoplay permission to their iframes to allow autoplay with sound.

但我想更自由地管理音频,以便UI制作一个好的游戏。

为了实现我的目标,我想我需要引入另一个库或 API 到 JavaScript 代码中,或者仍然使用带有一些技巧的音频标签。

我认为选择之一可能是 Web Audio API

你能告诉我一些建议吗?

进度

我尝试了如下代码,当我使用点击事件处理程序点击 div 元素时它起作用了:

<div id="my-div">play</div>

<audio id="myAudio">
<source src="url of source" type="audio/mpeg">
</audio>
const myAudio = document.getElementById("myAudio");
const btn = document.getElementById("my-div");
btn.addEventListener("click",() => {
  myAudio.play();
});

然而,当我像下面这样写时,即使我似乎没有违反自动播放政策,它也没有用同样的错误:

document.getElementById('my-div').addEventListener('click', () => {
    const audio = new Audio('url of source');
    audio.play();
});
//Uncaught (in promise) DOMException: play() failed because 
//the user didn't interact with the document first. 
//https://developers.google.com/web/updates/2017/09/autoplay-policy-changes

上面两段代码的主要区别在于我是把音频源文件的url写在audio标签里,还是写在audio标签里面的source标签里。我猜这会有所不同,但我不明白问题到底是什么。

你是对的。如果响应用户手势开始播放,您只能确保播放不会被自动播放策略阻止。带有点击处理程序的按钮是典型示例,但点击处理程序也可以附加到 div。假设您的 div 有一个名为 my-div 的 ID。在这种情况下,以下应该有效。

document.getElementById('my-div').addEventListener('click', () => {
    const audio = new Audio('url of source');

    audio.play(); 
});

使用网络音频API 不会更改自动播放政策。通常,无论使用哪种浏览器,都适用相同的规则。API。