> ## Documentation Index
> Fetch the complete documentation index at: https://docs.senseaudio.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# 同声传译 WebSocket

> 基于 WebSocket 的实时同声传译协议参考

## 说明

基于 WebSocket 的同声传译接口，支持实时语音识别、翻译与译文播报。通信包含 JSON 控制消息与二进制音频消息两类。

* **接入地址**：`wss://api.senseaudio.cn/ws/v1/audio/simulat-interpreting`
* **鉴权方式**：Bearer Token，格式 `Authorization: Bearer SENSEAUDIO_API_KEY`
* **音频格式**：PCM signed 16-bit little-endian，采样率 16000Hz，单声道
* **模型参数**：`sensenova-livetranslate-1.0`
* **计费单位**：按输入音频时长计费，详见 [计费说明](/guides/account/billing)
* **使用场景**：跨语言会议、实时交流、直播与国际活动

<Warning>
  - 音频必须为 **PCM 16-bit little-endian / 16kHz / 单声道**。
  - 控制消息必须以 **JSON 文本帧** 发送，音频数据必须以 **二进制帧** 发送。
  - 客户端需等待 `connected_success` 后再发送 `task_start`，等待 `task_started` 后再开始推送音频。
  - 当前 API 不支持断线恢复，连接断开后需要重新建立连接并创建新任务。
</Warning>

## 请求头 (Request Headers)

| 参数名               | 必填 | 说明                                      | 示例                  |
| :---------------- | :- | :-------------------------------------- | :------------------ |
| **Authorization** | 是  | 鉴权 Token。格式：Bearer SENSEAUDIO\_API\_KEY | Bearer sk-123456... |

***

## 通信流程

```
1. 客户端建立 WebSocket 连接
   ↓
2. 服务端返回 connected_success 事件
   ↓
3. 客户端发送 task_start 事件
   ↓
4. 服务端返回 task_started 事件
   ↓
5. 客户端持续发送二进制 PCM 音频帧
   ↓
6. 服务端返回原文、译文、译文 TTS 事件
   ↓
7. 客户端发送 task_finish 事件
   ↓
8. 服务端返回 task_finished 事件并关闭连接
```

```mermaid theme={null}
sequenceDiagram
    participant Client as 客户端
    participant Server as 服务端

    Client->>Server: WebSocket Connect + Authorization
    Server-->>Client: connected_success
    Client->>Server: task_start (JSON)
    Server-->>Client: task_started

    loop 实时推流
        Client->>Server: PCM Audio (binary)
        Server-->>Client: si_segment_start
        Server-->>Client: si_token
        opt 启用译文 TTS
            Server-->>Client: si_tts_start
            Server-->>Client: si_tts_file
            Server-->>Client: si_tts_end
        end
        Server-->>Client: si_segment_done
    end

    Client->>Server: task_finish (JSON)
    Server-->>Client: task_finished
    Server-->>Client: Close Connection
```

***

## 客户端事件

### 1. task\_start - 开始任务

客户端收到 `connected_success` 后发送 `task_start` 事件配置参数。服务端返回 `task_started` 后方可开始推送二进制音频帧。

**请求参数**

| 参数名                       | 类型     | 必填 | 说明                                      |
| :------------------------ | :----- | :- | :-------------------------------------- |
| **event**                 | string | 是  | 固定值：`task_start`                        |
| **model**                 | string | 是  | 模型名称，目前使用 `sensenova-livetranslate-1.0` |
| **audio\_setting**        | object | 是  | 音频参数设置                                  |
| **vad\_setting**          | object | 否  | VAD（语音活动检测）设置                           |
| **voice\_input\_setting** | object | 否  | 源语言与目标语言设置                              |
| **tts\_setting**          | object | 否  | 译文 TTS 输出设置                             |

#### audio\_setting

| 参数名              | 类型     | 必填 | 说明                 |
| :--------------- | :----- | :- | :----------------- |
| **sample\_rate** | int    | 是  | 采样率，目前仅支持 `16000`  |
| **channel**      | int    | 是  | 声道数，目前仅支持 `1`（单声道） |
| **format**       | string | 是  | 音频格式，目前仅支持 `pcm`   |

#### vad\_setting（可选）

| 参数名                         | 类型     | 说明                   | 默认值   |
| :-------------------------- | :----- | :------------------- | :---- |
| **threshold**               | number | VAD 阈值，有效范围 `(0, 1]` | 0.45  |
| **silence\_duration**       | int    | 静音断句时长，单位 ms         | 500   |
| **min\_speech\_duration**   | int    | 最短语音时长，单位 ms         | 500   |
| **soft\_max\_duration**     | int    | 分句软上限，单位 ms          | 10000 |
| **hard\_max\_duration**     | int    | 分句硬上限，单位 ms          | 20000 |
| **soft\_silence\_duration** | int    | 达到软上限后的静音断句时长，单位 ms  | 250   |

#### voice\_input\_setting

| 参数名                  | 类型        | 必填 | 说明                                   |
| :------------------- | :-------- | :- | :----------------------------------- |
| **language**         | string    | 否  | 输入语言，例如 `Chinese`、`English`          |
| **target\_language** | string    | 否  | 目标语言，例如 `English`、`Chinese`；为空时不生成译文 |
| **hot\_words**       | string\[] | 否  | 热词列表                                 |
| **abbreviations**    | object    | 否  | 缩写或专有词映射，键为原词，值为期望内容                 |

当前可用的输入语言与目标语言包括：

* `Chinese`
* `English`
* `Japanese`
* `Korean`
* `Cantonese`
* `German`
* `French`
* `Spanish`
* `Portuguese`
* `Italian`
* `Russian`

#### tts\_setting

| 字段            | 类型      | 默认值   | 说明                           |
| ------------- | ------- | ----- | ---------------------------- |
| **enable**    | boolean | false | 是否生成译文 TTS 音频                |
| **mode**      | string  | 空     | TTS 模式；可选 `clone` 或 `preset` |
| **voice\_id** | string  | 空     | TTS 音色 ID；启用 TTS 时应传入可用音色    |

**请求示例**

```json theme={null}
{
  "event": "task_start",
  "model": "sensenova-livetranslate-1.0",
  "audio_setting": {
    "sample_rate": 16000,
    "format": "pcm",
    "channel": 1
  },
  "voice_input_setting": {
    "language": "Chinese",
    "target_language": "English"
  },
  "tts_setting": {
    "enable": false
  }
}
```

任务启动成功后，服务端返回 `task_started`。

### 2. 发送音频

音频通过 WebSocket 二进制消息发送，不要放入 JSON，也不要进行 Base64 编码。

音频必须符合以下要求：

* PCM signed 16-bit
* 小端序（little-endian）
* 采样率 16000Hz
* 单声道

建议每次发送约 100ms 音频，即 3200 字节。

### 3. task\_finish

音频发送完成后，客户端发送：

```json theme={null}
{
  "event": "task_finish"
}
```

发送 `task_finish` 后，不要继续发送音频或其他业务事件。服务端会继续处理已经接收的剩余音频，随后返回 `task_finished`。

***

## 服务端事件

| 事件                  | 说明                       |
| ------------------- | ------------------------ |
| `connected_success` | 连接建立成功                   |
| `task_started`      | 任务已开始，客户端收到后才能发送音频       |
| `si_segment_start`  | 同传分句开始                   |
| `si_token`          | 同传增量输出                   |
| `si_segment_done`   | 同传分句完成，包含原文与译文           |
| `si_segment_error`  | 同传分句处理失败                 |
| `si_tts_start`      | 译文 TTS 开始                |
| `si_tts_file`       | 译文 TTS 文件，包含 Base64 音频数据 |
| `si_tts_end`        | 译文 TTS 结束                |
| `heartbeat`         | 服务端心跳事件                  |
| `task_finished`     | 任务完成                     |
| `task_failed`       | 任务失败，包含错误码与错误信息          |

### 通用消息格式

除 WebSocket Ping 控制帧外，服务端业务事件均为 JSON 文本消息：

```json theme={null}
{
  "event": "connected_success",
  "session_id": "session-id-xxx",
  "base_resp": {
    "status_code": 0,
    "status_msg": "success"
  }
}
```

| 字段                      | 类型     | 说明                    |
| ----------------------- | ------ | --------------------- |
| `event`                 | string | 事件类型                  |
| `session_id`            | string | 当前 WebSocket 任务的会话 ID |
| `data`                  | object | 事件数据。没有数据时不返回该字段      |
| `base_resp.status_code` | int    | 状态码，`0` 表示成功          |
| `base_resp.status_msg`  | string | 状态详情                  |

***

## 错误处理

连接建立后的错误通过 `task_failed.base_resp` 返回。客户端应同时记录 `status_code`、`status_msg` 和 `session_id`。

常见错误包括：

* 首条消息不是 `task_start`
* 建立连接后长时间未发送 `task_start`
* 重复发送 `task_start`
* 在 `task_started` 前发送音频
* 在 `task_finish` 后继续发送音频
* 使用文本帧发送音频
* 使用二进制帧发送 JSON
* 输入音频不是 16000Hz、16-bit、单声道 PCM
* 模型不存在或不支持同声传译
* 余额不足或并发受限

***

## 调用示例

### Python

依赖：

```bash theme={null}
pip install websockets
```

示例代码：

```python theme={null}
import asyncio
import json
import os

import websockets

WS_URL = "wss://api.senseaudio.cn/ws/v1/audio/simulat-interpreting"
API_KEY = os.environ["SENSEAUDIO_API_KEY"]
AUDIO_FILE = "input_16k_s16le_mono.pcm"


async def wait_for_event(ws, expected):
    while True:
        message = json.loads(await ws.recv())
        if message.get("event") == "task_failed":
            raise RuntimeError((message.get("base_resp") or {}).get("status_msg"))
        if message.get("event") == expected:
            return message


async def receive_events(ws):
    async for raw in ws:
        message = json.loads(raw)
        event = message.get("event")
        data = message.get("data") or {}

        if event == "si_segment_done":
            print(f"原文: {data.get('original_text', '')}")
            print(f"译文: {data.get('text', '')}")
        elif event == "task_failed":
            raise RuntimeError((message.get("base_resp") or {}).get("status_msg"))
        elif event == "task_finished":
            return


async def main():
    headers = {"Authorization": f"Bearer {API_KEY}"}

    async with websockets.connect(WS_URL, additional_headers=headers) as ws:
        await wait_for_event(ws, "connected_success")

        await ws.send(json.dumps({
            "event": "task_start",
            "model": "sensenova-livetranslate-1.0",
            "audio_setting": {
                "sample_rate": 16000,
                "format": "pcm",
                "channel": 1,
            },
            "voice_input_setting": {
                "language": "Chinese",
                "target_language": "English",
            },
            "tts_setting": {"enable": False},
        }))
        await wait_for_event(ws, "task_started")

        receive_task = asyncio.create_task(receive_events(ws))

        with open(AUDIO_FILE, "rb") as audio:
            while chunk := audio.read(3200):
                await ws.send(chunk)
                await asyncio.sleep(0.1)

        await ws.send(json.dumps({"event": "task_finish"}))
        await receive_task


asyncio.run(main())
```

### Node.js

依赖：

```bash theme={null}
npm install ws
```

示例代码：

```javascript theme={null}
const fs = require('fs')
const WebSocket = require('ws')

const WS_URL = 'wss://api.senseaudio.cn/ws/v1/audio/simulat-interpreting'
const API_KEY = process.env.SENSEAUDIO_API_KEY
const AUDIO_FILE = 'input_16k_s16le_mono.pcm'

const ws = new WebSocket(WS_URL, {
  headers: {
    Authorization: `Bearer ${API_KEY}`,
  },
})

let audioStream = null

ws.on('message', (raw, isBinary) => {
  if (isBinary) return

  const message = JSON.parse(raw.toString())
  const event = message.event
  const data = message.data || {}

  switch (event) {
    case 'connected_success':
      ws.send(JSON.stringify({
        event: 'task_start',
        model: 'sensenova-livetranslate-1.0',
        audio_setting: {
          sample_rate: 16000,
          format: 'pcm',
          channel: 1,
        },
        voice_input_setting: {
          language: 'Chinese',
          target_language: 'English',
        },
        tts_setting: { enable: false },
      }))
      break

    case 'task_started':
      audioStream = fs.createReadStream(AUDIO_FILE, { highWaterMark: 3200 })
      audioStream.on('data', (chunk) => {
        audioStream.pause()
        ws.send(chunk, { binary: true }, () => {
          setTimeout(() => audioStream.resume(), 100)
        })
      })
      audioStream.on('end', () => {
        ws.send(JSON.stringify({ event: 'task_finish' }))
      })
      break

    case 'si_segment_done':
      console.log('原文:', data.original_text || '')
      console.log('译文:', data.text || '')
      break

    case 'task_failed':
      console.error('任务失败:', message.base_resp?.status_msg)
      break
  }
})
```

***

## 计费说明

请参考 [计费规则](/guides/account/billing)。

***

## 相关资源

<CardGroup cols={2}>
  <Card title="同声传译介绍" icon="book-open" href="/guides/simultaneous-interpretation/overview">
    查看同声传译能力概览、使用场景与参数建议。
  </Card>

  <Card title="模型列表" icon="list" href="/guides/account/model-list">
    查看同声传译模型与其他可调用模型。
  </Card>
</CardGroup>
