WebSocket接入文档
更新时间:
实时语音翻译 WebSocket 接入文档
通过本文,您可以通过WebSocket接入,来实现实时语音场景下的翻译业务。
接口要求
内容
说明
请求协议
wss (WebSocket Protocol Version13)
请求地址
wss://rtvt-bj-test.ilivedata.com/gate/websocket
请求行
GET /service/websocket HTTP/1.1
接口鉴权
签名机制,使用 HMAC 方法,详见 Token 鉴权
字符编码
UTF-8
数据格式
控制消息使用 JSON 格式,音频数据使用 Binary 格式
音频格式
单声道、16kHz、16bit
1. 建立 WebSocket 连接
通过 URL 携带参数完成连接与识别配置:
serverURL := "wss://rtvt-bj-test.ilivedata.com/gate/websocket"
pid := 81700002 // 项目ID
ts := time.Now().Unix() // 当前时间戳(秒)
token := genHMACToken(pid, ts, secretKey) // 生成token,见下方方法
// 构建包含完整配置的 URL
url := fmt.Sprintf("%s?pid=%d&token=%s&ts=%d&version=1.0&srcLanguage=%s&destLanguage=%s&asrResult=%t&asrTempResult=%t&transResult=%t&ttsResult=%t&codec=%d&userId=%s&vadSilenceTime=%s",
serverURL, pid, token, ts,
"zh", // 源语言
"en", // 目标语言
true, // 返回最终ASR结果
true, // 返回临时ASR结果
true, // 返回翻译结果
false, // TTS结果
0, // 编码格式(0=PCM)
"test_user", // 用户ID
"1000") // VAD静音时间(ms)
语音识别配置
语音识别配置通过连接 URL 中的参数完成,连接成功后服务端自动:
- 解析 URL 中的配置参数
- 初始化语音识别会话
URL 参数说明:
参数
类型
描述
默认值
示例值
srcLanguage
string
源语言代码
"zh"
"zh"
destLanguage
string
目标语言代码
"en"
"en"
asrResult
bool
是否返回最终 ASR 结果
true
"true"
asrTempResult
bool
是否返回临时 ASR 结果
true
"true"
transResult
bool
是否返回翻译结果
true
"true"
ttsResult
bool
是否返回 TTS 结果
false
"false"
codec
int
音频编码格式
0
"0"
userId
string
用户自定义 ID
"test_user"
"user123"
vadSilenceTime
string
VAD 静音时间(ms)
"1000"
"1000"
token生成方法
func genHMACToken(pid int32, ts int64, key string) string {
content := fmt.Sprintf("%d:%d", pid, ts)
keyb, _ := base64.StdEncoding.DecodeString(key)
h := hmac.New(sha256.New, keyb)
h.Write([]byte(content))
return base64.StdEncoding.EncodeToString(h.Sum(nil))
}
链接示例
conn, _, err := websocket.DefaultDialer.Dial(url, nil)
鉴权结果
如果握手成功,会返回HTTP 101状态码,表示协议升级成功;如果握手失败,则根据不同错误类型返回不同HTTP Code状态码,同时携带错误描述信息,详细错误说明如下:
2. 登录/握手
WS连接即登录,连接建立后直接进入业务流程。
3. 流式发送音频数据
使用 WebSocket Binary 消息直接发送原始音频字节:
// 读取音频数据(例如从文件或麦克风)
audioData := make([]byte, 640) // 20ms PCM 数据
err := conn.WriteMessage(websocket.BinaryMessage, audioData)
音频格式要求:
- 采样率:16kHz
- 声道:单声道
- 位深:16bit
- 每帧:640字节(20ms)
- 格式:PCM 原始音频数据
4. 接收识别与翻译结果
服务端会返回4种类型的结果消息:
4.1 最终识别结果(recognizedResult)
type RecognizedResult struct {
Method string `json:"method"` // "recognizedResult"
StreamId int64 `json:"streamId,string"` // 会话流ID(JSON中为字符串)
StartTs int64 `json:"startTs,string"` // 句子开始时间(毫秒,JSON中为字符串)
EndTs int64 `json:"endTs,string"` // 句子结束时间(毫秒,JSON中为字符串)
Asr string `json:"asr"` // 识别文本
Lang string `json:"lang"` // 语种
RecTs int64 `json:"recTs,string"` // 识别时间戳(JSON中为字符串)
TaskId int64 `json:"taskId,string"` // 结果序号(JSON中为字符串)
}
4.2 临时识别结果(recognizedTempResult)
type RecognizedResult struct {
Method string `json:"method"` // "recognizedTempResult"
StreamId int64 `json:"streamId,string"` // 会话流ID(JSON中为字符串)
StartTs int64 `json:"startTs,string"` // 句子开始时间(毫秒,JSON中为字符串)
EndTs int64 `json:"endTs,string"` // 0(临时结果无结束时间,JSON中为字符串)
Asr string `json:"asr"` // 识别文本
Lang string `json:"lang"` // 语种
RecTs int64 `json:"recTs,string"` // 识别时间戳(JSON中为字符串)
TaskId int64 `json:"taskId,string"` // 结果序号(JSON中为字符串)
}
4.3 最终翻译结果(translatedResult)
type TranslatedResult struct {
Method string `json:"method"` // "translatedResult"
StreamId int64 `json:"streamId,string"` // 会话流ID(JSON中为字符串)
StartTs int64 `json:"startTs,string"` // 句子开始时间(毫秒,JSON中为字符串)
EndTs int64 `json:"endTs,string"` // 句子结束时间(毫秒,JSON中为字符串)
Trans string `json:"trans"` // 翻译文本
Lang string `json:"lang"` // 目标语种
RecTs int64 `json:"recTs,string"` // 识别时间戳(JSON中为字符串)
TaskId int64 `json:"taskId,string"` // 结果序号(JSON中为字符串)
}
4.4 临时翻译结果(translatedTempResult)
type TranslatedResult struct {
Method string `json:"method"` // "translatedTempResult"
StreamId int64 `json:"streamId,string"` // 会话流ID(JSON中为字符串)
StartTs int64 `json:"startTs,string"` // 句子开始时间(毫秒,JSON中为字符串)
EndTs int64 `json:"endTs,string"` // 0(临时结果无结束时间,JSON中为字符串)
Trans string `json:"trans"` // 翻译文本
Lang string `json:"lang"` // 目标语种
RecTs int64 `json:"recTs,string"` // 识别时间戳(JSON中为字符串)
TaskId int64 `json:"taskId,string"` // 结果序号(JSON中为字符串)
}
重要说明:
- JSON 字符串格式:所有数值字段(StreamId、StartTs、EndTs、RecTs、TaskId)在 JSON 中以字符串形式传输,使用 ,string 标签确保跨语言兼容性和避免大整数精度丢失
- 消息类型区分:通过 Method 字段区分消息类型
- recognizedResult / translatedResult:最终识别/翻译结果,包含完整的时间信息
- recognizedTempResult / translatedTempResult:临时识别/翻译结果,EndTs 通常为 0
5. 结束语音识别
发送 voiceEnd 消息
voiceEndReq := map[string]interface{}{
"method": "voiceEnd",
}
msgBytes, _ := json.Marshal(voiceEndReq)
err := conn.WriteMessage(websocket.TextMessage, msgBytes)
说明:
- 发送后服务端会处理剩余的音频数据并返回最终结果
- 建议等待结果返回后再关闭连接
6. 断开连接与资源释放
- 发送 voiceEnd 后,可关闭 WebSocket 连接,释放资源。
7. 完整流程
sequenceDiagram
participant Client
participant Server
Client->>Server: WebSocket 连接 (带鉴权+语音识别参数)
loop 音频流传输
Client->>Server: Binary音频数据 (原始字节)
Server-->>Client: recognizedTempResult (临时识别结果)
Server-->>Client: translatedTempResult (临时翻译结果)
Server-->>Client: recognizedResult (最终识别结果)
Server-->>Client: translatedResult (最终翻译结果)
end
Client->>Server: voiceEnd (结束消息)
Server-->>Client: 最终结果处理完成
Client-->>Server: 断开连接
8. 使用示例 (golang)
包含完整的连接、鉴权、音频发送、结果接收等流程。
完整使用示例
// 1. 创建客户端
client := NewASRClient()
defer client.Close()
// 2. 设置语音识别参数
client.SetVoiceStartParams("zh", "en")
// 3. 构建认证 URL(包含语音识别配置)
ts := time.Now().Unix()
token := genHMACToken(pid, ts, secretKey)
baseURL := fmt.Sprintf("%s?pid=%d&token=%s&ts=%d&version=1.0", serverURL, pid, token, ts)
// 4. 连接(自动完成语音识别初始化)
err := client.Connect(baseURL)
if err != nil {
log.Fatal("连接失败:", err)
}
// 5. 发送音频数据
for {
audioData := make([]byte, 640) // 20ms PCM 数据
// 从麦克风或文件读取音频数据
n, err := audioSource.Read(audioData)
if err != nil {
break // 音频结束
}
// 直接发送原始音频字节
err = client.SendVoiceData(audioData[:n])
if err != nil {
log.Printf("发送音频失败: %v", err)
break
}
time.Sleep(20 * time.Millisecond) // 20ms 间隔
}
// 6. 结束识别
err = client.EndVoiceRecognition()
if err != nil {
log.Printf("结束识别失败: %v", err)
}
如需进一步说明或异常处理细节,请联系云上曲率技术支持。
实时语音翻译 WebSocket 接入文档
通过本文,您可以通过WebSocket接入,来实现实时语音场景下的翻译业务。
接口要求
内容 | 说明 |
---|---|
请求协议 | wss (WebSocket Protocol Version13) |
请求地址 | wss://rtvt-bj-test.ilivedata.com/gate/websocket |
请求行 | GET /service/websocket HTTP/1.1 |
接口鉴权 | 签名机制,使用 HMAC 方法,详见 Token 鉴权 |
字符编码 | UTF-8 |
数据格式 | 控制消息使用 JSON 格式,音频数据使用 Binary 格式 |
音频格式 | 单声道、16kHz、16bit |
1. 建立 WebSocket 连接
通过 URL 携带参数完成连接与识别配置:
serverURL := "wss://rtvt-bj-test.ilivedata.com/gate/websocket"
pid := 81700002 // 项目ID
ts := time.Now().Unix() // 当前时间戳(秒)
token := genHMACToken(pid, ts, secretKey) // 生成token,见下方方法
// 构建包含完整配置的 URL
url := fmt.Sprintf("%s?pid=%d&token=%s&ts=%d&version=1.0&srcLanguage=%s&destLanguage=%s&asrResult=%t&asrTempResult=%t&transResult=%t&ttsResult=%t&codec=%d&userId=%s&vadSilenceTime=%s",
serverURL, pid, token, ts,
"zh", // 源语言
"en", // 目标语言
true, // 返回最终ASR结果
true, // 返回临时ASR结果
true, // 返回翻译结果
false, // TTS结果
0, // 编码格式(0=PCM)
"test_user", // 用户ID
"1000") // VAD静音时间(ms)
语音识别配置
语音识别配置通过连接 URL 中的参数完成,连接成功后服务端自动:
- 解析 URL 中的配置参数
- 初始化语音识别会话
URL 参数说明:
参数 | 类型 | 描述 | 默认值 | 示例值 |
---|---|---|---|---|
srcLanguage |
string | 源语言代码 | "zh" |
"zh" |
destLanguage |
string | 目标语言代码 | "en" |
"en" |
asrResult |
bool | 是否返回最终 ASR 结果 | true |
"true" |
asrTempResult |
bool | 是否返回临时 ASR 结果 | true |
"true" |
transResult |
bool | 是否返回翻译结果 | true |
"true" |
ttsResult |
bool | 是否返回 TTS 结果 | false |
"false" |
codec |
int | 音频编码格式 | 0 |
"0" |
userId |
string | 用户自定义 ID | "test_user" |
"user123" |
vadSilenceTime |
string | VAD 静音时间(ms) | "1000" |
"1000" |
token生成方法
func genHMACToken(pid int32, ts int64, key string) string {
content := fmt.Sprintf("%d:%d", pid, ts)
keyb, _ := base64.StdEncoding.DecodeString(key)
h := hmac.New(sha256.New, keyb)
h.Write([]byte(content))
return base64.StdEncoding.EncodeToString(h.Sum(nil))
}
链接示例
conn, _, err := websocket.DefaultDialer.Dial(url, nil)
鉴权结果
如果握手成功,会返回HTTP 101状态码,表示协议升级成功;如果握手失败,则根据不同错误类型返回不同HTTP Code状态码,同时携带错误描述信息,详细错误说明如下:
2. 登录/握手
WS连接即登录,连接建立后直接进入业务流程。
3. 流式发送音频数据
使用 WebSocket Binary 消息直接发送原始音频字节:
// 读取音频数据(例如从文件或麦克风)
audioData := make([]byte, 640) // 20ms PCM 数据
err := conn.WriteMessage(websocket.BinaryMessage, audioData)
音频格式要求:
- 采样率:16kHz
- 声道:单声道
- 位深:16bit
- 每帧:640字节(20ms)
- 格式:PCM 原始音频数据
4. 接收识别与翻译结果
服务端会返回4种类型的结果消息:
4.1 最终识别结果(recognizedResult)
type RecognizedResult struct {
Method string `json:"method"` // "recognizedResult"
StreamId int64 `json:"streamId,string"` // 会话流ID(JSON中为字符串)
StartTs int64 `json:"startTs,string"` // 句子开始时间(毫秒,JSON中为字符串)
EndTs int64 `json:"endTs,string"` // 句子结束时间(毫秒,JSON中为字符串)
Asr string `json:"asr"` // 识别文本
Lang string `json:"lang"` // 语种
RecTs int64 `json:"recTs,string"` // 识别时间戳(JSON中为字符串)
TaskId int64 `json:"taskId,string"` // 结果序号(JSON中为字符串)
}
4.2 临时识别结果(recognizedTempResult)
type RecognizedResult struct {
Method string `json:"method"` // "recognizedTempResult"
StreamId int64 `json:"streamId,string"` // 会话流ID(JSON中为字符串)
StartTs int64 `json:"startTs,string"` // 句子开始时间(毫秒,JSON中为字符串)
EndTs int64 `json:"endTs,string"` // 0(临时结果无结束时间,JSON中为字符串)
Asr string `json:"asr"` // 识别文本
Lang string `json:"lang"` // 语种
RecTs int64 `json:"recTs,string"` // 识别时间戳(JSON中为字符串)
TaskId int64 `json:"taskId,string"` // 结果序号(JSON中为字符串)
}
4.3 最终翻译结果(translatedResult)
type TranslatedResult struct {
Method string `json:"method"` // "translatedResult"
StreamId int64 `json:"streamId,string"` // 会话流ID(JSON中为字符串)
StartTs int64 `json:"startTs,string"` // 句子开始时间(毫秒,JSON中为字符串)
EndTs int64 `json:"endTs,string"` // 句子结束时间(毫秒,JSON中为字符串)
Trans string `json:"trans"` // 翻译文本
Lang string `json:"lang"` // 目标语种
RecTs int64 `json:"recTs,string"` // 识别时间戳(JSON中为字符串)
TaskId int64 `json:"taskId,string"` // 结果序号(JSON中为字符串)
}
4.4 临时翻译结果(translatedTempResult)
type TranslatedResult struct {
Method string `json:"method"` // "translatedTempResult"
StreamId int64 `json:"streamId,string"` // 会话流ID(JSON中为字符串)
StartTs int64 `json:"startTs,string"` // 句子开始时间(毫秒,JSON中为字符串)
EndTs int64 `json:"endTs,string"` // 0(临时结果无结束时间,JSON中为字符串)
Trans string `json:"trans"` // 翻译文本
Lang string `json:"lang"` // 目标语种
RecTs int64 `json:"recTs,string"` // 识别时间戳(JSON中为字符串)
TaskId int64 `json:"taskId,string"` // 结果序号(JSON中为字符串)
}
重要说明:
- JSON 字符串格式:所有数值字段(StreamId、StartTs、EndTs、RecTs、TaskId)在 JSON 中以字符串形式传输,使用 ,string 标签确保跨语言兼容性和避免大整数精度丢失
- 消息类型区分:通过 Method 字段区分消息类型
- recognizedResult / translatedResult:最终识别/翻译结果,包含完整的时间信息
- recognizedTempResult / translatedTempResult:临时识别/翻译结果,EndTs 通常为 0
5. 结束语音识别
发送 voiceEnd 消息
voiceEndReq := map[string]interface{}{
"method": "voiceEnd",
}
msgBytes, _ := json.Marshal(voiceEndReq)
err := conn.WriteMessage(websocket.TextMessage, msgBytes)
说明:
- 发送后服务端会处理剩余的音频数据并返回最终结果
- 建议等待结果返回后再关闭连接
6. 断开连接与资源释放
- 发送 voiceEnd 后,可关闭 WebSocket 连接,释放资源。
7. 完整流程
sequenceDiagram
participant Client
participant Server
Client->>Server: WebSocket 连接 (带鉴权+语音识别参数)
loop 音频流传输
Client->>Server: Binary音频数据 (原始字节)
Server-->>Client: recognizedTempResult (临时识别结果)
Server-->>Client: translatedTempResult (临时翻译结果)
Server-->>Client: recognizedResult (最终识别结果)
Server-->>Client: translatedResult (最终翻译结果)
end
Client->>Server: voiceEnd (结束消息)
Server-->>Client: 最终结果处理完成
Client-->>Server: 断开连接
8. 使用示例 (golang)
包含完整的连接、鉴权、音频发送、结果接收等流程。
完整使用示例
// 1. 创建客户端
client := NewASRClient()
defer client.Close()
// 2. 设置语音识别参数
client.SetVoiceStartParams("zh", "en")
// 3. 构建认证 URL(包含语音识别配置)
ts := time.Now().Unix()
token := genHMACToken(pid, ts, secretKey)
baseURL := fmt.Sprintf("%s?pid=%d&token=%s&ts=%d&version=1.0", serverURL, pid, token, ts)
// 4. 连接(自动完成语音识别初始化)
err := client.Connect(baseURL)
if err != nil {
log.Fatal("连接失败:", err)
}
// 5. 发送音频数据
for {
audioData := make([]byte, 640) // 20ms PCM 数据
// 从麦克风或文件读取音频数据
n, err := audioSource.Read(audioData)
if err != nil {
break // 音频结束
}
// 直接发送原始音频字节
err = client.SendVoiceData(audioData[:n])
if err != nil {
log.Printf("发送音频失败: %v", err)
break
}
time.Sleep(20 * time.Millisecond) // 20ms 间隔
}
// 6. 结束识别
err = client.EndVoiceRecognition()
if err != nil {
log.Printf("结束识别失败: %v", err)
}
如需进一步说明或异常处理细节,请联系云上曲率技术支持。