然后再去下载识别、合成 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;
}
}
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文件夹中
经过测试,使用k16.pcm(原来的名字是16k.pcm文件),可以输出[“北京科技馆,”];但是用test.pcm输出空,log显示:3301错误码