本文介绍了如何使用阿里云智能语音服务提供的iOS NUI SDK,包括SDK下载安装、关键接口及代码示例。
前提条件
下载安装
- 说明
请下载后在样例初始化代码中替换您的阿里云账号信息、appkey和token才可运行。
解压ZIP包,使用nuisdk.framework进行集成。
说明代码采用Ojective-C和C++混合编程方式,请您调用.mm扩展名文件。
使用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);
调用步骤
初始化SDK、录音实例。
根据业务需求配置参数。
调用nui_dialog_start开始识别。
根据音频状态回调audio_state_changed_callback,打开录音机。
在user_data_callback回调中提供录音数据。
在EVENT_ASR_PARTIAL_RESULT和EVENT_SENTENCE_END事件回调中获取识别结果。
调用nui_dialog_cancel结束识别。
结束调用,使用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];
在文档使用中是否遇到以下问题
更多建议
匿名提交