AVSpeechSynthesizer的问题,任何解决方法? [英] An issue with AVSpeechSynthesizer, Any workarounds?

查看:1129
本文介绍了AVSpeechSynthesizer的问题,任何解决方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用AVSpeechSynthesizer播放文本。我有一个发音阵列。

I am using AVSpeechSynthesizer to play text. I have an array of utterances to play.

    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];
    }

我有一个取消按钮可停止说话。当我说出第一个话语时点击取消按钮,语音停止,它清除队列中的所有话语。如果在说出第一话语(即第二话语)之后我按取消按钮,则停止话音不刷新话语队列。我使用的代码是:

I have a cancel button to stop speaking. When I click the cancel button when the first utterance is spoken, the speech stops and it clears all the utterances in the queue. If I press the cancel button after the first utterance is spoken (i.e. second utterance), then stopping the speech does not flush the utterances queue. The code that I am using for this is:

  [speech stopSpeakingAtBoundary:AVSpeechBoundaryImmediate];

有人可以确认这是API中的错误还是我使用API​​不正确?如果是错误,是否有解决这个问题的解决方法?

Can someone confirm if this is a bug in the API or am I using the API incorrectly? If it is a bug, is there any workaround to resolve this issue?

推荐答案

很可能是一个错误,委托方法合成器didCancelSpeechUtterance 在第一个语句后不被调用;

quite likely to be a bug, in that the delegate method synthesizer didCancelSpeechUtterance isn't called after the first utterance;

一个解决方法是链接语句,而不是将它们放在数组并立即排队。

A workaround would be to chain the utterances rather than have them in an array and queue them up at once.

使用代理方法 synthesizer didFinishSpeechUtterance 增加数组指针,并从该数组中下一个文本。然后,当试图停止语音时,在尝试说出下一个文本之前,设置在此委托方法中检查的BOOL。

Use the delegate method synthesizer didFinishSpeechUtterance to increment an array pointer and speak the the next text from that array. Then when trying to stop the speech, set a BOOL that is checked in this delegate method before attempting to speak the next text.

例如:

1)在执行语音合成的视图控制器中实现协议



1) implement the protocol in the view controller that is doing the speech synthesis

#import <UIKit/UIKit.h>
@import AVFoundation;
@interface ViewController : UIViewController <AVSpeechSynthesizerDelegate>

@end

2)实例化AVSpeechSynthesizer并将其委托设置为self

2) instantiate the AVSpeechSynthesizer and set its delegate to self

speechSynthesizer   = [AVSpeechSynthesizer new];
speechSynthesizer.delegate = self;

3)使用发音计数器,在发言开始时设置为零

3) use an utterance counter, set to zero at start of speaking

4)使用文本数组说话

4) use an array of texts to speak

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从数组中说出下一个语句
增加语音计数器

5) add delegate method didFinishSpeechUtterance to speak the next utterance from the array of texts and increment the utterance counter

- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didFinishSpeechUtterance:(AVSpeechUtterance *)utterance{
    if(utteranceCounter < utterances.count){
        AVSpeechUtterance *utterance = utterances[utteranceCounter];
        [synthesizer speakUtterance:utterance];
        utteranceCounter++;
    }
}

5)停止说话,将发声计数器设置为

5) to stop speaking, set the utterance counter to the count of the texts array and attempt to get the synthesizer to stop

utteranceCounter = utterances.count;

BOOL speechStopped =  [speechSynthesizer stopSpeakingAtBoundary:AVSpeechBoundaryImmediate];
if(!speechStopped){
    [speechSynthesizer stopSpeakingAtBoundary:AVSpeechBoundaryWord];
}

6)再次发言时,将发声计数器重置为零

6) when speaking again, reset the utterance counter to zero

这篇关于AVSpeechSynthesizer的问题,任何解决方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆