
# 语音合成(webSocket版)
#### 前提条件
- 确保已经按照配置好Android开发环境。
- 请参考[SDK（websocket）](https://support.huaweicloud.com/sdkreference-sis/sis_05_0004.html)获取最新版本SDK包。
 
#### 初始化Client
初始化RttsClient，其中参数包含AuthInfo和SisHttpConfig和RttsResponseListener。其中AuthInfo和SisHttpConfig的参数如[表1]所示。
 表1AuthInfo 
| 参数名称            | 是否必选 | 参数类型   | 描述                                                                                     |
|:---|:---|:---|:---|
| 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)。                         |
   
表2SisHttpConfig 
| 参数名称                 | 是否必选 | 参数类型          | 描述                               |
|:---|:---|:---|:---|
| connectionTimeout    | 否    | Integer       | 连接超时，默认10000，单位ms。               |
| readTimeout          | 否    | Integer       | 读取超时，默认10000，单位ms。               |
| websocketWaitTimeout | 否    | Integer       | webSocket返回数据时等待时间，默认20000，单位毫秒。 |
| ProxyHostInfo        | 否    | ProxyHostInfo | 代理类。                             |
   
表3ProxyHostInfo 
| 参数名称     | 是否必选 | 参数类型   | 描述                               |
|:---|:---|:---|:---|
| userName | 否    | String | 代理用户名（例：test）。                   |
| passWord | 否    | String | 代理密码（例：test）。                    |
| hostName | 否    | String | 代理地址（例："proxy.huaweicloud.com"）。 |
| port     | 否    | int    | 代理端口号（例：8080）。                   |
   
其中RttsResponseListener是用户自定义的，建立webSocket之后，接收服务端返回消息的Listener。
表4RttsResponseListener 
| 函数名称                                              | 作用                |
|:---|:---|
| void onTranscriptionConnect();                    | webSocket建立连接后回调。 |
| void onTranscriptionClose();                      | webSocket连接关闭后回调。 |
| void onTranscriptionFail(RttsResponse response);  | 长连接连接失败时回调。       |
| void onTranscriptionBegin(RttsResponse response); | 开始合成音频数据时回调。      |
| void onTranscriptionEnd(RttsResponse response);   | 合成音频数据结束时回调。      |
| void onTranscriptionError(RttsResponse response); | 合成音频数据过程中失败时回调。   |
| void onTranscriptionResponse(byte\[\] bytes);     | 返回合成的二进制数据。       |
   
#### 请求参数
请求类为RttsRequest，其中参数包含text,command,Config,详见[表5]。
 表5RttsRequest 
| 参数名称    | 是否必选 | 参数类型   | 描述                                              |
|:---|:---|:---|:---|
| text    | 是    | String | 待合成的文本，文本长度限制小于500字符。                           |
| command | 是    | String | 需设置为START，表示开始识别请求。                             |
| Config  | 是    | String | 配置信息。可参照[表6]。 |
   
 表6Config 
| 参数名称         | 是否必选 | 参数类型    | 描述                                                                                                                                             |
|:---|:---|:---|:---|
| audio_format | 否    | String  | 待合成的音频格式，可选mp3，wav等，默认wav。具体信息请参见《API参考》中[语音合成](https://support.huaweicloud.com/api-sis/sis_03_0111.html)章节。                                   |
| pitch        | 否    | Integer | 音高，\[-500,500\] ，默认是0。                                                                                                                         |
| speed        | 否    | Integer | 语速，\[-500,500\] ，默认是0。                                                                                                                         |
| volume       | 否    | Integer | 音量，\[0,100\]，默认是50。                                                                                                                            |
| sample_rate  | 否    | String  | 采样率，支持"8000"、"16000"，默认"8000"。                                                                                                                 |
| property     | 否    | String  | 特征字符串，{language}_{speaker}_{domain}，默认chinese_xiaoqi_common。具体信息请参见《API参考》中[语音合成](https://support.huaweicloud.com/api-sis/sis_03_0111.html)章节。 |
   
#### 建立连接，发送合成数据
```
rttsClient.connect();
rttsClient.sendData(rttsRequest);
```
#### 发送关闭连接请求
```
rttsClient.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.tts;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.cloud.sdk.util.StringUtils;
import com.huaweicloud.sdk.core.utils.JsonUtils;
import com.huaweicloud.sis.android.demo.R;
import com.huaweicloud.sis.android.demo.service.AudioTrackService;
import com.huaweicloud.sis.android.demo.Config;
import com.huaweicloud.sis.android.demo.service.AudioTrackServiceCallback;
import sis.android.sdk.RttsClient;
import sis.android.sdk.bean.AuthInfo;
import sis.android.sdk.bean.SisHttpConfig;
import sis.android.sdk.bean.request.RttsRequest;
import sis.android.sdk.bean.response.RttsResponse;
import sis.android.sdk.exception.SisException;
import sis.android.sdk.listeners.RttsResponseListener;
/**
 * 功能描述
 * 语音合成 websocket
 *
 * @since 2022-07-18
 */
public class RttsActivity extends AppCompatActivity {
private EditText textView;
private Button startPlay;
private RttsClient rttsClient;
private SisHttpConfig sisHttpConfig;
private AudioTrackService audioTrackService;
private AudioTrackServiceCallback audioPlayerCallback;
private AuthInfo authInfo;
private static int dataAcceptanceTime = 1000 * 60 * 5;
private RttsResponseListener rttsResponseListener = new RttsResponseListener() {
@Override
public void onTranscriptionConnect() {
Log.i("info", "建立连接后回调");
}
@Override
public void onTranscriptionClose() {
Log.i("info", "关闭连接后回调");
}
@Override
public void onTranscriptionFail(RttsResponse response) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "出现异常" + JsonUtils.toJSON(response), Toast.LENGTH_SHORT).show();
}
});
updateButtonState(startPlay, true);
Log.i("info", "长连接失败后回调" + JsonUtils.toJSON(response));
}
@Override
public void onTranscriptionBegin(RttsResponse response) {
Log.i("info", "开始合成时的响应事件" + response.toString());
}
@Override
public void onTranscriptionEnd(RttsResponse response) {
rttsClient.close();
audioTrackService.setPlayState(AudioTrackService.PlayState.playEnd);
}
@Override
public void onTranscriptionError(RttsResponse response) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "出现异常" + JsonUtils.toJSON(response), Toast.LENGTH_SHORT).show();
}
});
updateButtonState(startPlay, true);
Log.i("info", "合成时发生错误的响应事件" + response.toString());
}
@Override
public void onTranscriptionResponse(byte[] bytes) {
Log.i("info", "合成过程中返回的二进制流");
audioTrackService.setAudioData(bytes);
}
};
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.rtts);
}
@Override
protected void onStart() {
super.onStart();
initView();
initResources();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (audioTrackService != null) {
audioTrackService.stop();
audioTrackService.releaseTrack();
}
}
/**
 * 初始化UI
 */
private void initView() {
textView = findViewById(R.id.itext);
startPlay = findViewById(R.id.startplay);
startPlay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
updateButtonState(startPlay, false);
new Thread(new Runnable() {
@Override
public void run() {
try {
audioTrackService.play();
rttsClient = new RttsClient(authInfo, sisHttpConfig, rttsResponseListener);
RttsRequest rttsRequest = rttsRequets();
rttsClient.connect();
rttsClient.sendData(rttsRequest);
} catch (SisException e) {
Log.e("error", e.getErrorCode() + e.getErrorMsg());
}
}
}).start();
}
});
}
// 用于设置按钮的状态
private void updateButtonState(final Button btn, final boolean state) {
runOnUiThread(new Runnable() {
@Override
public void run() {
btn.setEnabled(state);
}
});
}
/**
 * 初始化资源
 */
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);
sisHttpConfig = new SisHttpConfig();
// 设置等待事件为5分钟
sisHttpConfig.setWebsocketWaitTimeout(dataAcceptanceTime);
audioPlayerCallback = new AudioTrackServiceCallback() {
@Override
public void playStart() {
}
@Override
public void playOver() {
updateButtonState(startPlay, true);
}
};
audioTrackService = new AudioTrackService(audioPlayerCallback);
}
/**
 * 功能描述
 * 语音合成websocket 版
 */
private RttsRequest rttsRequets() {
RttsRequest rttsRequest = new RttsRequest();
RttsRequest.Config config = new RttsRequest.Config();
config.setAudioFormat("pcm");
config.setProperty("chinese_huaxiaomei_common");
config.setSampleRate("16000");
config.setPitch(0);
config.setVolume(50);
rttsRequest.setCommand("START");
rttsRequest.setConfig(config);
String text = textView.getText().toString().trim();
if (!StringUtils.isNullOrEmpty(text)) {
rttsRequest.setText(text);
} else {
rttsRequest.setText("请输入合成音频");
}
return rttsRequest;
}
}
```
