iOS原生語音識別使用的正確姿勢

7年前發布 | 29K 次閱讀 語音識別 iOS開發 移動開發

語音識別技術這幾年在移動App上的應用越來越廣,各種第三方語音識別SDK也是層出不窮,例如科大訊飛、百度語音等,同時引入語音識別技術也是一個提高App逼格的好方法:grin:。所以今年的WWDC上,蘋果開放了他的語音識別的API  。有了語音識別技術我們開發者就可以開發出像Siri這樣炫酷的應用。這不,最近我們也要上這個功能,所以我調研一些這方面的東西。本文主要介紹iOS語音識別SDK的用法。

  • 首先需要在plist文件中申請語音識別和麥克風使用權限:

  • 引入頭文件
    #import <Speech/Speech.h>
    #import <AVFoundation/AVFoundation.h>
  • 申請權限

    - (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;
              }
    
          });
      }];
    }
  • 核心代碼

    • 識別實時音頻流,如下

      - (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 = @"正在錄音。。。";
      }
      - (SFSpeechRecognizer *)speechRecognizer{
      if (!_speechRecognizer) {
          //要為語音識別對象設置語言,這里設置的是中文
          NSLocale *local =[[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"];
      
          _speechRecognizer =[[SFSpeechRecognizer alloc] initWithLocale:local];
          _speechRecognizer.delegate = self;
      }
      return _speechRecognizer;
      }
    • 識別本地音頻文件,如下
      - (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;
          }
      }];
      }
  • 注意
    • iOS語音識別Api只支持iOS10SDK以及以后的版本,開發工具至少要Xcode8.0。

 

來自:http://www.jianshu.com/p/a9c64ac2c586

 

 本文由用戶自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!