当前位置:   article > 正文

Android集成科大讯飞语音识别、语音唤醒、语音播报简易封装_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中

  1. <uses-permission android:name="android.permission.INTERNET" />
  2. <uses-permission android:name="android.permission.RECORD_AUDIO" />
  3. <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  4. <!-- App 需要使用的部分权限 -->
  5. <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  6. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  7. <!-- 科大讯飞 -->
  8. <uses-permission
  9. android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
  10. tools:ignore="ProtectedPermissions" />
  11. <uses-permission
  12. android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
  13. tools:ignore="ProtectedPermissions" />
  14. <uses-permission
  15. android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
  16. tools:ignore="ProtectedPermissions" />
  17. <uses-permission
  18. android:name="android.permission.READ_PHONE_NUMBERS"
  19. tools:ignore="ProtectedPermissions" />

注意需要在applicaion的onCreate()方法中注册或者在唤醒之前注册都可以

  1. /**
  2. * 科大讯飞
  3. * 语音sdk
  4. * 初始化
  5. */
  6. private void initKedaXun() {
  7. // 初始化参数构建
  8. StringBuffer param = new StringBuffer();
  9. //IflytekAPP_id为我们申请的Appid
  10. param.append("appid=" + "IflytekAPP_id");
  11. param.append(",");
  12. // 设置使用v5+
  13. param.append(SpeechConstant.ENGINE_MODE + "=" + SpeechConstant.MODE_MSC);
  14. SpeechUtility.createUtility(XiaoYaApp.this, param.toString());
  15. }

7、唤醒工具类封装

 其中IflytekAPP_id为科大讯飞平台的应用id

  1. public abstract class WakeUpUtil {
  2. // private static AutoTouch autoTouch = new AutoTouch();//自动点击屏幕
  3. /**
  4. * 唤醒的回调
  5. */
  6. public abstract void wakeUp(String resultString);
  7. // Log标签
  8. private static final String TAG = "WakeUpUtil";
  9. // 上下文
  10. private static Context mContext;
  11. // 语音唤醒对象
  12. private VoiceWakeuper mIvw;
  13. //唤醒门限值
  14. //门限值越高,则要求匹配度越高,才能唤醒
  15. //值范围:[03000]
  16. //默认值:1450
  17. private static int curThresh = 1450;
  18. public WakeUpUtil(Context context) {
  19. initKedaXun(context);
  20. mContext = context;
  21. // 初始化唤醒对象
  22. mIvw = VoiceWakeuper.createWakeuper(context, null);
  23. Log.d("initLogData", "===进入唤醒工具类====");
  24. }
  25. /**
  26. * 获取唤醒词功能
  27. *
  28. * @return 返回文件位置
  29. */
  30. private static String getResource() {
  31. final String resPath = ResourceUtil.generateResourcePath(mContext, RESOURCE_TYPE.assets, "ivw/" + "cf22564a" + ".jet");
  32. return resPath;
  33. }
  34. /**
  35. * 唤醒
  36. */
  37. public void wake() {
  38. Log.d("initLogData", "===进入唤醒工具类====");
  39. // 非空判断,防止因空指针使程序崩溃
  40. VoiceWakeuper mIvw = VoiceWakeuper.getWakeuper();
  41. if (mIvw != null) {
  42. // textView.setText(resultString);
  43. // 清空参数
  44. mIvw.setParameter(SpeechConstant.PARAMS, null);
  45. // 设置唤醒资源路径
  46. mIvw.setParameter(SpeechConstant.IVW_RES_PATH, getResource());
  47. // 唤醒门限值,根据资源携带的唤醒词个数按照“id:门限;id:门限”的格式传入
  48. mIvw.setParameter(SpeechConstant.IVW_THRESHOLD, "0:" + curThresh);
  49. // 设置唤醒模式
  50. mIvw.setParameter(SpeechConstant.IVW_SST, "wakeup");
  51. // 设置持续进行唤醒
  52. mIvw.setParameter(SpeechConstant.KEEP_ALIVE, "1");
  53. mIvw.startListening(mWakeuperListener);
  54. Log.d("initLogData", "====唤醒====");
  55. } else {
  56. Log.d("initLogData", "===唤醒未初始化11====");
  57. // Toast.makeText(mContext, "唤醒未初始化1", Toast.LENGTH_SHORT).show();
  58. }
  59. }
  60. public void stopWake() {
  61. mIvw = VoiceWakeuper.getWakeuper();
  62. if (mIvw != null) {
  63. mIvw.stopListening();
  64. } else {
  65. Log.d("initLogData", "===唤醒未初始化222====");
  66. // Toast.makeText(mContext, "唤醒未初始化2", Toast.LENGTH_SHORT).show();
  67. }
  68. }
  69. String resultString = "";
  70. private WakeuperListener mWakeuperListener = new WakeuperListener() {
  71. @Override
  72. public void onResult(WakeuperResult result) {
  73. try {
  74. String text = result.getResultString();
  75. JSONObject object;
  76. object = new JSONObject(text);
  77. StringBuffer buffer = new StringBuffer();
  78. buffer.append("【RAW】 " + text);
  79. buffer.append("\n");
  80. buffer.append("【操作类型】" + object.optString("sst"));
  81. buffer.append("\n");
  82. buffer.append("【唤醒词id】" + object.optString("id"));
  83. buffer.append("\n");
  84. buffer.append("【得分】" + object.optString("score"));
  85. buffer.append("\n");
  86. buffer.append("【前端点】" + object.optString("bos"));
  87. buffer.append("\n");
  88. buffer.append("【尾端点】" + object.optString("eos"));
  89. resultString = buffer.toString();
  90. stopWake();
  91. // autoTouch.autoClickPos( 0.1, 0.1);
  92. wakeUp(resultString);
  93. // MyEventManager.postMsg("" + resultString, "voicesWakeListener");
  94. } catch (JSONException e) {
  95. MyEventManager.postMsg("" + "结果解析出错", "voicesWakeListener");
  96. resultString = "结果解析出错";
  97. wakeUp(resultString);
  98. e.printStackTrace();
  99. }
  100. // Logger.d("===开始说话==="+resultString);
  101. }
  102. @Override
  103. public void onError(SpeechError error) {
  104. // MyEventManager.postMsg("" + "唤醒出错", "voicesWakeListener");
  105. }
  106. @Override
  107. public void onBeginOfSpeech() {
  108. Log.d("initLogData", "===唤醒onBeginOfSpeech====");
  109. }
  110. @Override
  111. public void onEvent(int eventType, int isLast, int arg2, Bundle obj) {
  112. // Log.d("initLogData", "===唤醒onEvent===" + eventType);
  113. }
  114. @Override
  115. public void onVolumeChanged(int i) {
  116. // Log.d("initLogData", "===开始说话==="+i);
  117. }
  118. };
  119. /**
  120. * 科大讯飞
  121. * 语音sdk
  122. * 初始化
  123. */
  124. public void initKedaXun(Context context) {
  125. // 初始化参数构建
  126. StringBuffer param = new StringBuffer();
  127. //IflytekAPP_id为我们申请的Appid
  128. param.append("appid=" + context.getString(R.string.IflytekAPP_id));
  129. param.append(",");
  130. // 设置使用v5+
  131. param.append(SpeechConstant.ENGINE_MODE + "=" + SpeechConstant.MODE_MSC);
  132. SpeechUtility.createUtility(context, param.toString());
  133. Log.d("initLogData", "===在appacation中初始化=====");
  134. }
  135. }

使用直接调用即可

  1. /**
  2. * 科大讯飞
  3. * 语音唤醒
  4. * 对象
  5. */
  6. private WakeUpUtil wakeUpUtil;
  7. private void voiceWake() {
  8. Log.d("initLogData", "===执行唤醒服务====");
  9. wakeUpUtil = new WakeUpUtil(this) {
  10. @Override
  11. public void wakeUp(String result) {
  12. MyEventManager.postMsg("" + "唤醒成功", "voicesWakeListener");
  13. Log.d("initLogData", "====唤醒成功===========" + result);
  14. // 开启唤醒
  15. wakeUpUtil.wake();
  16. }
  17. };
  18. wakeUpUtil.wake();
  19. }

到此语音唤醒已经集成结束,接下来是语音识别。

二、语音识别

1、工具类

  1. /**
  2. * 科大讯飞
  3. * 语音识别
  4. * 工具类
  5. */
  6. public class KDVoiceRegUtils {
  7. private SpeechRecognizer mIat;
  8. private RecognizerListener mRecognizerListener;
  9. private InitListener mInitListener;
  10. private StringBuilder result = new StringBuilder();
  11. // 函数调用返回值
  12. private int resultCode = 0;
  13. /**
  14. * 利用AtomicReference
  15. */
  16. private static final AtomicReference<KDVoiceRegUtils> INSTANCE = new AtomicReference<KDVoiceRegUtils>();
  17. /**
  18. * 私有化
  19. */
  20. private KDVoiceRegUtils() {
  21. }
  22. /**
  23. * 用CAS确保线程安全
  24. */
  25. public static final KDVoiceRegUtils getInstance() {
  26. for (; ; ) {
  27. KDVoiceRegUtils current = INSTANCE.get();
  28. if (current != null) {
  29. return current;
  30. }
  31. current = new KDVoiceRegUtils();
  32. if (INSTANCE.compareAndSet(null, current)) {
  33. return current;
  34. }
  35. Log.d("initLogData", "===科大讯飞实例化===大哥大哥==");
  36. }
  37. }
  38. /**
  39. * 初始化
  40. * 监听
  41. */
  42. public void initVoiceRecorgnise(Context ct) {
  43. if (mInitListener != null || mRecognizerListener != null) {
  44. return;
  45. }
  46. mInitListener = new InitListener() {
  47. @Override
  48. public void onInit(int code) {
  49. // Log.e(TAG, "SpeechRecognizer init() code = " + code);
  50. Log.d("initLogData", "===科大讯飞唤醒初始化===" + code);
  51. if (code != ErrorCode.SUCCESS) {
  52. // showToast("初始化失败,错误码:" + code + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
  53. }
  54. }
  55. };
  56. //识别监听
  57. mRecognizerListener = new RecognizerListener() {
  58. @Override
  59. public void onBeginOfSpeech() {
  60. // 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入
  61. Log.d("initLogData", "=====开始说话======");
  62. }
  63. @Override
  64. public void onError(SpeechError error) {
  65. // Tips:
  66. // 错误码:10118(您没有说话),可能是录音机权限被禁,需要提示用户打开应用的录音权限。
  67. // Log.d("initLogData", "====错误说话=====" + error.getPlainDescription(true));
  68. senVoicesMsg(300, "识别错误 ");//100启动语音识别 200识别成功 300识别错误
  69. mIat.stopListening();
  70. hideDialog();
  71. }
  72. @Override
  73. public void onEndOfSpeech() {
  74. // 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入
  75. mIat.stopListening();
  76. // Log.d("initLogData", "=====结束说话======");
  77. hideDialog();
  78. }
  79. @Override
  80. public void onResult(RecognizerResult results, boolean isLast) {
  81. String text = parseIatResult(results.getResultString());
  82. // Log.d("initLogData", "==说话==语音识别结果==initVoice==" + text);
  83. result.append(text);
  84. if (!text.trim().isEmpty() && boxDialog != null) {
  85. senVoicesMsg(200, "识别成功");//100启动语音识别 200识别成功 300识别错误
  86. boxDialog.showTxtContent(result.toString());
  87. senVoicesMsg(200, "" + result.toString());
  88. }
  89. if (isLast) {
  90. result.setLength(0);
  91. }
  92. }
  93. @Override
  94. public void onVolumeChanged(int volume, byte[] data) {
  95. //showToast("当前正在说话,音量大小:" + volume);
  96. if (volume > 0 && boxDialog != null) {
  97. boxDialog.showTxtContent("录音中...");
  98. }
  99. Log.d("initLogData", "===说话==onVolumeChanged:====" + volume);
  100. }
  101. @Override
  102. public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
  103. // 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因
  104. // 若使用本地能力,会话id为null
  105. if (SpeechEvent.EVENT_SESSION_ID == eventType) {
  106. String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
  107. }
  108. }
  109. };
  110. // 初始化识别无UI识别对象
  111. // 使用SpeechRecognizer对象,可根据回调消息自定义界面;
  112. mIat = SpeechRecognizer.createRecognizer(ct, mInitListener);
  113. if (mIat != null) {
  114. setIatParam();//参数配置
  115. }
  116. }
  117. /**
  118. * 执行语音
  119. * 识别
  120. */
  121. public void startVoice(Context context) {
  122. senVoicesMsg(100, "启动语音识别");//100启动语音识别 200识别成功 300识别错误
  123. if (mIat != null) {
  124. showDialog(context);
  125. mIat.startListening(mRecognizerListener);
  126. }
  127. }
  128. /**
  129. * 科大讯飞
  130. * 语音识别
  131. * 参数配置
  132. */
  133. private void setIatParam() {
  134. // 清空参数
  135. mIat.setParameter(com.iflytek.cloud.SpeechConstant.PARAMS, null);
  136. // 设置听写引擎
  137. mIat.setParameter(com.iflytek.cloud.SpeechConstant.ENGINE_TYPE, com.iflytek.cloud.SpeechConstant.TYPE_CLOUD);
  138. // 设置返回结果格式
  139. mIat.setParameter(com.iflytek.cloud.SpeechConstant.RESULT_TYPE, "json");
  140. // 设置语言
  141. mIat.setParameter(com.iflytek.cloud.SpeechConstant.LANGUAGE, "zh_cn");
  142. // 设置语言区域
  143. mIat.setParameter(com.iflytek.cloud.SpeechConstant.ACCENT, "mandarin");
  144. // 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理
  145. mIat.setParameter(com.iflytek.cloud.SpeechConstant.VAD_BOS, "4000");
  146. // 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音
  147. mIat.setParameter(com.iflytek.cloud.SpeechConstant.VAD_EOS, "500");
  148. // 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点
  149. mIat.setParameter(com.iflytek.cloud.SpeechConstant.ASR_PTT, "0");
  150. Log.d("initLogData", "==语音是被==初始化成功:====");
  151. // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
  152. // 注:AUDIO_FORMAT参数语记需要更新版本才能生效
  153. // mIatDialog.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
  154. // mIatDialog.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/MyApplication/" + filename + ".wav");
  155. }
  156. /**
  157. * 语音
  158. * 识别
  159. * 解析
  160. */
  161. public static String parseIatResult(String json) {
  162. StringBuffer ret = new StringBuffer();
  163. try {
  164. JSONTokener tokener = new JSONTokener(json);
  165. JSONObject joResult = new JSONObject(tokener);
  166. JSONArray words = joResult.getJSONArray("ws");
  167. for (int i = 0; i < words.length(); i++) {
  168. // 转写结果词,默认使用第一个结果
  169. JSONArray items = words.getJSONObject(i).getJSONArray("cw");
  170. JSONObject obj = items.getJSONObject(0);
  171. ret.append(obj.getString("w"));
  172. }
  173. } catch (Exception e) {
  174. e.printStackTrace();
  175. }
  176. return ret.toString();
  177. }
  178. /**
  179. * 对话框
  180. * getApplicationContext()
  181. */
  182. private VoiceDialog boxDialog;
  183. private void showDialog(Context context) {
  184. View inflate = LayoutInflater.from(context).inflate(R.layout.donghua_layout, null, false);
  185. boxDialog = new VoiceDialog(context, inflate, VoiceDialog.LocationView.BOTTOM);
  186. boxDialog.show();
  187. }
  188. /**
  189. * 隐藏
  190. * 对话框
  191. */
  192. private void hideDialog() {
  193. if (boxDialog != null) {
  194. boxDialog.dismiss();
  195. }
  196. }
  197. /**
  198. * 发送语音
  199. * 识别消息
  200. *
  201. * @param code
  202. * @param conn
  203. */
  204. private void senVoicesMsg(int code, String conn) {
  205. VoiceRecognizeResult voiceRecognizeResult = new VoiceRecognizeResult();
  206. voiceRecognizeResult.setCode(code);//100启动语音识别 200识别成功 300识别错误
  207. voiceRecognizeResult.setMsg("" + conn);
  208. String std = JSON.toJSONString(voiceRecognizeResult);
  209. MyEventManager.postMsg("" + std, "VoiceRecognizeResult");
  210. }
  211. /**
  212. * 科大讯飞
  213. * 语音sdk
  214. * 初始化
  215. */
  216. public void initKedaXun(Context context) {
  217. // 初始化参数构建
  218. StringBuffer param = new StringBuffer();
  219. //IflytekAPP_id为我们申请的Appid
  220. param.append("appid=" + context.getString(R.string.IflytekAPP_id));
  221. param.append(",");
  222. // 设置使用v5+
  223. param.append(SpeechConstant.ENGINE_MODE + "=" + SpeechConstant.MODE_MSC);
  224. SpeechUtility.createUtility(context, param.toString());
  225. Log.d("initLogData", "===在appacation中初始化=====");
  226. }
  227. }

2、使用

  1. KDVoiceRegUtils.getInstance().initKedaXun(mWXSDKInstance.getContext());
  2. KDVoiceRegUtils.getInstance().initVoiceRecorgnise(mUniSDKInstance.getContext());//语音识别初始化
  3. KDVoiceRegUtils.getInstance().startVoice(mUniSDKInstance.getContext());

注意其实代码还可以优化,由于公司业务需要,封装的不怎么彻底,使用者可在此基础上进一步封装。

三、语音播报

 1、工具类

  1. public class VoiceAnno {
  2. /**
  3. * 利用AtomicReference
  4. */
  5. private static final AtomicReference<VoiceAnno> INSTANCE = new AtomicReference<VoiceAnno>();
  6. /**
  7. * 私有化
  8. */
  9. private VoiceAnno() {
  10. initSpeechKD();
  11. }
  12. /**
  13. * 用CAS确保线程安全
  14. */
  15. public static final VoiceAnno getInstance() {
  16. for (; ; ) {
  17. VoiceAnno current = INSTANCE.get();
  18. if (current != null) {
  19. return current;
  20. }
  21. current = new VoiceAnno();
  22. if (INSTANCE.compareAndSet(null, current)) {
  23. return current;
  24. }
  25. }
  26. }
  27. /**
  28. * 参数
  29. * 初始化
  30. */
  31. private SpeechSynthesizer mTts;
  32. private void initSpeechKD() {
  33. //1.创建SpeechSynthesizer对象, 第二个参数:本地合成时传InitListener
  34. mTts = SpeechSynthesizer.createSynthesizer(XiaoYaApp.getContext(), null);
  35. //2.合成参数设置,详见《科大讯飞MSC API手册(Android)》SpeechSynthesizer 类
  36. mTts.setParameter(SpeechConstant.VOICE_NAME, "aisxping");//设置发音人
  37. mTts.setParameter(SpeechConstant.SPEED, "50");//设置语速
  38. mTts.setParameter(SpeechConstant.VOLUME, "80");//设置音量,范围0~100
  39. mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD); //设置云端
  40. //设置合成音频保存位置(可自定义保存位置),保存在“./sdcard/iflytek.pcm”
  41. //保存在SD卡需要在AndroidManifest.xml添加写SD卡权限
  42. //如果不需要保存合成音频,注释该行代码
  43. // mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, "./sdcard/iflytek.pcm");
  44. }
  45. /**
  46. * 开始
  47. * 语音识别
  48. *
  49. */
  50. public void startVoice(String conntent,SynthesizerListener mSynListener) {
  51. //3.开始合成
  52. mTts.startSpeaking(conntent, mSynListener);
  53. }

2、使用

  1. VoiceAnno.getInstance().startVoice("你好,我是蘑菇头,请问有什么可以帮助您。", new SynthesizerListener() {
  2. @Override
  3. public void onSpeakBegin() {
  4. }
  5. @Override
  6. public void onBufferProgress(int i, int i1, int i2, String s) {
  7. }
  8. @Override
  9. public void onSpeakPaused() {
  10. }
  11. @Override
  12. public void onSpeakResumed() {
  13. }
  14. @Override
  15. public void onSpeakProgress(int i, int i1, int i2) {
  16. }
  17. @Override
  18. public void onCompleted(SpeechError speechError) {
  19. }
  20. @Override
  21. public void onEvent(int i, int i1, int i2, Bundle bundle) {
  22. }
  23. });

四、  Game over

        good bye

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/538829
推荐阅读
相关标签
  

闽ICP备14008679号