82 lines
2.6 KiB
Markdown
82 lines
2.6 KiB
Markdown
# 语音通信
|
|||
|
|
|
||
|
|
> 用户流程:按下 PTT 按钮 → 发送语音 → 松开 PTT 按钮 → 停止语音
|
||
|
|
> 对应程序流程:前置条件检查 → StartCapture → 循环 TsClient.sendVoice(clientID, codec, frame) → StopCapture
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 一、状态树
|
||
|
|
|
||
|
|
### 语音状态
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
flowchart TD
|
||
|
|
VOICE[语音状态<br/>维护 Opus 帧发送过程]
|
||
|
|
|
||
|
|
VOICE --> V0[静默 Silent<br/>没有发送语音帧]
|
||
|
|
VOICE --> V1[采集中 Capturing<br/>上层正在生成 Opus 帧]
|
||
|
|
VOICE --> V2[发送中 Sending<br/>循环调用 sendVoice]
|
||
|
|
VOICE --> V3[受阻 Blocked<br/>未连接、采集失败或发送异常]
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 二、时序:发送语音帧与异常停止
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
sequenceDiagram
|
||
|
|
participant UI as PTT 控件<br/>接收按下、松开和取消操作
|
||
|
|
participant VFSM as 语音发送状态机<br/>检查连接与频道前置条件
|
||
|
|
participant CAP as 音频采集与编码器<br/>生成原始 Opus 帧
|
||
|
|
participant BRIDGE as TSBridge<br/>调用 TsClient API
|
||
|
|
participant SDK as Go SDK (gomobile)<br/>通过 SendVoice 发送语音
|
||
|
|
participant TS as TeamSpeak 服务器<br/>转发语音给频道成员
|
||
|
|
|
||
|
|
UI->>VFSM: PttPressed
|
||
|
|
VFSM->>VFSM: 检查 connected 和 joinedChannel
|
||
|
|
|
||
|
|
alt 前置条件不满足
|
||
|
|
VFSM-->>UI: Blocked(reason)
|
||
|
|
else 前置条件满足
|
||
|
|
VFSM->>CAP: StartCapture()
|
||
|
|
CAP-->>VFSM: CaptureReady
|
||
|
|
VFSM->>VFSM: 状态改为 transmitting
|
||
|
|
loop 每个 Opus 帧
|
||
|
|
CAP-->>VFSM: opusFrame
|
||
|
|
VFSM->>BRIDGE: sendVoice(clientID, codec, frame)
|
||
|
|
BRIDGE->>SDK: gomobile SendVoice
|
||
|
|
SDK->>TS: UDP voice frame
|
||
|
|
end
|
||
|
|
|
||
|
|
alt 用户松开或取消
|
||
|
|
UI->>VFSM: PttReleased / PointerCancelled
|
||
|
|
VFSM->>CAP: StopCapture()
|
||
|
|
VFSM->>VFSM: 状态恢复 silent
|
||
|
|
else 连接断开
|
||
|
|
SDK-->>VFSM: onDisconnected(error)
|
||
|
|
VFSM->>CAP: StopCapture()
|
||
|
|
VFSM->>VFSM: 状态改为 blocked
|
||
|
|
end
|
||
|
|
end
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 三、事件依赖
|
||
|
|
|
||
|
|
### 语音前置依赖矩阵
|
||
|
|
|
||
|
|
| 操作或事件 | 必须依赖 | 建议依赖 | 依赖失败时的处理 |
|
||
|
|
| --- | --- | --- | --- |
|
||
|
|
| `TsClient.sendVoice` | 已连接、已有可发送的 Opus 帧 | 当前用户已在有效频道 | 任一前置失效立即停止发送 |
|
||
|
|
|
||
|
|
### 权威性划分
|
||
|
|
|
||
|
|
| 数据 | 推荐权威来源 | 原因 |
|
||
|
|
| --- | --- | --- |
|
||
|
|
| 语音发送结果 | `TsClient.sendVoice` 返回值 | 表示本次本地发送调用结果,不代表对方播放成功 |
|
||
|
|
|
||
|
|
### 统一实现原则(语音相关)
|
||
|
|
|
||
|
|
- **语音只在连接和频道前置条件满足时发送。** 断开或被踢必须立即停止。
|