Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autoplay sound in chrome background tab

I have an HTML5 game that uses audio notifications.

When users are searching for other players with match-making they frequently change tabs to do other things and rely on the audio notification to know when to come back. This no longer works after Chrome (desktop) changed to disallow audio notifications.

How can I ensure the audio notifications still work in the background?

like image 929
Harry Avatar asked Feb 20 '16 16:02

Harry


People also ask

How do I autoplay audio in Chrome?

Just add an invisible iframe with an . mp3 as its source and allow="autoplay" before the audio element. As a result, the browser is tricked into starting any subsequent audio file.

How do I enable autoplay in Chrome?

Step 1 - Open the Google Chrome browser. Step 3 - Click the Autoplay policy drop-down and select "No user gesture is required." This will make it so that you don't need to intereact with the page in order for the video or audio to start playing automatically. Step 4 - Restart the browser.

How do I turn off autoplay on Google Chrome?

First, launch Chrome on your phone or tablet and go to Settings > Site Settings. Next, scroll down the menu and tap on Media, and then Autoplay and toggle the switch off.


2 Answers

The solution that worked for me was to play a small blank sound (0.1 second is enough) once the page is loaded. After that even if you switch to another tab, the tab in the background will still be able to play the sound on some external or internal event.

like image 165
Ostap Maliuvanchuk Avatar answered Sep 26 '22 03:09

Ostap Maliuvanchuk


Example 1

Here is an example that creates a div and uses HTML5 <audio> tag with a fallback to <embed> that plays an audio file 3 seconds after clicking the button.

To test it, run the sample and click the button, then change tabs and count 3 seconds. You should see the speaker icon on this tab and hear the coin drop sound after 3 seconds even though this tab is not the current tab.

function playCoinDrop() {
  soundDiv = document.createElement("div");
  soundDiv.innerHTML = '<audio autoplay="autoplay"><source src="http://themushroomkingdom.net/sounds/wav/smw/smw_coin.wav" type="audio/wav" /><embed hidden="true" autostart="true" loop="false" src="http://themushroomkingdom.net/sounds/wav/smw/smw_coin.wav" /></audio>';
}
<button onclick="setTimeout(playCoinDrop, 3000)">play sound</button>

You can replace the audio file as you see fit.


Example 2 - localStorage

Here is a more advanced way that utilizes localStorage which will probably be your best option. This allows you to preload the notification sound by downloading it into localStorage as Base64 and then you can invoke playing it when the tab is in the background without causing additional network transfers.

A major benefit to this approach is that there is only one download of the notification file, and then after that it is played locally from the browsers localStorage.

downloadCoin() function stores the file in localStoarge as base64
playCoinDrop() creates a div on the fly and plays the base64 data
playCoinDropJS() plays the base64 data without creating any div

function downloadCoin() {
  var coin = 'smw_coin.wav';
  var xhr = new XMLHttpRequest();
  xhr.open('GET', coin, true);
  xhr.responseType = 'blob';
  xhr.onload = function(e) {
    if (this.status == 200) {
      var blob = new Blob([this.response], {
        type: 'audio/wav'
      });
      var reader = new window.FileReader();
      reader.readAsDataURL(blob);
      reader.onloadend = function() {
        var coinB64 = reader.result;
        var myStorage = localStorage.setItem('coin_base64', coinB64)
      }
    }
  };
  xhr.send();
}

function playCoinDrop() {
  var coinB64 = localStorage.getItem('coin_base64');
  var soundDiv = document.createElement('div');
  soundDiv.innerHTML = '<audio autoplay="autoplay"><source src="' + coinB64 + '" type="audio/wav" />';
}

function playCoinDropJS(){
    var coinB64 = localStorage.getItem("coin_base64");
    var snd = new Audio(coinB64); 
    snd.play();
}
<button onclick="downloadCoin()">download</button>
<button onclick="setTimeout(playCoinDrop, 3000)">play sound</button>
<button onclick="setTimeout(playCoinDropJS, 3000)">play sound JS</button>

demo on github

like image 28
Tim Penner Avatar answered Sep 26 '22 03:09

Tim Penner