Handle the problem of Google playing Audio after updating from 2018 (not completely resolved, to be updated)

Posted May 27, 20202 min read

Writing a mall back-end system requires a prompt tone when there is a new order ...

The first time I thought about it is to create an Audio b tag or js, and executeaudio.play()when there is an order notification, and then you will see an error message on Google Chrome:

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

This means that people s browsers do not allow you to perform audio playback. The reason is that Chrome s autoplay policy was changed in April 2018. The changed music autoplay only works in the following concentrated situations:

  1. There are user actions like(click, tap, etc)
  2. For desktop programs, users have played audio in advance
  3. For mobile users, add audio URL to home screen

Knowing the reason, you click the page with the mouse, and when you come back to the message, no error will be reported, and there will be a prompt tone, but when the user does not operate, the error will always be resolved.

The answer given by Baidu is basically to modify the browser configuration

  1. Enter chrome://flags/# autoplay-policy in the url
  2. Then change the Default to No user gesture is required in the Autoplay policy
  3. Finally click on "RELAUNCH NOW" below and you're done!

As a programmer, you must not allow users to modify the browser configuration, and the above methods will take a look at the knowledge.

In the process of Baidu, although I did not find a solution to the Audio tag, I found an audio API AudioContext


 playAudio() {//This method is called when there is an order
        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); //stop immediately
            }
          }

          function playSound() {
            source = context.createBufferSource();
            source.buffer = audioBuffer;
            source.loop = true; //loop playback
            source.connect(context.destination);
            source.start(0); //Play immediately
          }

          function initSound(arrayBuffer) {
            context.decodeAudioData(arrayBuffer, function(buffer) {//Callback function when decoding is successful
              audioBuffer = buffer;
              playSound();
            }, function(e) {//Callback function when decoding error
              console.log('Error decoding file', e);
            });
          }

          function loadAudioFile(url) {
            var xhr = new XMLHttpRequest(); //download audio file via XHR
            xhr.open('GET', url, true);
            xhr.responseType = 'arraybuffer';
            xhr.onload = function(e) {//download complete
              initSound(this.response);
            };
            xhr.send();
          }
          loadAudioFile('../../../static/mp3/12774.wav');
           var t = setTimeout(function() {
              context.close() //Close after two seconds, release all occupied system resources
            }, 2000);
        } catch(e) {
          console.log('! Your browser does not support AudioContext');
        }
      },

After switching to AudioContext, even if the user does not perform interactive operations, the browser will not report a red error, but a yellow warning. Although this bug is not completely resolved, but I have learned a point of knowledge, it is worth recording, and find a complete treatment later The method will be updated.