2014-10-21 2 views
7

Я использую AVSpeechSynthesizer в одноэлементном режиме. В iOS 8, когда приложение получает какое-то время, когда он возобновляется, синглтон AVSpeechSynthesizer больше не будет говорить. Эта проблема не возникает на iOS 7.AVSpeechSynthesizer перестает работать после фонового рисунка

Когда приложение получает фоновый, следующее сообщение появляется в моем журнале:

AVSpeechSynthesizer Audio interruption notification: { 
    AVAudioSessionInterruptionTypeKey = 1; 
} 

Я инициализировать AVSpeechSynthesizer, как это в init методе Синглтон:

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?

+0

ли это произойдет на тренажере и самого устройства? – FiddleMeRagged

+0

На устройстве - AVSpeechSynthesizer вообще не работает на симуляторе (по крайней мере, в Xcode 6.0). – bmueller

+0

AVSpeechSynth работает в симуляторе в 8.2 beta 5. –

ответ

12

Я провел целый день, преследуя это безумие, и я думаю, что нашел решение. Моя проблема заключалась в том, что AVSpeechSynthesizer будет отлично работать на переднем плане и фон с уклоном другого звука прямо до момента вызова телефона.

В этот момент речь перестанет работать молча, без каких-либо ошибок. Все объекты все еще существуют, но вызовы делегатов не будут вызваны, ни начать, ни завершить.

Я заметил, что с помощью телефонных звонков мое приложение получит уведомление о AudioRouteChanged. Таким образом, когда это произойдет, я бы воссоздал речевую настройку: в основном уничтожьте существующий AVSpeechSynthesizer и снова создайте его. С этого момента разговор продолжится. Это будет даже работать во время телефонного звонка :)

+0

Да, это работает! Спасибо, что нашли время, чтобы отсортировать его. О, и правильное имя уведомления - 'AVAudioSessionRouteChangeNotification' для всех, кто получает это в будущем. – bmueller

+0

Неужели этот хак по-прежнему работает? У меня такой же сценарий, но в моем случае это не работает. iOS8.3/Xcode 6.3.2.Я использую AVAudioSessionCategoryPlayback + AVAudioSessionCategoryOptionDuckOthers – Ivan

+0

Мне пришлось использовать: var err: NSError? = nil AVAudioSession.sharedInstance(). setCategory (AVAudioSessionCategoryAmbient, error: & err) – BaseZen

0

После исследования, похоже, что AVSpeechSynthesizer ломается, когда приложение запускается в фоновом режиме (из-за фоновой выборки или чего-то еще). Простой вызов, чтобы проверить, активно ли приложение в данный момент, прежде чем говорить, решит проблему.

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

Но, используя это, вы в основном не позволяете говорить, работая в фоновом режиме, что не идеально, особенно для фитнес-приложений. AVSpeechSynth отлично работает в фоновом режиме до телефонного звонка, после чего звонки делегатов AVSpeechSynth не происходят, и разговоры вообще не выполняются. –

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://stackoverflow.com/a/19200177/330067)