1. Asr录音机控件的使用
为了方便在Android平台下的开发者,可使用AsrRecorder控件来简化一边录音,一边识别的场景。
AsrRecorder,把上述的Asr初始化-session初始化-加载语法-识别-卸载语法-识别结束-session释放-asr释放等过程全都封装,并与AudioRecorder相结合,开发者只需调用少量代码,即可完成录音识别。
1.1 集成
推荐将开发包中的sdk\Examples\ASR_Recorder_Example\
工程导入到AndroidStudio中,参考开发。
1.1.1 通用模块初始化
在调用ASR能力之前,需要初始化灵云SDK的通用模块。详见灵云SDK开发手册
Android示例代码
// 创建初始化参数辅助类 InitParam initparam = new InitParam(); // 授权文件所在路径,此项必填 String authDirPath = context.getFilesDir() .getAbsolutePath();; initparam.addParam (InitParam.AuthParam.PARAM_KEY_AUTH_PATH, authDirPath) ; // 灵云云服务的接口地址,此项必填 initparam.addParam (InitParam.AuthParam.PARAM_KEY_CLOUD_URL, "http://api.hcicloud.com:8888"); // 开发者密钥,此项必填,由捷通华声提供 initparam.addParam (InitParam.AuthParam.PARAM_KEY_DEVELOPER_KEY, "01234567890"); // 应用程序序号,此项必填,由捷通华声提供 initparam.addParam (InitParam.AuthParam.PARAM_KEY_APP_KEY, "1234abcd"); // 日志的路径,可选,如果不传或者为空则不生成日志 String logDirPath = "/storage/emulated/0/sinovoice/com.sinovoice. example/log"; initparam.addParam (InitParam.LogParam.PARAM_KEY_LOG_FILE_PATH, logDirPath); //日志等级,0=无,1=错误,2=警告,3=信息,4=细节,5=调试 //SDK将输出小于等于logLevel的日志信息 initparam.addParam (InitParam.LogParam.PARAM_KEY_LOG_LEVEL, "5"); // 灵云系统初始化 // 第二个参数在Android平台下,必须为当前的Context int errCode = HciCloudSys.hciInit (initparam.getStringConfig(), this); if(errCode != HciErrorCode.HCI_ERR_NONE) { // "系统初始化失败" return; }
1.1.2 授权检测
在初始化灵云SDK的通用模块后,还需要调用授权检测函数获取云端授权。
Android示例代码
// 获取授权 private int checkAuthAndUpdateAuth() { // 获取系统授权到期时间 int initResult; AuthExpireTime objExpireTime = new AuthExpireTime (); initResult = HciCloudSys.hciGetAuthExpireTime (objExpireTime); if (initResult == HciErrorCode.HCI_ERR_NONE) { // 显示授权日期,如用户不需要关注该值,此处代码可忽 略 Date date = new Date (objExpireTime.getExpireTime() * 1000); SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd",Locale.CHINA); Log.i(TAG, "expire time: " + sdf.format(date)) ; if (objExpireTime.getExpireTime() * 1000 > System.currentTimeMillis()) { Log.i(TAG, "checkAuth success"); return initResult; } } // 获取过期时间失败或者已经过期 initResult = HciCloudSys.hciCheckAuth(); if (initResult == HciErrorCode.HCI_ERR_NONE) { Log.i(TAG, "checkAuth success"); return initResult; } else { Log.e(TAG, "checkAuth failed: " + initResult); return initResult; } }
1.1.3 初始化AsrRecorder
Android代码
AndroidAsrRecorder recorder = new AndroidAsrRecorder(new AsrRecorderListener.Skeleton() { @Override public void onStart(AsrRecorder recorder) { String info = "录音机已启动"; printLog(info); } @Override public void onStopping(AsrRecorder recorder) { printLog("录音机停止中..."); } @Override public void onFinish(AsrRecorder recorder, int reason) { String strReason; switch (reason) { case AsrRecorderListener.NO_VOICE_INPUT: strReason = "NoVoiceInput"; break; case AsrRecorderListener.STOPPED: strReason = "Normal"; break; case AsrRecorderListener.CANCELLED: strReason = "Cancelled"; break; case AsrRecorderListener.RECOG_ERROR: strReason = "RecognizeError"; break; case AsrRecorderListener.DEVICE_ERROR: strReason = "DeviceError"; break; case AsrRecorderListener.VOICE_ENDED: strReason = "VoiceEnded"; break; case AsrRecorderListener.EXCEPTION: strReason = "Exception"; break; default: strReason = "Unknown"; break; } strReason += "(" + reason + ")\n"; printLog("录音机已停止,原因 - " + strReason); } @Override public void onDeviceError(AsrRecorder recorder, String stage, int errorCode) { printLog("录音设备错误,场景 - " + stage + ", 错误码 - " + errorCode); } @Override public void onRecogError(AsrRecorder recorder, String stage, int errorCode) { printLog("语音识别错误,场景 - " + stage + ", 错误码 - " + errorCode); } @Override public void onException(AsrRecorder recorder, Exception e) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); printLog("发生异常:" + sw.toString()); } @Override public void onRecogResult(AsrRecorder recorder, AsrResult result) { if (result == null) { printLog("无识别结果"); } else { if (realtimeCfg == "rt") { // 实时反馈结果中有时间戳信息 printLog("录音识别结果: 置信度 = " + result.score + ", 文本 = " + result.text + ", 开始时间 = " + result.startTime + " 结束时间 = " + result.endTime); } else { printLog("录音识别结果: 置信度 = " + result.score + ", 文本 = " + result.text); } } } @Override public boolean onNoVoiceInput(AsrRecorder recorder, int nth) { printLog("第 " + nth + " 次未检测到语音输入"); // 返回 false 将中止录音会话,返回 true 将继续录音并识别 return bContinueIfNoVoiceInput; } @Override public boolean onEndOfVoice(AsrRecorder recorder) { printLog("语音末端点(语音结束)完成识别"); return bContinueIfVoiceEnded; } @Override public void onAudioRecorded(byte[] audioData, int audioLevel) { // 20ms 会被调用一次(在录音线程上),需要保证效率 if (lastAudioLevel == audioLevel) { // 和上次相同无须更新界面,直接返回 return; } lastAudioLevel = audioLevel; // 更新 lastAudioLevel } @Override public void onVoiceBegin(AsrRecorder recorder) { // SDK 中还未实现,此为预留接口 printLog("语音输入检测到前端点"); } @Override public void onVoiceEnd(AsrRecorder recorder) { printLog("语音输入检测到末端点"); } }); // 设定需要返回音频数据以及音频音量等级 recorder.setAudioReportMethod(AsrRecorder.REPORT_AUDIO_AND_LEVEL); }
1.1.4 启动录音识别
如果需要语法识别,请传入grammarData 参数。
Android代码
if (asrConfig.contains("local.grammar")) { // 加载本地语法获取语法ID grammarData = loadGrammar("stock_10001.gram"); grammarConfigString = "capkey=" + AccountInfo .getInstance().getCapKey() + ",isFile=no,grammarType=jsgf"; RadioGroup rg = (RadioGroup) findViewById(R.id.radioGroupReadltime); rg.getChildAt(1).setEnabled(false); } // 开始录音 recorder.start(asrConfig, asrInitConfig, grammarData, grammarConfigString);
1.1.5 停止录音识别
在录音识别过程中,可以通过调用recorder.stop()方法。
Android代码
if (needCancel) { // 停止录音并取消识别,不会有识别结果传出 recorder.stop(true); } else { // 停止录音,将会有识别结果传出 recorder.stop(false); }
1.1.6 ASR反初始化
当应用不再需要语音识别后,进行反初始化,资源释放
Android代码
HciCloudSys.hciRelease();