我正在使用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];
}
我有个取消按钮要停止讲话。当我在第一次发言时单击“取消”按钮时,该演讲停止,它将清除队列中的所有语句。如果我在第一次发言(即第二次发言)之后按下“取消”按钮,那么停止讲话并不会刷新语音队列。我为此使用的代码是:
[speech stopSpeakingAtBoundary:AVSpeechBoundaryImmediate];
是否有人能确认这是API中的错误,还是我使用了错误的API?如果它是一个bug,有什么解决办法来解决这个问题吗?
发布于 2013-11-18 17:32:19
很可能是一个错误,因为委托方法合成器didCancelSpeechUtterance不会在第一次发言之后调用;
一种解决办法是将话语串起来,而不是将它们放在一个数组中,然后立即排队。
使用委托方法合成器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)当再次发言时,将话语计数器重置为零。
发布于 2014-03-06 15:40:02
我找到了一个解决办法:
- (void)stopSpeech
{
if([_speechSynthesizer isSpeaking]) {
[_speechSynthesizer stopSpeakingAtBoundary:AVSpeechBoundaryImmediate];
AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:@""];
[_speechSynthesizer speakUtterance:utterance];
[_speechSynthesizer stopSpeakingAtBoundary:AVSpeechBoundaryImmediate];
}
}
调用stopSpeakingAtBoundary:
,对空语句进行排队,并再次调用stopSpeakingAtBoundary:
来停止和清理队列。
发布于 2016-09-10 03:24:13
这里所有的答案都失败了,我想出的是停止合成器,然后重新实例化它:
- (void)stopSpeech
{
if([_speechSynthesizer isSpeaking]) {
[_speechSynthesizer stopSpeakingAtBoundary:AVSpeechBoundaryImmediate];
_speechSynthesizer = [AVSpeechSynthesizer new];
_speechSynthesizer.delegate = self;
}
}
https://stackoverflow.com/questions/19672814
复制相似问题