本文档介绍如何通过WebSocket协议实时访问同传大模型 (AST)服务,主要包含鉴权相关、协议详情、常见问题和使用Demo四部分。支持s2s(Speech-to-Speech),s2t(Speech-to-Text),目前支持支持克隆本身说话人的音色,支持中英互译。
AST 服务使用的接口地址是:wss://openspeech.bytedance.com/api/v4/ast/v2/translate
在 websocket 建连的 HTTP 请求头(Header 中)添加以下信息
携带信息 | 对应的 HTTP Header | 填写的值 |
|---|---|---|
X-Api-App-Key | 使用火山引擎控制台获取的APP ID,可参考 控制台使用FAQ-Q1 | 123456789 |
X-Api-Access-Key | 使用火山引擎控制台获取的Access Token,可参考 控制台使用FAQ-Q1 | your-access-key |
X-Api-Resource-Id | 表示调用服务的资源信息 ID,是固定值 | volc.service_type.10053 |
websocket 握手成功后,会返回 Response header
Key | 说明 | Value 示例 |
|---|---|---|
X-Tt-Logid | 服务端返回的 logid,建议用户获取和打印方便定位问题 | 202407261553070FACFE6D19421815D605 |
GET /api/v4/ast/v2/translate Host: openspeech.bytedance.com X-Api-App-Key: 123456789 X-Api-Access-Key: your-access-key X-Api-Resource-Id: volc.service_type.10053 # 返回 Header X-Tt-Logid: 202407261553070FACFE6D19421815D605
构建方法:下载并解压上面的gzip压缩包后,参考其中的HOWTO.md教程
目前有Go,Python, Java语言的构建教程,此压缩包为Go的示例教程, Python, Java语言的构建教程直接打包在下方Client Demo中,请直接下载获取。
Go:
WebSocket protobuf传输数据。
发送端 Event Type:
Event | 取值 | 描述 |
|---|---|---|
StartSession | 100 | 建联请求 |
UpdateConfig | 201 | 更新参数 |
TaskRequest | 200 | 发送音频数据 |
FinishSession | 102 | 结束session |
接收端 Event Type:
Type | 取值 | 描述 |
|---|---|---|
SessionStarted | 150 | 建联成功 |
SourceSubtitleStart | 650 | 原文开始 |
SourceSubtitleResponse | 651 | 原文数据 |
SourceSubtitleEnd | 652 | 原文结束 |
TranslationSubtitleStart | 653 | 译文开始 |
TranslationSubtitleResponse | 654 | 译文数据 |
TranslationSubtitleEnd | 655 | 译文结束 |
TTSSentenceStart | 350 | TTS开始 |
TTSResponse | 352 | TTS数据 |
TTSSentenceEnd | 351 | TTS结束 |
UsageResponse | 154 | 计量计费 |
SessionFinished | 152 | 会话正常结束 |
SessionFailed | 153 | 会话失败 |
AudioMuted | 250 | 静音事件 |
根据 WebSocket 协议本身的机制,client 会发送 HTTP GET 请求和 server 建立连接做协议升级。
需要在其中根据身份认证协议加入鉴权签名头。设置方法请参考鉴权。
WebSocket 建立连接后,发送的第一个请求是 建联 request。请求体字段说明:
一级字段 | 二级字段 | 三级字段 | 说明 | 层级 | 格式 | 是否必填 | 备注 |
|---|---|---|---|---|---|---|---|
request_meta | 请求元信息 | 1 | dict | 请求元信息 | |||
session_id | 会话ID | string | ✓ | 建议采用UUID | |||
event | 请求事件说明 | 1 | enum(int32) | ✓ | 建联请求的event 为100,见上文Event 字段描述 | ||
user | 用户相关配置 | 1 | dict | 提供后可供服务端过滤日志 | |||
uid | 用户标识 | 2 | string | 建议采用 IMEI 或 MAC。 | |||
did | 设备名称 | 2 | string | ||||
platform | 操作系统及API版本号 | 2 | string | iOS/Android/Linux | |||
sdk_version | sdk版本 | 2 | string | ||||
request | 请求相关配置 | 1 | dict | ✓ | 请求配置说明 | ||
mode | 模式 | 2 | string | s2t/s2s 选一个, 控制是否需要语音 | |||
source_language | 源语言 | 2 | zh/en 注意,source和target必须不同 | ||||
target_language | 目标语言 | 2 | zh/en | ||||
corpus | 语料/干预词等 | 2 | 自定义词典,该object的所有配置字段(热词和术语)加和不超过1000个。超过则会报错。 | ||||
hot_words_list | 热词列表 | 3 | array of string | 原文字幕识别时使用的热词词库,用来指导模型,不一定干预生效,示例:["视频直播","赛事直播","智能家居"] | |||
glossary_list | 术语列表 | 3 | dict, 内层key value都是string | 原文翻译成译文时使用的热词词库,,用来指导模型,不一定干预生效,示例: | |||
source_audio | 源音频相关配置 | 1 | dict | ✓ | 源音频信息 | ||
format | 音频容器格式 | 2 | string | ✓ | wav,仅支持wav | ||
codec | 音频编码格式 | 2 | string | raw, raw(表示pcm编码) 。 仅支持raw | |||
rate | 音频采样率 | 2 | int | 必须是16000 | |||
bits | 音频采样点位数 | 2 | int | 必须是16 | |||
channel | 音频声道数 | 2 | int | 1(mono) / 2(stereo),当前仅支持单声道,必须传1 | |||
target_audio | 目标音频相关配置 | 1 | dict | s2s时必填,s2t时非必填 | 目标音频信息 | ||
format | 音频容器格式 | 2 | string | s2s时必填,s2t时非必填 | pcm/ogg_opus | ||
rate | 音频采样率 | 2 | int | s2s时必填,s2t时非必填 | 默认为 24000。支持16000/24000 |
参数示例:
Request中的
request_meta.session_id为必填字段,不可缺省
{ "request_meta": { "session_id": "xxxxxxxx-xxxxxxxxxx-xxxxxxx-xxxxxxxxxx" } "event": event.Type_StartSession, "user": { "uid": "388808088185088", "did": "xxxxxx" }, "source_audio": { "format": "wav", "rate": 16000, "bits": 16, "channel": 1, }, "target_audio": { "format": "pcm", "rate": 48000 }, "request": { "mode": "s2s", "source_language": "zh", "target_language": "en", "corpus": { "hot_words_list": ["xxxxx","xxxxx"], "glossary_list": { "xxxxx": "yyy", "zzzzz": "www", }, } } }
Client 发送 建连请求后,再发送包含音频数据的 TaskRequest。音频应采用建立连接request 中指定的格式(音频格式、编解码器、采样率、声道)。二进制数据放在protobuf 的request体内部
例如在流式语音识别中如果每次发送 100ms 的音频数据,那么data中的 内容 就是 100ms 的音频数据。
注意:需要等到收到服务端响应的SessionStarted后再发参数包及音频包
字段 | 说明 | 层级 | 格式 | 是否必填 | 备注 |
|---|---|---|---|---|---|
event | 请求事件说明 | 1 | enum (int32) | ✓ | 发送音频数据的的event 为200,见上文Event 字段描述 |
source_audio | 源音频相关配置 | 1 | dict | ✓ | 源音频信息 |
data | 音频数据 | 2 | bytes | ✓ | 音频流的二进制数据, 要求16khz,16bit,单通道wav/pcm, 建议80ms 一包 |
参数示例:
{ "event": event.Type_TaskRequest, "source_audio": { "data": "ff\xa2\xfe*\xfeB\xfe\xa3\xfe\x9c\xff\xe2\x0" } }
用于在session中更新语料/干预词等
参数示例:
{ "event": event.Type_UpdateConfig, "request": { "mode": "s2s", // 注意:当前不支持在会话中切换语言及mode,如需切换,请重新建立连接 "corpus": { // 用于在中间包修改热词和术语列表 "hot_words_list": [], "glossary_list": {}, } } }
单独的结束事件,不带音频,在要发送的音频全部发送完毕后发送
参数示例:
{ "event": event.FinishSession }
Client 发送请求,服务端都会返回response。格式具体见protobuf定义,具体关键字段说明如下:
字段 | 说明 | 层级 | 格式 | 是否必填 | 备注 |
|---|---|---|---|---|---|
response_meta | 响应元信息 | 1 | dict | ||
status_code | 错误码 | 2 | int | ||
message | 错误信息 | 2 | string | ||
billing | 计量计费信息 | 2 | dict | 仅计量计费-UsageResponse event返回此字段 | |
duration_msec | 音频的持续时长 | 3 | int | 单位:毫秒 | |
items | 计量计费详情 | 3 | array | ||
unit | token分类 | 4 | string | 取值为: | |
quantity | 消耗token量 | 4 | float | ||
event | 响应事件 | 1 | int | 响应事件标志,例如建联成功(SessionStarted 取值为150) | |
text | 整个音频的识别结果文本 | 1 | string | 原文或者译文 | |
data | 响应数据 | 1 | raw | 响应的二进制数据 | |
start_time | 起始时间(毫秒) | 1 | int | 仅当识别成功时填写 | |
end_time | 结束时间(毫秒) | 1 | int | 仅当识别成功时填写 | |
spk_chg | 说话人是否发生了切换的标志 | 1 | bool | 默认为false,在检测到说话人发生切换的那个句子的SourceSubtitleStart和TranslationSubtitleStart响应的响应体里会把此参数设置为true | |
muted_duration_ms | 静音时间 | int | 单位ms, 表示静音了多久,存在误差,不是精确值 |
响应示例:
{ "event": event.Type_SessionStarted }
标记原文开始发送,包含开始时间戳(startTime), 说话人切换信号(如开启相关功能)
{ "event": event.Type_SourceSubtitleStart, "start_time": xxx, "spk_chg": false //默认为false,如果检测到此句说话人发生切换,那么为true }
发送音频,要求16khz,16bit,单通道wav/pcm, 建议80ms一包
{ "event": event.Type_SourceSubtitleResponse, "text": "xxx" //原文文本 }
{ "event": event.Type_SourceSubtitleEnd, "start_time": xxx, "end_time": xxx, "text": "xxx" }
{ "event": event.Type_TranslationSubtitleStart, "start_time": xxx, "spk_chg": false //默认为false,如果检测到此句说话人发生切换,那么为true }
{ "event": event.Type_TranslationSubtitleResponse, "text": "xxx" }
{ "event": event.Type_TranslationSubtitleEnd, "start_time": xxx, "end_time": xxx, "text": "xxx" }
{ "event": event.Type_TTSSentenceStart, "start_time": xxx }
音频数据:data (音频数据,按设置的target_audio格式返回),
{ "event": event.Type_TTSResponse, "data": "xxx" }
{ "event": event.Type_TTSSentenceEnd, "data": "xxx", "start_time": xxx, "end_time": xxx }
{ "event": event.Type_UsageResponse, "responseMeta": { "session_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "status_code": 20000000, // 成功的状态码 "message": "OK", "billing": { // 计费详情 "items": [ { "unit": "output_text_tokens", // API调用token, 文本输出 "quantity": 15.0 // 消耗的token量 }, { "unit": "output_audio_tokens", // API调用token, 音频输出 "quantity": 11.0 // 消耗的token量 }, { "unit": "input_audio_tokens", // API调用token,音频输入 "quantity": 4.0 // 消耗的token量 } ], "duration_msec": 640 // 音频的持续时间,单位:毫秒 } } }
{ "event": event.Type_SessionFinished }
{ "event": event.Type_SessionFailed }
vad检测到静音时会响应静音事件,第一次响应为静音2s后,之后每静音约1s返回一次wen
{ "event": event.Type_Type_AudioMuted, "muted_duration_ms": xxx //单位ms, 表示静音了多久,存在误差,不是精确值 }
当 server 发现无法解决的二进制/传输协议问题时,将发送 Error message from server 消息(例如,client 以 server 不支持的序列化格式发送消息)。格式见前文response_meta字段:
错误码 | 含义 | 说明 |
|---|---|---|
20000000 | 成功 | |
45000001 | 请求参数无效 | 请求参数缺失必需字段 / 字段值无效 / 重复请求。 |
45000002 | 空音频 | |
45000081 | 等包超时 | |
45000151 | 音频格式不正确 | |
550xxxxx | 服务内部处理错误 | |
55000031 | 服务器繁忙 | 服务过载,无法处理当前请求。 |