写一个商城后台系统需要当有新订单时有提示音....

第一时间想到的就是 html创建Audiob标签或者js创建,在有订单通知时执行audio.play() ,然后你就会在谷歌浏览器上看到错误信息:

`Uncaught(in promise)DOMException:play()`

意思就是人家浏览器不允许你执行播放音频的操作,原因就是Chrome的autoplay政策在2018年4月做了更改。更改后音乐的autoplay 只有在下面集中情况下起作用:

  1. 有用户行为发生像(click,tap,etc)
  2. 对于桌面程序,用户已经提前播放了音频
  3. 对于移动端用户将音频网址home screen

知道原因了,你用鼠标点击一下页面,再来消息的时候不报错了,也有提示音了,但这用户未操作的时候报错总是要解决的。

百度后给出的答案基本都是修改浏览器配置

  1. 在url中输入chrome://flags/#autoplay-policy
  2. 接着在Autoplay policy中将Default改为No user gesture is required
  3. 最后点击下方的“RELAUNCH NOW”,就大功告成了!

作为程序员肯定不能让用户去修改浏览器配置,以上方法也就看一看当涨知识了。

在百度的过程中虽然没有找到Audio标签解决的方法,但发现浏览器的一个音频API AudioContext

 playAudio() {//当有订单时调用此方法
        window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext;
        try {
          var context = new window.AudioContext();;
          var source = null;
          var audioBuffer = null;

          function stopSound() {
            if (source) {
              source.stop(0); //立即停止
            }
          }

          function playSound() {
            source = context.createBufferSource();
            source.buffer = audioBuffer;
            source.loop = true; //循环播放
            source.connect(context.destination);
            source.start(0); //立即播放
          }

          function initSound(arrayBuffer) {
            context.decodeAudioData(arrayBuffer, function (buffer) { //解码成功时的回调函数
              audioBuffer = buffer;
              playSound();
            }, function (e) { //解码出错时的回调函数
              console.log('Error decoding file', e);
            });
          }

          function loadAudioFile(url) {
            var xhr = new XMLHttpRequest(); //通过XHR下载音频文件
            xhr.open('GET', url, true);
            xhr.responseType = 'arraybuffer';
            xhr.onload = function (e) { //下载完成
              initSound(this.response);
            };
            xhr.send();
          }
          loadAudioFile('../../../static/mp3/12774.wav');
           var t=setTimeout(function(){
              context.close()//两秒后关闭,释放占用的所有系统资源     
            },2000);
        } catch (e) {
          console.log('!Your browser does not support AudioContext');
        }
      },

换成 AudioContext 后即使用户未进行交互操作,浏览器也不会报红色的错误,而是一个黄色警告,虽然没有完全解决这个bug,但又学到了一个知识点,值得记录一下,后续找到完整处理方法会更新的。


JSWalkingMan
3 声望0 粉丝