整体模型
对象模型可以概括为:SRTCEngine:SDK 主入口,负责入会和创建本地轨道Channel:一次真实的频道连接,负责发布、订阅、用户列表和事件分发Track:音频或视频流的抽象对象ChannelDelegate/TrackDelegate:事件回调入口SRTCVideoView/SRTCVideoRenderer:视频渲染层SRTC:只做一件事 —— 把宿主的 Context 交给 SDK(见下方「为什么需要SRTC.init」)
- 连接状态
- 用户状态
- 媒体轨道状态
为什么需要 SRTC.init
getContext() 只在 UI 组件里可用),所以必须由集成方在 UIAbility.onCreate
里交一次。
SRTCEngine 与 Channel
SRTCEngine
更像一个「工厂 + 会话入口」,通常只用它做两件事:
joinChannel(tokenString, options?)createLocalMicTrack(...)/createLocalCameraTrack(...)/createLocalScreenTrack(...)
Channel
加入频道成功后,真正承载业务状态的是 Channel:
- 发布本地轨道、订阅远端轨道
- 获取频道信息与用户信息
- 监听用户进出、轨道变化、断线重连、自定义消息
joinChannel 可以调用多次,一个引擎能同时加入多个频道,各频道的发布、订阅、成员与事件
互不干扰;srtc.channels 是当前存活的频道列表,srtc.defaultChannel 是最早加入的那个。
轨道属于引擎而不是频道 —— 同一条采集轨道可以发布给多个频道,采集只做一次。
Track 体系
继承关系(父类一般不用直接接触,但知道层级有助于理解类型标注):本地轨道
本地轨道类本身都是无参构造,预设要经引擎传入 —— 写
new LocalCameraTrack(preset)
是编不过的。startCapture 不 publish,就是「本地预览、不推流」;这也是不需要服务端就能自测
采集与渲染链路的办法。
远端轨道
远端轨道由信令先建对象、订阅协商完成后才绑定底层轨道 —— 所以拿到
Track 对象不等于
已经有帧,渲染组件内部会等 onTrackBindRtcTrack 再挂。
音频的 Mix 模式
SeaStart 引擎支持在服务端把多路音频混成一路下发,客户端只订阅这一条 (RemoteAudioMixTrack),省掉 N 路解码。
- 混音轨的 id 与描述固定是
audio_mix,与其它端一致 —— 服务端按这个字符串识别 channel.getFilterUids()非空时表示只混指定用户的音频
视频渲染
SRTCVideoView(推荐)
SDK 自带的 ArkUI 组件,视频帧由底层直接写进 XComponent 的 surface,不经过 ArkUI 的
绘制流程 —— 这是唯一能承受 30fps 全屏刷新的路径。
SRTCVideoRenderer / VideoRendererRegistry
需要自己接渲染(比如画到自定义画布、或做录制)时用这一层。VideoRendererRegistry
维护 trackKey → 渲染器的映射,SRTCVideoView 内部也是走它。
绝大多数业务不需要碰这层。
设备管理
DeviceManager.shared 是单例,提供:
- 摄像头 / 麦克风 / 扬声器枚举:
cameras()/microphones()/speakers()/getDevices() - 热插拔事件:
DeviceManagerDelegate
deviceId 可以直接喂回采集参数(CameraCaptureOptions.deviceId),
这条回路是设备切换能力的地基。
音频输出路由是另一套:AudioRouteSession,负责扬声器 / 听筒的持久设置与通话中临时
切换。外接设备(蓝牙 / 有线)由系统接管,SDK 只上报不主动切换。
流媒体引擎
频道用哪套引擎由服务端下发的stream_vendor 决定,SDK 侧对应 StreamVendor:
业务代码通常不需要关心这个,但排障时
channel.streamVendor 能告诉你当前走的是哪条路。
事件模型
频道级事件走ChannelDelegate:加入成功、重连 / 断开、用户加入离开更新、远端轨道增删改、
自定义消息、网络质量、活跃说话人、Simulcast 层切换。
轨道级事件走 TrackDelegate:轨道信息变化、静音 / 取消静音、采集结束、镜像变化、
底层轨道绑定完成。