Skip to main content

两种写法


常规多路:用 SMeetingRemoteVideoView

组件出现时订阅、消失时(防抖 300ms)退订,不用自己管。

@Prop 是这里最容易踩的坑

meeting(以及 SRTCVideoViewtrack)不能声明成 @PropArkTS 的 @Prop 对复杂类型做深拷贝,且拷贝过程中除基本类型 / Map / Set / Date / Array 之外会丢失类型 —— SMeetingEngine / Track 拷过来会变成一个 没有方法的普通对象。后果:画面黑屏,事件也永远收不到,而且不会报错。@Link / @ObjectLink 能引用传递,但要求父组件为每一路画面单独持有一个 @State,多路远端画面根本写不出来。所以:走普通成员变量(按引用传入),换对象靠组件重建 —— 让 if 分支或 ForEach 的 key 带上 uid / trackId。

同一路画面渲染在多处

同一 uid + trackDesc 同时挂两个 SMeetingRemoteVideoView 实例 (大窗 + 缩略图)会出问题:关掉其中一个,防抖窗口后整路流被退订,另一个变黑屏。这个场景要自己订阅一次,把同一个 track 交给两个 SRTCVideoView
退订时机自己控制(比如切换主讲人时)。

为什么组件不用守卫版退订

SDK 有 unsubscribeRemoteVideoTrackIfNoRenderers() —— 靠 RemoteVideoTrack.hasRenderers 引用计数判断,理论上正好解决上面的问题。 但它在 ArkUI 的 aboutToDisappear不可靠 父组件的 aboutToDisappear 先于子组件执行。SMeetingRemoteVideoView.aboutToDisappear 里调守卫版时, 子 SRTCVideoView 还没 removeRenderer,会永远判成”还有渲染器”而永不退订 —— 那是带宽泄漏,比黑屏更糟。 所以组件选了防抖退订这个更保守的方案。你自己在明确时机调守卫版是可以的。

surface 与轨道的生命周期不同步

SRTCVideoView 内部处理了两个方向,但理解它有助于排查黑屏:
  1. surface 比轨道晚到:远端轨道是信令先建对象、订阅协商完成后才绑底层轨道 (所以拿到 Track 不等于有帧);本地轨道可能在组件挂载前就采集好了。
  2. surface 会重建:切后台、旋屏都会走一遍 destroy → create。
组件的做法是「挂载时主动挂一次 + 监听 onTrackBindRtcTrack 补挂」, 前提是保持同一个组件实例 —— 不要每次 build 都换 trackKey

宫格 + 大窗的典型布局

ArkTS 的 @Observed / @State 只观测第一层属性的赋值this.users / this.others 这类数组永远用「建新数组再整体赋值」, 不要 push / splice 原数组 —— 那样 UI 不会刷新。

大型会议:用 MCU 合流

人多时不要 N 路各自订阅,改订服务端合成的一路:
客户端解码开销不随人数线性上升。布局由主持人的 adminUpdateLayout(layoutData) 控制,LayoutType 有 20 种预置。

相关阅读