概述
SFU 会周期性下发一组控制面消息,SDK 把它们转成四个ChannelDelegate 事件:
这四个事件仅 SeaStart(SFU)引擎有。它们走的是订阅 PeerConnection 上的信令 DataChannel,而 WangSu(CDN)引擎没有这条通道,因此走 CDN 时不会收到任何一个,
getConnectionQuality() 也返回 nil。用 ChannelInfo.vendor 判断当前引擎,见 类型定义。网络质量:两条轨,别混用
质量走双轨设计,因为两类需求的触发频率差了一个量级:didReceiveQualityReport—— 每次服务端上报都触发,是原始数值流didChangeConnectionQuality—— 只在等级跳档时触发,是断言
QualityReport 分 pub(上行,客户端到 SFU)与 sub(下行,SFU 到客户端)两个 QualitySample,字段含义见 类型定义。要点:
level是服务端给出的等级,score(0100)与4.5)都是越大越好mos(1.0loss是 0~1 的比例,不是百分数rtt、jitter单位是毫秒,bitrate单位是 kbps- 排查「谁的问题」时看两侧:
pub差是自己上行有问题,sub差是下行或对端上行的问题
ConnectionQualityChange 里的 evaluation.overall 取上下行较差的那一档(unknown < excellent < good < poor < lost),evaluation.mos 取上下行较小值 —— 都是按「用户感知最弱的一侧」来的。previous 是跳档前的等级,首次跳档时为 .unknown。
冷启动:进页面就要显示等级
事件只在变化时来,UI 刚创建时手上没有值。用getConnectionQuality() 取一次当前快照补上:
nil(与「收到了但等级是 unknown」是两件事)。
断线重连后 SDK 会清空质量缓存(最近评估、跳档基线、说话人快照),避免恢复后 UI 上残留旧的
poor 等级。所以重连后 getConnectionQuality() 会短暂返回 nil,直到新报告到达 —— 这是有意的,UI 上按「暂无数据」处理即可。活跃说话人
snapshot.speakers 是全量列表,SDK 已经把服务端的增量协议(谁开始说、谁停止说)合并成完整快照并按 level 降序排好。所以:
- 业务侧直接整体覆盖 UI 状态即可,不需要自己维护「谁还在说话」的集合
- 无人说话时
speakers是空数组,不是不发事件 level是 0~1 的归一化线性音量,可以直接用来画音量条
ActiveSpeakerInfo 带 uid 与 trackId —— 同一个用户可能有多条音频轨道,要精确定位到轨道时用后者。
大小流:主动切层
发布端开了联播(simulcast)时,同一路视频会有多个层。默认由 SFU 按带宽自动选层,切完通过didSwitchLayer 通知(reason 是 bwe_down / bwe_up 这类服务端原因):
didSwitchLayer,此时 reason 为 client。
可能抛出:
SRTCError.engineNotSupported(_:)—— 当前不是 SeaStart 引擎(如走 CDN)SRTCError.transportNotReady—— 信令通道尚未就绪(刚入会、或正在重连)SRTCError.webrtcError(_:)—— 信令通道发送失败(通常是缓冲区拥塞)