javascriptiosaudiocreatejssoundjs

How to initialise SoundJS for IOS 9


We've been using the CreateJS suite for a while now, but have just realised that our audio is not working on IOS9. Unfortunately we only have one IOS9 test device, running IOS9.2.4, but are getting mixed results with audio playback.

The rough process I'm using is;

It would be advantageous to be able to preload all audio before presenting that splash screen. The splash screen was added initially to allow audio to play on mobile Safari, with an empty sound played on click. This does of course work for IOS7/8, but not for 9.

I've created this test case on codepen as an attempt to track down the issue and try some options.

Codepen sample

HTML

<p id="status">Hello World</p>
<canvas id="canvas" width="200" height="200"></canvas>

JS

var canvas, stage, rect;

function init() {
  canvas = document.getElementById('canvas');
  canvas.style.background = "rgb(10,10,30)";
  stage = new createjs.Stage("canvas");

  createjs.Touch.enable(stage);

  rect = new createjs.Shape();
  rect.graphics.f("#f00").dr(50,75,100, 50);
  rect.on("mousedown", handleStart, null, true);
  rect.on("touchend", handleStart, null, true);
  //rect.on("click", handleStart, null, true);
  stage.addChild(rect);
  stage.update();

  $('#status').text("Touch to Start");
  createjs.Sound.initializeDefaultPlugins();
  //createjs.Sound.alternateExtensions = ["ogg"];
  createjs.Sound.registerSound("https://www.freesound.org/data/previews/66/66136_606715-lq.mp3", "ding1");

}

function handleStart(event) {
  createjs.WebAudioPlugin.playEmptySound();

  $('#status').text("Touch to Play");

  rect.graphics._fill.style = '#0f0';
  rect.removeAllEventListeners();
  rect.on('click', handlePlay);
  stage.update();
}

function handlePlay(){
  createjs.Sound.play("ding1");
  $('#status').text("Playing");
}

init();

Apologies for the lack of ogg version, was struggling to get test files to load x-domain.

With this, audio partially works for us on IOS9. If we leave clicking the red rectangle (figure start button) and leave it ~20 seconds, then click the green button no audio plays. If we click it immediately, audio plays fine.

I have been reviewing this bug/thread and attempting to follow Grant's suggestions. I gather SoundJS v0.6.2 now automatically attempts to play the empty sound appropriate when plugins are initialized, however moving the initializeDefaultPlugins and registerSounds calls into the handleStart function appears to make no difference. If I'm understanding the issue correctly, calling the WebAudioPlugin.playEmptySound method should be sufficient?

Have also been looking at the event binding, trying mousedown/touchend instead of click, but the result is the same with the 20 second wait. Event also appears to fire twice, although I could probably dig deeper into that if I could get it to work correctly.

I'm aware of the Mobile Safe Approach article aimed at this issue, but the need for a namespace at this level would mean a substantial rewrite of our existing content. Could someone perhaps advise if it is completely necessary to take this approach? I'm under the impression it should be feasible by correctly playing some empty audio within that initial handler.

Can't actually get the main project to this point, but if I can get a working example perhaps I'll be a step closer.

Any thoughts would be appreciated!


Solution

  • The Mobile-safe tutorial is not really relevant anymore since the updates in 0.6.2. It will likely be updated or removed in the near future.

    Based on this, you should be able to play sound once anywhere in the document has been clicked, regardless of whether you listen for it or not.

    That is not to say that there isn't a bug, just that the steps you are taking shouldn't be necessary. I did some testing, and it appears to work in iOS9. Here is a simplified fiddle. https://jsfiddle.net/lannymcnie/b4k19fwc/ (link updated Dec 3, 2018)