IOS 9 Web Audio Issue

When iOS 9 came out a lot of HTML5 games using the Web Audio API on Safari Mobile went silent. Audio events such as loaded and play complete work so the games work, except without sound. This post is here to investigate why and how to fix it.

This issue seems to be fixed as of iOS 9.2.1.

Simple Web Audio Player Test

I created a simplified web audio player (mp3, iOS only, etc.). Tapping the "Load Sound" will call the player.load method. Tapping afterward will call the player.play method.

In the first version we initiate the sound load via a touchstart event. This approach fails in iOS 9.0 - 9.2.

Load Sound

In the second version we initiate the sound load via a touchstart and mousedown event. This approach works even in iOS 9.0 - 9.2.

Load Sound

In the third version we initiate the sound load via a touchend event. This approach works even in iOS 9.0 - 9.2.

Load Sound

Code

Here is the code for the simplified web audio player:

var simpleWebAudioPlayer = function () {
  "use strict";
	
  var player = {},
    sounds = [],
    ctx,
    masterGain;
	
  player.load = function (sound, callback) {
    var request;
		
    sounds[sound.name] = sound;
	
    // Load the sound
    request = new window.XMLHttpRequest();
    request.open("get", sound.src, true);
    request.responseType = "arraybuffer";
    request.onload = function() {
      ctx.decodeAudioData(request.response, function(buffer) {
        sounds[sound.name].buffer = buffer;
          // Invoke a function if a callback is specified
          if (sounds[sound.name].callback) {
            sounds[sound.name].callback();
          }
        });
      };
      request.send();
    };
	
  player.play = function (name) {	
    var inst = {};
		
      if (sounds[name]) {
			
        // Create a new source for this sound instance
        inst.source = ctx.createBufferSource();
        inst.source.buffer = sounds[name].buffer;
        inst.source.connect(masterGain);
						
        // Play the sound
        inst.source.start(0);
      }
  };
	
  // Create audio context
  ctx = new window.AudioContext();
  // Create the master gain node
  masterGain = ctx.createGain();
  // Connect the master gain node to the context's output
  masterGain.connect(ctx.destination);

  return player;
};

See additional details on Adrian Holovaty's post: http://www.holovaty.com/writing/ios9-web-audio/

This issue seems to be fixed as of iOS 9.2.1.

Share This Post