Android科大讯飞语音集成,非常详细的使用讲解

讯飞语音开发集成地址http://www.xfyun.cn/ 解压后的doc文件夹下的msc develop 文件中有详细集成步骤 
这里写图片描述 
AppId:

这里写图片描述 
1.先要注册开发者账户, 添加我的应用 , 下载sdk

这里写图片描述

2.下载后将sdk解压, 把案例导入工程中运行看看效果 
这里写图片描述

3.将libs下的两个jar包添加到libs目录下, 将同路径下的其它 .so文件(与c进行交互)复制到main路径下新建的 jniLibs(L要大写)目录下(别忘了jar包要add) , 将assert目录拷贝到main目录下 
注意 : 这些都是自己创建的应用生成的, 在申请appid时就与自己的应用绑定了, 拷贝别人的是没有用的

这里写图片描述

4.添加权限

<!--连接网络权限,用于执行云端语音能力 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!--获取手机录音机使用权限,听写、识别、语义理解需要用到此权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<!--读取网络信息状态 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!--获取当前wifi状态 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!--允许程序改变网络连接状态 -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<!--读取手机信息权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<!--读取联系人权限,上传联系人需要用到此权限 -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<!--外存储写权限,构建语法需要用到此权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--外存储读权限,构建语法需要用到此权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!--配置权限,用来记录应用配置信息 -->
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<!--手机定位信息,用来为语义等功能提供定位,提供更精准的服务-->
<!--定位信息是敏感信息,可通过Setting.setLocationEnable(false)关闭定位请求 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!--如需使用人脸识别,还要添加:摄相头权限,拍照需要用到 -->
<uses-permission android:name="android.permission.CAMERA" />

5.创建类 , 以下是代码: initSpeech()方法下的APPID需要改成上面介绍中自己应用生成的appId

 
  1. package atguigu.com.speechdemo2;

  2.  
  3. import android.app.Activity ;

  4. import android.os.Bundle ;

  5. import android.util.Log ;

  6. import android.view.View ;

  7. import android.widget.Button ;

  8. import android.widget.EditText ;

  9. import android.widget.Toast ;

  10.  
  11. import com.iflytek.cloud.ErrorCode ;

  12. import com.iflytek.cloud.InitListener ;

  13. import com.iflytek.cloud.RecognizerListener ;

  14. import com.iflytek.cloud.RecognizerResult ;

  15. import com.iflytek.cloud.SpeechConstant ;

  16. import com.iflytek.cloud.SpeechError ;

  17. import com.iflytek.cloud.SpeechRecognizer ;

  18. import com.iflytek.cloud.SpeechSynthesizer ;

  19. import com.iflytek.cloud.SpeechUtility ;

  20. import com.iflytek.cloud.SynthesizerListener ;

  21. import com.iflytek.cloud.ui.RecognizerDialog ;

  22. import com.iflytek.cloud.ui.RecognizerDialogListener ;

  23.  
  24. import org.json.JSONException ;

  25. import org.json.JSONObject ;

  26.  
  27. import java.util.HashMap ;

  28. import java.util.LinkedHashMap ;

  29.  
  30. public class MainActivity extends Activity implements View.OnClickListener {

  31.  
  32. private static final String TAG = MainActivity.class .getSimpleName();

  33. private EditText et_input;

  34. private Button btn_startspeech, btn_startspeektext ;

  35.  
  36. // 用HashMap存储听写结果

  37. private HashMap<String, String> mIatResults = new LinkedHashMap<String , String>();

  38.  
  39. @Override

  40. protected void onCreate(Bundle savedInstanceState) {

  41. super .onCreate(savedInstanceState) ;

  42. initView() ;

  43. initSpeech() ;

  44. }

  45.  
  46. private void initView() {

  47. setContentView(R.layout.activity_main) ;

  48. et_input = (EditText) findViewById(R.id.et_input );

  49. btn_startspeech = (Button) findViewById(R.id.btn_startspeech );

  50. btn_startspeektext = (Button) findViewById(R.id.btn_startspeektext );

  51. btn_startspeech .setOnClickListener(this) ;

  52. btn_startspeektext .setOnClickListener(this) ;

  53. }

  54.  
  55. private void initSpeech() {

  56. // 将“12345678”替换成您申请的 APPID,申请地址: http://www.xfyun.cn

  57. // 请勿在 “ =”与 appid 之间添加任务空字符或者转义符

  58. SpeechUtility. createUtility( this, SpeechConstant. APPID + "=56ffe0ae" );

  59. }

  60.  
  61. @Override

  62. public void onClick(View v) {

  63. switch (v.getId()) {

  64. case R.id.btn_startspeech: //语音识别(把声音转文字)

  65. startSpeechDialog();

  66. break;

  67. case R.id. btn_startspeektext:// 语音合成(把文字转声音)

  68. speekText();

  69. break;

  70. }

  71.  
  72. }

  73.  
  74. private void speekText() {

  75. //1. 创建 SpeechSynthesizer 对象 , 第二个参数: 本地合成时传 InitListener

  76. SpeechSynthesizer mTts = SpeechSynthesizer.createSynthesizer( this, null);

  77. //2.合成参数设置,详见《 MSC Reference Manual》 SpeechSynthesizer 类

  78. //设置发音人(更多在线发音人,用户可参见 附录 13.2

  79. mTts.setParameter(SpeechConstant. VOICE_NAME, "vixyun" ); // 设置发音人

  80. mTts.setParameter(SpeechConstant. SPEED, "50" );// 设置语速

  81. mTts.setParameter(SpeechConstant. VOLUME, "80" );// 设置音量,范围 0~100

  82. mTts.setParameter(SpeechConstant. ENGINE_TYPE, SpeechConstant. TYPE_CLOUD); //设置云端

  83. //设置合成音频保存位置(可自定义保存位置),保存在 “./sdcard/iflytek.pcm”

  84. //保存在 SD 卡需要在 AndroidManifest.xml 添加写 SD 卡权限

  85. //仅支持保存为 pcm 和 wav 格式, 如果不需要保存合成音频,注释该行代码

  86. mTts.setParameter(SpeechConstant. TTS_AUDIO_PATH, "./sdcard/iflytek.pcm" );

  87. //3.开始合成

  88. mTts.startSpeaking( et_input.getText().toString(), new MySynthesizerListener()) ;

  89.  
  90. }

  91.  
  92. class MySynthesizerListener implements SynthesizerListener {

  93.  
  94. @Override

  95. public void onSpeakBegin() {

  96. showTip(" 开始播放 ");

  97. }

  98.  
  99. @Override

  100. public void onSpeakPaused() {

  101. showTip(" 暂停播放 ");

  102. }

  103.  
  104. @Override

  105. public void onSpeakResumed() {

  106. showTip(" 继续播放 ");

  107. }

  108.  
  109. @Override

  110. public void onBufferProgress(int percent, int beginPos, int endPos ,

  111. String info) {

  112. // 合成进度

  113. }

  114.  
  115. @Override

  116. public void onSpeakProgress(int percent, int beginPos, int endPos) {

  117. // 播放进度

  118. }

  119.  
  120. @Override

  121. public void onCompleted(SpeechError error) {

  122. if (error == null) {

  123. showTip("播放完成 ");

  124. } else if (error != null ) {

  125. showTip(error.getPlainDescription( true));

  126. }

  127. }

  128.  
  129. @Override

  130. public void onEvent(int eventType, int arg1 , int arg2, Bundle obj) {

  131. // 以下代码用于获取与云端的会话 id,当业务出错时将会话 id提供给技术支持人员,可用于查询会话日志,定位出错原因

  132. // 若使用本地能力,会话 id为null

  133. //if (SpeechEvent.EVENT_SESSION_ID == eventType) {

  134. // String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);

  135. // Log.d(TAG, "session id =" + sid);

  136. //}

  137. }

  138. }

  139.  
  140. private void startSpeechDialog() {

  141. //1. 创建RecognizerDialog对象

  142. RecognizerDialog mDialog = new RecognizerDialog(this, new MyInitListener()) ;

  143. //2. 设置accent、 language等参数

  144. mDialog.setParameter(SpeechConstant. LANGUAGE, "zh_cn" );// 设置中文

  145. mDialog.setParameter(SpeechConstant. ACCENT, "mandarin" );

  146. // 若要将UI控件用于语义理解,必须添加以下参数设置,设置之后 onResult回调返回将是语义理解

  147. // 结果

  148. // mDialog.setParameter("asr_sch", "1");

  149. // mDialog.setParameter("nlp_version", "2.0");

  150. //3.设置回调接口

  151. mDialog.setListener( new MyRecognizerDialogListener()) ;

  152. //4. 显示dialog,接收语音输入

  153. mDialog.show() ;

  154. }

  155.  
  156. class MyRecognizerDialogListener implements RecognizerDialogListener {

  157.  
  158. /**

  159. * @param results

  160. * @param isLast 是否说完了

  161. */

  162. @Override

  163. public void onResult(RecognizerResult results, boolean isLast) {

  164. String result = results.getResultString(); //为解析的

  165. showTip(result) ;

  166. System. out.println(" 没有解析的 :" + result);

  167.  
  168. String text = JsonParser.parseIatResult(result) ;//解析过后的

  169. System. out.println(" 解析后的 :" + text);

  170.  
  171. String sn = null;

  172. // 读取json结果中的 sn字段

  173. try {

  174. JSONObject resultJson = new JSONObject(results.getResultString()) ;

  175. sn = resultJson.optString("sn" );

  176. } catch (JSONException e) {

  177. e.printStackTrace();

  178. }

  179.  
  180. mIatResults .put(sn, text) ;//没有得到一句,添加到

  181.  
  182. StringBuffer resultBuffer = new StringBuffer();

  183. for (String key : mIatResults.keySet()) {

  184. resultBuffer.append(mIatResults .get(key));

  185. }

  186.  
  187. et_input.setText(resultBuffer.toString());// 设置输入框的文本

  188. et_input .setSelection(et_input.length()) ;//把光标定位末尾

  189. }

  190.  
  191. @Override

  192. public void onError(SpeechError speechError) {

  193.  
  194. }

  195. }

  196.  
  197. class MyInitListener implements InitListener {

  198.  
  199. @Override

  200. public void onInit(int code) {

  201. if (code != ErrorCode.SUCCESS) {

  202. showTip("初始化失败 ");

  203. }

  204.  
  205. }

  206. }

  207.  
  208. /**

  209. * 语音识别

  210. */

  211. private void startSpeech() {

  212. //1. 创建SpeechRecognizer对象,第二个参数: 本地识别时传 InitListener

  213. SpeechRecognizer mIat = SpeechRecognizer.createRecognizer( this, null); //语音识别器

  214. //2. 设置听写参数,详见《 MSC Reference Manual》 SpeechConstant类

  215. mIat.setParameter(SpeechConstant. DOMAIN, "iat" );// 短信和日常用语: iat (默认)

  216. mIat.setParameter(SpeechConstant. LANGUAGE, "zh_cn" );// 设置中文

  217. mIat.setParameter(SpeechConstant. ACCENT, "mandarin" );// 设置普通话

  218. //3. 开始听写

  219. mIat.startListening( mRecoListener);

  220. }

  221.  
  222.  
  223. // 听写监听器

  224. private RecognizerListener mRecoListener = new RecognizerListener() {

  225. // 听写结果回调接口 (返回Json 格式结果,用户可参见附录 13.1);

  226. //一般情况下会通过onResults接口多次返回结果,完整的识别内容是多次结果的累加;

  227. //关于解析Json的代码可参见 Demo中JsonParser 类;

  228. //isLast等于true 时会话结束。

  229. public void onResult(RecognizerResult results, boolean isLast) {

  230. Log.e (TAG, results.getResultString());

  231. System.out.println(results.getResultString()) ;

  232. showTip(results.getResultString()) ;

  233. }

  234.  
  235. // 会话发生错误回调接口

  236. public void onError(SpeechError error) {

  237. showTip(error.getPlainDescription(true)) ;

  238. // 获取错误码描述

  239. Log. e(TAG, "error.getPlainDescription(true)==" + error.getPlainDescription(true ));

  240. }

  241.  
  242. // 开始录音

  243. public void onBeginOfSpeech() {

  244. showTip(" 开始录音 ");

  245. }

  246.  
  247. //volume 音量值0~30, data音频数据

  248. public void onVolumeChanged(int volume, byte[] data) {

  249. showTip(" 声音改变了 ");

  250. }

  251.  
  252. // 结束录音

  253. public void onEndOfSpeech() {

  254. showTip(" 结束录音 ");

  255. }

  256.  
  257. // 扩展用接口

  258. public void onEvent(int eventType, int arg1 , int arg2, Bundle obj) {

  259. }

  260. };

  261.  
  262. private void showTip (String data) {

  263. Toast.makeText( this, data, Toast.LENGTH_SHORT).show() ;

  264. }

  265. }

 

6.json解析类:

 

 
  1. package atguigu.com.speechdemo2;

  2.  
  3. import org.json.JSONArray ;

  4. import org.json.JSONObject ;

  5. import org.json.JSONTokener ;

  6.  
  7. /**

  8. * Json结果解析类

  9. */

  10. public class JsonParser {

  11.  
  12. public static String parseIatResult(String json) {

  13. StringBuffer ret = new StringBuffer() ;

  14. try {

  15. JSONTokener tokener = new JSONTokener(json) ;

  16. JSONObject joResult = new JSONObject(tokener) ;

  17.  
  18. JSONArray words = joResult.getJSONArray("ws" );

  19. for (int i = 0; i < words.length(); i++) {

  20. // 转写结果词,默认使用第一个结果

  21. JSONArray items = words.getJSONObject(i).getJSONArray("cw" );

  22. JSONObject obj = items.getJSONObject(0 );

  23. ret.append(obj.getString("w" ));

  24. // 如果需要多候选结果,解析数组其他字段

  25. // for(int j = 0; j < items.length(); j++)

  26. // {

  27. // JSONObject obj = items.getJSONObject(j);

  28. // ret.append(obj.getString("w"));

  29. // }

  30. }

  31. } catch (Exception e) {

  32. e.printStackTrace();

  33. }

  34. return ret.toString();

  35. }

  36.  
  37. public static String parseGrammarResult(String json) {

  38. StringBuffer ret = new StringBuffer() ;

  39. try {

  40. JSONTokener tokener = new JSONTokener(json) ;

  41. JSONObject joResult = new JSONObject(tokener) ;

  42.  
  43. JSONArray words = joResult.getJSONArray("ws" );

  44. for (int i = 0; i < words.length(); i++) {

  45. JSONArray items = words.getJSONObject(i).getJSONArray("cw" );

  46. for (int j = 0; j < items.length() ; j++)

  47. {

  48. JSONObject obj = items.getJSONObject(j);

  49. if (obj.getString("w").contains( "nomatch"))

  50. {

  51. ret.append( "没有匹配结果.") ;

  52. return ret.toString();

  53. }

  54. ret.append( "【结果】" + obj.getString("w" ));

  55. ret.append("【置信度】 " + obj.getInt("sc" ));

  56. ret.append("\n ");

  57. }

  58. }

  59. } catch (Exception e) {

  60. e.printStackTrace();

  61. ret.append(" 没有匹配结果 .");

  62. }

  63. return ret.toString();

  64. }

  65.  
  66. public static String parseLocalGrammarResult(String json) {

  67. StringBuffer ret = new StringBuffer() ;

  68. try {

  69. JSONTokener tokener = new JSONTokener(json) ;

  70. JSONObject joResult = new JSONObject(tokener) ;

  71.  
  72. JSONArray words = joResult.getJSONArray("ws" );

  73. for (int i = 0; i < words.length(); i++) {

  74. JSONArray items = words.getJSONObject(i).getJSONArray("cw" );

  75. for (int j = 0; j < items.length() ; j++)

  76. {

  77. JSONObject obj = items.getJSONObject(j);

  78. if (obj.getString("w").contains( "nomatch"))

  79. {

  80. ret.append( "没有匹配结果.") ;

  81. return ret.toString();

  82. }

  83. ret.append( "【结果】" + obj.getString("w" ));

  84. ret.append("\n ");

  85. }

  86. }

  87. ret.append("【置信度】 " + joResult.optInt("sc" ));

  88.  
  89. } catch (Exception e) {

  90. e.printStackTrace();

  91. ret.append(" 没有匹配结果 .");

  92. }

  93. return ret.toString();

  94. }

  95. }

7.布局文件: 

 
  1. <? xml version="1.0" encoding= "utf-8"?>

  2. <LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"

  3. android :layout_width="match_parent"

  4. android :layout_height="match_parent"

  5. android :orientation="vertical"

  6. >

  7.  
  8. <EditText

  9. android :id="@+id/et_input"

  10. android :layout_margin="10dp"

  11. android :layout_width="match_parent"

  12. android :layout_height="80dp"

  13. android :hint="请输入文本信息 ..." />

  14.  
  15.  
  16. <Button

  17. android :id="@+id/btn_startspeech"

  18. android :text="点击按钮语音输入 "

  19. android :layout_width="match_parent"

  20. android :layout_height="wrap_content" />

  21.  
  22. <Button

  23. android :id="@+id/btn_startspeektext"

  24. android :text="语音合成(把文字转声音) "

  25. android :layout_width="match_parent"

  26. android :layout_height="wrap_content" />

  27.  
  28.  
  29. </LinearLayout>

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 在Unity中使用科大讯飞语音的过程中,有一些常见问题需要注意。首先,关于路径的问题,需要确保ivw_res_path路径中不包含中文字符,否则会报错10102。此外,路径中的斜杠需要替换为反斜杠,否则也会报错10102。\[1\] 其次,关于QIVWAudioWrite接口需要调用两次的问题,这是因为在写入音频数据时,需要先调用一次MSP_AUDIO_SAMPLE_CONTINUE表示音频数据的中间部分,然后再调用一次MSP_AUDIO_SAMPLE_LAST表示音频数据的最后一部分。这样做是为了确保音频数据的完整性。\[2\] 最后,关于QIVWRegisterNotify接口后面需要使用Sleep的问题,这是因为在注册通知后,需要给科大讯飞语音一些时间来处理注册的操作。使用Sleep函数可以暂停程序的执行,让科大讯飞语音有足够的时间来完成注册。具体的等待时间可以根据实际情况进行调整。\[2\] 总结起来,在Unity中使用科大讯飞语音时,需要注意路径中不包含中文字符,斜杠需要替换为反斜杠;在写入音频数据时,需要调用两次接口来表示音频数据的中间部分和最后一部分;在注册通知后,需要使用Sleep函数给科大讯飞语音足够的时间来完成注册操作。 #### 引用[.reference_title] - *1* *2* [Unity 科大讯飞语音唤醒](https://blog.csdn.net/weixin_42208093/article/details/107364588)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值