Search code examples
iosobjective-cavaudiosession

How can you configure AVAudioSession to duck music and pause spoken audio?


I'm working on a navigation app that uses AVSpeechSynthesizer to call out directions. If I'm playing a podcast I would like to be able to pause the audio while a direction is spoken and resume it afterwards. This is successfully achieved using:

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback
                               withOptions:AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers
                                       error:nil];

However, if I play music using the above code the instruction gets mixed with the music without the volume of the music being reduced - making it difficult to hear the instruction. So I tried:

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback
                                 withOptions:AVAudioSessionCategoryOptionDuckOthers
                                       error:nil]; 

Now the background music reduces in volume, which is what I want, but when I play spoken audio (i.e. a podcast) it is no longer paused and instead gets mixed with the instruction - albeit at a reduced volume.

What I really want is something like: AVAudioSessionCategoryOptionInterruptSpokenAudioAndDuckWithOthers. However, that doesn't exist. I know that this combination is possible, because other apps (like Waze) have this behaviour.

I know that you can detect when audio is playing using:

BOOL isOtherAudioPlaying = [[AVAudioSession sharedInstance] isOtherAudioPlaying];

But, I couldn't find a way of determining if that Audio was spoken or not. If I could I could set things up according to what is playing at any given time. Can anyone help with this, preferably in Objective C?


Solution

  • This is how it's done:

    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback
                                     withOptions:AVAudioSessionCategoryOptionDuckOthers | AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers
                                           error:nil];
    

    Works a charm!