1

My application wants to play some text when it is available, and if there is some music playing in the background I want to lower the voice for the music while my app is playing its text, what I did is:

[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback
                                 withOptions:AVAudioSessionCategoryOptionDuckOthers
                                      error:&err];
[[AVAudioSession sharedInstance] setActive:YES error:&err];

The option AVAudioSessionCategoryOptionDuckOthers will lower the music volume while my app is playing its text. Then play the text with the speechSynthesizer, after that in:

- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didFinishSpeechUtterance:(AVSpeechUtterance *)

utterance I do:

[[AVAudioSession sharedInstance] setActive:NO withFlags:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];

so the music will be back to it original volume.

The problem by setting the session active to NO, I am loosing the volume control (the iPhone hardware volume control the one in the left side of the phone). i.e I can not upper or lower the volume for my app unless there is a text actively playing in my app at the moment I am changing the volume.

Alladinian
  • 34,483
  • 6
  • 89
  • 91

2 Answers2

2

Thank you very much, It works if I did this, before I play my text:

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

I had to setActive:NO as without it the second time when I play my text the music will be paused!!

And then After I play my text, I do this:

[[AVAudioSession sharedInstance] setActive:NO withOptions:0 error:nil];
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryAmbient withOptions: 0 error: nil];
[[AVAudioSession sharedInstance] setActive:YES withOptions: 0 error:nil];
0

Immediately after setting setActive: to NO, set it to YES again! Set the category to Ambient so the background sound can continue playing.

So, before you play:

[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryAmbient
                                 withOptions: AVAudioSessionCategoryOptionDuckOthers
                                       error: nil];
[[AVAudioSession sharedInstance] setActive:YES withOptions: 0 error:nil];

After you play:

[[AVAudioSession sharedInstance] setActive:NO withOptions:0 error:nil];
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryAmbient
                                 withOptions: 0
                                       error: nil];
[[AVAudioSession sharedInstance] setActive:YES withOptions: 0 error:nil];
matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Here's my discussion of audio sessions, including a working example of ducking: http://www.apeth.com/iOSBook/ch27.html#_audio_session – matt Apr 22 '14 at 21:50
  • So in `didFinishSpeechUtterance` I did this:`[[AVAudioSession sharedInstance] setActive:NO withOptions:0 error:nil]; [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient withOptions: 0 error: nil]; [[AVAudioSession sharedInstance] setActive:YES withOptions: 0 error:nil];` – user3456603 Apr 23 '14 at 16:16
  • and when I need to play the second text from my app, the music in the background is stopped and never come back, it is stopped in this line: `[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionDuckOthers error:nil];` which I am setting before I play my app text every time. – user3456603 Apr 23 '14 at 16:21
  • Use `setCategory:AVAudioSessionCategoryAmbient` throughout. `Playback` stops other audio. Pls read the docs, and see the code I already referred you to. – matt Apr 23 '14 at 17:23
  • Thank you, Yes, I know that you recommended to use the `AVAudioSessionCategoryAmbient` but I need to use the `Playback` as I want the voice to my app to stand out and lower the music sound, but with `CategoryAmbient` the sound for my app voice will be mixed with the other music, and even though I am using the option `DuckOthers` I did not hear my app voice stand out over the music voice if I use `Ambient` – user3456603 Apr 23 '14 at 18:45
  • Because you didn't activate the session. You set the category but then you must activate it. Please look at the code! It works. – matt Apr 23 '14 at 19:17
  • You cannot use ducking with `Playback`. You may have thought it was working but it wasn't. `Playback` causes other audio to stop. – matt Apr 23 '14 at 19:23
  • Thanks matt for making your book available online, and I'm sure for some devices the behavior was as you write here, but I think at the very least you should note your code conflicts with Apple's dox which (now) say AVAudioSessionCategoryOptionDuckOthers is "Valid only if the audio session category is AVAudioSessionCategoryPlayAndRecord or AVAudioSessionCategoryPlayback." Also on an iOS9 iPhone 6 I am seeing the audio restart ok with Playback + Duck. So I think this code may be problematic on modern devices. At least people should be warned of this issue so they can decide for themselves. – Louis Semprini May 07 '16 at 10:06
  • Also I should note that when I stop the session I am using the AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation flag, which came in with iOS 6. It's possible that might be helping the audio to restart. – Louis Semprini May 07 '16 at 10:07