如何在AVSpeechUtterance之后始终停止AVAudioSession

kro*_*oss 6 ios avaudiosession ios7 avspeechsynthesizer

我想做的是让我的应用程序AVSpeechSynthesizer在背景音频应用播放音频时使用话语.当我的应用发言时,我希望后台应用的音频"昏暗",然后在我的应用完成讲话后返回原始音量.

在我的AudioFeedback课堂上,我初始化我设置AVAudioSessions如下:

    self.session = [AVAudioSession sharedInstance];
    NSError *error;
    [self.session setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionDuckOthers error:&error];
Run Code Online (Sandbox Code Playgroud)

每当我想说一个新的话语时,我都会做以下事情.我按照AVSpeechSynthesizer的问题提出的建议,任何解决方法?每次创建一个新的AVSpeechSynthesizer以"确保"始终接收取消(它似乎工作,我不知道为什么).

- (AVSpeechUtterance *) utteranceWithString: (NSString *) string
{
    AVSpeechUtterance *utterance = [AVSpeechUtterance  speechUtteranceWithString:string];
    utterance.voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"en-ES"];
    [utterance setRate:(AVSpeechUtteranceDefaultSpeechRate+AVSpeechUtteranceMinimumSpeechRate)/2.0];
    return utterance;
}

- (void) sayString: (NSString *) string cancelPrevious: (BOOL) cancelPrevious
{
    [self.session setActive:enabled error:nil];
    if (cancelPrevious) {
        AVSpeechSynthesizer *oldSynthesizer = self.voice;
        self.voice = nil;
        [oldSynthesizer stopSpeakingAtBoundary:AVSpeechBoundaryImmediate];
        self.voice = [[AVSpeechSynthesizer alloc] init];
        self.voice.delegate = self;
    }

    // Keep track of the final utterance, we'll use this to determine whether or not we should stop the audio session
    self.finalUtterance = [self utteranceWithString:string];
    [self.voice speakUtterance:self.finalUtterance];
}
Run Code Online (Sandbox Code Playgroud)

在我的AVSpeechSynthesizer委托方法中,如果当前的AVSpeechSynthesizer和当前的AVSpeechUtterance匹配最后一个已知的合成器和话语,我检查是否应该停止音频会话以将背景音频返回到正常音量.

-(void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didFinishSpeechUtterance:(AVSpeechUtterance *)utterance
{
    NSError *error;
    // Only stop the audio session if this is the last created synthesizer
    if (synthesizer == self.voice  && self.finalUtterance == utterance) {
        if ([self.session setActive:enabled error:&error]]) {
            NSLog(@"Stopped the audio session: Speech synthesizer still speaking %d", synthesizer.speaking);
        } else {
            NSLog(@"ERROR failed to stop the audio session: %@. Speech synthesizer still speaking %d", error, synthesizer.speaking);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是,有时,音频会话将停止而没有问题,其他时候,音频会话将无法停止,并出现以下错误:

错误域= NSOSStatusErrorDomain代码= 2003329396"操作无法完成.(OSStatus错误2003329396.)"

我不知道如何保证我可以停止AVAudioSession.[[AVAudioSession sharedInstance] setActive:NO error:&error]只要我无法停止音频会话,我就试着继续打电话,但这似乎不起作用.任何帮助将不胜感激.谢谢!

Sha*_*DES 0

我也遇到过同样的问题,我相信我已经找到了原因。对我来说,如果我所说的短语太短,就会给出错误。如果“足够长”,则不会出现错误。

我测试过

NSString *phraseToSay = [NSString stringWithFormat:@"One Two Three Four Five"]; // Gives the error
NSString *phraseToSay = [NSString stringWithFormat:@"One Two Three Four Five Six"]; // No error
Run Code Online (Sandbox Code Playgroud)

我找到的唯一解决方案是使短语ToSay 更长。