How do I make AVAudioSession work in silent mode and with .mixWithOthers

1.8k Views Asked by At

I'm writing an iOS app in Swift (Xcode 11.5) using AVAudioEngine

It's all working fine, but I can't get it to play along with other audio apps when the iPhone/iPad has the mute button off.

With this:

try AVAudioSession.sharedInstance().setCategory(.playback)

my audio works with the mute button on or off, but if I'm playing something from Apple Music, when I hit play on my audio, Apple Music pauses.

With this:

try AVAudioSession.sharedInstance().setCategory(.ambient, options: .mixWithOthers)

my audio works with Apple Music, but doesn't play if the mute button is off.

With this:

try AVAudioSession.sharedInstance().setCategory(.playback, options: [.mixWithOthers])

having .mixWithOthers makes no difference.

I'm sure there is a combination of options that will make it work with the mute button on or off and not stop other audio playing, but I can't find it!

TIA for any suggestions.

Ian

1

There are 1 best solutions below

6
On

I've figured this out and, as pointed out by matt, I was doing something wrong! I can't post my code here because it is pretty big. Basically, I've written and audio class that handles all the audio files, declares the engine, AVAudioEngine(); nodes, AVAudioPlayerNode(); and does all the playing and so on.

My mistake was to put this sort of stuff in that class, and it was obviously the wrong place:

do {
  let audioSession = AVAudioSession.sharedInstance()
  try audioSession.setActive(false)
  if resetOptions.muteOtherApps {
    try audioSession.setCategory(.playback, options: [])
  } else {
    try audioSession.setCategory(.playback, options: [.mixWithOthers])
  }
} catch {
  print("Audio error")
}

Since I'm letting the user choose between these options, it was convenient for me to put it in my main ViewController class. However, if it's set fixed for the app, from what I've read a good place to put it is in AppDelegate.Swift in the didFinishLaunchingWithOptions function. The main point, at least what worked for me, is to keep these things separate to the class that is actually managing the audio.

So, thanks Matt.

Ian