WebSocket Integration

Real-Time Voice Translation WebSocket Client Integration

This document explains how to integrate the real-time voice translation service over WebSocket.

API Requirements

Item Description
Protocol wss (WebSocket Protocol Version 13)
Endpoint wss://rtvt-cn-app.ilivedata.com/gate/websocket
Request line GET /gate/websocket HTTP/1.1
Authentication HMAC signature. See Token Authentication for details
Character encoding UTF-8
Data format JSON for control messages and Binary for audio data
Audio format Mono, 16kHz, 16-bit

1. Establish a WebSocket Connection

Pass all configuration parameters in the connection URL to establish the connection and configure speech recognition in one step:

serverURL := "wss://rtvt-cn-app.ilivedata.com/gate/websocket"
pid := 81700002 // Project ID
ts := time.Now().Unix() // Current Unix timestamp in seconds
token := genHMACToken(pid, ts, secretKey) // Generate a token as shown below

// Build the URL with the complete configuration
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&asrModel=%s&hotWordListId=%s",
    serverURL, pid, token, ts,
    "zh",                // Source language
    "en",                // Target language
    true,                // Return final ASR results
    true,                // Return interim ASR results
    true,                // Return translation results
    false,               // TTS results
    0,                   // Audio codec (0=PCM)
    "test_user",         // User ID
    "1000",              // VAD silence duration (ms)
    "ViiTor",              // ASR large model; pass an empty string or omit to disable
    "<hotword-list-id>") // Hotword list ID; pass an empty string or omit when unused

Speech Recognition Configuration

Speech recognition is configured using parameters in the connection URL.

URL Parameters

Parameter Type Description Default Example
srcLanguage string Source language code "zh" "zh"
destLanguage string Target language code "en" "en"
asrResult bool Whether to return final ASR results true "true"
asrTempResult bool Whether to return interim ASR results true "true"
transResult bool Whether to return translation results true "true"
ttsResult bool Whether to return TTS results false "false"
codec int Audio codec: 0=PCM, 1=Opus 0 "0"
userId string Custom user ID "test_user" "user123"
vadSilenceTime string VAD silence duration in milliseconds "1000" "1000"
srcAltLanguage string[] Alternative source language list Empty array ["en","ja"]
asrModel string ASR model; ViiTor enables the large model. An empty or omitted value keeps the default recognition flow Empty string "ViiTor"
hotWordListId string Hotword list ID Empty string "<hotword-list-id>"

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

Connection Example

conn, _, err := websocket.DefaultDialer.Dial(url, nil)

Authentication Result

A successful handshake returns HTTP status 101, indicating that the protocol upgrade succeeded. A failed handshake returns an HTTP status code and an error message based on the error type:

HTTP Code Description Error message Resolution
401 Missing or invalid parameters {"message":"Missing parameters"} Check that all required parameters are present
401 Failed to parse signature parameters {"message":"failed to parse parameters"} Check that all signature parameters are complete and valid, especially the copied secret
401 Signature verification failed {"message":"failed to verify"} Check the secret, confirm that the signature parameters are concatenated as specified, and verify that the generated Base64 signature is valid

2. Login and Handshake

The WebSocket connection also performs login. The business flow can start as soon as the connection is established.


3. Stream Audio Data

Send raw audio bytes directly in WebSocket Binary messages:

// Read audio data from a file or microphone
audioData := make([]byte, 640) // 20ms of PCM data
err := conn.WriteMessage(websocket.BinaryMessage, audioData)

Audio Format Requirements

  • Sample rate: 16kHz
  • Channels: Mono
  • Bit depth: 16-bit
  • Frame size: 640 bytes (20ms)
  • Format: Raw PCM audio data

4. Receive Recognition and Translation Results

The server returns four types of result messages:

4.1 Final Recognition Result (recognizedResult)

type RecognizedResult struct {
    Method   string `json:"method"`           // "recognizedResult"
    StreamId int64  `json:"streamId,string"`  // Session stream ID (a string in JSON)
    StartTs  int64  `json:"startTs,string"`   // Sentence start time in ms (a string in JSON)
    EndTs    int64  `json:"endTs,string"`     // Sentence end time in ms (a string in JSON)
    Asr      string `json:"asr"`              // Recognized text
    Lang     string `json:"lang"`             // Language
    RecTs    int64  `json:"recTs,string"`     // Recognition timestamp (a string in JSON)
    TaskId   int64  `json:"taskId,string"`    // Result sequence number (a string in JSON)
}

4.2 Interim Recognition Result (recognizedTempResult)

type RecognizedResult struct {
    Method   string `json:"method"`           // "recognizedTempResult"
    StreamId int64  `json:"streamId,string"`  // Session stream ID (a string in JSON)
    StartTs  int64  `json:"startTs,string"`   // Sentence start time in ms (a string in JSON)
    EndTs    int64  `json:"endTs,string"`     // 0 for interim results (a string in JSON)
    Asr      string `json:"asr"`              // Recognized text
    Lang     string `json:"lang"`             // Language
    RecTs    int64  `json:"recTs,string"`     // Recognition timestamp (a string in JSON)
    TaskId   int64  `json:"taskId,string"`    // Result sequence number (a string in JSON)
}

4.3 Final Translation Result (translatedResult)

type TranslatedResult struct {
    Method   string `json:"method"`           // "translatedResult"
    StreamId int64  `json:"streamId,string"`  // Session stream ID (a string in JSON)
    StartTs  int64  `json:"startTs,string"`   // Sentence start time in ms (a string in JSON)
    EndTs    int64  `json:"endTs,string"`     // Sentence end time in ms (a string in JSON)
    Trans    string `json:"trans"`            // Translated text
    Lang     string `json:"lang"`             // Target language
    RecTs    int64  `json:"recTs,string"`     // Recognition timestamp (a string in JSON)
    TaskId   int64  `json:"taskId,string"`    // Result sequence number (a string in JSON)
}

4.4 Interim Translation Result (translatedTempResult)

type TranslatedResult struct {
    Method   string `json:"method"`           // "translatedTempResult"
    StreamId int64  `json:"streamId,string"`  // Session stream ID (a string in JSON)
    StartTs  int64  `json:"startTs,string"`   // Sentence start time in ms (a string in JSON)
    EndTs    int64  `json:"endTs,string"`     // 0 for interim results (a string in JSON)
    Trans    string `json:"trans"`            // Translated text
    Lang     string `json:"lang"`             // Target language
    RecTs    int64  `json:"recTs,string"`     // Recognition timestamp (a string in JSON)
    TaskId   int64  `json:"taskId,string"`    // Result sequence number (a string in JSON)
}

Important Notes

  • JSON string representation: All numeric fields (StreamId, StartTs, EndTs, RecTs, and TaskId) are transmitted as strings in JSON. The ,string tag provides cross-language compatibility and prevents precision loss for large integers.
  • Message types: Use the Method field to distinguish message types.
    • recognizedResult / translatedResult: Final recognition or translation results with complete timing information.
    • recognizedTempResult / translatedTempResult: Interim recognition or translation results. EndTs is usually 0.

5. End Speech Recognition

Send a voiceEnd message:

voiceEndReq := map[string]interface{}{
    "method": "voiceEnd",
}
msgBytes, _ := json.Marshal(voiceEndReq)
err := conn.WriteMessage(websocket.TextMessage, msgBytes)

Notes:

  • The server processes any remaining audio data and returns the final results after receiving this message.
  • Wait for the final results before closing the connection.

6. Disconnect and Release Resources

  • After sending voiceEnd, close the WebSocket connection to release resources.

7. Complete Sequence

sequenceDiagram
    participant Client
    participant Server

    Client->>Server: WebSocket connection (authentication and ASR parameters)
    loop Audio streaming
        Client->>Server: Binary audio data (raw bytes)
        Server-->>Client: recognizedTempResult (interim recognition result)
        Server-->>Client: translatedTempResult (interim translation result)
        Server-->>Client: recognizedResult (final recognition result)
        Server-->>Client: translatedResult (final translation result)
    end

    Client->>Server: voiceEnd (end message)
    Server-->>Client: Final result processing completed

    Client-->>Server: Disconnect

8. Golang Example

Complete Example

// 1. Create a client
client := NewASRClient()
defer client.Close()

// 2. Set speech recognition parameters (the model and hotword list are independent and optional)
client.SetVoiceStartParams("zh", "en", "ViiTor", "<hotword-list-id>")
client.SetSrcAltLanguages([]string{"en", "ja"})

// 3. Build the authentication URL with the speech recognition configuration
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. Establish the connection
err := client.Connect(baseURL)
if err != nil {
    log.Fatal("Connection failed:", err)
}

// 5. Send audio data
for {
    audioData := make([]byte, 640) // 20ms of PCM data
    // Read audio data from a microphone or file
    n, err := audioSource.Read(audioData)
    if err != nil {
        break // End of audio
    }

    // Send the raw audio bytes
    err = client.SendVoiceData(audioData[:n])
    if err != nil {
        log.Printf("Failed to send audio: %v", err)
        break
    }

    time.Sleep(20 * time.Millisecond) // 20ms interval
}

// 6. End recognition
err = client.EndVoiceRecognition()
if err != nil {
    log.Printf("Failed to end recognition: %v", err)
}

For additional field descriptions or error-handling details, contact LiveData technical support.