根据具体场景选择合适的语音合成大模型API。
接口 | 推荐场景 | 接口功能 | 文档链接 |
|---|---|---|---|
| WebSocket协议,实时交互场景,支持文本实时流式输入,流式输出音频。 | 语音合成、声音复刻、混音 | |
| WebSocket协议,一次性输入合成文本,流式输出音频。 | 语音合成、声音复刻、混音 | |
| HTTP Chunked协议,一次性输入全部合成文本,流式输出音频。 | 语音合成、声音复刻、混音 | |
| HTTP SSE协议,一次性输入全部合成文本,流式输出音频。 | 语音合成、声音复刻、混音 |
双向流式API为用户提供文本转语音能力,支持多语种、多方言,支持WebSocket协议流式调用,同时支持一包发送请求数据或者边发边收数据的流式交互方式。
该接口会处理碎片化的文本或者过长的文本,整理为长度合适的句子。因此最大的优势是平衡延迟和合成效果。
在对接大文本模型时,推荐将流式输出的文本直接输入该接口,而不要额外增加切句或者攒句的逻辑。同样的文本调用一次该接口与多次调用合成接口相比,前者会更为自然,情绪更饱满。
推荐使用链接复用的方式接入,在每次使用时只需要建立一次websocket连接,即发送startconnection,在收到ConnectionStarted后,即为链接建立成功。此时,发送startsession,通过taskrequest发送文本,同时接收音频。在没有文本可以发送时,需立即发送finish session。如果还有文本发送需要合成,此时无需断开链接,待收到SessionFinished后(必须),重新发送startsession,开启新一轮session。如果再没有文本需要合成,即可发送finish connection断开链接。具体流程可参考该页交互示例**。**
注意,同一个WebSocket链接下支持多次session,但不支持同时多个session。
wss://openspeech.bytedance.com/api/v3/tts/bidirection在 websocket 建连的 HTTP 请求头(Request Header 中)添加以下信息
使用新版控制台时,推荐采用以下更简化的鉴权方式。
Key | 说明 | 参数类型 | 是否必须 | Value示例 |
|---|---|---|---|---|
X-Api-Key | 使用火山引擎控制台获取的API Key,可参考 控制台API Key管理 | string | 必须 | "your-api-key" |
X-Api-Resource-Id | 表示调用服务的资源信息 ID,可以用来选择不同的模型版本效果,也决定了计费方式。 | string | 必须 | 豆包语音合成大模型
同时,
豆包声音复刻大模型
同时,
|
X-Api-Connect-Id | 用于追踪当前连接情况的标志 ID | string | 可选 | “67ee89ba-7050-4c04-a3d7-ac61a63499b3” |
headers = { "X-Api-Key": "your-api-key", "X-Api-Resource-Id": "seed-tts-2.0" }
若使用旧版控制台,鉴权方式如下。建议尽快切换至新版,以体验更便捷的鉴权流程。
Key | 说明 | 参数类型 | 是否必须 | Value示例 |
|---|---|---|---|---|
X-Api-App-Id | 使用火山引擎控制台获取的APP ID,可参考 控制台使用FAQ-Q1(旧版控制台使用,新版控制台只需要X-Api-Key即可) | string | 必须 | “123456789” |
X-Api-Access-Key | 使用火山引擎控制台获取的Access Token,可参考 控制台使用FAQ-Q1(旧版控制台使用,新版控制台只需要X-Api-Key即可) | string | 必须 | “your-access-key” |
X-Api-Resource-Id | 表示调用服务的资源信息 ID,可以用来选择不同的模型版本效果,也决定了计费方式。 | string | 必须 | 豆包语音合成大模型
同时,
豆包声音复刻大模型
同时,
|
X-Api-Connect-Id | 用于追踪当前连接情况的标志 ID | string | 可选 | “67ee89ba-7050-4c04-a3d7-ac61a63499b3” |
headers = { "X-Api-App-Id": "123456789", "X-Api-Access-Key": "your-access-key", "X-Api-Resource-Id": "seed-tts-2.0" }
Key | 说明 | 是否必须 | Value示例 |
|---|---|---|---|
X-Control-Require-Usage-Tokens-Return | 请求消耗的用量返回控制标记。当携带此字段,在SessionFinish事件(152)中会携带用量数据 | 否 |
|
在 websocket 握手成功后,会返回这些 Response header
Key | 说明 | Value 示例 |
|---|---|---|
X-Tt-Logid | 服务端返回的 logid,建议用户获取和打印方便定位问题 | 202407261553070FACFE6D19421815D605 |
WebSocket 使用二进制协议传输数据。
协议的组成由至少 4 个字节的可变 header、payload size 和 payload 三部分组成,其中
需注意:协议中整数类型的字段都使用大端表示。
Byte | Left 4-bit | Right 4-bit | 说明 |
|---|---|---|---|
0 - Left half | Protocol version | 目前只有v1,始终填 | |
0 - Right half | Header size (4x) | 目前只有4字节,始终填 | |
1 | Message type | Message type specific flags | 下文详细说明 |
2 - Left half | Serialization method |
| |
2 - Right half | Compression method |
| |
3 | Reserved | 留空( | |
[4 ~ 7] | [Optional field,like event number,...] | 取决于Message type specific flags,可能有、也可能没有 | |
... | Payload | 可能是音频数据、文本数据、音频文本混合数据 | |
Message type & specific flags是重点扩展的部分,详细说明如下:
Message type | 含义 | Message type specific flags | 是否包含Event number | 备注 |
|---|---|---|---|---|
0b0001 | Full-client request | 0b0100 | 是 | 完整请求体,用于触发服务端session初始化 |
0b1001 | Full-server response | 0b0100 | 是 | TTS:前端信息、文本音频混合数据等(Serialization=JSON) |
0b1011 | Audio-only response | 0b0100 | 是 | |
0b1111 | Error information | None | 否 |
注意:TTS服务参数设置仅在StartSession时生效,每次发送的文本在TaskRequest时生效。
TTS服务参数具体如下:
字段 | 描述 | 是否必须 | 类型 | 默认值 |
|---|---|---|---|---|
user | 用户信息 | |||
user.uid | 用户uid | |||
event | 请求的事件 | √ | ||
namespace | 请求方法 | string | BidirectionalTTS | |
req_params.text | required,输入文本(双向流式不支持ssml) | √ | string | |
req_params.model | 以下参数仅针对声音复刻2.0生效。取值有以下两种:
如果不传model参数,默认使用 | string | ||
req_params.speaker | 发音人,具体见发音人列表 | √ | string | |
req_params.audio_params | 音频参数,便于服务节省音频解码耗时 | √ | object | |
req_params.audio_params.format | 音频编码格式,mp3/ogg_opus/pcm。接口传入wav并不会报错,在流式场景下传入wav会多次返回wav header,这种场景建议使用pcm。 | string | mp3 | |
req_params.audio_params.sample_rate | 音频采样率,可选值 [8000,16000,22050,24000,32000,44100,48000] | number | 24000 | |
req_params.audio_params.bit_rate | 音频比特率,可传16000、32000等。 | number | ||
req_params.audio_params.emotion | 设置音色的情感。示例:"emotion": "angry" | string | ||
req_params.audio_params.emotion_scale | 调用emotion设置情感参数后可使用emotion_scale进一步设置情绪值,范围1~5,不设置时默认值为4。 | number | 4 | |
req_params.audio_params.speech_rate | 语速,取值范围[-50,100],100代表2.0倍速,-50代表0.5倍数 | number | 0 | |
req_params.audio_params.loudness_rate | 音量,取值范围[-50,100],100代表2.0倍音量,-50代表0.5倍音量(mix音色暂不支持) | number | 0 | |
req_params.audio_params.enable_timestamp | 设置 "enable_timestamp": true 返回句级别字的时间戳(默认为 false,参数传入 true 即表示启用)
注:该参数只在TTS1.0("豆包语音合成模型1.0"的音色)、ICL1.0生效。 | bool | false | |
req_params.audio_params.enable_subtitle | 设置 "enable_subtitle": true 返回句级别字的时间戳(默认为 false,参数传入 true 即表示启用)
注:该参数只在TTS2.0、ICL2.0生效。 | bool | false | |
req_params.additions | 用户自定义参数 | jsonstring | ||
req_params.additions.silence_duration | 设置该参数可在句尾增加静音时长,范围0~30000ms。(注:增加的句尾静音主要针对传入文本最后的句尾,而非每句话的句尾) | number | 0 | |
req_params.additions.enable_language_detector | 自动识别语种 | bool | false | |
req_params.additions.disable_markdown_filter | 是否开启markdown解析过滤, | bool | false | |
req_params.additions.disable_emoji_filter | 开启emoji表情在文本中不过滤显示,默认为false,建议搭配时间戳参数一起使用。 | bool | false | |
req_params.additions.mute_cut_remain_ms | 该参数需配合mute_cut_threshold参数一起使用,其中:
| string | ||
req_params.additions.enable_latex_tn | 是否可以播报latex公式,需将disable_markdown_filter设为true | bool | false | |
req_params.additions.latex_parser | 是否使用lid 能力播报latex公式,相较于latex_tn 效果更好; | string | ||
req_params.additions.max_length_to_filter_parenthesis | 是否过滤括号内的部分,0为不过滤,100为过滤 | int | 100 | |
req_params.additions.explicit_language(明确语种) | 仅读指定语种的文本
DIT 声音复刻场景:
当音色是使用model_type=3训练的,即采用dit还原版效果时,必须指定明确语种,目前支持:
声音复刻 ICL2.0场景:
当音色是使用model_type=5 训练的
GoLang示例: | string | ||
req_params.additions.context_language(参考语种) | 给模型提供参考的语种
| string | ||
req_params.additions.explicit_dialect | 明确方言,目前仅
参数情况举例说明:
| string | ||
req_params.additions.unsupported_char_ratio_thresh | 默认: 0.3,最大值: 1.0 | float | 0.3 | |
req_params.additions.aigc_watermark | 默认:false | bool | false | |
req_params.additions.aigc_metadata (meta 水印) | 在合成音频 header加入元数据隐式表示,支持 mp3/wav/ogg_opus | object | ||
req_params.additions.aigc_metadata.enable | 是否启用隐式水印 | bool | false | |
req_params.additions.aigc_metadata.content_producer | 合成服务提供者的名称或编码 | string | "" | |
req_params.additions.aigc_metadata.produce_id | 内容制作编号 | string | "" | |
req_params.additions.aigc_metadata.content_propagator | 内容传播服务提供者的名称或编码 | string | "" | |
req_params.additions.aigc_metadata.propagate_id | 内容传播编号 | string | "" | |
req_params.additions.cache_config(缓存相关参数) | 开启缓存,开启后合成相同文本时,服务会直接读取缓存返回上一次合成该文本的音频,可明显加快相同文本的合成速率,缓存数据保留时间1小时。 | object | ||
req_params.additions.cache_config.text_type(缓存相关参数) | 和use_cache参数一起使用,需要开启缓存时传1 | int | 1 | |
req_params.additions.cache_config.use_cache(缓存相关参数) | 和text_type参数一起使用,需要开启缓存时传true | bool | true | |
req_params.additions.cache_config.use_segment_cache(缓存相关参数) | 和text_type参数一起使用,需要开启缓存时传true | bool | true | |
req_params.additions.post_process | 后处理配置 | object | ||
req_params.additions.post_process.pitch | 音调取值范围是[-12,12] | int | 0 | |
req_params.additions.context_texts | 语音指令,语音合成的辅助信息,用于模型对话式合成,能更好的体现语音情感;
注意:
| string list | null | |
req_params.additions.section_id | 多轮会话 ID 用于关联同一上下文中的多次串行语音合成请求。服务端通过该 ID 在一次语音合成结束后保存对话历史,并在后续语音合成请求中,使用相同的 ID 读取对应的历史记录。
| string | "" | |
req_params.additions.use_tag_parser | 是否开启语音标签cot解析能力。cot能力可以辅助当前语音合成,对语速、情感等进行调整。
示例: | bool | false | |
[]req_params.mix_speaker | 混音参数结构
| object | ||
req_params.mix_speaker.speakers | 混音音色名以及影响因子列表
| list | null | |
req_params.mix_speaker.speakers[i].source_speaker | 混音源音色名
| string | "" | |
req_params.mix_speaker.speakers[i].mix_factor | 混音源音色名影响因子
| float | 0 |
单音色请求参数示例:
{ "user": { "uid": "12345" }, "event": 100, "req_params": { "text": "明朝开国皇帝朱元璋也称这本书为,万物之根", "speaker": "zh_female_shuangkuaisisi_moon_bigtts", "audio_params": { "format": "mp3", "sample_rate": 24000 }, } } }
mix请求参数示例:
{ "user": { "uid": "12345" }, "req_params": { "text": "明朝开国皇帝朱元璋也称这本书为万物之根", "speaker": "custom_mix_bigtts", "audio_params": { "format": "mp3", "sample_rate": 24000 }, "mix_speaker": { "speakers": [{ "source_speaker": "zh_male_bvlazysheep", "mix_factor": 0.3 }, { "source_speaker": "BV120_streaming", "mix_factor": 0.3 }, { "source_speaker": "zh_male_ahu_conversation_wvae_bigtts", "mix_factor": 0.4 }] } } }
主要关注建连阶段 HTTP Response 的状态码和 Body
Byte | Left 4-bit | Right 4-bit | 说明 |
|---|---|---|---|
0 - Left half | Protocol version | 目前只有v1,始终填 | |
0 - Right half | Header size (4x) | 目前只有4字节,始终填 | |
1 | Message type | Message type specific flags | 下文详细说明 |
2 - Left half | Serialization method |
| |
2 - Right half | Compression method |
| |
3 | Reserved | 留空( | |
[4 ~ 7] | [Optional field,like event number,...] | 取决于Message type specific flags,可能有、也可能没有 | |
... | Payload | 可能是音频数据、文本数据、音频文本混合数据 | |
字段 | 描述 | 类型 | 默认值 |
|---|---|---|---|
data | 返回的二进制数据包 | []byte | |
event | 返回的事件类型 | number | |
res_params.text | 经文本分句后的句子 | string |
Byte | Left 4-bit | Right 4-bit | 说明 |
|---|---|---|---|
0 - Left half | Protocol version | 目前只有v1,始终填 | |
0 - Right half | Header size (4x) | 目前只有4字节,始终填 | |
1 | Message type | Message type specific flags | 固定为 |
2 - Left half | Serialization method |
| |
2 - Right half | Compression method |
| |
3 | Reserved | 留空( | |
[4 ~ 7] | Error code | 错误码 | |
... | Payload | 错误消息对象 | |
在 TTS 场景中,Event 是正常数据帧(包括上行和下行)的必要字段,事件定义了请求过程中必要的状态转移。具体的使用过程详见交互示例部分
Event code | 含义 | 事件类型 | 应用阶段:上行/下行 |
|---|---|---|---|
1 | StartConnection,Websocket 阶段申明创建连接 | Connect 类 | 上行 |
2 | FinishConnection,结束连接 | Connect 类 | 上行 |
50 | ConnectionStarted,成功建连 | Connect 类 | 下行 |
51 | ConnectionFailed,建连失败 | Connect 类 | 下行 |
52 | ConnectionFinished 结束连接成功 | Connect 类 | 下行 |
100 | StartSession,Websocket 阶段申明创建会话 | Connect 类 | 上行 |
101 | CancelSession,取消会话(上行) | Session 类 | 上行 |
102 | FinishSession,声明结束会话(上行) | Session 类 | 上行 |
150 | SessionStarted,成功开始会话 | Session 类 | 下行 |
151 | SessionCanceled,已取消会话 | Session 类 | 下行 |
152 | SessionFinished,会话已结束(上行&下行) | Session 类 | 下行 |
153 | SessionFailed,会话失败 | Session 类 | 下行 |
200 | TaskRequest,传输请求内容 | 数据类 | 上行 |
350 | TTSSentenceStart,TTS 返回句内容开始 | 数据类 | 下行 |
351 | TTSSentenceEnd,TTS 返回句内容结束 | 数据类 | 下行 |
352 | TTSResponse,TTS 返回句的音频内容 | 数据类 | 下行 |
TTS1.0 | TTS2.0 | |
|---|---|---|
事件交互区别 | 合成有多个子句会多次返回 | 合成有多个子句,仅返回一次 |
返回时机 | 一个子句的时间戳返回之后才会开始返回下一句音频。 | 在一句音频合成之后,不会立即返回该句的字幕。 |
句子返回格式 | 字幕信息是基于tn打轴 说明
第一句:
第二句:
| 字幕信息是基于原文打轴 说明
第一句:
第二句:
|
语种 | 中、英,不支持小语种、方言 | 中、英,不支持小语种、方言 |
latex | enable_latex_tn=true,有字幕返回 | enable_latex_tn=true,无字幕返回,接口不报错 |
ssml | req_params.ssml不为空,有字幕返回 | req_params.ssml不为空,无字幕返回,接口不报错 |
注:连接建立和断开的部分相同,下图省略。
CancelSession注意事项:
CancelSession支持客户端主动放弃当前session,结束合成,并且释放服务端资源。CancelSession包发送的最佳时机:收到SessionStarted后,发送FinishSession之前。SessionCanceled包之后,如果想要继续合成,需要重新创建session,即重新执行StartSession。Connection 类:
StartConnection包(RequestMeta):Byte | Left 4-bit | Right 4-bit | 备注 | |
|---|---|---|---|---|
0 | 0001 | 0001 | v1 | 4-byte header |
1 | 0001 | 0100 | Full-client request | with event number |
2 | 0001 | 0000 | JSON | no compression |
3 | 0000 | 0000 | ||
4 - 7 | int32( | event type | ||
8 - 11 | uint32( | len( | ||
12 - 93 |
|
| ||
FinishConnection包(RequestMeta):Byte | Left 4-bit | Right 4-bit | 备注 | |
|---|---|---|---|---|
0 | 0001 | 0001 | v1 | 4-byte header |
1 | 0001 | 0100 | Full-client request | with event number |
2 | 0001 | 0000 | JSON | no compression |
3 | 0000 | 0000 | ||
4 - 7 | int32( | event type | ||
8-11 | uint32( | len( | ||
12-13 |
|
| ||
ConnectionStarted包:Byte | Left 4-bit | Right 4-bit | 备注 | |
|---|---|---|---|---|
0 | 0001 | 0001 | v1 | 4-byte header |
1 | 1001 | 0100 | Full-server response | with event number |
2 | 0001 | 0000 | JSON | no compression |
3 | 0000 | 0000 | ||
4 - 7 | int32( | event type | ||
8 - 11 | uint32( | len( | ||
12 - 18 |
| connection_id | ||
19 - 22 | uint32( | len( | ||
23 - 24 |
|
| ||
允许客户端不填connection_id,由网关下发一个唯一的ID
ConnectionFailed包(ResponseMeta):Byte | Left 4-bit | Right 4-bit | 备注 | |
|---|---|---|---|---|
0 | 0001 | 0001 | v1 | 4-byte header |
1 | 1001 | 0100 | Full-server response | with event number |
2 | 0001 | 0000 | JSON | no compression |
3 | 0000 | 0000 | ||
4 - 7 | int32( | event type | ||
8 - 11 | uint32( | len( | ||
12 - 15 | uint32( | len( | ||
16 - 73 |
| response_meta_json
| ||
Session 类:
StartSession包(RequestMeta):Byte | Left 4-bit | Right 4-bit | 备注 | |
|---|---|---|---|---|
0 | 0001 | 0001 | v1 | 4-byte header |
1 | 0001 | 0100 | Full-client request | with event number |
2 | 0001 | 0000 | JSON | no compression |
3 | 0000 | 0000 | ||
4 - 7 | int32( | event type | ||
8 - 11 | uint32( | len( | ||
12 - 23 |
| session_id | ||
24 - 27 | uint32( | len( | ||
28 - ... |
| tts_session_meta | ||
不允许客户端不填session_id
FinishSession包(RequestMeta):Byte | Left 4-bit | Right 4-bit | 备注 | |
|---|---|---|---|---|
0 | 0001 | 0001 | v1 | 4-byte header |
1 | 0001 | 0100 | Full-client request | with event number |
2 | 0001 | 0000 | JSON | no compression |
3 | 0000 | 0000 | ||
4 - 7 | int32( | event type | ||
8 - 11 | int32( | len( | ||
12 - 23 |
| session_id | ||
24 - 27 | uint32( | len( | ||
28 - 29 |
|
| ||
CancelSession包(RequestMeta):Byte | Left 4-bit | Right 4-bit | 备注 | |
|---|---|---|---|---|
0 | 0001 | 0001 | v1 | 4-byte header |
1 | 0001 | 0100 | Full-client request | with event number |
2 | 0001 | 0000 | JSON | no compression |
3 | 0000 | 0000 | ||
4 - 7 | int32( | event type | ||
8 - 11 | int32( | len( | ||
12 - 23 |
| session_id | ||
24 - 27 | uint32( | len( | ||
28 - 29 |
|
| ||
SessionStarted包(ResponseMeta):Byte | Left 4-bit | Right 4-bit | 备注 | |
|---|---|---|---|---|
0 | 0001 | 0001 | v1 | 4-byte header |
1 | 1001 | 0100 | Full-server response | with event number |
2 | 0001 | 0000 | JSON | no compression |
3 | 0000 | 0000 | ||
4 - 7 | int32( | event type | ||
8 - 11 | uint32( | len( | ||
12 - 23 |
| session_id | ||
24 - 27 | uint32( | len( | ||
28 - 29 |
|
| ||
SessionFinished包(ResponseMeta):Byte | Left 4-bit | Right 4-bit | 备注 | |
|---|---|---|---|---|
0 | 0001 | 0001 | v1 | 4-byte header |
1 | 1001 | 0100 | Full-server response | with event number |
2 | 0001 | 0000 | JSON | no compression |
3 | 0000 | 0000 | ||
4 - 7 | int32(Event_SessionFinished) | event type | ||
8 - 11 | uint32( | len( | ||
12 - 23 |
| session_id | ||
24 - 27 | uint32(48) | len( | ||
28 - 75 |
| response_meta_json
| ||
SessionFailed包(ResponseMeta):与SessionFinished类似SessionCanceled包(ResponseMeta):与SessionFinished类似数据类:
Event_TaskRequest事件为例):Byte | Left 4-bit | Right 4-bit | 备注 | |
|---|---|---|---|---|
0 | 0001 | 0001 | v1 | 4-byte header |
1 | 0010 | 0100 | Audio-only request | with event number |
2 | 0000 | 0000 | raw | no compression |
3 | 0000 | 0000 | ||
4 - 7 | int32( | event type | ||
8 - 11 | uint32( | len( | ||
12 - 23 |
| session_id | ||
24 - 27 | uint32( | len( | ||
28 - ... |
| audio_binary | ||
Byte | Left 4-bit | Right 4-bit | 备注 | |
|---|---|---|---|---|
0 | 0001 | 0001 | v1 | 4-byte header |
1 | 0010 | 0000 | Audio-only request | no event number |
2 | 0000 | 0000 | raw | no compression |
3 | 0000 | 0000 | ||
8 - 11 | uint32( | len( | ||
12 - 23 |
| session_id | ||
24 - 27 | uint32( | len( | ||
28 - ... |
| audio_binary | ||
Event_TaskRequest事件为例):Byte | Left 4-bit | Right 4-bit | 备注 | |
|---|---|---|---|---|
0 | 0001 | 0001 | v1 | 4-byte header |
1 | 0001 | 0100 | Full-client request | with event number |
2 | 0001 | 0000 | JSON | no compression |
3 | 0000 | 0000 | ||
4 - 7 | int32( | event type | ||
8 - 11 | uint32( | len( | ||
12 - 23 |
| session_id | ||
24 - 27 | uint32( | len( | ||
28 - ... |
|
| ||
CodeOK Code = 20000000 //成功 CodeClientError Code = 45000000 //客户端通用错误 CodeServerError Code = 55000000 //服务端通用错误 CodeSessionError Code = 55000001 //服务端session错误 CodeInvalidReqError Code = 45000001 //客户端请求参数错误
<appid>:使用控制台获取的APP ID,可参考 控制台使用FAQ-Q1。<access_token>:使用控制台获取的Access Token,可参考 控制台使用FAQ-Q1。<voice_type>:您预期使用的音色ID,可参考 大模型音色列表。python3 -m pip install --upgrade pip
mkdir -p volcengine_bidirection_demo tar xvzf volcengine_bidirection_demo.tar.gz -C ./volcengine_bidirection_demo cd volcengine_bidirection_demo python3 -m venv .venv source .venv/bin/activate python3 -m pip install --upgrade pip pip3 install -e .
<appid>替换为您的APP ID。<access_token>替换为您的Access Token。<voice_type>替换为您预期使用的音色ID,例如zh_female_cancan_mars_bigtts。
python3 examples/volcengine/bidirection.py --appid <appid> --access_token <access_token> --voice_type <voice_type> --text "你好,我是火山引擎的语音合成服务。这是一个美好的旅程。"