Android 科大讯飞 在线和离线语音听写
2016-09-20 23:28
525 查看
效果图:
参考资料
http://blog.csdn.net/imhxl/article/details/50854146
项目里要用语音听写,想到了科大讯飞,参考上面的资料完成了最简单的在线有UI的语音识别,后面想要改成离线也可以使用。参考下面的文章
http://blog.csdn.net/q4878802/article/details/47834601
下载好语记和离线资源之后,想要改成有UI的RecognizerDialog离线语音听写,但是没成功,试了一下没有UI的SpeechRecognizer,发现可以,只需在设置参数的时候加上一句
就可以使用了。可能是RecognizerDialog带有UI界面,已经默认写成在线的了吧
下面只贴出主活动的代码,其他参考上面的资料
—————————————————————————————————
2016.11.2更新
离线语音做了个简单的UI,效果如图:
完整代码如下,改动部分已注释:
注:经过多次测试后发现,第一次点击按钮离线语音听写无法识别,第二次点击按钮才可正常实现听写,之后都可以正常听写,这个bug目前还没有解决
—————————————————————————————————
2016.11.6 更新
第一次离线语音听写无反应bug的解决办法:在onCreat()里先执行一次,不显示UI,这样再点击就是第二次了。。。虽然很蠢,但是功能上算是实现了,后面有时间再仔细想想更好的办法
注:调试过程中又发现,在单独使用在线的情况下,在线的RecognizerDialogListener的onResult()会调用两次,输出两个str,第一个是听写内容,第二个是标点符号。如果是if (!isLast),那么输出的是听写内容,如果是if (isLast),输出的是标点符号。很显然,需要的是听写内容,这时要用if (!isLast)。
如果和离线的混用,就像上面一样,在onCreat()里先执行了一次startNoDialogOffline(),那么经测试RecognizerDialogListener的onResult()只会调用一次,输出一个str,听写内容和标点符号连在一起的(具体原因不清楚),这时候如果是if (!isLast),就不会有输出了。所以这里要用if (isLast)。
单独使用离线的情况下,RecognizerListener的onResult()是只会调用一次,输出一个str。这时候如果是if (!isLast),就不会有输出了。所以这里要用if (isLast)。
所以说在线的要和离线的分开使用,本文只是个例子,实际使用过程中也不会同时使用。简单来说,在线用if (!isLast)判断,离线用if (isLast)判断
参考资料
http://blog.csdn.net/imhxl/article/details/50854146
项目里要用语音听写,想到了科大讯飞,参考上面的资料完成了最简单的在线有UI的语音识别,后面想要改成离线也可以使用。参考下面的文章
http://blog.csdn.net/q4878802/article/details/47834601
下载好语记和离线资源之后,想要改成有UI的RecognizerDialog离线语音听写,但是没成功,试了一下没有UI的SpeechRecognizer,发现可以,只需在设置参数的时候加上一句
recognizer.setParameter(SpeechConstant.ENGINE_TYPE,SpeechConstant.TYPE_LOCAL);//调用语记接口
就可以使用了。可能是RecognizerDialog带有UI界面,已经默认写成在线的了吧
下面只贴出主活动的代码,其他参考上面的资料
package com.example.administrator.voicerecognition; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.Toast; import com.iflytek.cloud.ErrorCode; import com.iflytek.cloud.InitListener; import com.iflytek.cloud.RecognizerListener; import com.iflytek.cloud.RecognizerResult; import com.iflytek.cloud.SpeechConstant; import com.iflytek.cloud.SpeechError; import com.iflytek.cloud.SpeechRecognizer; import com.iflytek.cloud.SpeechUtility; import com.iflytek.cloud.ui.RecognizerDialog; import com.iflytek.cloud.ui.RecognizerDialogListener; public class MainActivity extends AppCompatActivity { private Button btn_voiceRec,btn_voiceRecOffline; private RecognizerDialog iatDialog=null; private SpeechRecognizer recognizer=null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); SpeechUtility.createUtility(this, "appid=xxx");//替换为实际的appid btn_voiceRec = (Button) findViewById(R.id.btn_voiceRec); btn_voiceRec.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (iatDialog!=null){ iatDialog.cancel(); iatDialog.destroy(); } startDialogOnline(); } }); btn_voiceRecOffline= (Button) findViewById(R.id.btn_voiceRecOffline); btn_voiceRecOffline.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // if (recognizer!=null){ // recognizer.cancel(); // recognizer.destroy(); // } startNoDialogOffline(); } }); } /** * 初始化监听器。 */ private InitListener mInitListener = new InitListener() { @Override public void onInit(int code) { Log.d("tag", "SpeechRecognizer init() code = " + code); if (code != ErrorCode.SUCCESS) { Log.d("tag", "初始化失败,错误码:" + code); } } }; public void startDialogOnline() { //1.创建SpeechRecognizer对象,第二个参数:本地听写时传InitListener iatDialog = new RecognizerDialog(this, mInitListener); //2.设置听写参数 iatDialog.setParameter(SpeechConstant.LANGUAGE, "zh_cn"); iatDialog.setParameter(SpeechConstant.ACCENT, "mandarin "); //3.设置回调接口 iatDialog.setListener(new RecognizerDialogListener() { @Override public void onResult(RecognizerResult recognizerResult, boolean b) { if (!b) { String json = recognizerResult.getResultString(); String str = JsonParser.parseIatResult(json); Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show(); } } @Override public void onError(SpeechError speechError) { Log.d("error", speechError.toString()); } }); //4.开始听写 iatDialog.show(); } private void startNoDialogOffline(){ //1.创建SpeechRecognizer对象,第二个参数:本地听写时传InitListener recognizer = SpeechRecognizer.createRecognizer(this,null); //2.设置听写参数 recognizer.setParameter(SpeechConstant.ENGINE_TYPE,SpeechConstant.TYPE_LOCAL);//调用语记接口 recognizer.setParameter(SpeechConstant.DOMAIN, "iat");//参数设为语音听写 recognizer.setParameter(SpeechConstant.LANGUAGE, "zh_cn");//中文 recognizer.setParameter(SpeechConstant.ACCENT, "mandarin ");//普通话 //3.设置回调接口 recognizer.startListening(new RecognizerListener() { @Override public void onVolumeChanged(int i, byte[] bytes) { } @Override public void onBeginOfSpeech() { } @Override public void onEndOfSpeech() { } @Override public void onResult(RecognizerResult recognizerResult, boolean isLast) { if (isLast) { String json = recognizerResult.getResultString(); String str = JsonParser.parseIatResult(json); Log.d("tag",str); Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show(); } } @Override public void onError(SpeechError speechError) { Log.d("error", speechError.toString()); } @Override public void onEvent(int i, int i1, int i2, Bundle bundle) { } }); } }
—————————————————————————————————
2016.11.2更新
离线语音做了个简单的UI,效果如图:
完整代码如下,改动部分已注释:
package com.example.administrator.voicerecognition; import android.app.ProgressDialog; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.Gravity; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.widget.Button; import android.widget.Toast; import com.iflytek.cloud.ErrorCode; import com.iflytek.cloud.InitListener; import com.iflytek.cloud.RecognizerListener; import com.iflytek.cloud.RecognizerResult; import com.iflytek.cloud.SpeechConstant; import com.iflytek.cloud.SpeechError; import com.iflytek.cloud.SpeechRecognizer; import com.iflytek.cloud.SpeechUtility; import com.iflytek.cloud.ui.RecognizerDialog; import com.iflytek.cloud.ui.RecognizerDialogListener; public class MainActivity extends AppCompatActivity { private Button btn_voiceRec,btn_voiceRecOffline; private RecognizerDialog iatDialog=null; private SpeechRecognizer recognizer=null; //新增对话框和语音听写完成标志------------------ private ProgressDialog pDialog=null; private boolean isFinish=false; //----------------------------------- @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); SpeechUtility.createUtility(this, "appid=xxx");//替换为实际的appid btn_voiceRec = (Button) findViewById(R.id.btn_voiceRec); btn_voiceRec.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (iatDialog!=null){ iatDialog.cancel(); iatDialog.destroy(); } startDialogOnline(); } }); btn_voiceRecOffline= (Button) findViewById(R.id.btn_voiceRecOffline); btn_voiceRecOffline.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // if (recognizer!=null){ // recognizer.cancel(); // recognizer.destroy(); // } startNoDialogOffline(); //显示对话框---------------- showProgressDialog(); //---------------------- } }); } //对话框显示方法----------------------------------- private void showProgressDialog() { pDialog = new ProgressDialog(MainActivity.this); pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); pDialog.setProgress(100); pDialog.setMessage("请稍等..."); pDialog.setIndeterminate(false); pDialog.show(); WindowManager.LayoutParams lp = pDialog.getWindow().getAttributes(); lp.gravity = Gravity.CENTER; Window win = pDialog.getWindow(); win.setAttributes(lp); new Thread(new Runnable() { @Override public void run() { //long startTime = System.currentTimeMillis(); int progress = 0; //while (System.currentTimeMillis() - startTime < 1000) { //语音听写完成后,释放对话框 while (!isFinish) { try { progress += 10; pDialog.setProgress(progress); Thread.sleep(100); } catch (InterruptedException e) { pDialog.dismiss(); } } pDialog.dismiss(); isFinish=false; } }).start(); } //-------------------------------------------------------- /** * 初始化监听器。 */ private InitListener mInitListener = new InitListener() { @Override public void onInit(int code) { Log.d("tag", "SpeechRecognizer init() code = " + code); if (code != ErrorCode.SUCCESS) { Log.d("tag", "初始化失败,错误码:" + code); } } }; public void startDialogOnline() { //1.创建SpeechRecognizer对象,第二个参数:本地听写时传InitListener iatDialog = new RecognizerDialog(this, mInitListener); //2.设置听写参数 iatDialog.setParameter(SpeechConstant.LANGUAGE, "zh_cn"); iatDialog.setParameter(SpeechConstant.ACCENT, "mandarin "); //3.设置回调接口 iatDialog.setListener(new RecognizerDialogListener() { @Override public void onResult(RecognizerResult recognizerResult, boolean isLast) { if (!isLast) { String json = recognizerResult.getResultString(); String str = JsonParser.parseIatResult(json); Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show(); } } @Override public void onError(SpeechError speechError) { Log.d("error", speechError.toString()); } }); //4.开始听写 iatDialog.show(); } private void startNoDialogOffline(){ //1.创建SpeechRecognizer对象,第二个参数:本地听写时传InitListener recognizer = SpeechRecognizer.createRecognizer(this,null); //2.设置听写参数 recognizer.setParameter(SpeechConstant.ENGINE_TYPE,SpeechConstant.TYPE_LOCAL);//调用语记接口 recognizer.setParameter(SpeechConstant.DOMAIN, "iat");//参数设为语音听写 recognizer.setParameter(SpeechConstant.LANGUAGE, "zh_cn");//中文 recognizer.setParameter(SpeechConstant.ACCENT, "mandarin ");//普通话 //3.设置回调接口 recognizer.startListening(new RecognizerListener() { @Override public void onVolumeChanged(int i, byte[] bytes) { } @Override public void onBeginOfSpeech() { } @Override public void onEndOfSpeech() { } @Override public void onResult(RecognizerResult recognizerResult, boolean isLast) { if (isLast) { String json = recognizerResult.getResultString(); String str = JsonParser.parseIatResult(json); Log.d("tag",str); Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show(); //语音听写完成标志--------------------------- isFinish=true; //------------------------------------------ } } @Override public void onError(SpeechError speechError) { Log.d("error", speechError.toString()); } @Override public void onEvent(int i, int i1, int i2, Bundle bundle) { } }); } }
注:经过多次测试后发现,第一次点击按钮离线语音听写无法识别,第二次点击按钮才可正常实现听写,之后都可以正常听写,这个bug目前还没有解决
—————————————————————————————————
2016.11.6 更新
第一次离线语音听写无反应bug的解决办法:在onCreat()里先执行一次,不显示UI,这样再点击就是第二次了。。。虽然很蠢,但是功能上算是实现了,后面有时间再仔细想想更好的办法
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); SpeechUtility.createUtility(this, "appid=xxx");//替换为实际的appid btn_voiceRec = (Button) findViewById(R.id.btn_voiceRec); btn_voiceRec.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startDialogOnline(); } }); btn_voiceRecOffline = (Button) findViewById(R.id.btn_voiceRecOffline); //先听写一次---------------------------- startNoDialogOffline(); //------------------------------------ btn_voiceRecOffline.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startNoDialogOffline(); showProgressDialog(); } }); }
注:调试过程中又发现,在单独使用在线的情况下,在线的RecognizerDialogListener的onResult()会调用两次,输出两个str,第一个是听写内容,第二个是标点符号。如果是if (!isLast),那么输出的是听写内容,如果是if (isLast),输出的是标点符号。很显然,需要的是听写内容,这时要用if (!isLast)。
如果和离线的混用,就像上面一样,在onCreat()里先执行了一次startNoDialogOffline(),那么经测试RecognizerDialogListener的onResult()只会调用一次,输出一个str,听写内容和标点符号连在一起的(具体原因不清楚),这时候如果是if (!isLast),就不会有输出了。所以这里要用if (isLast)。
单独使用离线的情况下,RecognizerListener的onResult()是只会调用一次,输出一个str。这时候如果是if (!isLast),就不会有输出了。所以这里要用if (isLast)。
所以说在线的要和离线的分开使用,本文只是个例子,实际使用过程中也不会同时使用。简单来说,在线用if (!isLast)判断,离线用if (isLast)判断
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories