【问题标题】:AVSpeechSynthesizer stops working after backgroundingAVSpeechSynthesizer 在后台运行后停止工作
【发布时间】:2015-08-06 15:03:26
【问题描述】:

我在单例中使用AVSpeechSynthesizer。在 iOS 8 中,当应用程序在后台运行一段时间后,当它恢复时,AVSpeechSynthesizer 单例将不再说话。此问题在 iOS 7 上不会发生。

当应用程序进入后台时,我的日志中会显示以下消息:

AVSpeechSynthesizer Audio interruption notification: {
    AVAudioSessionInterruptionTypeKey = 1;
}

我在单例的init 方法中像这样初始化AVSpeechSynthesizer

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

我这样说utterance

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];

有没有人在 iOS 8 上看到过类似的东西?

【问题讨论】:

  • 模拟器和设备本身会发生这种情况吗?
  • 在设备上 - AVSpeechSynthesizer 在模拟器上根本不工作(至少在 Xcode 6.0 中)。
  • AVSpeechSynth 在 8.2 beta 5 的模拟器中工作。

标签: ios ios8 avspeechsynthesizer


【解决方案1】:

我花了一整天的时间来追逐这种精神错乱,我想我已经找到了解决办法。我的问题是AVSpeechSynthesizer 在前景和背景中都可以正常工作,并且会一直躲避其他音频,直到接到电话。

在那一刻,说话将停止工作,没有任何错误。所有对象仍然存在,但不会调用委托调用,既不会开始也不会结束。

我注意到,通过电话,我的应用会收到有关AudioRouteChanged 的通知。因此,当这种情况发生时,我会重新创建语音设置:基本上销毁现有的AVSpeechSynthesizer 并重新创建它。从那时起,说话将继续工作。它甚至可以在通话期间工作:)

【讨论】:

  • 是的,这行得通!感谢您抽出宝贵的时间进行整理。哦,正确的通知名称是 AVAudioSessionRouteChangeNotification,对于将来收到此通知的任何人。
  • 这个黑客仍然有效吗?我有同样的情况,但在我的情况下这不起作用。 iOS8.3/Xcode 6.3.2。我正在使用 AVAudioSessionCategoryPlayback + AVAudioSessionCategoryOptionDuckOthers
  • 我不得不使用:var err: NSError? = nil AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient, error: &err)
  • 它仍然有效。 iOS9.1。这为我节省了很多时间。谢谢。
  • 你能发布正确的代码来解决这个问题吗?我有同样的问题,我有时只能得到这个..谢谢!!
【解决方案2】:
  1. 您必须在后台模式下设置“音频和 AirPlay”。
  2. 您必须在 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
    }
    

(见此贴:https://*.com/a/19200177/330067

【讨论】:

    【解决方案3】:

    经过进一步调查,当应用在后台启动时(由于后台提取或其他原因),似乎 AVSpeechSynthesizer 正在中断。一个简单的调用来在说话之前检查应用程序当前是否处于活动状态即可解决问题。

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

    【讨论】:

    • 但是使用这个,你基本上可以防止说话在后台工作,这并不理想,尤其是对于健身应用程序。 AVSpeechSynth 在后台工作得很好,直到接到电话,之后 AVSpeechSynth 代表呼叫不会发生,也不会说话。
    最近更新 更多