Android Studio环境下开发百度语音REST语音识别功能

       新年新气象,过年啦,就给大家分享一下自己年前这段时间开发安卓项目的收获,这次分享的是基于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.如果有什么问题可以留言,看到后会第一时间回复,如果对你有用请点赞,谢谢大家的支持。

猜你喜欢

转载自blog.csdn.net/m0_37259197/article/details/79337799