在 WebRTC 轨道与 WebSocket 端点之间流式传输音频和视频。支持从 WebSocket 源引入音频,以及向 WebSocket 消费者发送 WebRTC 音频和视频。视频出网支持为约 1 FPS 的 JPEG 格式。
- 具有用于音频处理的 WebSocket API 的 AI 服务
- 自定义音频处理管道
- 旧版系统桥接
- 服务器端音频生成和消费
- 视频快照和缩略图
- 计算机视觉引入(低 FPS)
通过 WebSocket 从外部源引入音频,以创建用于分发的 WebRTC 轨道。
graph LR
A[外部系统] -->|音频数据| B[WebSocket 端点]
B -->|适配器| C[Realtime SFU]
C -->|新会话| D[WebRTC 轨道]
D -->|WebRTC| E[WebRTC 客户端]
使用场景:
- AI 文本转语音(TTS)生成流式传输到 WebRTC
- 来自后端服务或数据库的音频
- 来自外部系统的实时音频源
关键特性:
- 自动创建新的会话 ID
- 使用
buffer模式进行分块音频传输 - 每个 WebSocket 消息最大 32 KB
通过 WebSocket 将现有 WebRTC 轨道中的音频和视频流式传输到外部系统以进行处理或存储。
graph LR
A[WebRTC 源] -->|WebRTC| B[Realtime SFU 会话]
B -->|适配器| C[WebSocket 端点]
C -->|媒体数据| D[外部系统]
使用场景:
- 实时语音转文本(转录)
- 音频录制和归档
- 实时音频处理管道
- 视频快照和缩略图
- 计算机视觉引入(低 FPS)
关键特性:
- 需要带有轨道的现有会话 ID
- 音频:在生成 PCM 帧时单独发送;每个帧都包含时间戳和序列号
- 视频:以大约 1 FPS 发送单个 JPEG 帧;每个帧都包含时间戳(序列号可能未设置)
- 在短暂断开连接或端点重启后,自动重试相同的 WebSocket 端点,最长可持续 5 秒。请参阅流式传输自动重新连接。
POST /v1/apps/{appId}/adapters/websocket/new{
"tracks": [
{
"location": "local",
"trackName": "string",
"endpoint": "wss://...",
"inputCodec": "pcm",
"mode": "buffer"
}
]
}| 参数 | 类型 | 描述 |
|---|---|---|
location |
string | 必填。必须为 "local" 以便引入音频 |
trackName |
string | 必填。要创建的新 WebRTC 轨道的名称 |
endpoint |
string | 必填。要从中接收音频的 WebSocket URL |
inputCodec |
string | 必填。传入音频的编解码器。目前仅支持 "pcm" |
mode |
string | 必填。本地模式下必须为 "buffer" |
{
"tracks": [
{
"trackName": "string",
"adapterId": "string",
"sessionId": "string", // 自动生成的新会话 ID
"endpoint": "string" // 请求端点的回显
}
]
}{
"tracks": [
{
"location": "remote",
"sessionId": "string",
"trackName": "string",
"endpoint": "wss://...",
"outputCodec": "pcm"
}
]
}| 参数 | 类型 | 描述 |
|---|---|---|
location |
string | 必填。必须为 "remote" 以便将媒体流出 |
sessionId |
string | 必填。包含该轨道的现有会话 ID |
trackName |
string | 必填。要流式传输的现有轨道的名称 |
endpoint |
string | 必填。要将媒体发送到的 WebSocket URL |
outputCodec |
string | 必填。传出媒体的编解码器。音频使用 "pcm",视频使用 "jpeg"(仅限出网) |
{
"tracks": [
{
"trackName": "string",
"adapterId": "string",
"sessionId": "string", // 与请求的 sessionId 相同
"endpoint": "string" // 请求端点的回显
}
]
}POST /v1/apps/{appId}/adapters/websocket/close{
"tracks": [
{
"adapterId": "string"
}
]
}- 编解码器:Opus
- 采样率:48 kHz
- 声道:立体声
媒体使用 Protocol Buffers。音频使用 PCM 负载;视频使用 JPEG 负载:
- 16 位有符号小端(little-endian)PCM
- 48 kHz 采样率
- 立体声(左右交错)
- 视频:JPEG 图像负载(每条消息一帧)
message Packet {
uint32 sequenceNumber = 1; // 仅在 Stream 模式下使用
uint32 timestamp = 2; // 仅在 Stream 模式下使用
bytes payload = 5; // 媒体数据
}引入模式 (buffer):仅使用 payload 字段,包含音频数据分块。
Stream 模式 (egress):
- 对于音频帧:
sequenceNumber:递增的数据包计数器timestamp:用于同步的时间戳payload:单个 PCM 音频帧数据
- 对于视频帧 (JPEG):
timestamp:用于同步的时间戳payload:JPEG 图像数据(每条消息一帧)- 注意:对于视频帧,
sequenceNumber可能未设置
- 支持的 WebRTC 输入编解码器:H264、H265、VP8、VP9
- 通过 WebSocket 输出:大约 1 FPS 的 JPEG 图像
连接到您的 WebSocket 端点:
- WebSocket 升级握手
- 针对
wss://URL 的安全连接 - 媒体流式传输开始
- 二进制消息:分块的 PCM 音频数据
- 最大消息大小:每个 WebSocket 消息 32 KB
- 重要提示:在对音频缓冲区进行分块时,应考虑到序列化开销
- 以小而频繁的分块发送音频,而不是大批量发送
- 二进制消息:带有元数据的单个帧(音频或视频)
- 音频帧包括:
- 时间戳信息
- 序列号
- PCM 音频帧数据
- 视频帧包括:
- 时间戳信息
- JPEG 图像数据
- 注意:对于视频帧,序列号可能未设置
- 从 WebRTC 轨道到达的帧会被单独发送
- 视频帧以大约 1 FPS 的速度发出
- 连接到 WebSocket 端点
- 音频流式传输开始
- 视频流式传输开始(如果已配置)
- 对于 WebRTC 到 WebSocket 的流式传输,在断开连接后短暂重试相同的端点
- 在关闭、出错或自动重新连接窗口耗尽后,连接将关闭
当您使用 WebSocket 适配器的 Stream 模式 (egress)将实时音频或视频从 SFU 发送到您自己的 WebSocket 端点 (WebRTC → WebSocket) 时,SFU 会在端点发生短暂断开连接或重启后自动重新连接。
SFU 会自动重试相同的 WebSocket 端点,最长可持续 5 秒。不需要修改 API。如果端点在重新连接窗口过后仍不可用,适配器将关闭,您的应用程序必须创建一个新的适配器才能恢复流式传输。
当 WebSocket 端点暂时不可用时,自动重新连接会使用实时优先(live-first)缓冲:
- 音频缓冲:SFU 保留一个短暂的、有界的音频帧积压。如果中断持续时间超过积压所能覆盖的范围,旧音频可能会被丢弃,从而使重新连接恢复保持在有界范围内。
- 视频缓冲:SFU 仅保留最新的可用 JPEG 帧。重新连接时,新帧会替换旧帧,因此视频会以接近实时的状态恢复,而不是重放陈旧的帧。
- 递送行为:缓冲减少了短暂中断期间的媒体丢失,但它不是重放机制,不保证无缝或恰好一次(exactly-once)的递送。
自动重新连接仅在配置为 Stream 模式 (egress) 时适用。它仅重试相同的端点,不提供多端点故障转移。
目前处于 Beta 阶段,免费使用。
一旦正式发布(GA),计费将遵循标准的 Cloudflare Realtime 定价,即每 GB 出网流量 0.05 美元。仅从 Cloudflare 流向 WebSocket 端点的流量会产生费用。从 WebSocket 端点引入到 Cloudflare 的流量不收取费用。
使用量会计入您的 1,000 GB Cloudflare Realtime 免费额度中。
- 关闭一个已经关闭的实例将返回成功
- 会话结束时关闭
- 当使用 Stream 模式 (egress) 时,请在 5 秒的流式传输自动重新连接窗口耗尽后,处理适配器关闭。
- 当从 WebSocket 引入到 WebRTC 时,如果连接中断,请在您的 WebSocket 客户端中实现重新连接逻辑。
- 使您的 WebSocket 端点具备重启安全性,以便在短暂重启期间能够接受对相同 URL 的重新连接。
- 将 WebSocket 端点部署在靠近 Cloudflare 边缘的位置
- 使用适当的缓冲区大小
- 监控连接质量
- 对 WebSocket 端点采用身份验证以确保安全
- 在生产环境中使用
wss:// - 实施速率限制
- WebSocket 负载:引入和流式传输支持 PCM(音频);流式传输支持 JPEG(视频)
- Beta 状态:API 可能会在未来的版本中发生变化
- 视频支持:仅限出网 (JPEG)
- 视频帧率:大约 1 FPS(Beta 阶段;不可配置)
- 流式传输重新连接:使用 Stream 模式 (egress) 时,SFU 仅在短暂断开连接时自动重试相同的 WebSocket 端点。它不会故障转移到备用端点。
- 尽力而为恢复:短暂的重新连接可以减少媒体丢失,但不保证无缝或恰好一次(exactly-once)的递送。
- 视频重新连接行为:视频从最新的可用 JPEG 帧恢复,而不是重放较旧的帧。
- 单向流:每个实例处理一个方向
| 错误代码 | 描述 |
|---|---|
400 |
请求参数无效 |
404 |
未找到会话或轨道 |
503 |
未找到适配器(用于关闭操作) |
- 音频 (PCM over WebSocket):Cloudflare Realtime 示例 – ai-tts-stt ↗
- 视频 (JPEG 出网):Cloudflare Realtime 示例 – video-to-jpeg ↗
- 将自定义信令替换为适配器 API 调用
- 更新 WebSocket 端点以处理 PCM 格式
- 实现适配器生命周期管理
- 移除自定义 STUN/TURN 配置
问:我可以使用同一个适配器来实现双向音频吗?
答:不能,每个实例都是单向的。分别为发送和接收创建独立的适配器。
问:如果 WebSocket 连接中断会发生什么?
答:当使用 Stream 模式 (egress) 时,SFU 会在最长 5 秒内自动重试相同的 WebSocket 端点。如果端点在此窗口内恢复连接,流式传输将自动恢复。
音频使用短暂且有界的积压缓冲区来减少短暂中断期间的听觉丢失。视频从最新的可用 JPEG 帧恢复,而不是重放较旧的帧。
如果端点在 5 秒的流式传输自动重新连接窗口过后仍不可用,则适配器关闭并必须重新创建。
当从 WebSocket 引入到 WebRTC 时,您的 WebSocket 客户端应根据需要重新连接并重新创建适配器。
问:并发适配器数量是否有限制?
答:限制遵循标准的 Cloudflare Realtime 配额。如有特定需求,请联系支持团队。
问:创建适配器后我能更改音频格式吗?
答:不能,音频格式在创建时即固定。对于不同格式,请创建新的适配器。