-
-
Notifications
You must be signed in to change notification settings - Fork 0
Voice Forwarding
DNTOF edited this page Aug 28, 2026
·
1 revision
启用 voice_enabled 后,插件在独立端口(默认 8082)上提供语音 WebSocket,实时推送服务器内所有频道的语音(近距离、对讲机、Intercom 全局广播、SCP 频道、旁观者等),解码为 48kHz 单声道 float32 PCM。开发代号 SPY(v2.3 推出)。
| 端点 | 说明 |
|---|---|
GET /ws?key=control_token(或 X-Control-Token 头) |
WebSocket 升级,实时语音流(需要 control_token 鉴权) |
GET /status?key=control_token(或 X-Control-Token 头) |
JSON:当前正在说话的玩家(昵称/UserID/角色/频道,1.5s 无新包视为停止) |
- 连接成功:文本帧
{"type":"hello","sampleRate":48000,"channels":1,"format":"float32"} - 说话者信息(新一轮讲话 / 频道或角色变化时推送):文本帧
{"type":"speaker","nickname":"...","userid":"...","playerid":n,"role":"...","channel":n} - 语音帧(二进制):
[0]=0x01 [1]=channel [2-3]=playerId(LE) [4-7]=seq(LE) [8..]=float32 PCM,每包为 10ms Opus 帧(480 样本,约 100 包/秒)
- 基于 LabAPI
PlayerEvents.SendingVoiceMessage事件(挂在VoiceTransceiver.ServerReceiveMessage上,服务器收到的每个语音包都会触发;保留按内容哈希去重的纵深防御,避免重复解码破坏 Opus 解码器状态) - 解码器按说话者(netId)分开维护,解码异常时自动重建自愈;所有状态以 netId 为键,不用 ReferenceHub(玩家断开后 Hub 销毁会抛 NRE)
- 主循环 MEC 协程内全程 try/catch 保护,任何异常都不会杀死转发管道
-
主线程零阻塞保证:读侧仅在有数据时非阻塞收取;发送侧先经
Poll可写检查(缓冲满跳帧,实时流允许丢帧),持续 3 秒不可写判死连接,外加 250ms 发送超时兜底——对端停止收数据绝不可能冻结服务器主线程 - 连接层防护:监听连接上限 8(满载时新连接在 TCP 层直接被关闭,中继侧应对为退避重连,不会得到 WS 层错误码)、握手超时 10 秒、鉴权失败当场断开