本文介紹了如何使用阿里云智能語音服務提供的Android NUI SDK,包括SDK下載安裝、關鍵接口及代碼示例。
前提條件
下載安裝
下載SDK。
重要請下載后在樣例初始化代碼中替換您的阿里云賬號信息、Appkey和Token才可運行。
對象
說明
SDK名稱
智能語音交互移動端SDK
開發者
阿里云計算有限公司
SDK版本
2.6.3-01B
SDK包名
com.alibaba.idst.nui
SDK更新時間
2024-12-19
SDK大小
MinSizeRel/nuisdk-release.aar
7.2MB
RelWithDebugInfo/nuisdk-release.aar
9.7MB
SDK MD5值
MinSizeRel/nuisdk-release.aar
c8e84d882a776797179b07cb55325a17
RelWithDebugInfo/nuisdk-release.aar
3bd1e2c2423c23e6522b7bc3ac072ec9
隱私政策
SDK整合包下載
類別
兼容范圍
系統
支持Android 4.0以上版本,API LEVEL 14
架構
armeabi-v7a,arm64-v8a,x86,x86_64
此SDK還包含如下功能,若未支持您想要的功能,請前往對應文檔獲取SDK。
功能
是否支持
一句話識別
是
實時語音識別
是
語音合成
是
實時長文本語音合成
是
流式文本語音合成
是
離線語音合成
否
錄音文件識別極速版
是
喚醒及命令詞
否
聽悟實時推流
是
解壓ZIP包,在app/libs目錄下獲取AAR格式的SDK包,將AAR包集成到您的工程項目中進行依賴。如果需要Android CPP接入方式,可在ZIP包的android_libs和android_include中獲得動態庫和頭文件。
使用Android Studio打開此工程查看參考代碼實現,其中一句話識別示例代碼為SpeechRecognizerActivity.java文件,替換Appkey和Token后可直接運行。
SDK關鍵接口
initialize:初始化SDK。
/** * 初始化SDK,SDK為單例,請先釋放后再次進行初始化。請勿在UI線程調用,可能會引起阻塞。 * @param callback:事件監聽回調,參見下文具體回調。 * @param parameters:json string形式的初始化參數,參見下方說明或接口說明:http://bestwisewords.com/document_detail/173298.html。 * @param level:log打印級別,值越小打印越多。 * @param save_log:是否保存log為文件,存儲目錄為ticket中的debug_path字段值。注意,log文件無上限,請注意持續存儲導致磁盤存滿。 * @return:參見錯誤碼:http://bestwisewords.com/document_detail/459864.html。 */ public synchronized int initialize(final INativeNuiCallback callback, String parameters, final Constants.LogLevel level, final boolean save_log)
其中,INativeNuiCallback類型包含如下回調。
onNuiAudioStateChanged:根據音頻狀態進行錄音功能的開關。
/** * 當start/stop/cancel等接口調用時,SDK通過此回調通知App進行錄音的開關操作。 * @param state:錄音需要的狀態(打開/關閉) */ void onNuiAudioStateChanged(AudioState state);
onNuiNeedAudioData:在回調中提供音頻數據。
/** * 開始識別時,此回調被連續調用,App需要在回調中進行語音數據填充。 * @param buffer:填充語音的存儲區。 * @param len:需要填充語音的字節數。 * @return:實際填充的字節數。 */ int onNuiNeedAudioData(byte[] buffer, int len);
onNuiEventCallback:SDK事件回調。
/** * SDK主要事件回調 * @param event:回調事件,參見如下事件列表。 * @param resultCode:參見錯誤碼,在出現EVENT_ASR_ERROR事件時有效。 * @param arg2:保留參數。 * @param kwsResult:語音喚醒功能(暫不支持)。 * @param asrResult:語音識別結果。 */ void onNuiEventCallback(NuiEvent event, final int resultCode, final int arg2, KwsResult kwsResult, AsrResult asrResult);
onNuiAudioRMSChanged:音頻能量值回調。
/** * 音頻能量值回調 * @param val: 音頻數據能量值回調,范圍-160至0,一般用于UI展示語音動效 */ public void onNuiAudioRMSChanged(float val);
事件列表:
名稱
說明
EVENT_VAD_START
檢測到人聲起點。
EVENT_VAD_END
檢測到人聲尾點。
EVENT_ASR_PARTIAL_RESULT
語音識別中間結果。
EVENT_ASR_RESULT
語音識別最終結果。
EVENT_ASR_ERROR
根據錯誤碼信息判斷出錯原因。
EVENT_MIC_EEROR
錄音錯誤,表示SDK連續2秒未收到任何音頻,可檢查錄音系統是否正常。
setParams:以JSON格式設置SDK參數。
/** * 以JSON格式設置參數 * @param params:參見接口說明:http://bestwisewords.com/document_detail/173298.html。 * @return:參見錯誤碼:http://bestwisewords.com/document_detail/459864.html。 */ public synchronized int setParams(String params);
startDialog:開始識別。
/** * 開始識別 * @param vad_mode:多種模式,對于識別場景,請使用P2T。 * @param dialog_params:json string形式的對話參數,參見接口說明:http://bestwisewords.com/document_detail/173298.html。 * @return:參見錯誤碼:http://bestwisewords.com/document_detail/459864.html。 */ public synchronized int startDialog(VadMode vad_mode, String dialog_params);
stopDialog:結束識別。
/** * 結束識別,調用該接口后,服務端將返回最終識別結果并結束任務。 * @return:參見錯誤碼:http://bestwisewords.com/document_detail/459864.html。 */ public synchronized int stopDialog();
cancelDialog:立即結束識別。
/** * 立即結束識別,調用該接口后,不等待服務端返回最終識別結果就立即結束任務。 * @return:參見錯誤碼:http://bestwisewords.com/document_detail/459864.html。 */ public synchronized int cancelDialog();
release:釋放SDK。
/** * 釋放SDK資源 * @return:參見錯誤碼:http://bestwisewords.com/document_detail/459864.html。 */ public synchronized int release();
GetVersion:獲得當前SDK版本信息。
/** * 獲得當前SDK版本信息 * @return: 字符串形式的SDK版本信息 */ public synchronized String GetVersion();
調用步驟
初始化SDK、錄音實例。
根據業務需求設置參數。
調用startDialog開始識別。
根據音頻狀態回調onNuiAudioStateChanged,打開錄音機。
在onNuiNeedAudioData回調中提供錄音數據。
在EVENT_ASR_PARTIAL_RESULT事件回調中獲取識別中間結果。
調用stopDialog結束識別,并從EVENT_ASR_RESULT事件回調中獲得最終識別結果。
結束調用,使用release接口釋放SDK資源。
Proguard配置
如果代碼使用了混淆,請在proguard-rules.pro中配置:
-keep class com.alibaba.idst.nui.*{*;}
代碼示例
您如果有多個需求,也可以直接new對象進行使用。也可采用GetInstance獲得單例。
NUI SDK初始化
//這里獲得資源路徑, 即工作路徑
// 內部通過context.getApplicationContext().getFilesDir().toString() + "/asr_my" 創建工作路徑,
// 例如 /data/user/0/mit.alibaba.nuidemo/files/asr_my
String asset_path = CommonUtils.getModelPath(this);
//創建debug路徑
String debug_path = getExternalCacheDir().getAbsolutePath() + "/debug_" + System.currentTimeMillis();
Utils.createDir(debug_path);
//從nuisdk.aar中assets資源拷貝到workspace中
CommonUtils.copyAssetsData(this);
//初始化SDK,注意用戶需要在genInitParams中填入相關ID信息才可以使用。
NativeNui nui_instance = new NativeNui();
int ret = nui_instance.initialize(this, genInitParams(asset_path, debug_path), Constants.LogLevel.LOG_LEVEL_VERBOSE, true);
其中,genInitParams生成String JSON字符串,包含資源目錄和用戶信息。其中用戶信息包含如下字段。
private String genInitParams(String workpath, String debugpath) {
String str = "";
try{
//獲取賬號訪問憑證:
// getTicket為示例工程中提供了多種可能的方式,請選擇適合自身業務的安全方式
//
//注意:
// 語音交互服務需要先準備好賬號,并開通相關服務。具體步驟請查看:
// http://bestwisewords.com/zh/isi/getting-started/start-here
//
//原始賬號:
// 賬號(子賬號)信息主要包括AccessKey ID(后續簡稱為ak_id)和AccessKey Secret(后續簡稱為ak_secret)。
// 此賬號信息一定不可存儲在app代碼中或移動端側,以防賬號信息泄露造成資費損失。
//
//STS臨時憑證:
// 由于賬號信息下發給客戶端存在泄露的可能,阿里云提供的一種臨時訪問權限管理服務STS(Security Token Service)。
// STS是由賬號信息ak_id和ak_secret,通過請求生成臨時的sts_ak_id/sts_ak_secret/sts_token
// (為了區別原始賬號信息和STS臨時憑證, 命名前綴sts_表示STS生成的臨時憑證信息)
//什么是STS:http://bestwisewords.com/zh/ram/product-overview/what-is-sts
//STS SDK概覽:http://bestwisewords.com/zh/ram/developer-reference/sts-sdk-overview
//STS Python SDK調用示例:http://bestwisewords.com/zh/ram/developer-reference/use-the-sts-openapi-example
//
//賬號需求說明:
// 若使用離線功能(離線語音合成、喚醒), 則必須app_key、ak_id和ak_secret,或app_key、sts_ak_id、sts_ak_secret和sts_token
// 若使用在線功能(語音合成、實時轉寫、一句話識別、錄音文件轉寫等), 則只需app_key和token
JSONObject object = Auth.getTicket(Auth.GetTicketMethod.GET_TOKEN_FROM_SERVER_FOR_ONLINE_FEATURES);
if (!object.containsKey("token")) {
Log.e(TAG, "Cannot get token!!!");
}
object.put("device_id", Utils.getDeviceId()); // 必填, 推薦填入具有唯一性的id, 方便定位問題
object.put("url", "wss://nls-gateway.cn-shanghai.aliyuncs.com:443/ws/v1"); // 默認
object.put("workspace", workpath); // 必填, 且需要有讀寫權限
object.put("sample_rate", "16000");
object.put("format", "opus");
//當初始化SDK時的save_log參數取值為true時,該參數生效。表示是否保存音頻debug,該數據保存在debug目錄中,需要確保debug_path有效可寫。
//object.put("save_wav", "true");
//debug目錄,當初始化SDK時的save_log參數取值為true時,該目錄用于保存中間音頻文件。
object.put("debug_path", debugpath);
//AsrCloud = 4 // 在線一句話識別可以選這個
object.put("service_mode", Constants.ModeAsrCloud); // 必填
str = object.toString();
} catch (JSONException e) {
e.printStackTrace();
}
Log.i(TAG, "InsideUserContext:" + str);
return str;
}
參數設置
以JSON字符串形式進行設置。
//設置相關識別參數,具體參考API文檔
// initialize()之后startDialog之前調用
nui_instance.setParams(genParams());
private String genParams() {
String params = "";
try {
JSONObject nls_config = new JSONObject();
nls_config.put("enable_intermediate_result", true);
//參數可根據實際業務進行配置
//接口說明可見: http://bestwisewords.com/document_detail/173298.html
//查看 2.開始識別
//由于對外的SDK(01B版本)不帶有本地VAD模塊(僅帶有喚醒功能(029版本)的SDK具有VAD模塊),
//若要使用VAD模式,則需要設置nls_config參數啟動在線VAD模式(見genParams())
//
//模式說明:
//若使用P2T模式,即按下開始說話,放開結束說話的模式,則不啟動enable_voice_detection。
//若使用VAD模式,即自動判斷用戶說完一句話,則啟動enable_voice_detection。
if (vadMode.get()) {
nls_config.put("enable_voice_detection", true);
nls_config.put("max_start_silence", 10000);
nls_config.put("max_end_silence", 800);
}
//nls_config.put("enable_punctuation_prediction", true);
//nls_config.put("enable_inverse_text_normalization", true);
//nls_config.put("enable_voice_detection", true);
//nls_config.put("customization_id", "test_id");
//nls_config.put("vocabulary_id", "test_id");
//nls_config.put("max_start_silence", 10000);
//nls_config.put("max_end_silence", 800);
//nls_config.put("sample_rate", 16000);
//nls_config.put("sr_format", "opus");
/*若文檔中不包含某些參數,但是此功能支持這個參數,可以用如下萬能接口設置參數*/
//JSONObject extend_config = new JSONObject();
//extend_config.put("custom_test", true);
//nls_config.put("extend_config", extend_config);
JSONObject parameters = new JSONObject();
parameters.put("nls_config", nls_config);
parameters.put("service_type", Constants.kServiceTypeASR); // 必填
//如果有HttpDns則可進行設置
//parameters.put("direct_ip", Utils.getDirectIp());
params = parameters.toString();
} catch (JSONException e) {
e.printStackTrace();
}
return params;
}
開始識別
通過startDialog接口開啟監聽。
//默認使用Constants.VadMode.TYPE_P2T。
//Constants.VadMode.TYPE_VAD只在具有離線功能的SDK中支持,若想要啟動VAD,請設置參數enable_voice_detection。
NativeNui.GetInstance().startDialog(Constants.VadMode.TYPE_P2T, genDialogParams());
private String genDialogParams() {
String params = "";
try {
JSONObject dialog_param = new JSONObject();
//運行過程中可以在startDialog時更新參數,尤其是更新過期token
//dialog_param.put("token", "");
params = dialog_param.toString();
} catch (JSONException e) {
e.printStackTrace();
}
return params;
}
回調處理
onNuiAudioStateChanged:錄音狀態回調,SDK內部維護錄音狀態,調用時根據該狀態的回調進行錄音機的開關操作。
public void onNuiAudioStateChanged(Constants.AudioState state) { Log.i(TAG, "onNuiAudioStateChanged"); if (state == Constants.AudioState.STATE_OPEN) { Log.i(TAG, "audio recorder start"); mAudioRecorder.startRecording(); } else if (state == Constants.AudioState.STATE_CLOSE) { Log.i(TAG, "audio recorder close"); mAudioRecorder.release(); } else if (state == Constants.AudioState.STATE_PAUSE) { Log.i(TAG, "audio recorder pause"); mAudioRecorder.stop(); } }
onNuiNeedAudioData:錄音數據回調,在該回調中填充錄音數據。
public int onNuiNeedAudioData(byte[] buffer, int len) { int ret = 0; if (mAudioRecorder.getState() != AudioRecord.STATE_INITIALIZED) { Log.e(TAG, "audio recorder not init"); return -1; } ret = mAudioRecorder.read(buffer, 0, len); //返回值告知SDK讀到了多少數據。 //如果返回<0,則表示出錯。 //返回0,則表示無錄音數據,連續2s返回0,會觸發事件EVENT_MIC_ERROR。 return ret; }
onNuiEventCallback:NUI SDK事件回調,請勿在事件回調中調用SDK的接口,可能引起死鎖。
public void onNuiEventCallback(Constants.NuiEvent event, final int resultCode, final int arg2, KwsResult kwsResult, AsrResult asrResult) { Log.i(TAG, "event=" + event + " resultCode=" + resultCode); // asrResult包含task_id,task_id有助于排查問題,請用戶進行記錄保存。 // // 新版本新增asrResult.allResponse,若為非nullptr和非空,則給出json格式字符串的完整信息。 if (event == Constants.NuiEvent.EVENT_ASR_RESULT) { // 例如展示識別結果 showText(asrView, asrResult.asrResult); } else if (event == Constants.NuiEvent.EVENT_ASR_PARTIAL_RESULT) { // 例如展示識別中間結果 showText(asrView, asrResult.asrResult); } else if (event == Constants.NuiEvent.EVENT_ASR_ERROR) { // asrResult在EVENT_ASR_ERROR中為錯誤信息,搭配錯誤碼resultCode和其中的task_id更易排查問題,請用戶進行記錄保存。 } else if (event == Constants.NuiEvent.EVENT_MIC_ERROR) { // EVENT_MIC_ERROR表示2s未傳入音頻數據,請檢查錄音相關代碼、權限或錄音模塊是否被其他應用占用。 } else if (event == Constants.NuiEvent.EVENT_DIALOG_EX) { /* unused */ // 此事件可不用關注 } }
結束識別
nui_instance.stopDialog();
釋放SDK
nui_instance.release();