iOS background audio going nicely here under Unity, but I need a trigger to start the next audio track when the current track completes. Normally, there is setCallback() + FMOD_CHANNELCONTROL_CALLBACK_END, but apparently under iOS background mode, that callback doesn’t get fired until the app returns to the foreground.
What options are there to detect the end of a sound (stream) under these conditions?
As per our docs on Lock Screen & Background Audio on iOS, if you choose an AudioSession category that supports background audio, and enable background audio in your info property list, FMOD should work with iOS background mode as it normally does - have you done both of these things?
Also, I recall from one of your previous posts that you were only using the Core API, so just to clarify, are you using the FMOD for Unity integration, or your own C# wrapper?
Each frame getOpenState() is called. On the first OPENSTATE.READY for a track, system.playSound() is called and channel.setCallback() is bound.
When the channel callback sees CHANNELCONTROL_CALLBACK_TYPE.END it prints to log and do an iOS callback that queues UnityBatchPlayerLoop() to trigger a Unity Update() pass.
When not in background mode, things work as expected (once Update() sees a OPENSTATE.READY during playback, it initiates starting a new track).
In background mode, the CHANNELCONTROL_CALLBACK_TYPE callback does not show up until I switch back to foreground (confirmed by running under Xcode and not seeing that log message when the stream ends).
Perhaps the callback is only pushed from inside something like system.update() so therefore is not made until the Unity update loop resumes?
Thanks for the detailed repro! I’ve done some testing on my end, and I’m able to reproduce what you describe - i.e. CHANNELCONTROL_CALLBACK not firing when in background mode - when the AVAudioSession is configured incorrectly. If background audio capability is enabled in XCode (info.plist or target platform capabilities), and I set the app’s AudioSession to use the option: AVAudioSessionCategoryOptionMixWithOthers, then CHANNELCONTROL_CALLBACK_TYPE.END is fired as expected even when backgrounded. Please give that a shot and see whether it resolves your issue.
Strangely, adding ...MixWithOthers (with category AVAudioSessionCategoryPlayback) the background event still not not fire here. Unfortunately, even if it did, ...MixWithOthers removes the lock screen play control center (play/pause, prev/next, etc) which would be an issue since we are building a music player.
I have confirmed UIBackgroundModes contains audio (and also added fetch just in case that matters). If I am not mistaken, the app wouldn’t even be playing in the background if this was not set correctly.
This has been quite frustrating and time consuming your assistance is much appreciated! Any other thoughts? Hmm, what else could have caused the change you saw over there?