
# 一句话识别(websocket版)
#### 前提条件
- 确保已经按照配置好Android开发环境。
- 请参考[SDK（websocket）](https://support.huaweicloud.com/sdkreference-sis/sis_05_0004.html)获取最新版本SDK包。
 
#### 初始化Client
初始化SasrWsClient，其中参数包含AuthInfo，SisHttpConfig，SasrWsResponseListener，SasrWsConnProcessListener。
表1SasrWsClient 
| 参数                        | 是否必选 | 参数类型   | 描述                            |
|:---|:---|:---|:---|
| AuthInfo                  | 是    | Object | 鉴权信息类。                        |
| SisHttpConfig             | 是    | Object | 连接时网络的配置类。                    |
| SasrWsResponseListener    | 是    | Object | webSocket回调过程中，业务逻辑的Listener。 |
| SasrWsConnProcessListener | 否    | Object | webSocket生命周期的Listener。       |
   
其中AuthInfo和SisHttpConfig的参数如下表所示
表2AuthInfo 
| 参数名称            | 是否必选 | 参数类型   | 描述                                                                                     |
|:---|:---|:---|:---|
| ak              | 是    | String | 用户的ak，可参考[AK/SK认证](https://support.huaweicloud.com/sdkreference-sis/sis_05_0003.html)。 |
| sk              | 是    | String | 用户的sk，可参考[AK/SK认证](https://support.huaweicloud.com/sdkreference-sis/sis_05_0003.html)。 |
| serviceRegion   | 是    | String | 区域，如cn-north-4，参考[终端节点](https://support.huaweicloud.com/api-sis/sis_03_0004.html)。     |
| projectId       | 是    | String | 项目ID，同region一一对应，参考[获取项目ID](https://support.huaweicloud.com/api-sis/sis_03_0008.html)。 |
| serviceEndPoint | 否    | String | 终端节点，参考[终端节点](https://developer.huaweicloud.com/endpoint?SIS)。                         |
   
表3SisHttpConfig 
| 参数名称                 | 是否必选 | 参数类型          | 描述                               |
|:---|:---|:---|:---|
| connectionTimeout    | 否    | Integer       | 连接超时，默认10000，单位ms。               |
| readTimeout          | 否    | Integer       | 读取超时，默认10000，单位ms。               |
| websocketWaitTimeout | 否    | Integer       | webSocket返回数据时等待时间，默认20000，单位毫秒。 |
| ProxyHostInfo        | 否    | ProxyHostInfo | 代理类。                             |
   
表4ProxyHostInfo 
| 参数名称     | 是否必选 | 参数类型   | 描述                               |
|:---|:---|:---|:---|
| userName | 否    | String | 代理用户名（例：test）。                   |
| passWord | 否    | String | 代理密码（例：test）。                    |
| hostName | 否    | String | 代理地址（例："proxy.huaweicloud.com"）。 |
| port     | 否    | int    | 代理端口号（例：8080）。                   |
   
表5SasrWsResponseListener 
| 函数                                           | 描述                        |
|:---|:---|
| void onExceededAudio();                      | 识别时长超过一分钟时，响应，后续录入音频不再识别。 |
| void onResponseError(AsrResponse response);  | 识别过程中出现异常，调用。             |
| void onResponseEnd(AsrResponse response);    | 识别结束时回调。                  |
| void onResponseBegin(AsrResponse response);  | 识别开始时回调。                  |
| void onResponseMessage(AsrResponse message); | 返回识别的结果。                  |
   
表6SasrWsConnProcessListener 
| 函数                                          | 描述                   |
|:---|:---|
| void onTranscriptionConnect()               | webSocket连接建立后回调。    |
| void onTranscriptionClose();                | webSocket连接关闭后回调     |
| void onTranscriptionFail(AsrResponse var1); | webSocket长连接连接失败时回调。 |
   
#### 请求参数
请求类为SasrWsRequest，其中参数详见下表
表7SasrWsRequest 
| 参数名称    | 是否必选 | 参数类型   | 描述                                 |
|:---|:---|:---|:---|
| command | 是    | String | 需设置为START，表示开始识别请求;发送END，表示识别结束请求。 |
| config  | 是    | Object | 配置信息，详见下表。                         |
   
表8Config 
| 参数名称               | 是否必选 | 参数类型   | 描述                                                                                                                   |
|:---|:---|:---|:---|
| audioFormat        | 是    | String | 音频格式，支持pcm，alaw，ulaw等，如pcm8k16bit，具体规格请参见《API参考》中[开始识别](https://support.huaweicloud.com/api-sis/sis_03_0030.html)章节。 |
| property           | 是    | String | 属性字符串，language_sampleRate_domain， 如chinese_8k_common。                                                                |
| addPunc            | 否    | String | 表示是否在识别结果中添加标点，取值为yes 、 no，默认no。                                                                                     |
| digitNorm          | 否    | String | 表示是否将语音中的数字识别为阿拉伯数字，取值为yes 、 no，默认为yes。                                                                              |
| intermediateResult | 否    | String | 是否显示中间结果，yes 或 no，默认no。                                                                                              |
| vocabularyId       | 否    | String | 热词表id，若没有则不填。                                                                                                        |
| needWordInfo       | 否    | String | 表示是否在识别结果中输出分词结果信息，取值为"yes"和"no"，默认为"no"。                                                                            |
   
#### 建立连接
```
sasrWsClient.connect();
```
#### 发送开始识别指令和配置信息
```
sasrWsClient.sendStart(getStartRequest());
```
#### 发送识别数据
```
// data：发送byte数组
// byteSend :数组大小
// sleepTime : 休眠时间
sasrWsClient.sendByte(byte[] data, int byteSend, int sleepTime);
```
#### 发送结束指令
```
sasrWsClient.sendEnd();
```
#### 发送关闭连接请求
```
sasrWsClient.close();
```
#### 代码示例
如下示例仅供参考，最新代码请前往[SDK（websocket）](https://support.huaweicloud.com/sdkreference-sis/sis_05_0004.html)章节获取并运行。
```
/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 */
package com.huaweicloud.sis.android.demo.asr;
import java.util.concurrent.atomic.AtomicBoolean;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.huaweicloud.sdk.core.utils.JsonUtils;
import com.huaweicloud.sis.android.demo.R;
import com.huaweicloud.sis.android.demo.service.AudioRecordService;
import com.huaweicloud.sis.android.demo.Config;
import sis.android.sdk.SasrWsClient;
import sis.android.sdk.bean.AuthInfo;
import sis.android.sdk.bean.SisHttpConfig;
import sis.android.sdk.bean.request.SasrWsRequest;
import sis.android.sdk.bean.response.AsrResponse;
import sis.android.sdk.exception.SisException;
import sis.android.sdk.listeners.SasrWsResponseListener;
import sis.android.sdk.listeners.process.SasrWsConnProcessListener;
/**
 * 功能描述
 * 一句话识别websocket
 *
 * @since 2022-07-11
 */
public class SasrWsActivity extends AppCompatActivity {
private TextView result;
private Button startButton;
private AudioRecordService audioRecordService;
private AuthInfo authInfo;
private SasrWsClient sasrWsClient;
// 实时显示识别的结果
private StringBuffer realTimeResult;
// 是否需要发送end请求
private AtomicBoolean sendEndFlag = new AtomicBoolean(false);
private SasrWsResponseListener sasrWsResponseListener = new SasrWsResponseListener() {
@Override
public void onExceededAudio() {
sendEndFlag.set(true);
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "超过1分钟，识别结束...", Toast.LENGTH_SHORT).show();
}
});
}
// 一句话识别 回调结果更新到界面UI中
@Override
public void onResponseMessage(AsrResponse asrResponse) {
runOnUiThread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < asrResponse.getSegments().size(); i++) {
AsrResponse.Segment segment = asrResponse.getSegments().get(i);
result.setText(realTimeResult.toString() + segment.getResult().getText());
if (segment.getIsFinal()) {
realTimeResult.append(segment.getResult().getText());
}
}
}
});
}
/**
 * 开始时响应
 *
 * @param response 返回体
 */
@Override
public void onResponseBegin(AsrResponse response) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "连接成功，请录入音频...", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onResponseEnd(AsrResponse response) {}
/**
 * 传输过程中的错误时响应
 *
 * @param response 返回体
 */
@Override
public void onResponseError(AsrResponse response) {
runOnUiThread(new Runnable() {
@Override
public void run() {
// 调用失败给用户提示
Toast.makeText(getApplicationContext(), JsonUtils.toJSON(response), Toast.LENGTH_SHORT).show();
}
});
}
};
private SasrWsConnProcessListener sasrWsConnProcessListener = new SasrWsConnProcessListener() {
/**
 * 连接建立后回调
 */
@Override
public void onTranscriptionConnect() {
Log.i("info", "长连接开始");
}
/**
 * 连接关闭后回调
 */
@Override
public void onTranscriptionClose() {
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();
}
});
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sasr_websocket);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (audioRecordService != null) {
audioRecordService.releaseAudioRecord();
}
}
@Override
protected void onStart() {
super.onStart();
initView();
initResources();
}
/**
 * 初始化UI界面
 */
private void initView() {
result = findViewById(R.id.result);
startButton = findViewById(R.id.start);
startButton.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
audioRecordService.stopAudioRecord();
if (!sendEndFlag.get()) {
try {
sasrWsClient.sendEnd();
} catch (SisException e) {
Log.e("error", e.getErrorCode() + e.getErrorMsg());
}
sendEndFlag.set(false);
}
sasrWsClient.close();
break;
case MotionEvent.ACTION_DOWN:
try {
actionDown();
} catch (SisException e) {
Log.e("error", e.getErrorCode() + e.getErrorMsg());
}
break;
default:
break;
}
return true;
}
});
}
/**
 * 初始化请求资源
 */
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();
}
/**
 * 开始请求
 */
private SasrWsRequest getStartRequest() {
SasrWsRequest sasrWsRequest = new SasrWsRequest();
sasrWsRequest.setCommand("START");
SasrWsRequest.Config config = new SasrWsRequest.Config();
config.setAudioFormat("pcm16k16bit");
config.setProperty("chinese_16k_common");
config.setAddPunc("yes");
config.setInterimResults("yes");
sasrWsRequest.setConfig(config);
return sasrWsRequest;
}
/**
 * 按钮按下之后事件
 *
 * @throws SisException
 */
private void actionDown() throws SisException {
realTimeResult = realTimeResult.delete(0, realTimeResult.length());
try {
sasrWsClient = new SasrWsClient(authInfo, sasrWsResponseListener, sasrWsConnProcessListener, new SisHttpConfig());
audioRecordService.getAudioRecord().startRecording();
sasrWsClient.connect();
sasrWsClient.sendStart(getStartRequest());
audioRecordService.startSendRecordingData(sasrWsClient);
} catch (SisException e) {
Log.e("error", e.getErrorCode() + e.getErrorMsg());
}
}
}
```
