如何在没有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的自动播放策略很简单:

始终允许静音自动播放。如果出现以下情况,则允许自动播放声音:用户已经与域进行了交互(单击、点击等(。在桌面上,用户的媒体参与度指数阈值已经超过,这意味着用户以前播放过带声音的视频。用户已将网站添加到移动设备的主屏幕上,或在桌面上安装了PWA。顶级框架可以将自动播放权限委托给它们的iframe,以允许使用声音进行自动播放。

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

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

我认为其中一个选择可能是网络音频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写在音频标记中,还是将其写在音频标签内的源标记中。我想这会有一些不同,但我不知道到底是什么问题。

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

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

使用Web Audio API不会更改自动播放策略。无论使用哪种浏览器API,通常都适用相同的规则。

相关内容

最新更新