bmueller
bmueller

Reputation: 2711

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?

Upvotes: 7

Views: 5998

Answers (3)

Lukasz Czerwinski
Lukasz Czerwinski

Reputation: 15452

  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)

Upvotes: 2

Aleksandar Vacić
Aleksandar Vacić

Reputation: 4531

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 :)

Upvotes: 13

bmueller
bmueller

Reputation: 2711

After investigating further, it seems like AVSpeechSynthesizer is breaking when the app is launched in the background (due to background fetch or whatever). A simple call to check whether the app is currently active before speaking solves the problem.

if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive)
    [self.speechSynthesizer speakUtterance:utt];

Upvotes: 0

Related Questions