Latest Chrome Desktop update preventing SoundJS from playing sounds (related to autoplay)

1.5k Views Asked by At

I'm getting this JavaScript warning on the latest version of Chrome Desktop, which now prevents auto-playing of sound without user interaction: http://bgr.com/2018/03/22/google-chrome-autoplay-videos-sound-block/

So I'm getting this error/warning in my console logs: "The AudioContext was not allowed to start. It must be resume (or created) after a user gesture on the page"

Is there any way for me to resume sounds or the audio context of SoundJS upon user interaction, like a click or keyboard event on the page?

My setup is that I'm using preloadJS to load my MP3s like so:

queue.loadManifest([
  {id: 'sndScore', src: 'sndScore.mp3'}
]);

Then I play the sounds like this:

createjs.Sound.play("sndScore");

I tried putting a flag var unitInteracted= false; which I then set to true if the user interacts with the page, and modified my sound playing code like so to make sure that the page has been interacted with before I attempt to play sounds:

if (unitInteracted) {                                
  createjs.Sound.play("sndScore");
}

...but for some reason, I'm still getting the above error/warning and the page ends up still getting muted. Any way to unmute it once Chrome says: "The AudioContext was not allowed to start. It must be resume (or created) after a user gesture on the page"?

Thanks!

1

There are 1 best solutions below

3
Kaiido On

I didn't gone too deep into reading the source code of SoundJS, but it seems PreloadJS will trigger the creation of the AudioContext.

So to avoid it, you might need to start the fetching of your resources only in the user-gesture event: e.g you can present your users with a splash-screen, and only once they click a button on it, will you start fetching your audio resources:

// wait for user gesture
btn.onclick = e => {
  // now we can load our resources
  var queue = new createjs.LoadQueue();
  queue.installPlugin(createjs.Sound);
  queue.on("complete", handleComplete, this);
  queue.loadFile({
    id: "sound",
    src: "https://dl.dropboxusercontent.com/s/1cdwpm3gca9mlo0/kick.mp3"
  });
  btn.disabled = true;
  // and show our user we are loading things
  btn.textContent = 'loading';
};

function handleComplete() {
  // now we can play our sounds without issue
  btn.disabled = false;
  btn.textContent = 'play';
  btn.onclick = e =>
    createjs.Sound.play("sound");
  // we don't need a user gesture anymore
  setTimeout(btn.onclick, 2000);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/SoundJS/1.0.2/soundjs.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/PreloadJS/1.0.1/preloadjs.min.js"></script>

<!-- make it part of a splash-screen -->
<button id="btn">Let's start the awesome</button>