AVSpeechSynthesizer的问题,任何解决方法?
我正在使用AVSpeechSynthesizer播放文本。 我有一系列的发言。
NSMutableArray *utterances = [[NSMutableArray alloc] init]; for (NSString *text in textArray) { AVSpeechUtterance *welcome = [[AVSpeechUtterance alloc] initWithString:text]; welcome.rate = 0.25; welcome.voice = voice; welcome.pitchMultiplier = 1.2; welcome.postUtteranceDelay = 0.25; [utterances addObject:welcome]; } lastUtterance = [utterances lastObject]; for (AVSpeechUtterance *utterance in utterances) { [speech speakUtterance:utterance]; }
我有一个取消button来停止说话。 当我说第一个话语时点击取消button时,讲话停止,并清除队列中的所有话语。 如果在说出第一个话语(即第二话语)之后按下取消button,则停止话语不会冲洗话语队列。 我正在使用的代码是:
[speech stopSpeakingAtBoundary:AVSpeechBoundaryImmediate];
有人可以确认,如果这是一个错误的API或我使用API不正确? 如果这是一个错误,有没有解决这个问题的解决方法?
很可能是一个错误,因为委托方法合成器didCancelSpeechUserrance没有被调用后的第一个话语;
解决方法是链接话语,而不是把它们放在一个数组中,并一次排队。
使用委托方法合成器didFinishSpeechUtterance增加一个数组指针,并说出该数组中的下一个文本。 然后,当试图停止讲话时,在尝试说出下一个文本之前,设置一个在此委托方法中被选中的BOOL。
例如:
1)在正在进行语音合成的视图控制器中实现协议
#import <UIKit/UIKit.h> @import AVFoundation; @interface ViewController : UIViewController <AVSpeechSynthesizerDelegate> @end
2)实例化AVSpeechSynthesizer并将其委托设置为self
speechSynthesizer = [AVSpeechSynthesizer new]; speechSynthesizer.delegate = self;
3)使用发言计数器,在开始发言时设置为零
4)用一组文本说话
textArray = @[@"Mary had a little lamb, its fleece", @"was white as snow", @"and everywhere that Mary went", @"that sheep was sure to go"];
5)添加委托方法didFinishSpeechUtterance从文本数组中发出下一个话语并增加发言计数器
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didFinishSpeechUtterance:(AVSpeechUtterance *)utterance{ if(utteranceCounter < utterances.count){ AVSpeechUtterance *utterance = utterances[utteranceCounter]; [synthesizer speakUtterance:utterance]; utteranceCounter++; } }
5)停止发言,将发言计数器设置为文本数组的计数,并尝试让合成器停止
utteranceCounter = utterances.count; BOOL speechStopped = [speechSynthesizer stopSpeakingAtBoundary:AVSpeechBoundaryImmediate]; if(!speechStopped){ [speechSynthesizer stopSpeakingAtBoundary:AVSpeechBoundaryWord]; }
6)再次说话时,将话语计数器重置为零
我find了一个解决方法:
- (void)stopSpeech { if([_speechSynthesizer isSpeaking]) { [_speechSynthesizer stopSpeakingAtBoundary:AVSpeechBoundaryImmediate]; AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:@""]; [_speechSynthesizer speakUtterance:utterance]; [_speechSynthesizer stopSpeakingAtBoundary:AVSpeechBoundaryImmediate]; } }
调用stopSpeakingAtBoundary:
排队一个空的话语并调用stopSpeakingAtBoundary:
再次停止并清理队列。
这里的所有答案都失败了,我想到的是停止合成器,然后重新实例化它:
- (void)stopSpeech { if([_speechSynthesizer isSpeaking]) { [_speechSynthesizer stopSpeakingAtBoundary:AVSpeechBoundaryImmediate]; _speechSynthesizer = [AVSpeechSynthesizer new]; _speechSynthesizer.delegate = self; } }
我做了类似于SPA提到的东西。 从循环中一次一个地发言。 这是主意
NSMutableArray *arr; //array of NSStrings, declared as property AVSpeechUtterance *currentUtterence; //declared as property AVSpeechSynthesizer *synthesizer; //property - (void) viewDidLoad:(BOOL)anim { [super viewDidLoad:anim]; synthesizer = [[AVSpeechSynthesizer alloc]init]; //EDIT -- Added the line below synthesizer.delegate = self; arr = [self populateArrayWithString]; //generates strings to speak } //assuming one thread will call this - (void) speakNext { if (arr.count > 0) { NSString *str = [arr objectAtIndex:0]; [arr removeObjectAtIndex:0]; currentUtterence = [[AVSpeechUtterance alloc] initWithString:str]; //EDIT -- Commentted out the line below //currentUtterence.delegate = self; [synthesizer speakUtterance:utteranc]; } } - (void)speechSynthesizer:(AVSpeechSynthesizer *)avsSynthesizer didFinishSpeechUtterance:(AVSpeechUtterance *)utterance { if ([synthesizer isEqual:avsSynthesizer] && [utterance isEqual:currentUtterence]) [self speakNext]; } - (IBOutlet) userTappedCancelledButton:(id)sender { //EDIT <- replaced the object the method gets called on. [synthesizer stopSpeakingAtBoundary:AVSpeechBoundaryImmediate]; [arr removeAllObjects]; }
即使在didFinishSpeechUtterance方法中链接了话语,didCancelSpeechUserrance也不能与相同的AVSpeechSynthesizer对象一起使用。
-(void)speakInternal { speech = [[AVSpeechSynthesizer alloc] init]; speech.delegate = self; [speech speakUtterance:[utterances objectAtIndex:position++]]; }
在speakInternal中,我多次创buildAVSpeechSynthesizer对象以确保didCancelSpeechUtterance正常工作。 一种解决方法。
- 为什么heightForRowAtIndexPath:在cellForRowAtIndexPath之前:?
- 如何使一个可扩展的表格视图单元格?
- 在button上单击iOS中的另一个视图控制器
- 应用程序只启用肖像,但UIImagePickerController在iOS6中旋转
- 正确实现父/子NSManagedObjectContext
- iOS 5的Twitter框架:Tweeting没有用户input和确认(模态视图控制器)
- iOS – 防止iPhoneconfiguration文件被删除或检查是否已安装
- 在UIPopover中显示UINavigationController内容偏移量
- Xcode:将结构化数据放入Localizable.strings文件中