问题
使用audio在网页上使用js控制音频触发播放,每次播放特定次数或时间,如下:
框架:vue
html:
<audio id="warnFileId" preload hidden >
<source src="static/voice/warn.mp3" type="audio/mp3"></source>
<source src="static/voice/warn.wav" type="audio/wav"></source>
</audio>
js:
/**
* @method 调用实际播放方法
*/
playCircle(elem, max, times){
this.isPlaySound = true;
let start = 0;
elem.addEventListener("ended",() => {
if(this.allowPlay){
// 播放次数加1
start ++;
// 如果次数未满,继续播放
if (start < max) {
setTimeout(() =>{elem.play();}, times);
// 次数满足,停止播放
}else{
elem.pause();
this.isPlaySound = false;
}
}else{
elem.pause();
}
});
if(elem.paused){
this.$nextTick(()=>{
//默认播放
elem.play();
})
}
},
/**
* @method 播放警告声音
*/
playSound() {
let warn= document.getElementById("warnFileId");
this.$nextTick(()=>{
if(warn!=null)
this.allowPlay = true;
this.playCircle(warn,5,500); //执行循环播放函数,播放5次,每次间隔500毫秒
})
},
...
//触发声音播放
this.playSound()
在chrome或者firefox上执行时报错:
报错原因
Chrome firefox等一些浏览器(所有以Chromium为内核的浏览器)默认限制了自动播放音频视频等的政策,为提高用户体验,减少数据消耗,需要用户有点击的动作后才可以播放。这样的原因在于很多用户流量需要付费,而限制了自动播放可以避免用户在不知情的情况下产生高额的流量费用。
在60.X版本之前,chrome://flags中有一个disable-gesture-requirement-for-media-playback的选项,让用户在浏览器中输入chrome://flags/#disable-gesture-requirement-for-media-playback将该选项应用后即可。
而从60.X版本开始,这个选项被移除了,取而代之的是一个名为Autoplay policy的选项。我们在浏览器中输入chrome://flags/#autoplay-policy,然后在高亮的选项中,将Default换成No user gesture is required:
Chrome的autoplay 政策如下:
- muted autoplay始终被允许
- 音乐的autoplay 只有在下面集中情况下起作用:
2.1有用户行为发生像(click,tap,etc);
2.2 对于桌面程序,用户已经提前播放了音频;
2.3 对于移动端用户将音频网址home screen;
解决方法
客户端解决——修改浏览器修改自动播放的政策
1、在chrome的地址栏中输入:chrome://flags/#autoplay-policy,回车打开
2、看到黄色方框标记的字体:Autoplay policy ,该选项默认设置为Default,改为:No user gesture is required 保存
开发者解决——hack解决
考虑到需要在页面打开就播放声音的需求,如果叫用户在想听声音之前点击几下是不现实的,想要使浏览器认为当前已经默认用户已经交互,需要在页面上模拟用户交互,解除浏览器播放限制,目前有效的解决方法如下:
chrome目前对iframe这个同样可以加载音频视频进行播放的标签没有作严格限制,可以通过iframe来加载音频,触发播放权限,然后在此之后的声音的自动播放就可以正常进行了。
html:
<iframe allow="autoplay" style="display:none" src="static/voice/wave.mp3" @load = "handleLoadIframe"></iframe>
<audio id="wanrFileId" preload hidden>
<source src="static/voice/warn.mp3" type="audio/mp3"></source>
<source src="static/voice/warn.wav" type="audio/wav"></source>
</audio>
js:
handleLoadIframe(){
//iframe加载到声音文件后才执行之后的声音播放函数,才会触发到权限
console.log("load sound iframe")
},
iframe加载的音频文件可以是一个空文件,里面没有内容,新建一个声音文件即可。
参考资料:
https://blog.csdn.net/wo_shi_ma_nong/article/details/88077869