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