Hello,
Are there new updates fixes for iOS 17.5.1+ and iOS 18+ to prevent audio interruption during focus changes in Safari in the latest Phaser CE version?
Hello,
Are there new updates fixes for iOS 17.5.1+ and iOS 18+ to prevent audio interruption during focus changes in Safari in the latest Phaser CE version?
No, but we could add it.
Thanks samme. It would be awesome if you add that fix. Many many games and developers could benefit of it. Personally, I faced this issue in the last game I made which was a mahjong game. And now I am making an awesome match3 game using the latest phaser CE version. The game is almost finished and again it would be great that this fix will be added to phaser CE.
I don’t think I’ve reproduced the problem in iOS 16 and Phaser CE v2.20. See if you can reproduce it here (or full view):
I tested the example on both IOS 15 and IOS 18. And I could reproduce the problem using IOS 18 and the example you put. The audio stops if I click on home button and then go back to the example.
IOS 15:
https://www.dropbox.com/scl/fi/qp6dyg6e6porskowlp2by/IOS15.MP4?rlkey=z42w1t6fxmqlnso7tbpf37q55&e=1&st=u5wphj9f&dl=0
IOS 18:
https://www.dropbox.com/scl/fi/qm5jj2jqu5tv3l3yi34cd/IOS18.MP4?rlkey=x1k4667iovznqwex29q2geb9u&st=5zs4r2am&dl=0
I ran into the same audio issues on iOS 17.5–18 when using Phaser 2 and some older Phaser 3 builds. Even the official fixes added to the Phaser repo didn’t fully solve the problem in some cases, at least one device (iPhone 13 on iOS 18.6.2) was still affected. The only thing that reliably worked for me was the approach below.
Here’s the approach that solved it for me:
let runningOnIoS = /iPad|iPhone|iPod/.test(navigator.platform) ||
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
let onGameResume = () => {
game.sound.unlock();
if (runningOnIoS) {
game.sound.context.suspend();
game.sound.context.resume();
window.addEventListener(
'pointerup',
() => {
game.sound.context.suspend();
game.sound.context.resume();
},
{ once: true }
);
}
};
Then hook it to Phaser events (smthg like that):
//Phaser 3
this.game.events.addListener(Phaser.Core.Events.FOCUS, onGameResume, this);
this.game.events.addListener(Phaser.Core.Events.VISIBLE, onGameResume, this);
//Phaser 2
this.game.onResume.add(() => onGameResume());
Or, if you prefer using the document API:
document.addEventListener('visibilitychange', () => {
if (!document.hidden) {
onGameResume();
}
});
This combination has worked for me in every case so far.