温馨提示:这篇文章已超过421天没有更新,请注意相关的内容是否还可用!
摘要:本文介绍了Android系统集成了科大讯飞的语音识别、语音唤醒和语音播报功能,并进行了简易封装。通过集成这些功能,Android系统能够更智能地识别用户的语音指令,实现更便捷的人机交互。语音唤醒和播报功能也提升了用户体验,使得操作更为简便。这篇摘要简洁明了地概述了文章的主要内容。
目录
一、语音唤醒部分
1、首先在科大讯飞官网注册开发者账号
2、配置唤醒词然后下载sdk
3、选择对应功能下载
4、语音唤醒lib包全部复制到工程目录下
5、把语音唤醒词文件复制到工程的assets目录
6、复制对应权限到AndroidManifest.xml中
7、唤醒工具类封装
二、语音识别
1、工具类
2、使用
三、语音播报
1、工具类
2、使用
四、 Game over
一、语音唤醒部分
1、首先在科大讯飞官网注册开发者账号
控制台-讯飞开放平台
2、配置唤醒词然后下载sdk
3、选择对应功能下载
4、语音唤醒lib包全部复制到工程目录下
5、把语音唤醒词文件复制到工程的assets目录
6、复制对应权限到AndroidManifest.xml中
注意需要在applicaion的onCreate()方法中注册或者在唤醒之前注册都可以
/** * 科大讯飞 * 语音sdk * 初始化 */ private void initKedaXun() { // 初始化参数构建 StringBuffer param = new StringBuffer(); //IflytekAPP_id为我们申请的Appid param.append("appid=" + "IflytekAPP_id"); param.append(","); // 设置使用v5+ param.append(SpeechConstant.ENGINE_MODE + "=" + SpeechConstant.MODE_MSC); SpeechUtility.createUtility(XiaoYaApp.this, param.toString()); }
7、唤醒工具类封装
其中IflytekAPP_id为科大讯飞平台的应用id
public abstract class WakeUpUtil { // private static AutoTouch autoTouch = new AutoTouch();//自动点击屏幕 /** * 唤醒的回调 */ public abstract void wakeUp(String resultString); // Log标签 private static final String TAG = "WakeUpUtil"; // 上下文 private static Context mContext; // 语音唤醒对象 private VoiceWakeuper mIvw; //唤醒门限值 //门限值越高,则要求匹配度越高,才能唤醒 //值范围:[0,3000] //默认值:1450 private static int curThresh = 1450; public WakeUpUtil(Context context) { initKedaXun(context); mContext = context; // 初始化唤醒对象 mIvw = VoiceWakeuper.createWakeuper(context, null); Log.d("initLogData", "===进入唤醒工具类===="); } /** * 获取唤醒词功能 * * @return 返回文件位置 */ private static String getResource() { final String resPath = ResourceUtil.generateResourcePath(mContext, RESOURCE_TYPE.assets, "ivw/" + "cf22564a" + ".jet"); return resPath; } /** * 唤醒 */ public void wake() { Log.d("initLogData", "===进入唤醒工具类===="); // 非空判断,防止因空指针使程序崩溃 VoiceWakeuper mIvw = VoiceWakeuper.getWakeuper(); if (mIvw != null) { // textView.setText(resultString); // 清空参数 mIvw.setParameter(SpeechConstant.PARAMS, null); // 设置唤醒资源路径 mIvw.setParameter(SpeechConstant.IVW_RES_PATH, getResource()); // 唤醒门限值,根据资源携带的唤醒词个数按照“id:门限;id:门限”的格式传入 mIvw.setParameter(SpeechConstant.IVW_THRESHOLD, "0:" + curThresh); // 设置唤醒模式 mIvw.setParameter(SpeechConstant.IVW_SST, "wakeup"); // 设置持续进行唤醒 mIvw.setParameter(SpeechConstant.KEEP_ALIVE, "1"); mIvw.startListening(mWakeuperListener); Log.d("initLogData", "====唤醒===="); } else { Log.d("initLogData", "===唤醒未初始化11===="); // Toast.makeText(mContext, "唤醒未初始化1", Toast.LENGTH_SHORT).show(); } } public void stopWake() { mIvw = VoiceWakeuper.getWakeuper(); if (mIvw != null) { mIvw.stopListening(); } else { Log.d("initLogData", "===唤醒未初始化222===="); // Toast.makeText(mContext, "唤醒未初始化2", Toast.LENGTH_SHORT).show(); } } String resultString = ""; private WakeuperListener mWakeuperListener = new WakeuperListener() { @Override public void onResult(WakeuperResult result) { try { String text = result.getResultString(); JSONObject object; object = new JSONObject(text); StringBuffer buffer = new StringBuffer(); buffer.append("【RAW】 " + text); buffer.append("\n"); buffer.append("【操作类型】" + object.optString("sst")); buffer.append("\n"); buffer.append("【唤醒词id】" + object.optString("id")); buffer.append("\n"); buffer.append("【得分】" + object.optString("score")); buffer.append("\n"); buffer.append("【前端点】" + object.optString("bos")); buffer.append("\n"); buffer.append("【尾端点】" + object.optString("eos")); resultString = buffer.toString(); stopWake(); // autoTouch.autoClickPos( 0.1, 0.1); wakeUp(resultString); // MyEventManager.postMsg("" + resultString, "voicesWakeListener"); } catch (JSONException e) { MyEventManager.postMsg("" + "结果解析出错", "voicesWakeListener"); resultString = "结果解析出错"; wakeUp(resultString); e.printStackTrace(); } // Logger.d("===开始说话==="+resultString); } @Override public void onError(SpeechError error) { // MyEventManager.postMsg("" + "唤醒出错", "voicesWakeListener"); } @Override public void onBeginOfSpeech() { Log.d("initLogData", "===唤醒onBeginOfSpeech===="); } @Override public void onEvent(int eventType, int isLast, int arg2, Bundle obj) { // Log.d("initLogData", "===唤醒onEvent===" + eventType); } @Override public void onVolumeChanged(int i) { // Log.d("initLogData", "===开始说话==="+i); } }; /** * 科大讯飞 * 语音sdk * 初始化 */ public void initKedaXun(Context context) { // 初始化参数构建 StringBuffer param = new StringBuffer(); //IflytekAPP_id为我们申请的Appid param.append("appid=" + context.getString(R.string.IflytekAPP_id)); param.append(","); // 设置使用v5+ param.append(SpeechConstant.ENGINE_MODE + "=" + SpeechConstant.MODE_MSC); SpeechUtility.createUtility(context, param.toString()); Log.d("initLogData", "===在appacation中初始化====="); } }
使用直接调用即可
/** * 科大讯飞 * 语音唤醒 * 对象 */ private WakeUpUtil wakeUpUtil; private void voiceWake() { Log.d("initLogData", "===执行唤醒服务===="); wakeUpUtil = new WakeUpUtil(this) { @Override public void wakeUp(String result) { MyEventManager.postMsg("" + "唤醒成功", "voicesWakeListener"); Log.d("initLogData", "====唤醒成功===========" + result); // 开启唤醒 wakeUpUtil.wake(); } }; wakeUpUtil.wake(); }
到此语音唤醒已经集成结束,接下来是语音识别。
二、语音识别
1、工具类
/** * 科大讯飞 * 语音识别 * 工具类 */ public class KDVoiceRegUtils { private SpeechRecognizer mIat; private RecognizerListener mRecognizerListener; private InitListener mInitListener; private StringBuilder result = new StringBuilder(); // 函数调用返回值 private int resultCode = 0; /** * 利用AtomicReference */ private static final AtomicReference INSTANCE = new AtomicReference(); /** * 私有化 */ private KDVoiceRegUtils() { } /** * 用CAS确保线程安全 */ public static final KDVoiceRegUtils getInstance() { for (; ; ) { KDVoiceRegUtils current = INSTANCE.get(); if (current != null) { return current; } current = new KDVoiceRegUtils(); if (INSTANCE.compareAndSet(null, current)) { return current; } Log.d("initLogData", "===科大讯飞实例化===大哥大哥=="); } } /** * 初始化 * 监听 */ public void initVoiceRecorgnise(Context ct) { if (mInitListener != null || mRecognizerListener != null) { return; } mInitListener = new InitListener() { @Override public void onInit(int code) { // Log.e(TAG, "SpeechRecognizer init() code = " + code); Log.d("initLogData", "===科大讯飞唤醒初始化===" + code); if (code != ErrorCode.SUCCESS) { // showToast("初始化失败,错误码:" + code + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案"); } } }; //识别监听 mRecognizerListener = new RecognizerListener() { @Override public void onBeginOfSpeech() { // 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入 Log.d("initLogData", "=====开始说话======"); } @Override public void onError(SpeechError error) { // Tips: // 错误码:10118(您没有说话),可能是录音机权限被禁,需要提示用户打开应用的录音权限。 // Log.d("initLogData", "====错误说话=====" + error.getPlainDescription(true)); senVoicesMsg(300, "识别错误 ");//100启动语音识别 200识别成功 300识别错误 mIat.stopListening(); hideDialog(); } @Override public void onEndOfSpeech() { // 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入 mIat.stopListening(); // Log.d("initLogData", "=====结束说话======"); hideDialog(); } @Override public void onResult(RecognizerResult results, boolean isLast) { String text = parseIatResult(results.getResultString()); // Log.d("initLogData", "==说话==语音识别结果==initVoice==" + text); result.append(text); if (!text.trim().isEmpty() && boxDialog != null) { senVoicesMsg(200, "识别成功");//100启动语音识别 200识别成功 300识别错误 boxDialog.showTxtContent(result.toString()); senVoicesMsg(200, "" + result.toString()); } if (isLast) { result.setLength(0); } } @Override public void onVolumeChanged(int volume, byte[] data) { //showToast("当前正在说话,音量大小:" + volume); if (volume > 0 && boxDialog != null) { boxDialog.showTxtContent("录音中..."); } Log.d("initLogData", "===说话==onVolumeChanged:====" + volume); } @Override public void onEvent(int eventType, int arg1, int arg2, Bundle obj) { // 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因 // 若使用本地能力,会话id为null if (SpeechEvent.EVENT_SESSION_ID == eventType) { String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID); } } }; // 初始化识别无UI识别对象 // 使用SpeechRecognizer对象,可根据回调消息自定义界面; mIat = SpeechRecognizer.createRecognizer(ct, mInitListener); if (mIat != null) { setIatParam();//参数配置 } } /** * 执行语音 * 识别 */ public void startVoice(Context context) { senVoicesMsg(100, "启动语音识别");//100启动语音识别 200识别成功 300识别错误 if (mIat != null) { showDialog(context); mIat.startListening(mRecognizerListener); } } /** * 科大讯飞 * 语音识别 * 参数配置 */ private void setIatParam() { // 清空参数 mIat.setParameter(com.iflytek.cloud.SpeechConstant.PARAMS, null); // 设置听写引擎 mIat.setParameter(com.iflytek.cloud.SpeechConstant.ENGINE_TYPE, com.iflytek.cloud.SpeechConstant.TYPE_CLOUD); // 设置返回结果格式 mIat.setParameter(com.iflytek.cloud.SpeechConstant.RESULT_TYPE, "json"); // 设置语言 mIat.setParameter(com.iflytek.cloud.SpeechConstant.LANGUAGE, "zh_cn"); // 设置语言区域 mIat.setParameter(com.iflytek.cloud.SpeechConstant.ACCENT, "mandarin"); // 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理 mIat.setParameter(com.iflytek.cloud.SpeechConstant.VAD_BOS, "4000"); // 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音 mIat.setParameter(com.iflytek.cloud.SpeechConstant.VAD_EOS, "500"); // 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点 mIat.setParameter(com.iflytek.cloud.SpeechConstant.ASR_PTT, "0"); Log.d("initLogData", "==语音是被==初始化成功:===="); // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限 // 注:AUDIO_FORMAT参数语记需要更新版本才能生效 // mIatDialog.setParameter(SpeechConstant.AUDIO_FORMAT, "wav"); // mIatDialog.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/MyApplication/" + filename + ".wav"); } /** * 语音 * 识别 * 解析 */ public static String parseIatResult(String json) { StringBuffer ret = new StringBuffer(); try { JSONTokener tokener = new JSONTokener(json); JSONObject joResult = new JSONObject(tokener); JSONArray words = joResult.getJSONArray("ws"); for (int i = 0; i2、使用
KDVoiceRegUtils.getInstance().initKedaXun(mWXSDKInstance.getContext()); KDVoiceRegUtils.getInstance().initVoiceRecorgnise(mUniSDKInstance.getContext());//语音识别初始化 KDVoiceRegUtils.getInstance().startVoice(mUniSDKInstance.getContext());注意其实代码还可以优化,由于公司业务需要,封装的不怎么彻底,使用者可在此基础上进一步封装。
三、语音播报
1、工具类
public class VoiceAnno { /** * 利用AtomicReference */ private static final AtomicReference INSTANCE = new AtomicReference(); /** * 私有化 */ private VoiceAnno() { initSpeechKD(); } /** * 用CAS确保线程安全 */ public static final VoiceAnno getInstance() { for (; ; ) { VoiceAnno current = INSTANCE.get(); if (current != null) { return current; } current = new VoiceAnno(); if (INSTANCE.compareAndSet(null, current)) { return current; } } } /** * 参数 * 初始化 */ private SpeechSynthesizer mTts; private void initSpeechKD() { //1.创建SpeechSynthesizer对象, 第二个参数:本地合成时传InitListener mTts = SpeechSynthesizer.createSynthesizer(XiaoYaApp.getContext(), null); //2.合成参数设置,详见《科大讯飞MSC API手册(Android)》SpeechSynthesizer 类 mTts.setParameter(SpeechConstant.VOICE_NAME, "aisxping");//设置发音人 mTts.setParameter(SpeechConstant.SPEED, "50");//设置语速 mTts.setParameter(SpeechConstant.VOLUME, "80");//设置音量,范围0~100 mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD); //设置云端 //设置合成音频保存位置(可自定义保存位置),保存在“./sdcard/iflytek.pcm” //保存在SD卡需要在AndroidManifest.xml添加写SD卡权限 //如果不需要保存合成音频,注释该行代码 // mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, "./sdcard/iflytek.pcm"); } /** * 开始 * 语音识别 * */ public void startVoice(String conntent,SynthesizerListener mSynListener) { //3.开始合成 mTts.startSpeaking(conntent, mSynListener); }2、使用
VoiceAnno.getInstance().startVoice("你好,我是蘑菇头,请问有什么可以帮助您。", new SynthesizerListener() { @Override public void onSpeakBegin() { } @Override public void onBufferProgress(int i, int i1, int i2, String s) { } @Override public void onSpeakPaused() { } @Override public void onSpeakResumed() { } @Override public void onSpeakProgress(int i, int i1, int i2) { } @Override public void onCompleted(SpeechError speechError) { } @Override public void onEvent(int i, int i1, int i2, Bundle bundle) { } });四、 Game over
good bye
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。
还没有评论,来说两句吧...