CTICloud JS SDK 实时语音流开发指南

1 概述

1.1 功能介绍

CTICloud JS SDK 提供实时语音流(Real-time Audio Stream)能力,可在 WebRTC 通话过程中实时获取本地音频(座席麦克风)和远端音频(通常为客户),并通过 WebSocket 与业务方自建 Processor 服务建立连接,实现实时音频分析与处理。

开发者可基于该能力快速构建实时语音识别(ASR)、AI Agent、实时质检、情绪分析、座席辅助、声音美化、AI 变声、语音降噪、实时翻译等业务场景,而无需关注浏览器媒体采集、远端媒体接收、WebRTC 音频注入、连接管理及协议交互等底层实现。

整个语音流处理过程中:

  • CTICloud JS SDK 负责座席麦克风采集、远端媒体接收、WebSocket 会话管理、协议交互及音频注入。

  • Processor 服务 负责接收指定来源的实时音频,并根据业务需求进行分析或处理;对于本地音频 sendrecv Processor,可将处理后的音频实时返回 SDK。


1.2 功能特性

媒体能力

  • 支持 WebRTC 座席麦克风实时采集

  • 支持远端音频实时获取

  • 支持实时 PCM 音频流传输

  • 支持处理后音频实时回传

  • 支持音频格式动态协商

网络能力

  • 支持 WebSocket 双向通信

  • 支持 TLS 安全传输(wss://

  • 支持连接异常自动重连

  • 支持多通话并发连接

SDK 能力

  • 支持多个语音处理器(Processor)同时运行

  • 支持按音频来源选择本地音频或远端音频

  • 支持运行时动态更新配置

  • 支持完整的会话生命周期管理

  • 支持丰富的事件通知机制


1.3 典型应用场景

场景SourceMode是否回传音频说明
座席语音识别(ASR)localsendonly将座席语音实时推送至语音识别服务
客户语音识别(ASR)remotesendonly将客户语音实时推送至语音识别服务
实时质检local / remotesendonly对指定一侧的音频进行实时分析
客户情绪分析remotesendonly对客户语音进行情绪识别和意图分析
座席辅助remotesendonly获取客户语音,为座席提供实时提示
AI Agentlocal / remotesendonly获取指定一侧语音进行实时推理
声音美化localsendrecv对座席声音进行实时美化
AI 变声localsendrecv使用处理后的声音替换座席麦克风声音
AI 降噪localsendrecv对本地音频(座席麦克风)进行实时降噪
实时翻译localsendrecv将翻译后的语音发送给通话对端

说明当前版本仅支持本地音频使用 sendrecv。远端音频仅支持 sendonly,不支持通过 Processor 回传并替换远端音频。


1.4 系统架构

实时语音流整体架构如下图所示。

flowchart LR

Local["本地音频(座席麦克风)"]
Remote["远端音频(通常为客户)"]
SDK["CTICloud JS SDK"]
Processor["Processor 服务"]
Media["CTICloud 媒体服务器"]
Peer["通话对端"]

Local --> SDK
Media -->|WebRTC 远端音频| SDK
SDK -->|WebSocket:local/remote 音频| Processor
Processor -->|处理后本地音频(仅 local + sendrecv)| SDK
SDK -->|WebRTC 本地音频| Media
Media --> Peer

各组件职责如下:

组件职责
CTICloud JS SDK采集本地音频、接收远端音频、建立 WebSocket 会话、分发指定来源的音频流,并在本地音频 sendrecv 模式下注入处理后的音频
Processor 服务接收 SDK 推送的本地音频或远端音频,完成语音识别、质检、声音处理或 AI 推理,并根据配置决定是否返回处理后的本地音频
CTICloud 媒体服务器负责 WebRTC 媒体传输及与通话对端建立音频连接

1.5 工作流程

在通话过程中,SDK 会自动建立语音流会话,并与Processor 服务进行实时音频交互。

sequenceDiagram

participant SDK as CTICloud JS SDK
participant Service as Processor 服务

SDK->>Service: 建立 WebSocket 连接
SDK->>Service: 建立语音流会话

loop 通话期间

SDK->>Service: 推送指定来源音频(local/remote)

opt Mode = sendrecv

Service->>SDK: 返回处理后的本地音频

end

end

SDK->>Service: 结束语音流会话

语音流处理过程如下:

  1. SDK 在通话建立后自动创建语音流会话。

  2. SDK 根据 Processor 的 source 配置,获取本地音频或远端音频。

  3. SDK 将指定来源的音频实时发送至Processor 服务。

  4. Processor 服务完成语音分析或音频处理。

  5. 当 source 为 local 且 mode 为 sendrecv 时,Processor 服务将处理后的本地音频实时返回 SDK。

  6. SDK 将处理后的音频替换座席麦克风输入,并通过 WebRTC 发送给通话对端。

  7. 通话结束后,SDK 自动关闭语音流会话。

说明SDK 支持同时配置多个语音处理器(Processor)。每个 Processor 通过 source 选择 local 或 remote 音频。可同时配置多个 sendonly Processor,但同一时间最多只能配置一个 sendrecv Processor,且该 Processor 的 source 必须为 local


1.6 适用范围

本文档适用于以下产品及环境:

项目说明
SDKCTICloud JS SDK
座席类型WebRTC 座席
浏览器Chrome、Edge、Electron 等支持 WebRTC 的浏览器
语音处理服务业务方自建 WebSocket 服务

1.7 名词说明

名词说明
SDKCTICloud JS SDK。
座席端集成 CTICloud JS SDK 的浏览器页面,也是 local / remote 的观察视角。
Processor一个独立的语音处理服务实例,通过 WebSocket 与 SDK 建立会话,并通过 source 和 mode 指定音频来源及处理方式。
Processor 服务业务方自行开发并部署的 Processor 服务。
本地音频SDK 从当前座席浏览器麦克风采集的音频,对应 source: "local"
远端音频SDK 从 WebRTC 远端媒体轨道接收的通话对端音频,通常为客户,对应 source: "remote"
上行音频SDK 发送给 Processor 的实时音频,来源由 source 决定。
下行音频Processor 返回给 SDK 的处理后本地音频,仅适用于 source: "local" 且 mode: "sendrecv"
SessionSDK 与Processor 服务之间建立的一次语音流会话。
PCM原始音频数据,不包含 WAV、MP3 等文件头。

1.8 前置条件

开始接入前,请确认已满足以下条件:

  • 已开通 CTICloud WebRTC 能力。

  • 已完成 CTICloud JS SDK 集成。

  • 页面通过 HTTPS 访问,并已获取浏览器麦克风权限。

  • 已部署可访问的 WebSocket 服务。

  • WebSocket 服务支持 TLS(wss://)。

  • WebSocket 服务支持二进制消息处理。


2 快速开始

本章节介绍如何快速完成实时语音流能力接入。

完成本章节后,CTICloud JS SDK 将能够与Processor 服务建立 WebSocket 连接,并开始推送本地音频或远端音频流。

整个接入过程分为以下四个步骤:

  1. 配置 CTICloud JS SDK

  2. 部署语音处理服务

  3. 实现 WebSocket 协议

  4. 发起通话并验证接入


2.1 接入流程

完成实时语音流接入需要以下五个步骤:

步骤说明
步骤一配置 CTICloud JS SDK。
步骤二部署 Processor 服务。
步骤三实现 WebSocket 协议。
步骤四发起 WebRTC 通话。
步骤五验证语音流处理结果。

2.2 配置 SDK

通过 CTILink.setup() 开启实时语音流能力。

CTILink.setup({

    webrtc: true,

    media: {

        audio: {

            processors: [

                {

                    id: "voice-service",

                    source: "local",

                    mode: "sendrecv",

                    transport: {

                        protocol: "websocket",

                        url: "wss://voice.example.com/ws"

                    }

                }

            ]

        }

    }

});

配置完成后,SDK 会在每次 WebRTC 通话建立时自动创建对应的 Processor Session。

说明如未配置 media.audio.processors,SDK 不会建立语音流连接。


2.3 Processor 配置说明

一个 Processor 表示一个独立的语音处理服务。

SDK 支持同时配置多个 Processor。

processors: [

    {
        id: "asr",
        source: "remote",
        mode: "sendonly",
        transport: {
            protocol: "websocket",
            url: "wss://asr.example.com/ws"
        }
    },

    {
        id: "voice",
        source: "local",
        mode: "sendrecv",
        transport: {
            protocol: "websocket",
            url: "wss://voice.example.com/ws"
        }
    }

]

配置规则如下:

配置项说明
可配置多个 Processor
可配置多个 sendonly
可配置多个 sendrecv✘(最多一个)
Processor 独立建立 WebSocket 会话

每个 Processor 根据 source 接收对应的本地音频或远端音频。配置相同 source 的多个 sendonly Processor 会接收到同一份来源音频。

source: "local" 且 mode: "sendrecv" 的 Processor 返回的处理后音频将作为最终发送给通话对端的本地音频。


2.4 部署语音处理服务

业务方需部署符合 WebSocket 协议规范的语音处理服务。

服务需满足以下要求:

  • 支持 WebSocket(wss://

  • 支持二进制消息

  • 支持处理会话控制消息

  • 支持实时接收 PCM 音频

  • 在 sendrecv 模式下支持实时返回处理后的 PCM 音频

WebSocket 协议规范请参见《WebSocket 协议》章节。


2.5 发起通话

完成 SDK 配置后,正常登录 CTICloud,并发起 WebRTC 通话。

SDK 将自动完成以下操作:

  1. 建立 WebSocket 连接

  2. 创建语音流会话

  3. 根据 source 推送本地音频(座席麦克风)或远端音频(通常为客户)

  4. 在 local + sendrecv 模式下接收处理后的音频

  5. 通话结束后关闭语音流会话

整个过程无需业务代码参与。


2.6 验证接入

接入成功后,可通过以下方式验证:

浏览器控制台

确认 SDK 已成功建立 WebSocket 连接。

网络请求

浏览器开发者工具中应能够看到与语音处理服务建立的 WebSocket 长连接。

服务端日志

语音处理服务应能够收到:

  • 会话建立请求

  • 持续的音频数据

  • 通话结束通知

通话验证

对于:

  • sendonly 模式,可验证服务端是否持续收到 source 指定的音频。

  • sendrecv 模式,可验证通话对端是否能够听到处理后的声音。


3 SDK API

本章节介绍 CTICloud JS SDK 提供的实时语音流相关接口,包括初始化配置、Processor 配置及事件监听。


3.1 CTILink.setup()

通过 CTILink.setup() 初始化 CTICloud JS SDK,并开启实时语音流能力。

示例

CTILink.setup({

    webrtc: true,

    media: {

        audio: {

            processors: [

                {

                    id: "voice",

                    source: "local",

                    mode: "sendrecv",

                    transport: {

                        protocol: "websocket",

                        url: "wss://voice.example.com/ws"

                    }

                }

            ]

        }

    }

});

3.2 media.audio.processors

processors 用于配置一个或多个语音处理器(Processor)。

SDK 为每个 Processor 建立独立的 WebSocket 连接,并自动管理其生命周期。

示例

media: {

    audio: {

        processors: [

            {

                id: "asr",

                source: "remote",

                mode: "sendonly",

                transport: {

                    protocol: "websocket",

                    url: "wss://asr.example.com/ws"

                }

            },

            {

                id: "voice",

                source: "local",

                mode: "sendrecv",

                transport: {

                    protocol: "websocket",

                    url: "wss://voice.example.com/ws"

                }

            }

        ]

    }

}

Processor 配置项

参数类型必填默认值说明
idString-Processor 唯一标识,同一 SDK 实例内必须唯一。
sourceStringlocal音频来源,可选值为 localremote
modeStringsendonlyProcessor 工作模式。
transportObject-Processor 连接配置。

source

定义 Processor 接收的音频来源。local 和 remote 均以 CTICloud JS SDK 所在的座席浏览器为观察视角。

中文名称说明
local本地音频SDK 从当前浏览器麦克风采集的音频,即座席语音。
remote远端音频SDK 从 WebRTC 远端媒体轨道接收的音频,即通话对端语音,通常为客户。

限制remote 当前仅支持 sendonly。如配置 source: "remote" 与 mode: "sendrecv",SDK 应判定为无效配置并触发 processorError

mode

定义 Processor 的工作模式。

参数说明
sendonlySDK 将指定来源的音频发送给 Processor,不接收处理后的音频。适用于 ASR、实时质检、情绪分析、AI Agent 等场景。
sendrecvSDK 将本地音频发送给 Processor,同时接收处理后的音频,并替换座席麦克风输入。仅支持 source: "local"

说明一个 SDK 实例可同时配置多个 sendonly Processor,但最多只能配置一个 sendrecv Processor,且该 Processor 的 source 必须为 local


transport

定义 SDK 与 Processor 的连接方式。

目前仅支持 WebSocket。

示例

transport: {

    protocol: "websocket",

    url: "wss://voice.example.com/ws"

}

transport 配置项

参数类型必填默认值说明
protocolStringwebsocket传输协议,目前仅支持 websocket
urlString-Processor WebSocket 地址,仅支持 wss://

transport 鉴权

Processor WebSocket 服务由客户提供,SDK 不限制鉴权方式,推荐采用以下方式:

方式说明
Query TokenURL 携带短期有效 Token。
URL 签名时间戳 + 随机数 + 签名。
API 网关统一鉴权、限流及访问控制。
IP 白名单控制访问来源。

建议 Token 使用短有效期,并在 SessionStart 中再次校验企业及会话信息。


3.3 Processor 生命周期

SDK 自动管理 Processor 生命周期。

stateDiagram-v2

[*] --> NotCreated

NotCreated --> Connecting : 通话建立

Connecting --> Ready : Session Ready

Ready --> Streaming : 开始传输音频

Streaming --> Closed : 通话结束

Closed --> [*]

开发者无需主动创建或关闭 Processor。

SDK 会在以下时机自动完成生命周期管理:

  • 通话建立时创建 Processor。

  • 建立 WebSocket 连接。

  • 创建 Processor Session。

  • 通话结束后自动关闭 Processor。


3.4 注册事件

CTICloud JS SDK 通过 CTILink.event() 注册事件回调。

示例

CTILink.event("processorReady", handleProcessorReady);

CTILink.event("processorError", handleProcessorError);

CTILink.event("processorClosed", handleProcessorClosed);

3.5 Processor 事件

SDK 仅对外提供业务需要关注的事件。

processorReady

Processor Session 创建成功。

收到该事件后,表示 Processor 已开始正常处理语音流。

回调参数

字段类型说明
processorIdStringProcessor 唯一标识。
sessionIdStringProcessor Session ID。
uniqueIdString通话唯一标识。

processorError

Processor 运行过程中发生异常。

回调参数

字段类型说明
processorIdStringProcessor 唯一标识。
sessionIdStringProcessor Session ID。
uniqueIdString通话唯一标识。
codeNumber错误码。
messageString错误描述。

processorClosed

Processor Session 已关闭。

以下情况会触发该事件:

  • 通话结束;

  • SDK 主动关闭 Processor;

  • Processor 主动结束 Session。

回调参数

字段类型说明
processorIdStringProcessor 唯一标识。
sessionIdStringProcessor Session ID。
uniqueIdString通话唯一标识。

3.6 配置规则

Processor 配置需满足以下规则。

规则说明
Processor ID 唯一
source 支持 localremote
支持多个 sendonly Processor
最多一个 sendrecv Processor✔,且仅支持 source: "local"
每个 Processor 建立独立 WebSocket 连接
SDK 自动管理 Processor 生命周期
SDK 自动完成异常重连

3.7 资源消耗

启用 Processor 后,CTICloud JS SDK 会复制一份指定来源的 PCM 数据,并通过独立 WebSocket 连接发送至对应的 Processor。

每增加一个 Processor,将增加一条独立的 WebSocket 音频流。

网络带宽

默认音频格式:

参数
Sample Rate16000 Hz
Channels1
Sample Bits16 bit
Encodingpcm_s16le

单路原始 PCM 数据码率约为 256 kbps(约 32 KB/s)

考虑 WebSocket、TLS 及网络协议开销后,单路音频流的实际带宽约为 280~320 kbps(35~40 KB/s)

Processor 配置浏览器上行带宽浏览器下行带宽双向合计
source: "local" + sendonly约 280~320 kbps极低约 300 kbps
source: "remote" + sendonly约 280~320 kbps极低约 300 kbps
source: "local" + sendrecv约 280~320 kbps约 280~320 kbps约 600 kbps

如同时配置一个local的 sendonly Processor 和一个remote的 sendonly Processor,浏览器到 Processor 服务的总上行带宽约为 600 kbps

容量估算

以下数据按每个座席配置单个 Processor 估算:

在线座席单路 sendonly单路 sendrecv
100约 30 Mbps约 60 Mbps
500约 150 Mbps约 300 Mbps
1000约 300 Mbps约 600 Mbps

若每个座席同时推送 local 和 remote 两路 sendonly 音频,上行带宽约为单路 sendonly 的两倍。

以上数据仅包含浏览器与 Processor 之间的 WebSocket 音频流,不包含 WebRTC RTP 媒体流及业务信令。

CPU 消耗

浏览器仅负责音频数据复制、WebSocket 收发及本地音频 sendrecv 模式下的音频注入,不进行 AI 推理,因此 CPU 增量通常较低。

实际资源消耗取决于 Processor 数量、音频来源数量、浏览器性能和网络状况。

推荐配置

  • 支持配置多个 source: "local" 或 source: "remote" 的 sendonly Processor。

  • 同一 SDK 实例最多配置一个 sendrecv Processor,且仅支持本地音频。

  • 推荐单座席 Processor 总数不超过 5 个。

  • 如多个业务需要消费同一来源音频,建议优先由服务端进行分发,减少浏览器侧重复连接和带宽消耗。

Processor 语音流与 WebRTC 通话媒体流相互独立。启用 Processor 不会改变浏览器与媒体服务器之间的 WebRTC 音频编码码率,只会增加浏览器与 Processor 之间的 WebSocket 音频流。

3.8 最佳实践

建议遵循以下配置方式:

  • 座席或客户侧 ASR、实时质检、情绪分析、AI Agent 使用 sendonly

  • AI 变声、声音美化、语音降噪使用 source: "local" 和 sendrecv

  • 一个 Processor 仅负责一种业务能力,避免多个能力共用同一 Processor。

  • processorReady 表示 Processor 已可以正常处理语音。

  • processorError 用于处理业务异常或记录日志。

  • processorClosed 用于资源释放或业务状态更新。


4 WebSocket 协议

本章节介绍 CTICloud JS SDK 与 Processor 之间的 WebSocket 通信协议。

SDK 为每个 Processor 建立独立的 WebSocket 连接,并通过该连接完成 Processor Session 的创建、音频传输、状态同步及会话关闭。


4.1 协议概述

SDK 为每个 Processor 建立独立的 WebSocket 连接,并创建独立的 Processor Session。

每个 Processor Session 负责一次完整的语音处理过程,包括会话创建、实时音频传输及会话关闭。

消息的数据结构、消息类型及数据模型请参见《5 数据模型》章节。

4.2 消息交互流程

一次完整的 Processor Session 如下图所示。

sequenceDiagram

participant SDK as CTICloud JS SDK
participant Processor

SDK->>Processor: Control(SessionStart)

Processor-->>SDK: Session(Ready)

loop Streaming

SDK->>Processor: Audio(Uplink, source=local/remote)

opt Mode = sendrecv

Processor-->>SDK: Audio(Downlink, source=local)

end

end

SDK->>Processor: Control(SessionEnd)

消息交互过程如下:

  1. SDK 建立 WebSocket 连接。

  2. SDK 发送 Control(SessionStart) 创建 Processor Session。

  3. Processor 返回 Session(Ready)

  4. SDK 开始持续发送 source 指定的本地音频或远端音频。

  5. 当 source 为 local 且 mode 为 sendrecv 时,Processor 持续返回处理后的本地音频。

  6. 通话结束后,SDK 发送 Control(SessionEnd)

  7. SDK 关闭 Processor Session。


4.3 Processor Session 生命周期

Processor Session 生命周期如下图所示。

stateDiagram-v2

[*] --> Disconnected

Disconnected --> Connected : WebSocket Connected

Connected --> Opening : SessionStart

Opening --> Ready : Session Ready

Ready --> Streaming

Streaming --> Closing : SessionEnd

Closing --> Closed

Closed --> [*]

各状态说明如下:

状态说明
Disconnected未建立 WebSocket 连接。
ConnectedWebSocket 已建立。
Opening正在创建 Processor Session。
ReadyProcessor Session 创建成功。
Streaming正在传输实时音频。
Closing正在关闭 Processor Session。
ClosedProcessor Session 已结束。

4.4 WebSocket 连接

SDK 为每个 Processor 建立独立的 WebSocket 连接。

                 WebRTC Call
                      │
      ┌───────────────┼───────────────┐
      │               │               │
      ▼               ▼               ▼
 Processor(ASR)  Processor(QA)  Processor(Voice)
      │               │               │
      ▼               ▼               ▼
 WebSocket #1    WebSocket #2    WebSocket #3

连接管理规则如下:

  • 每个 Processor 建立一个独立的 WebSocket 连接。

  • 每个连接对应一个独立的 Processor Session。

  • 各 Processor Session 相互独立,互不影响。

  • SDK 自动管理所有连接生命周期,开发者无需自行维护连接。


4.5 重连机制

当 WebSocket 连接异常断开时,SDK 将自动重新建立连接,并重新创建 Processor Session。

flowchart LR

A[WebSocket 连接断开]
--> B[重新建立 WebSocket]
--> C[重新创建 Processor Session]
--> D[恢复音频传输]

重连完成后:

  • SDK 将重新发送 Control(SessionStart)

  • Processor 应创建新的 Processor Session。

  • 不应继续使用断开前的 Session 状态。

  • 后续音频数据将在新的 Processor Session 中继续传输。


5 数据模型

本章节定义 WebSocket 协议的数据模型及消息格式。

所有消息均采用统一的消息封装(Message Envelope),SDK 与 Processor 使用一致的消息结构进行通信。


5.1 Message Envelope

所有 WebSocket 消息均采用统一格式。

+------------------------+
| Header Length (4 Bytes)|
+------------------------+
| Header (JSON UTF-8)    |
+------------------------+
| Payload (Binary/JSON)  |
+------------------------+

字段说明:

字段说明
Header LengthHeader 长度,4 字节无符号整数(Big Endian)。
HeaderUTF-8 编码 JSON。
Payload消息体。其数据类型由 Header.type 决定:Control 与 Session 为 JSON,Audio 为 PCM Binary。

SDK 首先读取 Header Length,然后解析 Header,再根据 Header.type 解析对应的 Payload。


5.2 Header

所有消息均包含统一 Header。

Header 数据结构

字段类型必填说明
typeString消息类型。
actionStringControl 消息动作。
eventStringSession 消息事件。
sessionIdStringProcessor Session ID。
directionStringAudio 消息方向。
sourceString音频来源,取值为 local 或 remote,Audio 消息使用。

type

说明
Control生命周期控制消息。
SessionSession 状态消息。
Audio音频数据消息。

5.3 ProcessorSession

ProcessorSession 表示一次 SDK 与 Processor 建立的语音处理会话。

数据结构

字段类型必填说明
sessionIdStringSession 唯一标识。
processorIdStringProcessor ID。
sourceString音频来源,取值为 local 或 remote
modeString处理模式,取值为 sendonly 或 sendrecv
uniqueIdString通话唯一标识。
enterpriseIdString企业 ID。
cnoString座席工号。
customerNumberString客户号码。
callTypeInteger通话类型。
protocolVersionString协议版本。
uplinkFormatAudioFormat上行音频格式。
downlinkFormatAudioFormat下行音频格式。

示例

{
  "sessionId": "7db32cf6-17a6-4f58-8c09-d5d0db0ef871",
  "processorId": "voice",
  "source": "local",
  "mode": "sendrecv",
  "uniqueId": "sip-1-166514362901.12",
  "enterpriseId": "60000001",
  "cno": "8001",
  "customerNumber": "13800138000",
  "callType": 1,
  "protocolVersion": "1.0",
  "uplinkFormat": {
    "sampleRate": 16000,
    "channels": 1,
    "sampleBits": 16,
    "encoding": "pcm_s16le"
  },
  "downlinkFormat": {
    "sampleRate": 16000,
    "channels": 1,
    "sampleBits": 16,
    "encoding": "pcm_s16le"
  }
}

5.4 音频格式声明与确认

描述音频格式。

数据结构

字段类型必填说明
sampleRateInteger采样率(Hz)。
channelsInteger声道数。
sampleBitsInteger采样位数。
encodingString编码格式。

当前支持:

参数
sampleRate16000
channels1
sampleBits16
encodingpcm_s16le

音频格式协商

SDK 在创建 Processor Session 时,通过 SessionStart 携带 uplinkFormat 和(sendrecv 模式下)downlinkFormat

当前版本支持:

  • Encoding:pcm_s16le

  • Sample Rate:16000 Hz

  • Channels:1

  • Sample Bits:16

Processor 支持该格式时返回 Session(Ready);否则返回 Session(Error),错误码 1102 UnsupportedFormat


5.5 Control Message

Control 消息用于管理 Processor Session 生命周期。

SessionStart

Header:

{
  "type": "Control",
  "action": "SessionStart"
}

Payload:

{
  "session": {
    ...
  }
}

Payload 字段:

字段类型必填说明
sessionProcessorSessionSession 信息。

SessionEnd

Header:

{
  "type": "Control",
  "action": "SessionEnd"
}

Payload:

{
  "sessionId": "7db32cf6-17a6-4f58-8c09-d5d0db0ef871"
}

5.6 Session Message

Session 消息用于同步 Session 状态。

Ready

Header:

{
  "type": "Session",
  "event": "Ready"
}

Payload:

{
  "sessionId": "7db32cf6-17a6-4f58-8c09-d5d0db0ef871",
  "result": 1000,
  "description": "Success"
}

Error

Header:

{
  "type": "Session",
  "event": "Error"
}

Payload:

{
  "sessionId": "7db32cf6-17a6-4f58-8c09-d5d0db0ef871",
  "result": 1105,
  "description": "Internal Error"
}

5.7 Audio Message

Audio 消息用于传输实时 PCM 音频。

direction 始终以 SDK 与 Processor 之间的 WebSocket 传输方向为准,与 WebRTC 通话媒体方向无关:

  • Uplink:SDK → Processor;

  • Downlink:Processor → SDK。

Uplink

SDK 根据 Processor 配置中的 source 推送对应音频。

  • source: "local":本地音频(座席麦克风)。

  • source: "remote":远端音频。

Header:

{
  "type": "Audio",
  "direction": "Uplink",
  "source": "local",
  "sessionId": "7db32cf6-17a6-4f58-8c09-d5d0db0ef871"
}

Payload:

PCM Binary

Downlink

仅 source: "local" 且 mode: "sendrecv" 的 Processor 可以发送 Downlink Audio。

Header:

{
  "type": "Audio",
  "direction": "Downlink",
  "source": "local",
  "sessionId": "7db32cf6-17a6-4f58-8c09-d5d0db0ef871"
}

Payload:

PCM Binary

要求:

  • 不包含 WAV Header。

  • 音频格式应与对应来源的 AudioFormat 保持一致。

  • 音频数据应连续发送。

  • 建议实时返回,不缓存整段音频。


音频帧频率与包大小

SDK 默认按约 60 ms 一帧发送 Audio Message。

帧时长PCM 大小
20 ms640 bytes
40 ms1280 bytes
60 ms(默认)1920 bytes
100 ms3200 bytes

Processor 建议保持与 SDK 相同或接近的回包频率。

项目建议
回包周期20~60 ms
回包大小640~1920 bytes
最大建议不超过 100 ms / 3200 bytes

sendrecv 模式下应连续返回 PCM 数据,不建议缓存整段音频后一次发送。

5.8 ErrorCode

Code名称说明
1000Success成功。
1100InvalidRequest请求格式错误。
1101InvalidSessionSession 无效。
1102UnsupportedFormat不支持的音频格式。
1103UnsupportedMode不支持的处理模式。
1104AuthenticationFailed鉴权失败。
1105InternalErrorProcessor 内部异常。

5.9 数据模型关系

classDiagram

class Header {
    type
    action
    event
    sessionId
    direction
    source
}

class ProcessorSession {
    sessionId
    processorId
    source
    mode
    uniqueId
    enterpriseId
    cno
}

class AudioFormat {
    sampleRate
    channels
    sampleBits
    encoding
}

Header --> ProcessorSession
ProcessorSession --> AudioFormat

6 Processor 开发指南

本章节介绍如何开发符合 CTICloud 协议规范的 Processor。

Processor 负责接收 CTICloud JS SDK 推送的本地或远端实时语音流,并根据业务需求完成语音识别、AI 推理、质检、情绪分析或声音处理等能力。


6.1 Processor 架构

一个典型的 Processor 包括以下模块:

flowchart LR

WS["WebSocket Server"]
--> Session["Session Manager"]

Session --> Audio["Audio Pipeline"]

Audio --> Engine["AI / DSP Engine"]

Engine --> Output["Audio Output"]

Output --> WS

各模块职责如下:

模块职责
WebSocket Server建立 WebSocket 连接,收发协议消息。
Session Manager管理 Processor Session 生命周期。
Audio Pipeline接收、缓存及调度音频流。
AI / DSP Engine执行语音识别、声音处理、AI 推理等业务逻辑。
Audio Output将处理后的音频返回 SDK(仅 sendrecv 模式)。

6.2 Processor 生命周期

建议 Processor 按以下流程管理 Session。

stateDiagram-v2

[*] --> Idle

Idle --> Connected : WebSocket Connected

Connected --> Ready : SessionStart

Ready --> Processing : Audio

Processing --> Closing : SessionEnd

Closing --> Idle

生命周期说明:

  1. 建立 WebSocket 连接。

  2. 接收 SessionStart

  3. 创建 Processor Session。

  4. 接收实时音频。

  5. 执行业务处理。

  6. 返回处理后的音频(可选)。

  7. 接收 SessionEnd 后释放资源。


6.3 音频处理流程

Processor 收到音频后,应立即进入处理流程。

flowchart LR

PCM["PCM Audio"]

--> Buffer["Jitter Buffer"]

--> Process["AI / DSP"]

--> Output["PCM Audio"]

--> SDK["CTICloud JS SDK"]

推荐处理流程:

  • 接收 source 指定的 PCM 音频。

  • 根据业务需要进行缓冲或重采样。

  • 调用 AI 或 DSP 引擎处理。

  • sendrecv 模式下实时返回处理后的 PCM 音频。


6.4 sendonly 模式

sendonly 模式仅接收指定来源的音频,不返回处理后的音频。

适用于以下场景:

  • 实时语音识别(ASR)

  • AI Agent

  • 实时质检

  • 情绪分析

  • VAD 检测

Processor 无需发送 Audio Message。


6.5 sendrecv 模式

sendrecv 模式需要返回处理后的本地音频,当前仅支持 source: "local"

适用于以下场景:

  • AI 变声

  • 声音美化

  • 语音降噪

  • 实时翻译

要求:

  • 返回连续 PCM 数据。

  • 音频格式与 Session 协商结果保持一致。

  • 不得返回 WAV Header。

  • 保持实时输出,避免一次返回大段音频。


6.6 Session 管理

建议每个 Processor Session 独立管理。

推荐维护以下信息:

字段说明
sessionIdSession 唯一标识。
uniqueId通话唯一标识。
processorIdProcessor 标识。
source音频来源。
mode处理模式。
createTimeSession 创建时间。
lastAudioTime最近一次收到音频时间。

一个 Session 不应同时处理多个通话。


6.7 性能建议

为保证实时语音体验,建议遵循以下原则。

低延迟处理

  • 收到音频后立即处理。

  • 避免长时间缓存。

  • 尽量采用流式处理。

异步处理

建议将网络收发与 AI 推理解耦。

WebSocket IO
        │
        ▼
 Audio Queue
        │
        ▼
 AI Worker
        │
        ▼
 Output Queue
        │
        ▼
 WebSocket Send

并发处理

每个 Session 独立处理。

避免多个 Session 共用同一处理线程。


6.8 异常处理

建议 Processor 正确处理以下异常:

场景建议处理方式
Session 不存在返回 Session.Error
音频格式错误返回 UnsupportedFormat
AI 引擎异常返回 InternalError
WebSocket 断开立即释放 Session。
长时间无音频自动关闭 Session。

6.9 最佳实践

建议遵循以下实践:

  • 一个 Processor 仅负责一种业务能力。

  • 每个 Session 独立管理资源。

  • 使用无锁队列或 RingBuffer 传递音频。

  • AI 推理与 WebSocket IO 分离。

  • 避免阻塞 WebSocket 收发线程。

  • 返回音频保持连续,避免明显抖动。

  • 通话结束后及时释放 Session 资源。

7 Processor 示例

本章节通过一个 Echo Processor 示例,演示如何实现符合 CTICloud 协议规范的 Processor。

Echo Processor 不对音频进行任何处理,而是将收到的音频原样返回,可用于快速验证 SDK 接入及协议实现是否正确。


7.1 Processor 实现流程

一个典型 Processor 的处理流程如下。

flowchart LR

A[启动 WebSocket 服务]

--> B[等待 SDK 建立连接]

--> C[接收 SessionStart]

--> D[创建 Processor Session]

--> E[接收 Audio]

--> F[处理音频]

--> G[返回 Audio]

--> H[接收 SessionEnd]

--> I[释放资源]

7.2 Processor 生命周期

sequenceDiagram

participant SDK

participant Processor

SDK->>Processor: 建立 WebSocket

SDK->>Processor: Control(SessionStart)

Processor-->>SDK: Session(Ready)

loop Audio Streaming

SDK->>Processor: Audio(Uplink, source=local/remote)

Processor-->>SDK: Audio(Downlink, source=local)

end

SDK->>Processor: Control(SessionEnd)

7.3 Echo Processor

Echo Processor 是最简单的 Processor。

收到音频后立即原样返回。

处理流程如下:

收到 Audio

↓

无需处理

↓

立即发送 Audio

适用于:

  • SDK 联调

  • 网络验证

  • 音频格式验证

  • 延迟测试


7.4 Processor 处理逻辑

Processor 建议按照如下流程实现。

Control

收到:

SessionStart

处理:

  • 创建 Session。

  • 保存 Session 信息。

  • 返回 Session(Ready)

收到:

SessionEnd

处理:

  • 释放 Session。

  • 清理缓存。

  • 关闭 AI Engine。


Audio

收到 Audio 后:

PCM

↓

缓存(可选)

↓

AI/DSP

↓

PCM

↓

返回 SDK

对于:

sendonly

无需返回 Audio。

对于:

sendrecv

应持续返回处理后的 PCM。


7.5 推荐线程模型

建议网络收发与 AI 推理解耦。

flowchart LR

WS["WebSocket IO"]

--> Queue["Audio Queue"]

Queue --> Worker["AI Worker"]

Worker --> Output["Output Queue"]

Output --> Sender["WebSocket Sender"]

各模块职责:

模块职责
WebSocket IO接收协议消息。
Audio Queue音频缓冲。
AI WorkerAI 推理或 DSP 处理。
Output Queue等待发送音频。
WebSocket Sender返回 Audio。

7.6 Session 管理

建议每个 Session 独立维护状态。

推荐维护:

字段说明
sessionIdSession ID
processorIdProcessor ID
uniqueId通话唯一标识
createTime创建时间
lastAudioTime最近收到 Audio 时间

建议:

  • 一个 Session 对应一个通话。

  • 一个 Session 不共享状态。

  • Session 结束立即释放资源。


7.7 性能建议

建议:

  • 使用流式处理。

  • 不缓存整段音频。

  • AI 推理与 WebSocket IO 分离。

  • 使用无锁队列传递音频。

  • 控制内存占用。

  • Session 超时自动释放。

建议端到端处理延迟不超过:

指标建议值
单帧处理时间≤20 ms
Processor 平均处理延迟≤100 ms
最大处理延迟≤300 ms

7.8 联调建议

建议按照以下步骤进行联调。

  1. 完成 SDK 配置。

  2. 启动 Echo Processor。

  3. 建立 WebRTC 通话。

  4. 确认收到 SessionStart

  5. 确认持续收到 Audio。

  6. Echo 返回 Audio。

  7. 通话结束收到 SessionEnd

如果以上步骤均正常,则说明:

  • SDK 配置正确;

  • WebSocket 协议正确;

  • Audio 格式正确;

  • Processor 可以正常工作。


7.9 示例工程

为帮助开发者快速完成 Processor 开发,CTICloud 提供了示例工程。

目前提供以下示例:

示例说明
echo-processor-pythonPython 实现的 Echo Processor,用于快速验证 SDK 接入及 WebSocket 协议。

示例工程地址:

echo-processor-python   (暂未开放,后续发布)

示例工程包含以下能力:

  • WebSocket Server

  • Processor Session 管理

  • SessionStart / SessionEnd 处理

  • Audio Message 接收

  • Echo 音频回传

  • sendrecv 模式实现

  • 日志输出

8 常见问题

8.1 WebSocket 无法建立连接

请检查以下配置:

  • Processor 地址是否正确。

  • 是否使用 wss://

  • HTTPS 页面是否允许建立 WebSocket。

  • WebSocket 服务是否正常启动。

  • 网络、防火墙或代理是否阻止连接。


8.2 收不到 SessionStart

请确认:

  • 已成功发起 WebRTC 通话。

  • 已正确配置 media.audio.processors

  • Processor 已成功建立 WebSocket 连接。


8.3 收不到 Audio

请检查:

  • 浏览器是否已授权麦克风权限。

  • 座席是否正常发送语音。

  • Processor Session 是否已进入 Ready 状态。

  • AudioFormat 是否协商成功。


8.4 sendrecv 模式没有声音

请确认:

  • Processor 已持续返回 Audio Message。

  • 返回音频格式与 Session 协商一致。

  • 返回音频不包含 WAV Header。

  • 返回的是连续 PCM 数据,而不是整段录音。


8.5 Processor 收到异常关闭

Processor Session 可能因以下原因关闭:

  • 通话结束。

  • 浏览器关闭。

  • WebSocket 连接断开。

  • SDK 主动关闭 Processor。

收到 SessionEnd 后,应及时释放 Session 资源。


8.6 Processor 自动重连

当 WebSocket 连接异常断开时,SDK 将自动重新建立连接并创建新的 Processor Session。

Processor 不应继续使用旧 Session,应重新初始化相关资源。


8.7 如何选择 Source

业务需求Source
处理本地音频(座席麦克风)local
处理远端音频remote
同时处理本地与远端两路音频分别配置两个 sendonly Processor,或由服务端对两路音频进行关联处理

当前版本不提供 mixed 音频源。需要本地与远端音频混音时,建议由 Processor 服务根据同一 uniqueId 关联两路 Processor Session,并在服务端完成混音。


8.8 如何选择 Mode

建议根据业务场景选择:

场景SourceMode
座席语音识别(ASR)localsendonly
客户语音识别(ASR)remotesendonly
AI Agentlocal / remotesendonly
实时质检local / remotesendonly
AI 变声localsendrecv
声音美化localsendrecv
语音降噪localsendrecv
实时翻译localsendrecv

8.9 一个通话可以配置几个 Processor

支持同时配置多个 Processor。

限制如下:

  • 支持多个 sendonly Processor。

  • 同一时间最多只能配置一个 sendrecv Processor。

各 Processor 独立建立 WebSocket 连接,互不影响。


8.10 Audio Message 是否支持 WAV

不支持。

Audio Message 仅支持原始 PCM 数据。

请勿发送:

  • WAV

  • MP3

  • AAC

  • Opus

等包含文件头或压缩编码的数据。


8.11 如何降低处理延迟

建议:

  • 使用流式处理。

  • 避免缓存整段音频。

  • AI 推理与 WebSocket IO 分离。

  • 保持连续输出。

  • 单帧处理时间建议不超过 20 ms。

9 诊断与联调

本章节提供 Processor 联调及问题定位建议。

9.1 消息时序

一次正常会话建议按以下顺序完成。

序号消息方向
1WebSocket ConnectedSDK → Processor
2Control(SessionStart)SDK → Processor
3Session(Ready)Processor → SDK
4Audio(Uplink, source=local/remote)SDK → Processor
5Audio(Downlink, source=local,可选)Processor → SDK
6Control(SessionEnd)SDK → Processor

9.2 联调检查项

建议按以下顺序排查:

检查项说明
WebSocket 是否建立检查网络、TLS、鉴权。
SessionStart 是否收到检查 SDK 配置及 Processor 日志。
Session(Ready) 是否返回检查 Session 创建逻辑。
Audio 是否持续接收检查麦克风及 AudioFormat。
Audio 是否持续回传sendrecv 模式检查回包频率及大小。
SessionEnd 是否收到检查资源释放逻辑。

9.3 建议监控指标

指标建议值
WebSocket RTT< 100 ms
Processor 平均处理延迟< 100 ms
单帧处理时间≤ 20 ms
Audio 连续回包无明显间断
Session 创建成功率≥ 99.9%

9.4 建议日志

建议记录以下日志:

  • WebSocket 建立与关闭

  • SessionStart / SessionEnd

  • Session Error

  • Audio 收发统计

  • Processor 异常及堆栈

  • 平均处理耗时