百度语音REST API -- 简单Demo

先到百度语音官网上查看语音识别API
百度语音REST API -- 简单Demo_第1张图片


然后再去下载识别、合成 REST API 开发文档、示例代码
这里写图片描述

大概了解一下Sample.java里面的使用方式


我就直接上代码了,我是在Android Studio 2.3.3 平台上编译的
1、AndroidManifest.xml
这里只是添加了一个网络权限,其他都没动

<uses-permission android:name="android.permission.INTERNET"/>

2、MainActivity.java

package com.sky.baiduspeechwithrestapi;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.io.IOException;
import java.io.InputStream;

/**
 * REST API 就是将音频文件转换成某种特定格式,通过 http 请求发送给百度语音识别的服务器,
 * 再由百度语音识别的服务器进行语音识别,最后返回识别出的文本.
 *
 * 使用的方式简单说来是
 * 1、根据百度语音识别官方网站提供的App ID 和 API Key 获取 accessToken。
 * 2、根据上一步的 accessToken 连同其它请求参数一起向百度语音识别网关发出请求,获得识别的文本。
 *
 */
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private static final String TAG = "MainActivity";
    protected Button btnSendAudioFile;
    protected TextView tvShowRespondMessage;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
        btnHandle();
    }

    private void btnHandle() {
        btnSendAudioFile.setOnClickListener(this);
    }

    private void initView() {
        btnSendAudioFile = (Button)findViewById(R.id.btnSendAudioFile);
        tvShowRespondMessage = (TextView)findViewById(R.id.tvShowRespondMessage);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btnSendAudioFile:
                sendAudioFile();
                break;
            default:
                break;
        }
    }

    private void sendAudioFile() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                // 获取Access Token
                String accessToken = AuthService.getAccessToken();
                Log.d(TAG, "Access Token:" + accessToken);

                // 获取音频数据
                byte[] rawData = new byte[0];
                try {
                    rawData = readRawFile(R.raw.k16);
                } catch (IOException e) {
                    e.printStackTrace();
                }

                // 将音频数据和Access Token上传到服务器,并返回服务器解析结果
                try {
                    String result = UploadAudio.uploadAudioFileByRaw(rawData, accessToken);
                    Log.d(TAG, "result:" + result);
                    showServerResponse(result);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * 获取音频数据
     * @param resource 音频文件
     * @return 音频数据字节
     * @throws IOException
     */
    private byte[] readRawFile(int resource) throws IOException {
        // 获取资源文件的输入流
        InputStream is = getResources().openRawResource(resource);

        // 获取资源文件的大小 -- 非常重要(不能直接写固定大小)
        int len = is.available();
        Log.d(TAG, "len:" + len);

        // 读取资源文件内容
        byte[] bytes = new byte[len];
        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 ");
        }

        is.close();
        return bytes;
    }

    private void showServerResponse(final String response) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                tvShowRespondMessage.setText(response);
            }
        });
    }

}


3、AuthService.java

package com.sky.baiduspeechwithrestapi;

import android.util.Log;

import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 获取 Access Token 类
 */
public class AuthService {

    private static final String TAG = "AuthService";
    // 百度申请应用的 API Key
    private static final String apiKey = "替换成你申请的API Key";
    // 百度申请应用的 Secret Key
    private static final String secretKey = "替换成你申请的Secret Key";

    /**
     * 获取权限token
     * @return token
     */
    public static String getAccessToken() {
        return getAccessToken(apiKey, secretKey);
    }

    /**
     * 获取API访问token
     * @param ak - 百度申请应用的的 API Key
     * @param sk - 百度申请应用的的 Securet Key
     * @return assess token
     */
    public static String getAccessToken(String ak, String sk) {

        // 百度OAuth2.0授权服务地址
        String authHost = "https://aip.baidubce.com/oauth/2.0/token?";
        String getAccessTokenUrl = authHost
                // 1. grant_type为固定参数
                + "grant_type=client_credentials"
                // 2. API Key
                + "&client_id=" + ak
                // 3. Secret Key
                + "&client_secret=" + sk;

        String access_token = "";
        HttpURLConnection connection = null;
        BufferedReader mBufferedReader = null;
        try {
            URL realUrl = new URL(getAccessTokenUrl);
            connection = (HttpURLConnection) realUrl.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();

            // 获取服务器返回的数据
            InputStream is = connection.getInputStream();

            // 读取数据
            mBufferedReader = new BufferedReader(new InputStreamReader(is));

            String result = "";
            String line;
            while ((line = mBufferedReader.readLine()) != null) {
                result += line;
            }

            Log.d(TAG, "result:" + result);

            /**
             * "access_token" 字段即为请求 REST API 所需的令牌
             *  默认情况下,Access Token 有效期为一个月,
             *  开发者需要对 Access Token的有效性进行判断,如果Access Token过期可以重新获取。
             */
            JSONObject jsonObject = new JSONObject(result);
            access_token = jsonObject.getString("access_token");
            return access_token;
        } catch (Exception e) {
            Log.d(TAG, "获取token失败!");
            e.printStackTrace();
        }finally {
            if(mBufferedReader != null){
                try {
                    mBufferedReader.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if(connection != null){
                connection.disconnect();
            }
        }
        return null;
    }

    public static String getApiKey() {
        return apiKey;
    }

    public static String getSecretKey() {
        return secretKey;
    }
}

百度语音REST API -- 简单Demo_第2张图片


4、UploadAudio.java

package com.sky.baiduspeechwithrestapi;

import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class UploadAudio {

    private static final String TAG = "UploadAudio";

    // 语音文件上传服务器地址
    private static final String serverURL = "http://vop.baidu.com/server_api";

    // 用户唯一标识,用来区分用户。
    private static final String cuid = "skynoon";

    // 语种选择,中文=zh、粤语=ct、英文=en,不区分大小写,默认中文
    private static String language = "zh";

    /**
     * Raw方式上传语音数据
     * @param rawData 语音数据
     * @param token
     * @return 识别结果
     * @throws Exception
     */
    public static String uploadAudioFileByRaw(byte[] rawData, String token) throws Exception {

        String uploadServerUrl = serverURL
                + "?lan=" + language
                + "&cuid=" + cuid
                + "&token=" + token;

        URL realUrl = new URL(uploadServerUrl);
        HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();

        // 设置请求方式
        conn.setRequestMethod("POST");

        // 设置请求头
        conn.setRequestProperty("Content-Type", "audio/pcm; rate=16000");

        // 设置是否从conn读入,默认情况下是true;
        conn.setDoInput(true);

        // 设置是否向conn输出,因为这个是post请求,参数要放在
        // http正文内,因此需要设为true, 默认情况下是false;
        conn.setDoOutput(true);

        // 提交语音数据
        DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
        wr.write(rawData);
        wr.flush();
        wr.close();

        // 获取服务器返回数据
        return getServerResponse(conn);
    }

    /**
     * 获取服务器返回的数据
     * @param conn
     * @return 服务器返回的数据
     */
    private static String getServerResponse(HttpURLConnection conn) throws Exception {
        if (conn.getResponseCode() != 200) {
            // request error
            Log.d(TAG, "request error:");
            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();
        Log.d(TAG, "response:" + response.toString());
        return parseServerResponse(response.toString());
    }

    /**
     * 解析服务器返回的数据
     * 返回的数据格式:json格式
     * 字段"err_no" - 错误码
     * 字段"err_msg"  - 错误码描述
     * 字段"sn" - 语音数据唯一标识,系统内部产生。如果反馈及debug请提供sn。
     * 字段"result" - 识别结果数组,提供1-5 个候选结果, 优先使用第一个结果。utf-8 编码。
     * @param response - 服务器返回的数据
     * @return 识别结果
     */
    private static String parseServerResponse(String response){
        try {
            JSONObject jsonObject = new JSONObject(response);
            String result = jsonObject.getString("result");
            Log.d(TAG, "result:" + result);
            return result;
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }
}

布局文件就一个Button和TextView,这里就不贴代码了。
5、在res目录中新建一个raw文件夹,并将官网中下载的样例文件下载放到raw文件夹中
百度语音REST API -- 简单Demo_第3张图片


整个工程目录如下
百度语音REST API -- 简单Demo_第4张图片


经过测试,使用k16.pcm(原来的名字是16k.pcm文件),可以输出[“北京科技馆,”];但是用test.pcm输出空,log显示:3301错误码

你可能感兴趣的:(Android)