phaserjs / phaser-ce

Phaser CE is a fun, free and fast 2D game framework for making HTML5 games for desktop and mobile web browsers, supporting Canvas and WebGL rendering.

Home Page:http://phaser.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Phaser does not handle WebAudio interrupted state

SBCGames opened this issue · comments

A bug in the API: all versions

Currently Phaser does not handle "interrupted" state of WebAudio context. At least on iOS it is easy to get into it - just interrupt running game with incoming call (I used Skype to simulate it on iPad). After return into game audio is not playing and debug.sound says, that Wab Audio is interrupted.

I found, that I can simply resume context like this in SoundManager.update():

    update: function () {
        :
        :

        if (this.usingWebAudio && !this._interruptHandlingOn && this.context.state === 'interrupted')
        {
            this._interruptHandlingOn = true;
            var self = this;
            this.context.resume().then(function() {
                self._interruptHandlingOn = false;
            });
        }

        :
        :

I do not know, whether context state is changed immediatley, so I am using _interruptHandlingOn variable as lock to prevent calling resume multiple times. Lock is reset on Promise .then(). As it works with Promise returned by context.resume(), it may be problem if Promise is not supported.

There is possibility to use context.onstatechange instead of Promise, it looks like this:

        if (this.usingWebAudio && !this._interruptHandlingOn && this.context.state === 'interrupted')
        {
            this._interruptHandlingOn = true;
            var self = this;
   
            this.context.onstatechange = function() {
                self._interruptHandlingOn = false;            
                self.context.onstatechange = null;            
            }

            this.context.resume();
        }
commented

I think I can just resume the audio context for every game "focus" event.

commented

I can also add a SoundManager#onStateChange signal, but I'm not sure it would be super useful by itself.

commented

Here is a try at automatic resume: phaser-test.js.zip

Yes, this seems to work. Audio is resumed when returning from incoming call. Thanks 🥇 !