以下代码可能过长,请耐心查阅
最近项目中有播放背景声音的一个功能,后面发现刷新浏览器后,不对页面进行任何点击操作,浏览器不播放声音。作为一个后端开发,突然搞这么一个前端解决方案是有点懵逼的,下面是和一名前端大佬讨论的结果。
ps:上面所说的弹窗是在浏览器刷新后,并且检测到浏览器没有开启声音的时才会弹窗。
以下浏览器做过声音测试和引导弹窗测试
谷歌66版本以下都支持播放,66版本以上默认拦截声音播放;IE支持声音播放,不会有提示框
这里用静音的文件去测试浏览器是否可以正常播放,图标是浏览器的图标截图,大家自己随意取
<div v-if="sourceShow">
<embed ref="counterfeitAudio" src="@/voice/mute.wav" autostart="false" hidden="true" v-show="false" />
</div>
<div v-else>
<audio ref="counterfeitAudio" controls="controls" v-show="false">
<source src="@/voice/audio.wav" type="audio/wav"/>
</audio>
</div>
这里需要判断IE浏览器版本是否是大于9版本,如果大于9则用 embed 标签,其他浏览器和IE版本用 audio 标签。下面是IE浏览器的处理方式
//兼容ie告警声音处理
if(ieVersion()>9){
this.sourceShow = true
}else{
this.sourceShow = false
}
//在app.vue导入
import {ieVersion} from "./utils/ieVersion";
/***
* 判断当前浏览器是否是ie
* @returns {Number}
* -1代表不是ie浏览器 其他数字代表各个ie浏览器的版本
*/
export function ieVersion(){
let userAgent = navigator.userAgent; //取得浏览器的userAgent字符串
let isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器
let isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器
let isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1;
if(isIE) {
let reIE = new RegExp("MSIE (\\d+\\.\\d+);");
reIE.test(userAgent);
let fIEVersion = parseFloat(RegExp["$1"]);
if(fIEVersion == 7) {
return 7;
} else if(fIEVersion == 8) {
return 8;
} else if(fIEVersion == 9) {
return 9;
} else if(fIEVersion == 10) {
return 10;
} else {
return 6;//IE版本<=7
}
} else if(isEdge) {
return 'edge';//edge
} else if(isIE11) {
return 11; //IE11
}else{
return -1;//不是ie浏览器
}
}
这里是 voiceShow 是当用户登录过期或在其他情况时关闭提示框用
<template>
<div id="app" class="appCss">
<voice :voiceShow="voiceShow"/>
</div>
</template>
import voice from '@/components/voice/index'
export default {
name: 'App',
components: {voice},
data() {
return {
voiceShow: false
}
},
methods:{
closeDialog(){
// 关闭引导用户开启浏览器声音播放权限的提示框
this.voiceShow = false;
}
}
}
<template>
<el-dialog
title="提示"
:visible.sync="dialogVisible"
width="30%"
:close-on-click-modal="false"
:close-on-press-escape="false"
class="voiceTips">
<span>
<p>
系统检测到当前浏览器未开启背景声音播放权限,请前往浏览器设置开启<br/>
步骤如下:<br/>
</p>
</span>
<span v-if="browserInfo.type === 'IE'">
<p>
1.点击右上角的 <img src="@/voice/tipImg/IE.png"/> 图标,再选择 "Internet 选项"<br/>
2.选择 "高级",在设置一栏中往下拉,找到 "多媒体",再勾选 "在网页中播放声音",点击确定<br/>
3.重启计算机即可
</p>
</span>
<span v-else-if="browserInfo.type === 'Firefox'">
<p>
1.点击右上角的 <img src="@/voice/tipImg/Firefox.png"/> 图标,再选择 "选项"<br/>
2.选择左侧 "隐私与安全",再下拉找到权限一栏,点击 "自动播放" 的设置按钮<br/>
3.将 "所有网站的默认值" 设置为 "允许音频和视频",再点击 "保存更改"<br/>
4.返回当前页面即可
</p>
</span>
<span v-else-if="browserInfo.type === 'Chrome'">
<p>
1.点击左上角网址前面的 <img src="@/voice/tipImg/Chrome.png"/> 图标,再点击 "网站设置"<br/>
2.找到 "声音" 一栏,选择 "允许"<br/>
3.返回当前页面,点击浏览器上方提示的 "重新加载" 按钮即可
</p>
</span>
<span v-else-if="browserInfo.type === 'Opera'">
<p>
1.点击左上角网址前面的 <img src="@/voice/tipImg/Opera.png"/> 图标,再点击 "网站设置"<br/>
2.找到 "声音" 一栏,选择 "允许"<br/>
3.返回当前页面,点击浏览器上方提示的 "重新加载" 按钮即可
</p>
</span>
<span v-else-if="browserInfo.type === 'Safari'">
<p>
1.打开浏览器的设置,找到声音设置,选择允许声音播放<br/>
2.返回当前页面即可
</p>
</span>
<span v-else>
<p>
1.打开浏览器的设置,找到声音设置,选择允许声音播放<br/>
2.返回当前页面即可
</p>
</span>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="dialogVisible = false" style="text-align: center;">确 定</el-button>
</span>
</el-dialog>
</template>
<script>
import {getBrowserInfo, checkAutoPlay} from '@/utils/checkAudio'
export default {
name: "voice",
props: ['voiceShow'],
watch: {
$route: {
//监听路由变化
handler: function (val, oldVal) {
this.dialogVisible = this.voiceShow;
},
immediate: true,
deep: true
},
},
data() {
return {
title: '声音检测',
dialogVisible: false,
//获取浏览器的详细信息
browserInfo:{}
}
},
methods:{
// 检测浏览器类型
async getBrowserInfoFun(){
let info = await getBrowserInfo();
this.$nextTick(()=>{
this.browserInfo = info;
});
},
// 检测声音能否播放
async checkAutoPlayFun(){
// 检测当前流量器是否能自动播放背景声音
let autoplay = await checkAutoPlay();
if(autoplay === false){
this.dialogVisible = true;
}
},
},
created(){
},
mounted() {
const that = this;
// 监听浏览器刷新事件,用户为登录状态,且不在登录页时才弹出提示
let fullPath = that.$router.currentRoute.fullPath;
if(that.$store.getters.isLogin === 'true' || that.$store.getters.isLogin === true){
if(fullPath !== '/' && fullPath !== '/login'){
that.getBrowserInfoFun();
that.checkAutoPlayFun();
}
}
}
}
</script>
<style lang="scss">
.voiceTips{
margin-top: 93px;
z-index: 9999!important;
}
</style>
/**
* 获取浏览器类型和版本号
*/
export function getBrowserInfo (){
const agent = navigator.userAgent.toLowerCase();
const regStr_ie = /msie [\d.]+;/gi ;
const regStr_ff = /firefox\/[\d.]+/gi
const regStr_chrome = /chrome\/[\d.]+/gi ;
const regStr_saf = /safari\/[\d.]+/gi ;
const regStr_opera = /opr\/[\d.]+/gi ;
//ie
if (agent.indexOf("msie") >= 0) {
const ver= agent.match(regStr_ie)[0];
return {type:"IE",version:ver.replace(/[^0-9.]/ig,"")};
}
//firefox
else if (agent.indexOf("firefox") >= 0) {
const ver=agent.match(regStr_ff)[0];
return {type:"Firefox",version:ver.replace(/[^0-9.]/ig,"")};
}
//Opera
else if(agent.indexOf("opr") >= 0){
const ver=agent.match(regStr_opera)[0];
return {type:"Opera",version:ver.replace(/[^0-9.]/ig,"")};
}
//Chrome
else if(agent.indexOf("chrome") >= 0){
const ver=agent.match(regStr_chrome)[0];
return {type:"Chrome",version:ver.replace(/[^0-9.]/ig,"")};
}
//Safari
else if(agent.indexOf("Safari") >= 0){
const ver=agent.match(regStr_saf)[0];
return {type:"Safari",version:ver.replace(/[^0-9.]/ig,"")};
}
}
/**
* 检测浏览器是否支持自动播放!
* return @Promise boolean
*/
export function checkAutoPlay(){
// 返回一个promise以告诉调用者检测结果
return new Promise(resolve => {
const audio = document.createElement('audio');
// require一个本地文件,会变成base64格式,这里用的是没有声音的文件进行检测的
audio.src = require('@/voice/mute.wav');
document.body.appendChild(audio);
let autoplay = true;
// play返回的是一个promise
// audio.volume = 0;
audio.play().then(() => {
// 支持自动播放
autoplay = true;
}).catch(() => {
// 不支持自动播放
autoplay = false;
}).finally(() => {
audio.remove();
// 告诉调用者结果
resolve(autoplay);
});
});
}
参考网址:https://juejin.im/post/5af7129bf265da0b8262df4c.