Playing Sounds in All Browsers on All Platforms
May 28 2014 10:51pm | | Share

Playing Sounds in All Browsers on All Platforms

By Chad Upton

We've had the ability to play audio in the background of websites for at least 15 years now. So, you'd think it would be pretty easy to play a sound on any browser on any platform. You're probably reading this because you've discovered it isn't as easy as it should be. Once you get it working on Firefox, you notice it doesn't work on Chrome for Android. Once you've got it working on Chrome, you noticed it doesn't work on iOS. Then when it's working on iOS it doesn't work on Chrome anymore.

That said, it's fairly straight forward to give the user a way to play a song, but to trigger a sound from JavaScript on all desktop and mobile browsers is not simple -- until now.

Different browsers support different ways to play audio, each browser also supports different audio encoding formats. This is the most concise way I've discovered to play a sound on all popular browsers and platforms.

The trick is to combine HTML audio and the JavaScript audio API and then have the JavaScript use the one that is compatible with the current browser. In the case of html audio, let the browser decide which format it's going to play by providing the audio in all possible formats. The browser will use the first one it recognizes.

<html> 
<head> 
    <title>Audio Test</title> 
    <script> 
        var myAudioContext, myBuffers = {}, mySource; 
        function init() { 
            if ('webkitAudioContext' in window) { 
                myAudioContext = new webkitAudioContext(); 
                fetchSounds(); 
            } 
        } 
        function fetchSounds() { 
            var request = new XMLHttpRequest(); 
            request = new XMLHttpRequest(); 
            request.open('GET', 'sounds/beep.mp3', true); 
            request.responseType = 'arraybuffer'; 
            request.addEventListener('load', bufferSound, false); 
            request.send(); 
        } 
        function bufferSound(event) { 
            var request = event.target; 
            var buffer = myAudioContext.createBuffer(request.response, false); 
            myBuffers['beep'] = buffer; 
        } 
        function playSound() { 
            var source = myAudioContext.createBufferSource(); 
            source.buffer = myBuffers['beep']; 
            source.loop = false; 
            source.connect(myAudioContext.destination); 
            source.noteOn(0); 
            mySource = source; 
        } 
        function play() { 
            if ('webkitAudioContext' in window) { 
                playSound(); 
            } else { 
                var snd = document.getElementById('audio'); 
                snd.play(); 
            } 
        }; 
    </script> 
    <style> 
        input { 
            display: block; 
        } 
    </style> 
</head> 
<body onload="init()"> 
    <audio id="audio" name="audio" > 
      <source src="sounds/beep.ogg" type="audio/ogg"> 
      <source src="sounds/beep.wav" type="audio/wave"> 
      <source src="sounds/beep.mp3" type="audio/mpeg"> 
      <source src="sounds/beep.m4a" type="audio/mpeg"> 
    Your browser does not support the audio element. 
    </audio> 
    <input id="play" onclick="play()" type="button" value="Play Sound"/> 
</body> 
</html>