新年新气象,过年啦,就给大家分享一下自己年前这段时间开发安卓项目的收获,这次分享的是基于Android Studio开发的语音识别功能,能够完成语音到文字的转换,通过对转换文字的分析,进一步的执行其它的逻辑指令,废话不多说,请看下文。
1.在AbdriudManifest.xml中添加需要的权限
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.INTERNET"/>
2.音频获取。
语音识别的第一步是能够拿到音频数据,再将其通过一定的方式转换为文字,所以,先演示如何获取所需的音频文件。
提示:百度语音REST 方式完成语音识别对音频文件的要求很苛刻,必须按照官方文档的要求进行配置,这里可以直接赋值我的代码。
1)全变量声明
private MediaRecorder mediaRecorder; private Boolean isRecording; /* 录音状态 */ private String fileName; /* 名称 */ private File filePath; /* 存储路径 */
2)变量初始化
filePath= new File("/mnt/sdcard", "myfile.amr");
3)开始录音
protected void startRecord(){ if (mediaRecorder==null){ mediaRecorder=new MediaRecorder(); if(filePath.exists()) { /* 检测文件是否存在 */ filePath.delete(); } mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); /* 设置麦克风 */ mediaRecorder.setAudioSamplingRate(8000); mediaRecorder.setAudioChannels(1); /* 单声道采样 */ mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_WB); /* 设置输出格式 */ mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_WB); /* 设置采样波形 */ mediaRecorder.setAudioEncodingBitRate(16000); mediaRecorder.setOutputFile(filePath.getAbsolutePath()); /* 存储路径 */ try{ mediaRecorder.prepare(); mediaRecorder.start(); /* 开始录音 */ }catch (Exception e) { e.printStackTrace(); } } }
4)停止录音
protected void stopRecord(){ if (filePath!=null && filePath.exists()){ mediaRecorder.stop(); /* 停止录音 */ mediaRecorder.release(); /* 释放资源 */ mediaRecorder=null; /* 开始识别 */ try { getToken(); } catch (Exception e) { e.printStackTrace(); } } }
3 语音识别部分
语音识别是采用的百度百度语音REST方式,如果要使用,那么完成以下步骤:
①注册一个百度账号
②打开百度AI申请资格
③创建应用
④得到API Key 和 Secret Key
以上步骤完成的方法可以问度娘 一查一大堆,这里就不详细叙述
完成以上工作,我们就可以进行语音识别代码的编写了。
1)全局变量声明
private static final String serverURL = "http://vop.baidu.com/server_api"; //语音识别网关 private static String token=null; private static final String apiKey = "6MWklZjrp4038E1EgS8oLhta"; // API Key private static final String secretKey = "321ffa4a53cdd4c434508517ada16aa4"; // Secret Key private static final String cuid = "868540756380665"; //唯一表示码
由于是安卓开发,因此填写手机的唯一标识码,获取方式为拨号处输入: *#06#
APIKey、SecretKey和cuid 需要填写你自己的,否则可能无法正常使用。
2)GetToken
private void getToken(){ new Thread(new Runnable() { @Override public void run() { HttpURLConnection connection = null; String getTokenURL = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials" +"&client_id=" + apiKey + "&client_secret=" + secretKey; try { connection = (HttpURLConnection) new URL(getTokenURL).openConnection(); token = new JSONObject(printResponse(connection)).getString("access_token"); SpeechRecognition(); //开始语音识别 } catch (Exception e) { e.printStackTrace(); } finally { if(connection!=null) connection.disconnect(); } } }).start(); }
3)语音识别
private void SpeechRecognition{ new Thread(new Runnable() { @Override public void run() { String strc; try { File pcmFile = new File(filePath.getAbsolutePath()); HttpURLConnection conn = (HttpURLConnection) new URL(serverURL+ "?cuid=" + cuid + "&token=" + token).openConnection(); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "audio/amr; rate=16000"); conn.setDoInput(true); conn.setDoOutput(true); DataOutputStream wr = new DataOutputStream(conn.getOutputStream()); wr.write(loadFile(pcmFile)); wr.flush(); wr.close(); strc=printResponse(conn); Message message = new Message(); message.what = 0x02; message.obj =strc; handler.sendMessage(message); } catch (Exception e) { e.printStackTrace(); } } }).start(); }
4)字符处理
private String printResponse(HttpURLConnection conn) throws Exception { if (conn.getResponseCode() != 200) { return ""; } InputStream is = conn.getInputStream(); BufferedReader rd = new BufferedReader(new InputStreamReader(is)); String line; StringBuffer response = new StringBuffer(); while ((line = rd.readLine()) != null) { response.append(line); response.append('\r'); } rd.close(); Message message = new Message(); message.what = 0x01; message.obj = new JSONObject(response.toString()).toString(4); handler.sendMessage(message); return response.toString(); }
5文件加载
private byte[] loadFile(File file) throws IOException { InputStream is = new FileInputStream(file); long length = file.length(); byte[] bytes = new byte[(int) length]; int offset = 0; int numRead = 0; while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) { offset += numRead; } if (offset < bytes.length) { is.close(); throw new IOException("Could not completely read file " + file.getName()); } is.close(); return bytes; }
6)为了在线程中将信息传递出来,需要一个handler来实现
@SuppressLint("HandlerLeak") private Handler handler=new Handler(){ public void handleMessage(Message msg){ String response=(String)msg.obj; String strc=null; switch (msg.what){ case 0x01: Log.e("return:",response); //得到返回的所有结果 break; case 0x02: strc=getRectstr(response,"[","]"); //得到返回语音内容 Log.e("return:",strc); break; default: break; } } };
7)识别内容获取
private String getRectstr(String str,String strStart, String strEnd){ if (str.indexOf(strStart) < 0 || str.indexOf(strEnd) < 0) return ""; return str.substring(str.indexOf(strStart) + strStart.length()+1, str.indexOf(strEnd)-2); }
1.以上就是语音录制、识别的过程了,当然,为达到所需要的效果,还需设计一个界面添加一个按钮和文本框输出信息,这些步 骤就不再叙述了,大致就是添加一个Textview,一个Button,按下开启录音,松开停止录音送入识别即可。
2.该方法完成语音识别是在线识别,在没有网络的情况下无法完成。
3.如果有什么问题可以留言,看到后会第一时间回复,如果对你有用请点赞,谢谢大家的支持。