先看效果
效果视频
首先到阿里页面创建项目
传送门:https://help.aliyun.com/document_detail/71936.htm?spm=a2c4g.11186623.0.0.12a03787uqgGAh#2572188
下载sdk引入到项目并且依赖
传送门:https://gw.alipayobjects.com/os/bmw-prod/d5d24de6-599d-41ac-aad7-3bfa6fc38f42.zip?spm=a2c4g.11186623.0.0.12a037872vUnOu&file=d5d24de6-599d-41ac-aad7-3bfa6fc38f42.zip
解压ZIP包,在app/libs目录下获取AAR格式的SDK包,将AAR包集成到您的工程项目中进行依赖。
获取Token
Token需要请求服务器获取,可以跟后台沟通获取方式 以及后台给你返回的格式 ,如果只是玩玩demo 可以使用官网给的测试Token
传送门:https://help.aliyun.com/document_detail/450514.htm?spm=a2c4g.11186623.0.0.12a0344eej4i75#587dee8029x7r
以上准备工作结束接下来开始集成
集成还是很简单的基本上官网讲的还是很全面的
需要注意的几个点是在使用语音识别之前必须获取录音权限 否则识别失败。
接下来看主要代码封装成简单的工具类
public class AutomaticSpeechRecognitionUtils implements INativeNuiCallback {private static final String TAG = AutomaticSpeechRecognitionUtils.class.getName();private NativeNui nui_instance = new NativeNui();private final static int WAVE_FRAM_SIZE = 20 * 2 * 1 * 16000 / 1000; //20ms audio for 16k/16bit/monopublic final static int SAMPLE_RATE = 16000;private AudioRecord mAudioRecorder;private AutomaticSpeechRecognitionListener mAutomaticSpeechRecognitionListener;private Context mContext;private boolean mInit = false;//初始化是否成功/*** @date 8/17/22 4:02 PM* @description 请求token并且初始化**/public void voiceInitToken(Context context, AutomaticSpeechRecognitionListener automaticSpeechRecognitionListener) {this.mContext = context;this.mAutomaticSpeechRecognitionListener = automaticSpeechRecognitionListener;int time = (int) (System.currentTimeMillis() / 1000); //获取当前时间if (time > (SearchVoiceSp.getInstance(UKidsApplication.getInstance()).getSearchVoiceTime())) {RetrofitManager.getInstance().getAutomaticSpeechRecognition(new UkidsObserver<VoiceRecognitionEntity>() {@Overridepublic void onSubscribe(Disposable d) {super.onSubscribe(d);}@Overridepublic void onNext(VoiceRecognitionEntity voiceRecognitionEntity) {super.onNext(voiceRecognitionEntity);if (voiceRecognitionEntity != null) {String token = voiceRecognitionEntity.getToken();int expire = voiceRecognitionEntity.getExpire();SearchVoiceSp.getInstance(UKidsApplication.getInstance()).setSearchVoiceToken(token);SearchVoiceSp.getInstance(UKidsApplication.getInstance()).setSearchVoiceTime(expire);Log.i(TAG, "voiceInitToken onNext " + token);voiceInit(token);}}@Overridepublic void onError(Throwable e) {super.onError(e);mInit = false;if (mAutomaticSpeechRecognitionListener != null)mAutomaticSpeechRecognitionListener.initError();Log.i(TAG, "voiceInitToken onError " + e.toString());}@Overridepublic void onComplete() {super.onComplete();}});} else {String searchVoiceToken = SearchVoiceSp.getInstance(UKidsApplication.getInstance()).getSearchVoiceToken();voiceInit(searchVoiceToken);}}public boolean isInitVoice() {return mInit;}/*** @param* @date 8/17/22 2:46 PM* @description 初始化**/private void voiceInit(String token) {//获取工作路径String asset_path = CommonUtils.getModelPath(mContext);Log.i(TAG, "use workspace " + asset_path);String debug_path = mContext.getExternalCacheDir().getAbsolutePath() + "/debug_" + System.currentTimeMillis();FileUtils.createDir(debug_path);//这里主动调用完成SDK配置文件的拷贝if (CommonUtils.copyAssetsData(mContext)) {Log.i(TAG, "copy assets data done");} else {Log.i(TAG, "copy assets failed");return;}//初始化SDK,注意用户需要在Auth.getAliYunTicket中填入相关ID信息才可以使用。int ret = nui_instance.initialize(this, genInitParams(asset_path, debug_path, token), Constants.LogLevel.LOG_LEVEL_VERBOSE, true);Log.i(TAG, "是否初始化成功" + ret);//设置相关识别参数,具体参考API文档nui_instance.setParams(genParams());if (ret == Constants.NuiResultCode.SUCCESS) {mInit = true;if (mAutomaticSpeechRecognitionListener != null)mAutomaticSpeechRecognitionListener.initSucceed();} else {mInit = false;if (mAutomaticSpeechRecognitionListener != null)mAutomaticSpeechRecognitionListener.initError();}}/*** @param* @description 初始化录音功能**/public void initAudioRecorder() {if (mAudioRecorder == null) {//录音初始化,录音参数中格式只支持16bit/单通道,采样率支持8K/16KmAudioRecorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, SAMPLE_RATE,AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, WAVE_FRAM_SIZE * 4);}}/*** @date 8/17/22 2:46 PM* @description 开始识别**/public void startDialog() {if (nui_instance != null && mInit) {int ret = nui_instance.startDialog(Constants.VadMode.TYPE_P2T,genDialogParams());Log.i(TAG, "start done with " + ret);} else {ToastUtil.showShortToast(mContext, "初始化失败");}}/*** @param* @description 停止识别**/public void stopDialog() {if (nui_instance != null && mInit) {long ret = nui_instance.stopDialog();Log.i(TAG, "cancel dialog " + ret + " end");} else {ToastUtil.showShortToast(mContext, "初始化失败");}}/*** @date 8/17/22 2:46 PM**/public void cancelDialog() {if (nui_instance != null && mInit) {long ret = nui_instance.cancelDialog();Log.i(TAG, "cancel dialog " + ret + " end");} else {ToastUtil.showShortToast(mContext, "初始化失败");}}/*** @description 释放**/public void releaseVoice() {if (nui_instance != null) {nui_instance.release();}if (mAudioRecorder != null) {mAudioRecorder.release();mAudioRecorder = null;}}private String genDialogParams() {String params = "";try {JSONObject dialog_param = new JSONObject();params = dialog_param.toString();} catch (JSONException e) {e.printStackTrace();}Log.i(TAG, "dialog params: " + params);return params;}private String genParams() {String params = "";try {JSONObject nls_config = new JSONObject();nls_config.put("enable_intermediate_result", true);// 参数可根据实际业务进行配置//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("max_start_silence", 2000);nls_config.put("max_end_silence", 500);//nls_config.put("customization_id", "test_id");//nls_config.put("vocabulary_id", "test_id");//nls_config.put("sample_rate", 16000);//nls_config.put("sr_format", "opus");JSONObject parameters = new JSONObject();parameters.put("nls_config", nls_config);//需要请求的语音服务类型,一句话识别为“0”。parameters.put("service_type", Constants.kServiceTypeASR);// 如果有HttpDns则可进行设置// parameters.put("direct_ip", FileUtils.getDirectIp());params = parameters.toString();Log.i(TAG, "genParams: " + params);} catch (JSONException e) {e.printStackTrace();}return params;}private String genInitParams(String workPath, String debugPath, String token) {String str = "";try {JSONObject object = new JSONObject();object.put("app_key", "QhjdgLiaAFM3j8qY");object.put("token", token);object.put("url", "wss://nls-gateway.aliyuncs.com/ws/v1");object.put("device_id", FileUtils.getDeviceId());object.put("workspace", workPath);object.put("debug_path", debugPath);object.put("sample_rate", "16000");object.put("format", "opus");// object.put("save_wav", "true");str = object.toString();} catch (JSONException e) {e.printStackTrace();}Log.i(TAG, "InsideUserContext:" + str);return str;}//结果回掉@Overridepublic void onNuiEventCallback(Constants.NuiEvent nuiEvent, int i, int i1, KwsResult kwsResult, AsrResult asrResult) {Log.i(TAG, "event=" + nuiEvent);if (nuiEvent == Constants.NuiEvent.EVENT_ASR_RESULT) {//最终识别结果String json = asrResult.asrResult;Log.i(TAG, "event=end" + json);if (mAutomaticSpeechRecognitionListener != null) {mAutomaticSpeechRecognitionListener.accomplish(getResult(json));}} else if (nuiEvent == Constants.NuiEvent.EVENT_ASR_PARTIAL_RESULT) {//识别中结果String json = asrResult.asrResult;Log.i(TAG, "event=start" + json);if (mAutomaticSpeechRecognitionListener != null) {mAutomaticSpeechRecognitionListener.inProgress(getResult(json));}} else if (nuiEvent == Constants.NuiEvent.EVENT_ASR_ERROR) {//根据错误码信息判断出错原因HashMap<String, String> map = new HashMap<>();map.put("code", String.valueOf(i));UMengUtils.onEvent(UKidsApplication.getInstance(), "U23_voice_sdkerror", map);if (mAutomaticSpeechRecognitionListener != null) {mAutomaticSpeechRecognitionListener.accomplish("");}} else if (nuiEvent == Constants.NuiEvent.EVENT_DIALOG_EX) {UMengUtils.onEvent(UKidsApplication.getInstance(), "U23_voice_fault");if (mAutomaticSpeechRecognitionListener != null) {mAutomaticSpeechRecognitionListener.accomplish("");}}}private String getResult(String json) {AutomaticSpeechRecognitionEntity automaticSpeechRecognitionEntity = GsonUtils.fromJson(json, AutomaticSpeechRecognitionEntity.class);AutomaticSpeechRecognitionEntity.PayloadBean payload = automaticSpeechRecognitionEntity.getPayload();String result = payload.getResult();return result;}@Overridepublic int onNuiNeedAudioData(byte[] bytes, int i) {int ret = 0;if (mAudioRecorder.getState() != AudioRecord.STATE_INITIALIZED) {Log.e(TAG, "audio recorder not init");return -1;}ret = mAudioRecorder.read(bytes, 0, i);return ret;}@Overridepublic void onNuiAudioStateChanged(Constants.AudioState audioState) {Log.i(TAG, "onNuiAudioStateChanged");if (mAudioRecorder != null)if (audioState == Constants.AudioState.STATE_OPEN) {Log.i(TAG, "audio recorder start");mAudioRecorder.startRecording();} else if (audioState == Constants.AudioState.STATE_CLOSE) {Log.i(TAG, "audio recorder close");mAudioRecorder.release();} else if (audioState == Constants.AudioState.STATE_PAUSE) {Log.i(TAG, "audio recorder pause");mAudioRecorder.stop();}}//语音值回调@Overridepublic void onNuiAudioRMSChanged(float v) {}@Overridepublic void onNuiVprEventCallback(Constants.NuiVprEvent nuiVprEvent) {}}
基本就是这样
参数说明
语音服务的地址根据自己需求配置
交互图
基本就这些
错误码详情查看官网文档
传送门:https://help.aliyun.com/document_detail/173298.html