全部产品

iOS SDK

更新时间:2020-11-20 15:43:28

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

前提条件

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

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

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

下载安装

  1. 下载SDK和示例代码

  2. 解压ZIP包,使用nuisdk.framework进行集成。

    说明

    代码采用Ojective-C和C++混合编程方式,请您调用.mm扩展名文件。

  3. 使用Xcode打开此工程。

    其中实时语音识别示例代码为SpeechTranscriberViewController.mm文件。

SDK关键接口

  • nui_initialize:初始化SDK。

    /**
         * 初始化SDK,SDK为单例,请先释放后再进行初始化。请勿在UI线程调用,可能会引起阻塞。
         * @param parameters:初始化参数,参见接口说明。
         * @param listener:事件监听回调,参见下文具体回调。
         * @param async_listener:异步回调,设置nullptr采用同步方式调用。
         * @param level:log打印级别,值越小打印越多。
         * @param save_log:是否保存log为文件,存储目录为parameter中的debug_path字段值。
         * @return:参见错误码。
         */
    NuiResultCode nui_initialize(const char *parameters,
                        const NuiSdkListener *listener,
                        const NuiAsyncCallback *async_listener = nullptr,
                        NuiSdkLogLevel level = LOG_LEVEL_VERBOSE,
                        bool save_log = false);

    其中,NuiSdkListener类型如下表。

    名称

    类型

    说明

    event_callback

    FuncDialogListenerOnEvent

    NUI事件回调

    user_data_callback

    FuncDialogUserProvideData

    NUI麦克风数据请求回调

    audio_state_changed_callback

    FuncDialogAudioStateChange

    NUI麦克风状态回调

    audio_extra_event_callback

    FuncDialogAudioExtraEvent

    NUI特殊事件回调,暂不使用。

    user_data

    void *

    用户数据,上述回调中第一个参数。

    FuncDialogListenerOnEvent:SDK事件回调。

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

    事件列表:

    名称

    说明

    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

    停止语音识别后上报

    FuncDialogUserProvideData:在回调中提供音频数据。

    /**
         * 开始识别时,此回调被连续调用,App需要在回调中进行语音数据填充。
         * @param user_data:暂不使用。
         * @param buffer:填充语音的存储区。
         * @param len:需要填充语音的字节数。
         * @return:实际填充的字节数。
         */
        typedef int (*FuncDialogUserProvideData)(void *user_data, char *buffer, int len);

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

    /**
         * 当start/stop/cancel等接口调用时,SDK通过此回调通知App进行录音的开关操作。
         * @param user_data:暂不使用。
         * @param state:录音需要的状态(打开/关闭)。
         */
        typedef void (*FuncDialogAudioStateChange) (void *user_data, NuiAudioState state);
  • nui_set_params:以JSON格式设置SDK参数。

    /**
         * 以JSON格式设置参数
         * @param params:参数信息请参见接口说明。
         * @param async_listener:异步回调,设置nullptr采用同步方式调用。
         * @return:参见错误码。
         */
        NuiResultCode nui_set_params(const char *params, const NuiAsyncCallback *listener = nullptr);
  • nui_dialog_start:开始识别。

    /**
         * 开始识别
         * @param vad_mode:多种模式,对于识别场景,使用P2T。
         * @param dialog_params:设置识别参数,可不设置。
         * @param async_listener:异步回调,设置nullptr采用同步方式调用。
         * @return:参见错误码。
         */
        NuiResultCode nui_dialog_start(NuiVadMode vad_mode, const char *dialog_params, const NuiAsyncCallback *listener = nullptr);
  • nui_dialog_cancel:结束识别。

    /**
         * 结束识别,调用该接口后,服务端将返回最终识别结果并结束任务。
         * @param force:是否强制结束而忽略最终结果,false表示停止但是等待完整结果返回。
         * @param async_listener:异步回调,设置nullptr采用同步方式调用。
         * @return:参见错误码。
         */
        NuiResultCode nui_dialog_cancel(bool force, const NuiAsyncCallback *listener = nullptr);
    
  • nui_release:释放SDK。

    /**
         * 释放SDK资源
         * @param async_listener:异步回调,设置nullptr采用同步方式调用。
         * @return:参见错误码。
         */
        NuiResultCode nui_release(const NuiAsyncCallback *async_listener = nullptr);
    

调用步骤

  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资源。

代码示例

NUI SDK初始化

NSString * initParam = [self genInitParams];
    //nui listener
    NuiSdkListener nuiListener;
    nuiListener.event_callback = nuiDialogListenerOnEvent;
    nuiListener.audio_state_changed_callback = nuiDialogAudioStateChange;
    nuiListener.audio_extra_event_callback = nullptr;
    nuiListener.user_data = nullptr;
    nuiListener.user_data_callback = nuiDialogUserProvideData;
    [_nui nui_initialize:[initParam UTF8String] Listener:&nuiListener asyncCallback:nullptr 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:@(nuisdk::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] asyncCallback:nullptr];

开始识别

通过nui_dialog_start接口开启监听。

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

回调处理

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

    -(void)onNuiAudioStateChanged:(nuisdk::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:(nuisdk::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 == nuisdk::EVENT_ASR_PARTIAL_RESULT || nuiEvent == nuisdk::EVENT_SENTENCE_END) {
            TLog(@"ASR RESULT %s finish %d", asr_result, finish);
            NSString *result = [NSString stringWithUTF8String:asr_result];
            [myself showAsrResult:result];
        } else if (nuiEvent == nuisdk::EVENT_ASR_ERROR) {
            TLog(@"EVENT_ASR_ERROR error[%d]", code);
        } else if (nuiEvent == nuisdk::EVENT_MIC_ERROR) {
            TLog(@"MIC ERROR");
            [_voiceRecorder stop:true];
            [_voiceRecorder start];
        }
        if (finish) {
            [myself showStart];
        }
        return;
    }

结束识别

[_nui nui_dialog_cancel:false asyncCallback:nullptr];