Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AVSpeechSynthesizer stops working after backgrounding

I'm using AVSpeechSynthesizer in a singleton. In iOS 8, when the app gets backgrounded for a while, when it resumes the AVSpeechSynthesizer singleton will no longer speak. This issue does not happen on iOS 7.

When the app gets backgrounded, the following message shows up in my log:

AVSpeechSynthesizer Audio interruption notification: {
    AVAudioSessionInterruptionTypeKey = 1;
}

I initialize the AVSpeechSynthesizer like this in the singleton's init method:

    self.speechSynthesizer = [[AVSpeechSynthesizer alloc] init];
    self.speechSynthesizer.delegate = self;

and I speak the utterance like this:

AVSpeechUtterance *utt = [[AVSpeechUtterance alloc] initWithString:dialogue];
utt.voice = [AVSpeechSynthesisVoice voiceWithLanguage:voice];

utt.pitchMultiplier = pitch;
utt.rate = rate;
utt.preUtteranceDelay = preDelay;
utt.postUtteranceDelay = postDelay;
utt.volume = volumeSetting;

[self.speechSynthesizer speakUtterance:utt];

Has anyone seen anything like this on iOS 8?

like image 227
bmueller Avatar asked Oct 21 '14 04:10

bmueller


2 Answers

I spent entire day chasing this insanity and I think I have found solution. My issue was that AVSpeechSynthesizer would work fine in foreground and background with ducking other audio right until the moment a phone call happens.

At that moment, speaking would stop working silently, without any errors. All the objects are still there but delegate calls would not get called, neither start nor finish.

I noticed that with phone calls, my app would get notification about AudioRouteChanged. Thus when that happens, I would re-create the speech setup: basically destroy existing AVSpeechSynthesizer and re-create it again. From then on, speaking will continue working. It would even work during the phone call :)

like image 159
Aleksandar Vacić Avatar answered Nov 15 '22 15:11

Aleksandar Vacić


  1. You must set "Audio and AirPlay" in background modes.
  2. You have to configure the audio session in your AppDelegate:

    NSError *error = NULL;
    AVAudioSession *session = [AVAudioSession sharedInstance];
    [session setCategory:AVAudioSessionCategoryPlayback error:&error];
    if(error) {
        // Do some error handling
    }
    [session setActive:YES error:&error];
    if (error) {
        // Do some error handling
    }
    

(See this post: https://stackoverflow.com/a/19200177/330067)

like image 34
Lukasz Czerwinski Avatar answered Nov 15 '22 15:11

Lukasz Czerwinski