Fix AudioContext not resuming properly.
Fixes https://github.com/playcanvas/engine/issues/3977
Summary
Fix AudioContext not resuming properly in Mobile devices. Previously, the AudioContext often broke when minimising / switching tabs and going back to the page. Once broken, no Audio could be played, and the only resolution was reloading the entire page. This PR addresses this by re-writing the entire SoundManager suspend / resume flow.
I've added documentation to the code, but basically:
- If
AudioContextis locked (verifiable by checking if theAudioContext.stateissuspendedright after creation), allSoundInstances will wait until the Context is unlocked to actually start playing; - Once unlocked,
SoundManager.resume()(called manually or automatically onvisibilitychange) will callaudioContext.resume()if state wasinterrupted, andSoundInstances will only resume once that call was successful; - Once unlocked, every time the
AudioContext'sstatechages (onstatechange), an additional check will be made to resume theAudioContext.
I confirm I have read the contributing guidelines and signed the Contributor License Agreement.
Testing
Test project using custom engine with changes: https://playcanv.as/p/nwJQKFeE/
Tested the following situations on iPhone Chrome and Safari:
- Test 1
- Open page
- Tap to start playing audio
- Minimize app, wait 30 seconds
- Back to app, audio resumes immediately
- Test 2
- Open page
- Minimize app, wait 30 seconds
- Back to app, audio doesn't resume (still locked)
- Tap to unlock, audio plays
- Test 3
- Open page
- Tap to start playing audio
- Minimize app, turn off screen, wait 30 seconds
- Turn screen back on, back to app, audio resumes immediately
Tested the following situations on MacBook Chrome and Safari:
- Test 1
- Open page
- Click to start playing audio
- Minimize app, wait 30 seconds
- Back to app, audio resumes immediately
- Test 2
- Open page
- Minimize app, wait 30 seconds
- Back to app, audio doesn't resume (still locked)
- Tap to unlock, audio plays
Tested the following situtation on MacBook & iPhone Chrome & Safari:

(Available here: https://playcanv.as/p/nwJQKFeE/) Wait for tank to pass through each sphere - which performs the action in the text. This is done so there's no user interaction which would unlock the page - this way we can test what happens when context is unlocked in various stages.