iOS-Speech Framework

作者: Rick_Liu | 来源:发表于2016-12-06 16:59 被阅读856次

Speech Framework 是Apple公司在2016年WWDC上介绍的一个语音识别的API。它是Siri用来做语音识别的框架。在你的应用里面可以使用 Speech APIs 来拓展和提高语音识别功能,而不仅仅是单纯的使用键盘。

Speech APIs的执行需要使用一个设备内置的语音识别器和连接到苹果的服务器。如果发现语音识别器是用于一个特定的语言,例如英文、国语等,可以采用 SFSpeechRecognizerDelegate 协议。

因为你的应用可能需要连接到服务器进行识别,而这涉及到尊重用户的隐私问题,出于这个原因,我们在启动语音识别功能之前必须得到用户的明确许可。

做了一个demo,使用Speech Framework 实现语音转文字的功能。

Speech_DemoPic.png

上面这个效果图中的文字是识别我的话转出来的,接下来我们来实现一下。

1.我们要写个句子告诉用户在应用中可以如何使用这个语音功能。
例如,在这个例子中写了这么一句提示的话"Lets you mark an item as finished by saying Done."。

2.在 Info.plist里面添加两个键值对,分别是Privacy - Speech Recognition Usage Description (用于请求语音识别) 以及 Privacy - Microphone Usage Description(用于请求麦克风语音输入授权)。

3.创建 SFSpeechRecognizer 对象,使用 requestAuthorization: 去申请用户语音识别权限 。

@property (nonatomic,strong)SFSpeechRecognizer *speechRecognizer;

viewDidLoad:中初始化 speechRecognizer对象,并设置代理。

// zh-CN 代表是简体中文
 NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh-CN"];
    _speechRecognizer = [[SFSpeechRecognizer alloc] initWithLocale:locale];

    //把语音识别的代理设置为 self
    _speechRecognizer.delegate = self;

申请用户语音识别权限

[SFSpeechRecognizer requestAuthorization:^(SFSpeechRecognizerAuthorizationStatus status) {
       
        BOOL isButtonEnable = NO;

        //检查验证的状态。如果被授权了,让microphone按钮有效。如果没有,打印错误信息然后让microphone按钮失效。
        switch (status) {
            case SFSpeechRecognizerAuthorizationStatusAuthorized:
            {
                isButtonEnable = YES;
                NSLog(@"用户授权语音识别");
            }
                break;
            
            case SFSpeechRecognizerAuthorizationStatusDenied:
            {
                isButtonEnable = NO;
                NSLog(@"用户拒绝授权语音识别");
            }
                break;
            case SFSpeechRecognizerAuthorizationStatusRestricted:
            {
                isButtonEnable = NO;
                NSLog(@"设备不支持语音识别功能");
            }
                break;
            case SFSpeechRecognizerAuthorizationStatusNotDetermined:
            {
                isButtonEnable = NO;
                NSLog(@"结果未知 用户尚未进行选择");
            }
                break;
        }

运行后我们会发现授权请示如下:


语音识别授权.png 麦克风授权.png

4.在用户允许通过语音识别和麦克风授权之后,写一个方发startRecording用于语音识别请求。

//实例化recognitionRequest。在这里我们创建了SFSpeechAudioBufferRecognitionRequest对象。稍后我们利用它把语音数据传到苹果后台
    _recognitionRequest = [SFSpeechAudioBufferRecognitionRequest new];
    
    //当用户说话的时候让recognitionRequest报告语音识别的部分结果
    _recognitionRequest.shouldReportPartialResults = YES;
    
    //调用 speechRecognizer的recognitionTask 方法来开启语音识别。这个方法有一个completion handler回调。这个回调每次都会在识别引擎收到输入的时候,完善了当前识别的信息时候,或者被删除或者停止的时候被调用,最后会返回一个最终的文本      (进行请求)
    _recognitionTask = [_speechRecognizer recognitionTaskWithRequest:_recognitionRequest resultHandler:^(SFSpeechRecognitionResult * _Nullable result, NSError * _Nullable error) {
       
        //定义一个布尔值决定识别是否已经结束
        BOOL isFinal = NO;
        
        //如果结果 result 不是nil, 把 textView.text 的值设置为我们的最优文本。如果结果是最终结果,设置 isFinal为true
        if (result != nil) {
            
            self.textView.text = result.bestTranscription.formattedString;
            isFinal = result.isFinal;
        }
        
        //如果没有错误或者结果是最终结果,停止 audioEngine(语音输入)并且停止 recognitionRequest 和 recognitionTask.同时,使Start Recording按钮有效
        if (error != nil || isFinal) {
            
            [self.audioEngine stop];
            [inputNode removeTapOnBus:0];
            
            self.recognitionRequest = nil;
            self.recognitionTask = nil;
            
            self.microphoneButton.enabled = YES;
        }
    }];

在开始了recognitionTask之后向 recognitionRequest增加一个语音输入。Speech Framework 会在语音输入被加入的同时就开始进行解析识别

AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    
    [audioSession setCategory:AVAudioSessionCategoryRecord error:nil];
    [audioSession setMode:AVAudioSessionModeMeasurement error:nil];
    [audioSession setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];

    //检查 audioEngine(你的设备)是否有做录音功能作为语音输入
    AVAudioInputNode *inputNode = [_audioEngine inputNode];
    if (!inputNode) {
        NSLog(@"Audio engine has no input node");
    }

AVAudioFormat *recordingFormat = [inputNode outputFormatForBus:0];
    [inputNode installTapOnBus:0 bufferSize:1024 format:recordingFormat block:^(AVAudioPCMBuffer * _Nonnull buffer, AVAudioTime * _Nonnull when) {
       
        [self.recognitionRequest appendAudioPCMBuffer:buffer];
    }];

准备并且开始audioEngine,并让textView的文本为 "Say something, I'm listening!"。

    [_audioEngine prepare];
    [_audioEngine startAndReturnError:nil];
    _textView.text = @"Say something, I'm listening!";

我们让当前视图控制器作为speechRecognizer 的代理,在SFSpeechRecognizerDelegate中有可选的speechRecognizer:availabilityDidChange:方法,实现一下。

//当语音识别操作可用性发生改变时会被调用
- (void)speechRecognizer:(SFSpeechRecognizer *)speechRecognizer availabilityDidChange:(BOOL)available{

    if (available) {
        _microphoneButton.enabled = YES;
    }
    else{
        _microphoneButton.enabled = NO;
    }
}

下面是一些LocaleIdentifier,可以参考一下需要的语言。

LocaleIdentifier.png

到此,使用Speech Framework实现了语音转文字功能实现了。

相关文章

网友评论

    本文标题:iOS-Speech Framework

    本文链接:https://www.haomeiwen.com/subject/pzjrmttx.html