全部产品

iOS SDK

更新时间:2021-04-23 17:37:19

本文介绍了如何使用阿里云智能语音服务提供的iOS NUI SDK,包括SDK下载安装、关键接口及代码示例。

前提条件

  • 使用SDK前,请先阅读接口说明,详情请参见接口说明

  • 已获取项目appkey,详情请参见创建项目

  • 已获取Access Token,详情请参见获取Token

下载安装

  1. 下载SDK和示例代码

    说明

    请下载后在样例初始化代码中替换您的阿里云账号信息、appkey和token才可运行。为方便集成,2.5.14版本后iOS接口使用纯Object-C接口,不再使用C++混合接口。

  2. 解压ZIP包,将zip包中的nuisdk.framework添加到您的工程中,并在工程Build Phases的Link Binary With Libraries中添加nuisdk.framework。请确保在编译配置的General > Frameworks, Libraries, and Embedded Content中配置nuisdk.framework为Embed & Sign。

  3. 使用Xcode打开此工程,工程中提供了参考代码以及一些直接可使用的工具类,例如音频播放录制和文件操作,您可以直接复制源码到您的实际工程进行使用。其中实时转写示例代码为SpeechTranscriberViewController。

SDK关键接口

  • nui_initialize:初始化SDK。

      /**
           * 初始化SDK,SDK为单例,请先释放后再次进行初始化。请勿在UI线程调用,可能引起阻塞。
           * @param parameters: 初始化参数,参见接口说明文档
           * @param level: log打印级别,值越小打印越多
           * @param save_log: 是否保存log为文件,存储目录为parameter中的debug_path字段值
           * @return 参见错误码
           */
      -(NuiResultCode) nui_initialize:(const char *)parameters
                        logLevel:(NuiSdkLogLevel)level
                        saveLog:(BOOL)save_log;     
  • nui_set_params:以JSON格式设置SDK参数。

    /**
         * 以JSON格式设置参数
         * @param params: 参数信息请参见接口说明文档
         * @return 参见错误码
         */
        -(NuiResultCode) nui_set_params:(const char *)params;
  • nui_dialog_start:开始识别。

    /**
         * 开始识别
         * @param vad_mode: 多种模式,对于识别场景,请使用P2T
         * @param dialog_params: 设置识别参数,可不设置
         * @return 参见错误码
         */
        -(NuiResultCode) nui_dialog_start:(NuiVadMode)vad_mode
                          dialogParam:(const char *)dialog_params;
  • nui_dialog_cancel:结束识别。

    /**
         * 结束识别,调用该接口后,服务端将返回最终识别结果并结束任务
         * @param force: 是否强制结束而忽略最终结果,false表示停止但是等待完整结果返回
         * @return 参见错误码
         */
        -(NuiResultCode) nui_dialog_cancel:(BOOL)force;
  • nui_release:释放SDK。

    /**
         * 释放SDK资源
         * @return 参见错误码
         */
        -(NuiResultCode) nui_release;

  • NeoNuiSdkDelegate

    onNuiEventCallback:SDK事件回调。

    /**
         * SDK主要事件回调
         * @param event: 回调事件,参见如下事件列表
         * @param dialog: 会话编号,暂不使用
         * @param wuw: 语音唤醒功能使用
         * @param asr_result: 语音识别结果
         * @param finish: 本轮识别是否结束标志
         * @param resultCode: 参见错误码,在出现EVENT_ASR_ERROR事件时有效
         */
        -(void) onNuiEventCallback:(NuiCallbackEvent)nuiEvent
                              dialog:(long)dialog
                              kwsResult:(const char *)wuw
                              asrResult:(const char *)asr_result
                              ifFinish:(BOOL)finish
                              retCode:(int)code;

    NuiCallbackEvent事件列表:

    名称

    说明

    EVENT_VAD_START

    检测到人声起点

    EVENT_VAD_END

    检测到人声尾点

    EVENT_ASR_PARTIAL_RESULT

    语音识别中间结果

    EVENT_ASR_RESULT

    语音识别最终结果

    EVENT_ASR_ERROR

    根据错误码信息判断出错原因

    EVENT_MIC_EEROR

    录音错误

    EVENT_SENTENCE_START

    实时语音识别事件,检测到一句话开始。

    EVENT_SENTENCE_END

    实时语音识别事件,检测一句话结束,返回一句的完整结果。

    EVENT_SENTENCE_SEMANTICS

    暂不使用

    EVENT_TRANSCRIBER_COMPLETE

    停止语音识别后上报

    onNuiNeedAudioData:获取音频

    /**
         * 开始识别时,此回调被连续调用,App需要在回调中进行语音数据填充,语音数据来自App的录音
         * @param audioData: 填充语音的存储区
         * @param len: 需要填充语音的字节数
         * @return:实际填充的字节数
         */
        -(int) onNuiNeedAudioData:(char *)audioData length:(int)len;

    onNuiAudioStateChanged:根据音频状态进行录音功能的开关。

    /**
         * 当start/stop/cancel等接口调用时,SDK通过此回调通知App进行录音的开关操作
    
         * @param state:录音需要的状态(打开/关闭)
         */
        -(void) onNuiAudioStateChanged:(NuiAudioState)state;

    onNuiRmsChanged:音频能量事件。

    /**
         * SDK主要事件回调
         * @param rms: 语音能量值,范围为-160至0
         */
        -(void) onNuiRmsChanged:(float) rms;

调用步骤

  1. 初始化SDK、录音实例。

  2. 根据业务需求配置参数。

  3. 调用nui_dialog_start开始识别。

  4. 根据音频状态回调audio_state_changed_callback,打开录音机。

  5. 在user_data_callback回调中提供录音数据。

  6. 在EVENT_ASR_PARTIAL_RESULT和EVENT_SENTENCE_END事件回调中获取识别结果。

  7. 调用nui_dialog_cancel结束识别。

  8. 结束调用,使用nui_release接口释放SDK资源。

代码示例

说明

接口默认采用get_instance方式获得单例,您如果有多例需求,也可以直接alloc对象进行使用。

  • NUI SDK初始化

    NSString * initParam = [self genInitParams];
        [_nui nui_initialize:[initParam UTF8String] logLevel:LOG_LEVEL_VERBOSE saveLog:save_log];

    其中,genInitParams生成为String JSON字符串,包含资源目录和用户信息。其中用户信息包含如下字段。

        [dictM setObject:id_string forKey:@"device_id"];
        [dictM setObject:@"" forKey:@"url"];
        [dictM setObject:@"" forKey:@"app_key"];
    
        [dictM setObject:@"" forKey:@"token"];
  • 参数设置

    以JSON字符串形式进行设置。

    -(NSString*) genParams {
        NSMutableDictionary *nls_config = [NSMutableDictionary dictionary];
        [nls_config setValue:@true forKey:@"enable_intermediate_result"];
        [nls_config setValue:@true forKey:@"enable_voice_detection"];
      
        NSMutableDictionary *dictM = [NSMutableDictionary dictionary];
        [dictM setObject:nls_config forKey:@"nls_config"];
        [dictM setValue:@(SERVICE_TYPE_SPEECH_TRANSCRIBER) forKey:@"service_type"];
        
        NSData *data = [NSJSONSerialization dataWithJSONObject:dictM options:NSJSONWritingPrettyPrinted error:nil];
        NSString * jsonStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
        return jsonStr;
    }
    
    NSString * parameters = [self genParams];
    [_nui nui_set_params:[parameters UTF8String]];
    

  • 开始识别

    通过nui_dialog_start接口开启监听。

    [_nui nui_dialog_start:MODE_P2T dialogParam:[param_string UTF8String]];

  • 回调处理

    • onNuiAudioStateChanged:录音状态回调,SDK内部维护录音状态,调用时根据该状态的回调进行录音机的开关操作。

      -(void)onNuiAudioStateChanged:(NuiAudioState)state{
          TLog(@"onNuiAudioStateChanged state=%u", state);
          if (state == STATE_CLOSE || state == STATE_PAUSE) {
              [_voiceRecorder stop:YES];
          } else if (state == STATE_OPEN){
              self.recordedVoiceData = [NSMutableData data];
              [_voiceRecorder start];
          }
      }

    • onNuiNeedAudioData:录音数据回调,在该回调中填充录音数据。

      -(int)onNuiNeedAudioData:(char *)audioData length:(int)len {
          static int emptyCount = 0;
          @autoreleasepool {
              @synchronized(_recordedVoiceData){
                  if (_recordedVoiceData.length > 0) {
                      int recorder_len = 0;
                      if (_recordedVoiceData.length > len)
                          recorder_len = len;
                      else
                          recorder_len = _recordedVoiceData.length;
                      NSData *tempData = [_recordedVoiceData subdataWithRange:NSMakeRange(0, recorder_len)];
                      [tempData getBytes:audioData length:recorder_len];
                      tempData = nil;
                      NSInteger remainLength = _recordedVoiceData.length - recorder_len;
                      NSRange range = NSMakeRange(recorder_len, remainLength);
                      [_recordedVoiceData setData:[_recordedVoiceData subdataWithRange:range]];
                      emptyCount = 0;
                      return recorder_len;
                  } else {
                      if (emptyCount++ >= 50) {
                          TLog(@"_recordedVoiceData length = %lu! empty 50times.", (unsigned long)_recordedVoiceData.length);
                          emptyCount = 0;
                      }
                      return 0;
                  }
      
              }
          }
          return 0;
      }

    • onNuiEventCallback:NUI SDK事件回调,请勿在事件回调中调用SDK的接口,可能引起死锁。

      -(void)onNuiEventCallback:(NuiCallbackEvent)nuiEvent
                         dialog:(long)dialog
                      kwsResult:(const char *)wuw
                      asrResult:(const char *)asr_result
                       ifFinish:(bool)finish
                        retCode:(int)code {
          TLog(@"onNuiEventCallback event %d finish %d", nuiEvent, finish);
          if (nuiEvent == EVENT_ASR_PARTIAL_RESULT || nuiEvent == EVENT_SENTENCE_END) {
              TLog(@"ASR RESULT %s finish %d", asr_result, finish);
              NSString *result = [NSString stringWithUTF8String:asr_result];
              [myself showAsrResult:result];
          } else if (nuiEvent == EVENT_ASR_ERROR) {
              TLog(@"EVENT_ASR_ERROR error[%d]", code);
          } else if (nuiEvent == EVENT_MIC_ERROR) {
              TLog(@"MIC ERROR");
              [_voiceRecorder stop:true];
              [_voiceRecorder start];
          }
          
          if (finish) {
              [myself showStart];
          }
          
          return;
      }

  • 结束识别

    [_nui nui_dialog_cancel:NO];