我想做的是允许我的应用程序在后台音频应用程序播放音频时,使用AVSpeechSynthesizer来发出声音。当我的应用程序在讲话时,我希望后台应用程序的音频“昏暗”,然后在我的应用程序结束后返回到它们原来的音量。
在我的AudioFeedback类中,我初始化了AVAudioSessions,如下所示:
self.session = [AVAudioSession sharedInstance];
NSError *error;
[self.session setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionDuckOthers error:&error];每当我想说一句新的话时,我会做以下几件事。我遵循An issue with AVSpeechSynthesizer, Any workarounds?的建议,每次创建一个新的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];
}在我的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);
}
}
}我遇到的问题是,有时音频会话将在没有问题的情况下停止,而其他时候,音频会话将因以下错误而无法停止:
错误Domain=NSOSStatusErrorDomain Code=2003329396“操作无法完成。(OSStatus错误2003329396。)
我不知道如何保证我能阻止AVAudioSession。我一直试图打电话给[[AVAudioSession sharedInstance] setActive:NO error:&error],只要我不能停止音频会话,但这似乎不起作用。任何帮助都将不胜感激。谢谢!
发布于 2014-05-23 12:38:52
我发现如果我在几秒钟内再试一次,它就能工作了。我在用这个密码。
-(void)configureAVAudioSession:(bool)active {
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
if (deactivationAttempt < 3) { // This doesn't always work first time, but don't want to keep trying forever if it decides not to work ever.
NSError *activationError = nil;
success = [audioSession setActive:active error:&activationError];
if (!success) {
NSLog(@"(de)activation ERROR");
++deactivationAttempt;
[self performSelector:@selector(configureAVAudioSession:) withObject:false afterDelay:2.0];
}
else { // Success!
deactivationAttempt = 0;
}
}
else { // Failed, but reset the counter in case we have more luck next time
deactivationAttempt = 0;
}
}从医生那里:
如果当前正在运行任何关联的音频对象(如队列、转换器、播放机或记录器),则禁用会话将失败。
我想这句话需要一段时间才能从队列中清除出来。
发布于 2014-03-07 00:09:48
我也有过同样的问题,我相信我已经找到了一个原因。对我来说,如果我说的这个短语太短,它就会产生错误。如果是“足够长”,就没有错误。
我测试了
NSString *phraseToSay = [NSString stringWithFormat:@"One Two Three Four Five"]; // Gives the error
NSString *phraseToSay = [NSString stringWithFormat:@"One Two Three Four Five Six"]; // No error我找到的唯一解决方案是使phraseToSay更长。
https://stackoverflow.com/questions/21893007
复制相似问题