
# 声音复刻流式接口
#### 前提条件
- 确保已按照[配置Python环境](https://support.huaweicloud.com/sdkreference-sis/sis_05_0056.html)配置完毕，Python SDK仅支持Python3。
- 请参考[SDK（websocket）](https://support.huaweicloud.com/sdkreference-sis/sis_05_0004.html)获取最新版本SDK包。
- 使用预置音色或注册的声音合成语音。
- 仅上海一局点支持该接口。
 
#### 初始化Client
初始化vcs_client详解[表1]。
 表1vcs_client初始化参数 
| 参数名称             | 是否必选 | 参数类型   | 描述                                                                                     |
|:---|:---|:---|:---|
| 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)。 |
| region           | 是    | String | 区域，如：cn-east-3。具体请参考[终端节点](https://support.huaweicloud.com/api-sis/sis_03_0004.html)。  |
| project_id       | 是    | String | 项目ID，同region一一对应，参考获取项目ID。                                                             |
| service_endpoint | 否    | String | 终端节点，一般使用默认即可。                                                                         |
   
#### 请求参数
请求类型为vcs_request，详见[表2]。
 表2vcs_request 
| 参数名称        | 是否必选 | 参数类型   | 描述                                                                                            |
|:---|:---|:---|:---|
| command     | 是    | String | 指令：START、MSG、END，分别表示开始、语音合成、结束。                                                              |
| config      | 是    | Object | 详见[表3]。                                                      |
| text_pieces | 否    | String | 文本条数：ONLY(仅一次)、MULTI(可发送多次文本)。默认：MULTI。                                                       |
| text        | 是    | String | 待合成的文本，支持长度不大于300字符的文本。text_pieces取值为ONLY时，文本同配置一同发送，此值必填；text_pieces取值为MULTI时，文本后续发送，不需要该参数。 |
| audio_path  | 是    | String | 待合成音频存储路径。                                                                                    |
| text_path   | 否    | String | 待合成文本存储路径。用户既可以选择多次发送文本，也可以传入文本存储路径。                                                          |
   
 表3config 
| 参数名称         | 是否必选 | 参数类型    | 描述                                                                                     |
|:---|:---|:---|:---|
| audio_format | 否    | String  | 合成音频的格式。支持pcm、mp3，默认pcm                                                                |
| sample_rate  | 否    | String  | 合成音频的采样率。支持8kHz、16kHz、24kHz，默认16kHz                                                    |
| voice_name   | 是    | String  | 合成所使用的音色名称，可选择用户注册的音色或预置音色。预置音色取值范围参考[表4]。           |
| speed        | 否    | Integer | 语速。 取值范围：-500\~500 默认值：0   |
| pitch        | 否    | Integer | 音高。 取值范围： -500\~500 默认值：0 |
| volume       | 否    | Integer | 音量。 取值范围：0\~100 默认值：50     |
   
 表4timbre 
| 参数名称 | voice_name                  | 类型   | 使用场景 | 支持采样率（Hz）  |
|:---|:---|:---|:---|:---|
| 华小莉  | chinese_huaxiaoli_common    | 标准女声 | 中英混合 | 8k/16k/24k |
| 华小智  | chinese_huaxiaozhi_common   | 男童声  | 中英混合 | 8k/16k/24k |
| 华小天  | chinese_huaxiaotian_common  | 朝气男声 | 中英混合 | 8k/16k/24k |
| 华小媛  | chinese_huaxiaoyuan_common  | 成熟女声 | 中英混合 | 8k/16k/24k |
| 华小静  | chinese_huaxiaojing_common  | 女童声  | 中英混合 | 8k/16k/24k |
| 华小博  | chinese_huaxiaobo_common    | 标准男声 | 中英混合 | 8k/16k/24k |
| 华小柔  | chinese_huaxiaorou_common   | 标准女声 | 中英混合 | 8k/16k/24k |
| 华小悠  | chinese_huaxiaoyou_common   | 嘹亮女声 | 中英混合 | 8k/16k/24k |
| 华小晴  | chinese_huaxiaoqing_common  | 青春女声 | 中英混合 | 8k/16k/24k |
| 华小溪  | chinese_huaxiaoxi_common    | 温柔女声 | 中英混合 | 8k/16k/24k |
| 华小彤  | chinese_huaxiaotong_common  | 俏皮女声 | 中英混合 | 8k/16k/24k |
| 华小雅  | chinese_huaxiaoya_common    | 标准女声 | 中英混合 | 8k/16k/24k |
| 华小伟  | chinese_huaxiaowei_common   | 成熟男声 | 中英混合 | 8k/16k/24k |
| 华小帅  | chinese_huaxiaoshuai_common | 标准男声 | 中英混合 | 8k/16k/24k |
| 华小杰  | chinese_huaxiaojie_common   | 温柔男声 | 中英混合 | 8k/16k/24k |
   
#### 响应参数
响应参数分为正确响应，详见[表5]，和错误响应，详见[表6]。
 表5正确响应 
| 参数名称      | 参数类型   | 描述                     |
|:---|:---|:---|
| resp_type | String | 响应类型。参数值为END，表示语音合成结束。 |
| trace_id  | String | 服务内部的令牌，可用于在日志中追溯具体流程。 |
| reason    | String | 结束原因。                  |
   
 表6错误响应 
| 参数名称       | 参数类型   | 描述                                                                                                                                                                                                   |
|:---|:---|:---|
| resp_type  | String | 响应类型。 参数值为ERROR，表示错误响应。 参数值为FATAL_ERROR，表示此次合成发生不可恢复的错误。 参数值为EVENT，表示事件，详见[表7]。 |
| trace_id   | String | 服务内部的令牌，可用于在日志中追溯具体流程。                                                                                                                                                                               |
| error_code | String | 错误码列表。详细错误码解释，请参见错误码。                                                                                                                                                                                |
| error_msg  | String | 返回错误信息。                                                                                                                                                                                              |
   
 表7事件 
| 参数名称       | 参数类型   | 描述                                              |
|:---|:---|:---|
| event      | String | 事件类型，详见[表8]。 |
| time_stamp | Object | 时间戳。                                            |
   
 表8事件类型 
| 参数名称                       | 参数类型   | 描述              |
|:---|:---|:---|
| EXCEEDED_TOTAL_TEXT_LENGTH | String | MSG 总字数超过10万字符。 |
| VCS_END                    | String | 结束指令成功后，继续发送指令。 |
   
#### 请求示例
```
from huaweicloud_sis.client.vcs_stream_client import VcsStreamClient
from huaweicloud_sis.bean.vcs_stream_request import VcsStreamRequest
from huaweicloud_sis.bean.callback import VcsStreamCallBack
from huaweicloud_sis.bean.sis_config import SisConfig
import os
# 鉴权参数
# 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险，建议在配置文件或者环境变量中密文存放，使用时解密，确保安全；
ak = os.getenv("HUAWEICLOUD_SIS_AK")             # 从环境变量获取ak 参考https://support.huaweicloud.com/sdkreference-sis/sis_05_0003.html
assert ak is not None, "Please add ak in your develop environment"
sk = os.getenv("HUAWEICLOUD_SIS_SK")             # 从环境变量获取sk 参考https://support.huaweicloud.com/sdkreference-sis/sis_05_0003.html
assert sk is not None, "Please add sk in your develop environment"
project_id = ""     # project id 同region一一对应，参考https://support.huaweicloud.com/api-sis/sis_03_0008.html
region = ''  # region，支持上海一region，cn-east-3
# 可选参数,传入VcsStreamClient(ak=ak, sk=sk, use_aksk=True, region=region, project_id=project_id, callback=my_callback,config=config);
service_endpoint = "" # 可选，自定义endpoint，传入VcsClient(ak, sk, region, project_id, sis_config=config)
text_path=""  # 可选 待合成文本存储路径,例如"D://text.txt",要求文本中，每行句子不超过300字符
audio_path = ""  # 待合成的音频保存路径，如test.pcm
# 使用该脚本前,保证要使用的声音已经注册,voice_name为声音名称。若没有注册声音,请使用vcs_register_and_request.py脚本，注册声音和查询声音
voice_name = '' # 音色名称，可以使用注册音色或预置音色
class MyCallback(VcsStreamCallBack):
    """ 回调类，用户需要在对应方法中实现自己的逻辑，其中on_response必须重写 """
    def __init__(self, save_path):
        self._f = open(save_path, 'wb')
    def on_open(self):
        """ websocket连接成功会回调此函数 """
        print('websocket connect success')
    def on_start(self, message):
        """
            websocket 开始识别回调此函数
        :param message: 传入信息
        :return: -
        """
        print('websocket start to recognize, %s' % message)
    def on_response(self, data):
        """
            回调返回的音频合成数据，byte数组格式
        :param data byte数组，合成的音频数据
        :return: -
        """
        print('receive data %d' % len(data))
        self._f.write(data)
    def on_end(self, message):
        """
            websocket 结束识别回调此函数
        :param message: 传入信息
        :return: -
        """
        print('websocket is ended, %s' % message)
        self._f.close()
    def on_close(self):
        """ websocket关闭会回调此函数 """
        print('websocket is closed')
        self._f.close()
    def on_error(self, error):
        """
            websocket出错回调此函数
        :param error: 错误信息
        :return: -
        """
        print('websocket meets error, the error is %s' % error)
        self._f.close()
def vcs_stream_example(audio_path, voice_name):
    """
        声音复刻流式demo
    """
    # step1 初始化VcsStreamClient
    my_callback = MyCallback(audio_path)
    config = SisConfig()
    # 设置连接超时,默认是10
    config.set_connect_timeout(10)
    # 设置读取超时, 默认是10
    config.set_read_timeout(10)
    # 设置websocket等待时间
    config.set_websocket_wait_time(20)
    # websocket暂时不支持使用代理
    vcs_stream_client = VcsStreamClient(ak=ak, sk=sk, use_aksk=True, region=region, project_id=project_id, callback=my_callback,
                             config=config)
    # step2 构造请求
    vcs_stream_request = VcsStreamRequest()
    # 设置音色字符串，可以使用注册音色或预置音色
    vcs_stream_request.set_voice_name(voice_name)
    # 设置音频格式, pcm or mp3, 可参考api文档
    vcs_stream_request.set_audio_format('pcm')
    # 设置采样率，8000 or 16000 or 24000, 默认16000
    vcs_stream_request.set_sample_rate('16000')
    # 设置音量，[0, 100]，默认50
    vcs_stream_request.set_volume(50)
    # 设置音高, [-500, 500], 默认0
    vcs_stream_request.set_pitch(0)
    # 设置音速, [-500, 500], 默认0
    vcs_stream_request.set_speed(0)
    # ONLY模式下，用户发送一次文本，服务端流式返回语音数据；MULTI模式下，支持用户多次发送文本，服务端流式返回语音数据，可用于大模型输出实时播报等场景。
    text_pieces = 'MULTI'
    vcs_stream_request.set_text_pieces(text_pieces)
    if text_pieces == 'MULTI':
        # 发送开始请求、发送文本、发送end请求
        vcs_stream_client.sendStart(vcs_stream_request)
        # 发送文本，可连续发送多次，合成结果可以通过监听器获取
        # 方法一
        vcs_stream_client.sendMsg("你好")
        vcs_stream_client.sendMsg("欢迎使用华为云语音交互服务。")
        # 方法二
        # vcs_stream_client.send_msg_batch(text_path)  # 传入待合成文本储存路径
        # 文本发送完毕，发送结束指令
        vcs_stream_client.sendEnd()
    else:
        # ONLY模式下，发送一次文本
        vcs_stream_request.set_text("你好，欢迎使用华为云语音交互服务。")
        vcs_stream_client.synthesis(vcs_stream_request)
if __name__ == '__main__':
    vcs_stream_example(audio_path, voice_name)
```
#### 响应参数（开始合成）
声音复刻引擎收到合成请求后，会向客户端发送合成开始响应，表示开始处理声音复刻请求。
```
{  
    "resp_type": "START", 
    "trace_id": "567e8537-a89c-13c3-a882-826321939651"  
}
```
#### 响应参数（合成结果）
分多段返回二进制pcm格式或mp3的语音数据流。
#### 响应参数（合成结束）
当合成引擎处理完合成请求后，会发送合成结束响应。客户端收到该响应后关闭当前Websocket链接即可。
```
{  
    "resp_type": "END", 
     "trace_id": "567e8537-a89c-13c3-a882-826321939651", 
     "reason": "NORMAL" 
}
```
#### 响应参数（合成错误）
```
{  
    "resp_type": "ERROR", 
     "trace_id": "567e8537-a89c-13c3-a882-826321939651",  
     "error_code":"SIS.1010",   
     "error_msg":"No valid text, please enter Chinese characters, letters, or digits"
}
```
```
{  
    "resp_type": "FATAL_ERROR",  
     "trace_id": "567e8537-a89c-13c3-a882-826321939651",  
     "error_code": "SIS.0416",  
     "error_msg": "vcs wait text time out"  
}
```
```
{  
    "resp_type": "EVENT",     
     "trace_id": "567e8537-a89c-13c3-a882-826321939651",      
     "event":"VCS_END", 
     "timestamp":1712565936 
}
```
