I’m looking for a way to set the iOS audio session category to MediaPlayback on iOS. I’m working on a musical toy using Unity, and I want it to override the device mute switch and always play audio.
Is there a way to set the audio session category somewhere? Or do I need to write some plugin code to change it?
If anyone else is trying to do this, I ended up writing a simple plugin to set the audio session category.
I created a .m file called iOSAudio.m and put it in Assets/Plugins/iOS.
iOSAudio.m:
#import <AVFoundation/AVFoundation.h>
void iOSAudio_setupAudioSession()
{
// We want to make sure all audio stops from other apps, and we want to
// ignore the ringer/mute switch.
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
OSStatus result = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);
result = AudioSessionSetActive(YES);
// Can check result if you want...
}
In my Unity C# code that runs on launch, I do this to declare the extern function:
#if UNITY_IOS
// Check that it's actually an iOS device/simulator, not the Unity Player.
if (Application.platform == RuntimePlatform.IPhonePlayer)
{
iOSAudio_setupAudioSession();
}
#endif
Hope that helps, if someone else is trying to do the same thing.
Owen
SetupAudioSession.cs does not need to be there, iOSAudio.m has to be there.
You will need to add SetupAudioSession.cs to a gameobject in the scene in order to run the script (runs on start, so when the gameobject gets activated).
The big problem I see here is that the session setting does not apply at the very start of the app. In my case, I want to allow other audio sources, therefore I use the category AVAudioSessionCategoryAmbient. The value applies at loading the scene and not at loading the app, so the standard setting applies in the splash screen which is AVAudioSessionCategorySoloAmbient. Therefore all playing audio sources are stopped at the start of the app. Of course they don’t start playing again when switching the mode, so the user would need to hit the play button again and then switch to the unity app.
I also tried running the script with RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad), sadly this didn’t fix the problem. I’m not that used to working with xcode directly, but is there maybe a way to set the audio session category in the settings there? Or where in the unity start files would I need to hack this into?
Hi @Annopolus
Yep, I did go with including the setting in UnityAppController.mm in the iOS project. I changed the behavior of willFinishLaunchingWithOptions:
Of course you would need to change that every time you build your project. Or you could use a PostBuild script that replaces the file as I did
Still using Unity 5.6, so maybe the function has changed, but the idea should still work.
Hi @Johannski !
You are the best! Thank you for this.
Definitely it works - when my app is starting, it let the background music (ie Spotify) continue to play.
One small add for all, who wants to use your fix: add at the beginning of UnityAppController.mm #import <AVFoundation/AVFoundation.h> where the declarations for AVAudioSession exists.
Great, again - thank you!
However…
My App has a part of audio processing. It uses Microphone to listen music to get a data for ie. visualization. On android it works well getting external or internal music data through the Mic activated:
but not on iOS. Above code stops background music from Spotify (in fact stops Spotify from play).
Generally above is a signal for me that the problem is not only with AVAudioSessionCategoryAmbient wrongly set, but there is something deeper in Unity Sound system and iOS platform.
Hi! Have you dealer with this problem?? The same problem in unity 2019.3.13f1 - I’m playing video via URL and have no sound in iOS platform, only in headphones.