test/docs/realtime_meeting_websocket_...

7.5 KiB
Raw Blame History

实时会议 WebSocket 对接文档

本文档用于客户侧接入实时会议识别服务,包含接口地址、消息格式、返回示例和重连约定。

1. 接口地址

  • 推荐地址:/ws/v1/asr
  • 显式地址:/ws/v1/asr/qwen

说明:

  • 当前协议为 JSON 控制消息 + 音频二进制流。
  • 返回结构按实时会议场景组织,核心消息类型为:voice_id、start、sentences、end、error。

2. 交互流程

客户端调用顺序:

  1. 建立 WebSocket 连接
  2. 发送 start 文本消息
  3. 持续发送音频二进制数据
  4. 持续接收服务端返回的 voice_id、start、sentences
  5. 识别结束时发送 stop
  6. 接收最终 end

3. start 请求

3.1 请求示例

{
  "type": "start",
  "payload": {
    "format": "pcm",
    "sample_rate": 16000,
    "session_id": "meeting-abc-123",
    "language": null,
    "context": "",
    "enable_inverse_text_normalization": true,
    "silence_duration_ms": 800,
    "min_partial_sec": 0.3,
    "pre_roll_ms": 240,
    "max_sentence_count": 8,
    "partial_holdback_chars": 2,
    "unfixed_token_num": 3,
    "enable_native_partial_stream": true,
    "enable_speaker": true,
    "match_speaker_registry": true,
    "speaker_threshold": 0.6,
    "enable_realtime_vad_split": true,
    "enable_realtime_longform": false,
    "force_stable_segment_sec": 6,
    "force_stable_min_chars": 24,
    "max_segment_sec": 12
  }
}

3.2 主要参数说明

字段 类型 默认值 说明
format string pcm 建议传 pcm
sample_rate number 16000 音频采样率
session_id string 可不传 会话标识;断线重连时传同一个值可恢复同一会议会话
language string/null null 留空表示自动识别
context string "" 业务上下文提示,如会议主题、术语
enable_inverse_text_normalization boolean true 是否启用数字归一化
silence_duration_ms number 800 静音多久触发收段
min_partial_sec number 后端默认 最短 partial 窗口
pre_roll_ms number 240 句首预读时长
max_sentence_count number 8 单段最多句数
partial_holdback_chars number 后端默认 partial 尾部保留字数,减少尾字抖动
unfixed_token_num number 后端默认 native partial 模式下回滚 token 数
enable_native_partial_stream boolean false 是否启用原生流式 partial
enable_speaker boolean true 是否开启说话人分离
match_speaker_registry boolean false 是否匹配已注册声纹库
speaker_threshold number/null null 本次声纹匹配阈值
enable_realtime_vad_split boolean false 是否启用实时 VAD 拆段
enable_realtime_longform boolean false 是否启用长段重转写
force_stable_segment_sec number 后端默认 超时后软提交阈值
force_stable_min_chars number 后端默认 软提交最少字数
max_segment_sec number 后端默认 单段最长秒数

说明:

  • enable_speaker=true 时,服务端会先返回文本,再异步补充 speaker 归属。
  • match_speaker_registry=true 时,若匹配到声纹库,会返回实名 speaker 信息。

4. 音频发送

start 成功后,客户端持续发送音频二进制帧。

推荐格式:

  • 单声道 PCM
  • 16k 采样率
  • 小块连续发送

示例:

ws.send(pcmChunkArrayBuffer);

5. stop 请求

{
  "type": "stop"
}

6. 服务端返回

6.1 voice_id

连接建立并收到 start 后,服务端先返回:

{
  "type": "voice_id",
  "voice_id": "41ff1926",
  "session_id": "meeting-abc-123"
}

说明:

  • voice_id 为本次实时识别标识。
  • session_id 为本次会话标识;若未传,服务端会返回自动生成值。

6.2 start

服务端确认开始识别:

{
  "type": "start",
  "session_id": "meeting-abc-123"
}

6.3 sentences

识别过程中会持续返回 sentences。

重要说明:

  • sentence_type=0 / slice_type=1 表示实时 partial,仅用于实时展示。
  • sentence_type=1 / slice_type=2 表示该段最终定稿,建议作为最终入库依据。
  • 说话人可能异步补写,不保证和首个 final 同时返回。

partial 返回示例

{
  "type": "sentences",
  "code": 0,
  "voice_id": "41ff1926",
  "final": 0,
  "result": {
    "slice_type": 1,
    "index": 3,
    "voice_text_str": "今天这个会议主要讨论预算。"
  },
  "sentences": [
    {
      "sentence_id": 3,
      "sentence_type": 0,
      "speaker_id": -1,
      "start_time": 12000,
      "end_time": 15600,
      "sentence": "今天这个会议主要讨论预算。"
    }
  ]
}

final 返回示例

{
  "type": "sentences",
  "code": 0,
  "voice_id": "41ff1926",
  "final": 0,
  "result": {
    "slice_type": 2,
    "index": 3,
    "voice_text_str": "今天这个会议主要讨论预算。"
  },
  "sentences": [
    {
      "sentence_id": 3,
      "sentence_type": 1,
      "speaker_id": -1,
      "start_time": 12000,
      "end_time": 15880,
      "sentence": "今天这个会议主要讨论预算。",
      "speaker_name": "",
      "user_id": null
    }
  ]
}

speaker 回写示例

如果 speaker 后续识别完成,服务端会再次返回相同 sentence_id 的消息,只更新 speaker 信息:

{
  "type": "sentences",
  "code": 0,
  "voice_id": "41ff1926",
  "final": 0,
  "result": {
    "slice_type": 2,
    "index": 3,
    "voice_text_str": "今天这个会议主要讨论预算。"
  },
  "sentences": [
    {
      "sentence_id": 3,
      "sentence_type": 1,
      "speaker_id": 19,
      "start_time": 12000,
      "end_time": 15880,
      "sentence": "今天这个会议主要讨论预算。",
      "speaker_name": "Alan Paine",
      "user_id": "3"
    }
  ]
}

接入建议:

  • 客户端按 sentence_id 更新句子,不要把 speaker 回写当成新句子追加。
  • speaker_id=-1 代表当前 speaker 暂未确认,不代表识别失败。

6.4 end

识别结束后返回:

{
  "type": "end",
  "code": 0,
  "message": "",
  "voice_id": "41ff1926",
  "session_id": "meeting-abc-123",
  "final": 1,
  "result": {
    "slice_type": 2,
    "index": 5,
    "voice_text_str": "完整会议文本"
  },
  "sentences": []
}

6.5 error

异常时返回:

{
  "type": "error",
  "code": "INVALID_STATE",
  "message": "请先发送 start",
  "voice_id": "41ff1926"
}

7. 断线重连

支持基于 session_id 的会话恢复。

约定如下:

  1. 首次连接时,客户端可以自行生成 session_id 并放入 start.payload.session_id
  2. 若客户端未传,服务端会返回自动生成的 session_id
  3. 断线重连时,客户端使用同一个 session_id 再次发送 start
  4. 若服务端会话仍在保活期内,则恢复同一会议上下文

建议:

  • 客户端在会议生命周期内保持 session_id 稳定
  • 网络抖动或页面刷新后,优先使用上一次会话的 session_id 重连

8. 客户端接入建议

  • 实时展示可消费 sentence_type=0 的 partial
  • 业务落库建议只以 sentence_type=1 的 final 为准
  • 若后续收到相同 sentence_id 的 final 更新,应执行更新而不是新增
  • 若需要最佳实时体验,建议开启 enable_native_partial_stream=true
  • 若希望 speaker 识别更完整,建议开启 enable_speaker=true