Android 科大讯飞语音识别

转载:https://blog.csdn.net/chenli_001/article/details/73603917
html


1、语音识别java


1.下载SDK(地址:http://www.xfyun.cn/sdk/dispatcher),选择语音听写SDK(以下图) ,下载前会让你先建立应用,建立应用后会获得一个appid。而后点“当即开通”去开通“语音识别”功能,以后就会跳出“SDK下载”的页面,而后就能够下载了(未注册帐号的要先注册一个帐号)。android




2.将下载好的SDK中 libs 目录下的 Msc.jar包引入到工程中(参见http://blog.csdn.net/highboys/article/details/51549679,此外,由于本Demo中会用到json的东西,因此还得本身去网上下一个Gson的jar包,一并引进去)。以后在main目录下新建一个jniLibs目录,将 SDK中 libs 目录下的armeabi 拷进去,以下图所示(第④个先不用管): json



3.科大讯飞为咱们提供了一套语音听写时的UI,即听写的时候会有一个动画效果(以下图),这个时候咱们须要 先将 SDK 资源包 assets 路径下的资源文件拷贝至 android 工程asstes 目录下(没有的话本身新建),参照第2步图的④。网络



4.接下来就是代码的实现了。首先在Manifest中添加一下权限
app

[html]   view plain  copy
 
  1. <!--链接网络权限,用于执行云端语音能力 -->  
  2.     <uses-permission android:name="android.permission.INTERNET" />  
  3.     <!--获取手机录音机使用权限,听写、识别、语义理解须要用到此权限 -->  
  4.     <uses-permission android:name="android.permission.RECORD_AUDIO" />  
  5.     <!--读取网络信息状态 -->  
  6.     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />  
  7.     <!--获取当前wifi状态 -->  
  8.     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />  
  9.     <!--容许程序改变网络链接状态 -->  
  10.     <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />  
  11.     <!--读取手机信息权限 -->  
  12.     <uses-permission android:name="android.permission.READ_PHONE_STATE" />  
  13.   
  14.     <!--SD卡读写的权限(若是须要保存音频文件到本地的话)-->  
  15.     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />  
  16.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
  17.     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />  

其次是java代码(逻辑上是点击了某个Button以后,才执行下面的代码)。
[java]   view plain  copy
 
  1.     //有动画效果  
  2.     private RecognizerDialog iatDialog;  
  3.   
  4. // ①语音配置对象初始化  
  5.                 SpeechUtility.createUtility(MainActivity.this, SpeechConstant.APPID + "=578f1af7");//将这里的578f1af7替换成本身申请获得的8位appid  
  6.   
  7.                 // ②初始化有交互动画的语音识别器  
  8.                 iatDialog = new RecognizerDialog(MainActivity.this, mInitListener);  
  9.      //③设置监听,实现听写结果的回调  
  10.                 iatDialog.setListener(new RecognizerDialogListener() {  
  11.                     String resultJson = "[";//放置在外边作类的变量则报错,会形成json格式不对(?)  
  12.   
  13.                     @Override  
  14.                     public void onResult(RecognizerResult recognizerResult, boolean isLast) {  
  15.                         System.out.println("-----------------   onResult   -----------------");  
  16.                         if (!isLast) {  
  17.                             resultJson += recognizerResult.getResultString() + ",";  
  18.                         } else {  
  19.                             resultJson += recognizerResult.getResultString() + "]";  
  20.                         }  
  21.   
  22.                         if (isLast) {  
  23.                             //解析语音识别后返回的json格式的结果  
  24.                             Gson gson = new Gson();  
  25.                             List<DictationResult> resultList = gson.fromJson(resultJson,  
  26.                                     new TypeToken<List<DictationResult>>() {  
  27.                                     }.getType());  
  28.                             String result = "";  
  29.                             for (int i = 0; i < resultList.size() - 1; i++) {  
  30.                                 result += resultList.get(i).toString();  
  31.                             }  
  32.                             etText.setText(result);  
  33.                             //获取焦点  
  34.                             etText.requestFocus();  
  35.                             //将光标定位到文字最后,以便修改  
  36.                             etText.setSelection(result.length());  
  37.                         }  
  38.                     }  
  39.   
  40.                     @Override  
  41.                     public void onError(SpeechError speechError) {  
  42.                         //自动生成的方法存根  
  43.                         speechError.getPlainDescription(true);  
  44.                     }  
  45.                 });  
  46.                 //开始听写,需将sdk中的assets文件下的文件夹拷入项目的assets文件夹下(没有的话本身新建)  
  47.                 iatDialog.show();  

其中的mInitListener定义以下:
[java]   view plain  copy
 
  1. public static final String TAG = "MainActivity";  
  2. private InitListener mInitListener = new InitListener() {  
  3.     @Override  
  4.     public void onInit(int code) {  
  5.         Log.d(TAG, "SpeechRecognizer init() code = " + code);  
  6.         if (code != ErrorCode.SUCCESS) {  
  7.             Toast.makeText(MainActivity.this"初始化失败,错误码:" + code, Toast.LENGTH_SHORT).show();  
  8.         }  
  9.     }  
  10. };  

上面的代码用到了一个DictationResult类(一个用来接收转换 语音听写结果的类),须要本身新建,定义以下
[java]   view plain  copy
 
  1. /** 
  2.  * 解析 语音听写返回结果Json格式字符串 的模板类(多重嵌套Json) 
  3.  * 
  4.  * 语音识别结果Json数据格式(单条数据): 
  5.  * {"sn":1,"ls":true,"bg":0,"ed":0,"ws":[ 
  6.  * {"bg":0,"cw":[{"w":"今天","sc":0}]}, 
  7.  * {"bg":0,"cw":[{"w":"的","sc":0}]}, 
  8.  * {"bg":0,"cw":[{"w":"天气","sc":0}]}, 
  9.  * {"bg":0,"cw":[{"w":"怎么样","sc":0}]}, 
  10.  * {"bg":0,"cw":[{"w":"。","sc":0}]} 
  11.  * ]} 
  12.  * 
  13.  * sn  number :第几句 
  14.  * ls   boolean: 是否最后一句 
  15.  * bg  number :开始 
  16.  * ed  number :结束 
  17.  * ws  array :词 
  18.  * cw   array :中文分词 
  19.  * w  string :单字 
  20.  * sc  number :分数 
  21.  */  
  22. public class DictationResult {  
  23.     private String sn;  
  24.     private String ls;  
  25.     private String bg;  
  26.     private String ed;  
  27.   
  28.     private List<Words> ws;  
  29.   
  30.     public static class Words {  
  31.         private String bg;  
  32.         private List<Cw> cw;  
  33.   
  34.         public static class Cw {  
  35.             private String w;  
  36.             private String sc;  
  37.   
  38.             public String getW() {  
  39.                 return w;  
  40.             }  
  41.   
  42.             public void setW(String w) {  
  43.                 this.w = w;  
  44.             }  
  45.   
  46.             public String getSc() {  
  47.                 return sc;  
  48.             }  
  49.   
  50.             public void setSc(String sc) {  
  51.                 this.sc = sc;  
  52.             }  
  53.   
  54.             @Override  
  55.             public String toString() {  
  56.                 return w;  
  57.             }  
  58.         }  
  59.   
  60.         public String getBg() {  
  61.             return bg;  
  62.         }  
  63.   
  64.         public void setBg(String bg) {  
  65.             this.bg = bg;  
  66.         }  
  67.   
  68.         public List<Cw> getCw() {  
  69.             return cw;  
  70.         }  
  71.   
  72.         public void setCw(List<Cw> cw) {  
  73.             this.cw = cw;  
  74.         }  
  75.   
  76.         @Override  
  77.         public String toString() {  
  78.             String result = "";  
  79.             for (Cw cwTmp : cw) {  
  80.                 result += cwTmp.toString();  
  81.             }  
  82.             return result;  
  83.         }  
  84.     }  
  85.   
  86.     public String getSn() {  
  87.         return sn;  
  88.     }  
  89.   
  90.     public void setSn(String sn) {  
  91.         this.sn = sn;  
  92.     }  
  93.   
  94.     public String getLs() {  
  95.         return ls;  
  96.     }  
  97.   
  98.     public void setLs(String ls) {  
  99.         this.ls = ls;  
  100.     }  
  101.   
  102.     public String getBg() {  
  103.         return bg;  
  104.     }  
  105.   
  106.     public void setBg(String bg) {  
  107.         this.bg = bg;  
  108.     }  
  109.   
  110.     public String getEd() {  
  111.         return ed;  
  112.     }  
  113.   
  114.     public void setEd(String ed) {  
  115.         this.ed = ed;  
  116.     }  
  117.   
  118.     public List<Words> getWs() {  
  119.         return ws;  
  120.     }  
  121.   
  122.     public void setWs(List<Words> ws) {  
  123.         this.ws = ws;  
  124.     }  
  125.   
  126.     @Override  
  127.     public String toString() {  
  128.         String result = "";  
  129.         for (Words wsTmp : ws) {  
  130.             result += wsTmp.toString();  
  131.         }  
  132.         return result;  
  133.     }  
  134. }  

如此,即可实现语音听写了。这个过程可能会遇到各类各样的问题,具体错误码参见  http://www.xfyun.cn/doccenter/faq


5.说完了有动画效果的,下面就来讲说没有动画效果的(也比较简单)。ide

[java]   view plain  copy
 
  1. //1.建立SpeechRecognizer对象,第二个参数:本地识别时传InitListener  
  2.     SpeechRecognizer mIat = SpeechRecognizer.createRecognizer(context, null);  
  3.     //2.设置听写参数,详见SDK中《MSC Reference Manual》文件夹下的SpeechConstant类  
  4.     mIat.setParameter(SpeechConstant.DOMAIN,"iat");  
  5.     mIat.setParameter(SpeechConstant.LANGUAGE,"zh_cn");  
  6.     mIat.setParameter(SpeechConstant.ACCENT,"mandarin ");  
  7.   
  8.       //保存音频文件到本地(有须要的话)   仅支持pcm和wav,且须要自行添加读写SD卡权限  
  9.     mIat.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/msc/mIat.wav");  
  10.     // 3.开始听写  
  11.     mIat.startListening(mRecoListener);  
  12.     //听写监听器  
  13.     private RecognizerListener mRecoListener = new RecognizerListener() {  
  14.         //听写结果回调接口(返回Json格式结果,用户可参见附录13.1);  
  15.         // 通常状况下会经过onResults接口屡次返回结果,完整的识别内容是屡次结果的累加;  
  16.         // 关于解析Json的代码可参见Demo中JsonParser类;  
  17.         // isLast等于true时会话结束。  
  18.         public void onResult(RecognizerResult results, boolean isLast) {  
  19.             Log.d(TAG, "result:" + results.getResultString());  
  20.         }  
  21.   
  22.         //会话发生错误回调接口  
  23.         public void onError(SpeechError error) {  
  24.             //打印错误码描述  
  25.             Log.d(TAG, "error:" + error.getPlainDescription(true))  
  26.         }  
  27.   
  28.         //开始录音  
  29.         public void onBeginOfSpeech() {  
  30.         }  
  31.   
  32.         //    volume音量值0~30,data音频数据  
  33.         public void onVolumeChanged(int volume, byte[] data) {  
  34.         }  
  35.   
  36.         //结束录音  
  37.         public void onEndOfSpeech() {  
  38.         }  
  39.   
  40.         //扩展用接口  
  41.         public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {  
  42.         }  
  43.     };  

 

能够看到上面的onResult回调方法跟有动画效果时的onResult回调方法是同样的,因此主要的处理仍是在这个方法中,将有动画的那个onResult回调中的代码拷过来就好了。如此,简单的语音听写功能就实现了。(动画

//在最后必须从新设置一下,不是json格式就会报错
resultJson="[";

this