实时语音识别连续模式
前提条件
- 确保已经按照配置好Android开发环境。
- 请参考SDK(websocket)获取最新版本SDK包。
初始化Client
初始化RasrClient,其中参数包含AuthInfo,SisHttpCnfig,RasrResponseListener,RasrConnProcessListener
|
参数名称 |
是否必选 |
参数类型 |
描述 |
|---|---|---|---|
|
AuthInfo |
是 |
Object |
鉴权信息类。 |
|
SisHttpCnfig |
是 |
Object |
连接时网络的配置类。 |
|
RasrResponseListener |
是 |
Object |
webSocket回调过程中,业务逻辑的Listener。 |
|
RasrConnProcessListener |
否 |
Object |
webSocket生命周期的Listener。 |
|
参数名称 |
是否必选 |
参数类型 |
描述 |
|---|---|---|---|
|
ak |
是 |
String |
用户的ak,可参考AK/SK认证。 |
|
sk |
是 |
String |
用户的sk,可参考AK/SK认证。 |
|
serviceRegion |
是 |
String |
区域,如cn-north-4,参考终端节点。 |
|
projectId |
是 |
String |
项目ID,同region一一对应,参考获取项目ID。 |
|
serviceEndPoint |
否 |
String |
终端节点,参考地区和终端节点。 |
|
参数名称 |
是否必选 |
参数类型 |
描述 |
|---|---|---|---|
|
connectionTimeout |
否 |
Integer |
连接超时,默认10000,单位ms。 |
|
readTimeout |
否 |
Integer |
读取超时,默认10000,单位ms。 |
|
websocketWaitTimeout |
否 |
Integer |
webSocket返回数据时等待时间,默认20000,单位毫秒。 |
|
ProxyHostInfo |
否 |
ProxyHostInfo |
代理类。 |
|
参数名称 |
是否必选 |
参数类型 |
描述 |
|---|---|---|---|
|
userName |
否 |
String |
代理用户名(例:test)。 |
|
passWord |
否 |
String |
代理密码(例:test)。 |
|
hostName |
否 |
String |
代理地址(例:“proxy.huaweicloud.com”)。 |
|
port |
否 |
int |
代理端口号(例:8080)。 |
|
函数 |
描述 |
|---|---|
|
void onResponseBegin(AsrResponse response); |
识别开始时回调。 |
|
void onResponseEnd(AsrResponse response); |
识别结束时回调。 |
|
void onResponseError(AsrResponse response); |
识别过程中出现异常,调用。 |
|
void onResponseMessage(AsrResponse message); |
返回识别的结果。 |
|
void onVoiceStart(); |
单句模式下,响应VOICE_START事件,表示检测到语音,此时IVR可以做打断(连续模式可忽略)。 |
|
void onVoiceEnd(); |
单句模式下,响应VOICE_END事件,表示一句话结束,后续的音频将被忽略,不会再进行识别(连续模式可忽略)。 |
|
void onExcceededSilence(); |
单句模式下,响应EXCEEDED_SILENCE事件,表示超过vad_head没有检测到声音,通常表示用户一直没有说话。此时后续的音频将被忽略,不会再进行识别(连续模式可忽略)。 |
|
函数 |
描述 |
|---|---|
|
void onTranscriptionConnect() |
webSocket连接建立后回调。 |
|
void onTranscriptionClose(); |
webSocket连接关闭后回调。 |
|
void onTranscriptionFail(AsrResponse var1); |
webSocket长连接连接失败时回调。 |
请求参数
请求类为RasrRequest,其中参数详见下表
|
参数名称 |
是否必选 |
参数类型 |
描述 |
|---|---|---|---|
|
command |
是 |
String |
需设置为START,表示开始识别请求;发送END,表示识别结束请求。 |
|
config |
是 |
Object |
配置信息,详见表8。 |
|
参数名称 |
是否必选 |
参数类型 |
描述 |
|---|---|---|---|
|
audioFormat |
是 |
String |
音频格式,支持pcm,alaw,ulaw等,如pcm8k16bit,参见《API参考》中开始识别章节。 |
|
property |
是 |
String |
属性字符串,language_sampleRate_domain, 如chinese_16k_general,参见《API参考》中开始识别章节。 |
|
addPunc |
否 |
String |
表示是否在识别结果中添加标点,取值为yes 、 no,默认no。 |
|
digitNorm |
否 |
String |
表示是否将语音中的数字识别为阿拉伯数字,取值为yes 、 no,默认为yes。 |
|
vadHead |
否 |
Integer |
头部最大静音时间,[0, 60000],默认10000ms。 |
|
vadTail |
否 |
Integer |
尾部最大静音时间,[0, 3000],默认500ms。 |
|
maxSeconds |
否 |
Integer |
音频最长持续时间, [1, 60],默认30s。 |
|
intermediateResult |
否 |
String |
是否显示中间结果,yes 或 no,默认no。例如分3次发送音频,选择no结果一次性返回,选择yes分三次返回。 |
|
vocabularyId |
否 |
String |
热词表id,若没有则不填。 |
|
needWordInfo |
否 |
String |
表示是否在识别结果中输出分词结果信息,取值为“yes”和“no”,默认为“no”。 |
设置当前Client为连续模式
rasrClient.rasrContinueStreamConnect();
建立连接
rasrClient.connect();
发送开始识别指令和配置信息
rasrClient.sendStart(getStartRequest());
发送识别数据
// data:发送byte数组 // byteSend :数组大小 // sleepTime : 休眠时间 rasrClient.sendByte(byte[] data, int byteSend, int sleepTime);
发送结束指令
rasrClient.sendEnd();
发送关闭连接请求
rasrClient.close();
代码示例
如下示例仅供参考,最新代码请前往SDK(websocket)章节获取并运行。
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
*/
package com.huaweicloud.sis.android.demo.asr;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.huaweicloud.sis.android.demo.Config;
import com.huaweicloud.sis.android.demo.service.AudioRecordService;
import com.huaweicloud.sdk.core.utils.JsonUtils;
import com.huaweicloud.sis.android.demo.R;
import sis.android.sdk.RasrClient;
import sis.android.sdk.bean.AuthInfo;
import sis.android.sdk.bean.SisHttpConfig;
import sis.android.sdk.exception.SisException;
import sis.android.sdk.bean.request.RasrRequest;
import sis.android.sdk.bean.response.AsrResponse;
import sis.android.sdk.listeners.RasrResponseListener;
import sis.android.sdk.listeners.process.RasrConnProcessListener;
/**
* 功能描述
* 实时语音识别连续模式
*
* @since 2022-07-11
*/
public class RasrCsActivity extends AppCompatActivity {
private TextView title;
private TextView result;
private Button startButton;
private Button endButton;
private RasrClient rasrClient;
// 实时显示识别的结果
private StringBuffer realTimeResult;
private AudioRecordService audioRecordService;
private AuthInfo authInfo;
private RasrConnProcessListener rasrConnProcessListener = new RasrConnProcessListener() {
/**
* 连接关闭后回调
*/
@Override
public void onTranscriptionClose() {
Log.i("info", "长连接关闭");
}
/**
* 连接建立后回调
*/
@Override
public void onTranscriptionConnect() {
Log.i("info", "长连接开始");
}
/**
* 长连接连接失败时回调
*
* @param asrResponse 返回体
*/
@Override
public void onTranscriptionFail(AsrResponse asrResponse) {
Log.i("info", "长连接异常");
// 调用失败给用户提示
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "实时语音单句模式长连接失败" + JsonUtils.toJSON(asrResponse), Toast.LENGTH_SHORT).show();
}
});
rasrClient.close();
}
};
private RasrResponseListener rasrResponseListener = new RasrResponseListener() {
/**
* 检测到句子开始事件
*/
@Override
public void onVoiceStart() {
}
/**
* 检测到句子结束事件
*/
@Override
public void onVoiceEnd() {
}
/**
* 返回识别的信息
* @param message
*/
@Override
public void onResponseMessage(AsrResponse message) {
runOnUiThread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < message.getSegments().size(); i++) {
AsrResponse.Segment segment = message.getSegments().get(i);
// 实时语音识别连续模式 回调结果更新到界面UI中
result.setText(realTimeResult.toString() + segment.getResult().getText());
if (segment.getIsFinal()) {
realTimeResult.append(segment.getResult().getText());
}
}
}
});
}
/**
*
* 静音超长,也即没有检测到声音。响应事件
*/
@Override
public void onExcceededSilence() {
}
/**
* 返回识别的信息
* @param response
*/
@Override
public void onResponseBegin(AsrResponse response) {
}
@Override
public void onResponseEnd(AsrResponse response) {
}
@Override
public void onResponseError(AsrResponse response) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "实时语音识别连续模式,错误响应:" + JsonUtils.toJSON(response), Toast.LENGTH_SHORT).show();
}
});
rasrClient.close();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.rasr);
}
@Override
protected void onStart() {
super.onStart();
initResources();
initView();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (rasrClient != null) {
rasrClient.close();
}
if (audioRecordService != null && audioRecordService.getIsRecording().get()) {
audioRecordService.stopAudioRecord();
audioRecordService.releaseAudioRecord();
}
}
/**
* 初始化界面
*/
private void initView() {
result = findViewById(R.id.result);
title = findViewById(R.id.title);
title.setText("实时语音识别连续模式");
startButton = findViewById(R.id.start);
endButton = findViewById(R.id.end);
// 定义开始按钮点击事件
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
updateButtonState(startButton, false);
updateButtonState(endButton, true);
realTimeResult = realTimeResult.delete(0, realTimeResult.length());
new Thread(new Runnable() {
@Override
public void run() {
try {
rasrClient = new RasrClient(authInfo, rasrResponseListener, rasrConnProcessListener, new SisHttpConfig());
rasrClient.rasrContinueStreamConnect();
// 建立连接
rasrClient.connect();
rasrClient.sendStart(getStartRequest());
audioRecordService.startSendRecordingData(rasrClient);
} catch (SisException e) {
Log.e("error", e.getErrorCode() + e.getErrorMsg());
}
}
}).start();
Toast.makeText(getApplicationContext(), "正在进行录音中...", Toast.LENGTH_SHORT).show();
}
});
// 结束按钮识别事件
endButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
updateButtonState(startButton, true);
updateButtonState(endButton, false);
if (audioRecordService.getIsRecording().get()) {
audioRecordService.stopAudioRecord();
Toast.makeText(getApplicationContext(), "识别结束...", Toast.LENGTH_SHORT).show();
}
try {
rasrClient.sendEnd();
} catch (SisException e) {
Log.e("error", e.getErrorCode() + e.getErrorMsg());
}
rasrClient.close();
}
});
updateButtonState(startButton, true);
updateButtonState(endButton, false);
}
/**
* 初始化设置资源
*/
private void initResources() {
authInfo = new AuthInfo(this.getString(R.string.HUAWEICLOUD_SDK_AK), this.getString(R.string.HUAWEICLOUD_SDK_SK),
Config.REGION, Config.PROJECT_ID);
audioRecordService = new AudioRecordService(16000);
realTimeResult = new StringBuffer();
}
/**
* 开始请求
*
* @return 返回请求体内容
*/
private RasrRequest getStartRequest() {
RasrRequest rasrRequest = new RasrRequest();
rasrRequest.setCommand("START");
RasrRequest.Config config = new RasrRequest.Config();
config.setAudioFormat("pcm16k16bit");
config.setProperty("chinese_16k_general");
config.setAddPunc("yes");
config.setInterimResults("yes");
rasrRequest.setConfig(config);
return rasrRequest;
}
// 用于设置按钮的状态
private void updateButtonState(final Button btn, final boolean state) {
runOnUiThread(new Runnable() {
@Override
public void run() {
btn.setEnabled(state);
}
});
}
}