iOS原生语音识别使用的正确姿势

8年前
   <p>语音识别技术这几年在移动App上的应用越来越广,各种第三方语音识别SDK也是层出不穷,例如科大讯飞、百度语音等,同时引入语音识别技术也是一个提高App逼格的好方法:grin:。所以今年的WWDC上,苹果开放了他的语音识别的API  。有了语音识别技术我们开发者就可以开发出像Siri这样炫酷的应用。这不,最近我们也要上这个功能,所以我调研一些这方面的东西。本文主要介绍iOS语音识别SDK的用法。</p>    <ul>     <li>首先需要在plist文件中申请语音识别和麦克风使用权限: <p><img src="https://simg.open-open.com/show/6de05ce1d70b63099656f82395a7dcf4.png"></p> </li>     <li>引入头文件 <pre>  <code class="language-objectivec">#import <Speech/Speech.h>  #import <AVFoundation/AVFoundation.h></code></pre> </li>     <li> <p>申请权限</p> <pre>  <code class="language-objectivec">- (void)viewDidAppear:(BOOL)animated{    [super viewDidAppear:animated];    [SFSpeechRecognizer requestAuthorization:^(SFSpeechRecognizerAuthorizationStatus status) {        dispatch_async(dispatch_get_main_queue(), ^{            switch (status) {                case SFSpeechRecognizerAuthorizationStatusNotDetermined:                    self.recordButton.enabled = NO;                    [self.recordButton setTitle:@"语音识别未授权" forState:UIControlStateDisabled];                    break;                case SFSpeechRecognizerAuthorizationStatusDenied:                    self.recordButton.enabled = NO;                    [self.recordButton setTitle:@"用户未授权使用语音识别" forState:UIControlStateDisabled];                    break;                case SFSpeechRecognizerAuthorizationStatusRestricted:                    self.recordButton.enabled = NO;                    [self.recordButton setTitle:@"语音识别在这台设备上受到限制" forState:UIControlStateDisabled];                      break;                case SFSpeechRecognizerAuthorizationStatusAuthorized:                    self.recordButton.enabled = YES;                    [self.recordButton setTitle:@"开始录音" forState:UIControlStateNormal];                    break;                  default:                    break;            }          });    }];  }</code></pre> </li>     <li> <p>核心代码</p>      <ul>       <li> <p>识别实时音频流,如下</p> <pre>  <code class="language-objectivec">- (void)startRecording{      if (_recognitionTask) {         [_recognitionTask cancel];          _recognitionTask = nil;       }    AVAudioSession *audioSession = [AVAudioSession sharedInstance];  NSError *error;  [audioSession setCategory:AVAudioSessionCategoryRecord error:&error];  NSParameterAssert(!error);  [audioSession setMode:AVAudioSessionModeMeasurement error:&error];  NSParameterAssert(!error);  [audioSession setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&error];  NSParameterAssert(!error);    _recognitionRequest = [[SFSpeechAudioBufferRecognitionRequest alloc] init];  AVAudioInputNode *inputNode = self.audioEngine.inputNode;  NSAssert(inputNode, @"录入设备没有准备好");  NSAssert(_recognitionRequest, @"请求初始化失败");  _recognitionRequest.shouldReportPartialResults = YES;  __weak typeof(self) weakSelf = self;  _recognitionTask = [self.speechRecognizer recognitionTaskWithRequest:_recognitionRequest resultHandler:^(SFSpeechRecognitionResult * _Nullable result, NSError * _Nullable error) {      __strong typeof(weakSelf) strongSelf = weakSelf;      BOOL isFinal = NO;      if (result) {          strongSelf.resultStringLable.text = result.bestTranscription.formattedString;          isFinal = result.isFinal;      }      if (error || isFinal) {          [self.audioEngine stop];          [inputNode removeTapOnBus:0];          strongSelf.recognitionTask = nil;          strongSelf.recognitionRequest = nil;          strongSelf.recordButton.enabled = YES;          [strongSelf.recordButton setTitle:@"开始录音" forState:UIControlStateNormal];      }    }];    AVAudioFormat *recordingFormat = [inputNode outputFormatForBus:0];  [inputNode installTapOnBus:0 bufferSize:1024 format:recordingFormat block:^(AVAudioPCMBuffer * _Nonnull buffer, AVAudioTime * _Nonnull when) {      __strong typeof(weakSelf) strongSelf = weakSelf;      if (strongSelf.recognitionRequest) {          [strongSelf.recognitionRequest appendAudioPCMBuffer:buffer];      }  }];    [self.audioEngine prepare];  [self.audioEngine startAndReturnError:&error];   NSParameterAssert(!error);  self.resultStringLable.text = @"正在录音。。。";  }</code></pre> <pre>  <code class="language-objectivec">- (SFSpeechRecognizer *)speechRecognizer{  if (!_speechRecognizer) {      //要为语音识别对象设置语言,这里设置的是中文      NSLocale *local =[[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"];        _speechRecognizer =[[SFSpeechRecognizer alloc] initWithLocale:local];      _speechRecognizer.delegate = self;  }  return _speechRecognizer;  }</code></pre> </li>       <li>识别本地音频文件,如下 <pre>  <code class="language-objectivec">- (IBAction)recognizeLocalAudioFile:(UIButton *)sender {     NSLocale *local =[[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"];  SFSpeechRecognizer *localRecognizer =[[SFSpeechRecognizer alloc] initWithLocale:local];  NSURL *url =[[NSBundle mainBundle] URLForResource:@"录音.m4a" withExtension:nil];  if (!url) return;  SFSpeechURLRecognitionRequest *res =[[SFSpeechURLRecognitionRequest alloc] initWithURL:url];  [localRecognizer recognitionTaskWithRequest:res resultHandler:^(SFSpeechRecognitionResult * _Nullable result, NSError * _Nullable error) {      if (error) {          NSLog(@"语音识别解析失败,%@",error);      }      else      {          self.resultStringLable.text = result.bestTranscription.formattedString;      }  }];  }</code></pre> </li>      </ul> </li>     <li>注意      <ul>       <li>iOS语音识别Api只支持iOS10SDK以及以后的版本,开发工具至少要Xcode8.0。</li>      </ul> </li>    </ul>    <p> </p>    <p>来自:http://www.jianshu.com/p/a9c64ac2c586</p>    <p> </p>