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 中的参数完成,连接成功后服务端自动:

  1. 解析 URL 中的配置参数
  2. 初始化语音识别会话

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)
}

如需进一步说明或异常处理细节,请联系云上曲率技术支持。