刷新浏览器后不进行任何点击操做时,不播放声音 | 解决方案(VUE-Element)


如下代码可能过长,请耐心查阅

前言

最近项目中有播放背景声音的一个功能,后面发现刷新浏览器后,不对页面进行任何点击操做,浏览器不播放声音。做为一个后端开发,忽然搞这么一个前端解决方案是有点懵逼的,下面是和一名前端大佬讨论的结果。javascript


解决方案:

  • 1.将提供给用户的浏览器的播放声音权限打开,而后从新打包浏览器发出去;
  • 2.给用户一个弹窗提示,点击按钮,打开浏览器声音权限或直接跳转到设置声音的页面;(通过测试发现实现不了,由于系统部署在服务端,而打开的是本地浏览器的配置,没法实现这个功能)
  • 3.置顶一个弹窗,引导用户开启声音权限,达到一劳永逸的效果。(目前博主采用)

ps:上面所说的弹窗是在浏览器刷新后,而且检测到浏览器没有开启声音的时才会弹窗。css


已测试过的浏览器类型和版本:

如下浏览器作过声音测试和引导弹窗测试前端

  • 谷歌浏览器(版本83.0.4103.9七、72.0.3626.9六、65.0.3325.146)
  • 火狐浏览器(版本76.0.1 )
  • IE浏览器(版本11.836.18362.0)
  • Opera浏览器(版本68.0.3618.165)

谷歌66版本如下都支持播放,66版本以上默认拦截声音播放;IE支持声音播放,不会有提示框vue


静音文件和图标

这里用静音的文件去测试浏览器是否能够正常播放,图标是浏览器的图标截图,你们本身随意取java

  • 连接:https://pan.baidu.com/s/1H-lrgdBtf4LamOXWfP8vbg
  • 提取码:bqxv

播放声音的标签:

  • 1.embed
  • 2.audio
<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浏览器的处理方式web

//兼容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浏览器
	}
}

方案代码:

1.在app.vue里面引入组件

这里是 voiceShow 是当用户登陆过时或在其余状况时关闭提示框用chrome

<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;
		}
   }
}

2.引导用户的对话框:voice.vue
<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/>
        &nbsp;
      </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>

3.检测声音和浏览器类型和版本:checkAudio.js
/** * 获取浏览器类型和版本号 */
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);
    });
  });
}

自此已将所有逻辑写完,但愿对你们有用


参考网址:http://www.javashuo.com/article/p-qftxhnts-hy.html.后端