在融云全新上线的直播 SDK 2.0 中,完整封装 7 种合流布局是一大亮点。

事实上,主播和观众连麦是直播场景中非常热门的玩法之一。多人实时互动可以活跃直播氛围、激发观众参与热情,进而提升产品活跃度。因此,直播连麦在相亲、游戏、电商等不同业务场景广泛应用,已经逐渐成为视频直播产品的必备能力。

连麦时,用户通过申请连麦、邀请连麦、自由上麦等方式开启连麦,不同场景需要配置相应的布局模式,比如,PK 场景的双人、相亲场景的三人、多人参与的 X 宫格等等。这些都涉及对直播间连麦用户音视频流的合流布局及相应的麦位管理。在多数场景下,连麦用户还有切换音频和视频接入的需求。

融云直播 SDK 攻克直播场景下多人连麦中面临的合流布局难题:内置 7 种常见连麦布局,并支持自定义连麦模式;麦位信息通过融云 IM 提供的 KV 功能进行同步。开发者通过简单的接口调用,即可快速实现视频直播连麦功能。移步【融云全球互联网通信云】免费体验

本文介绍融云直播 SDK 的连麦布局方案如何实现,以及针对直播连麦业务中常见问题的最佳实践。

视频直播多人连麦

常见的连麦模式

随着直播连麦功能在不同行业的应用和发展,连麦的布局也千变万化,常见的模式有:

一对一:房主画面全屏显示,连麦用户以浮窗形式显示,画面有遮挡;

一对多:房主麦位固定,其他麦位围绕房主显示,各麦位画面无遮挡;

多宫格:房内所有连麦用户(含房主)麦位独立显示,画面无遮挡。

场景化视频直播 SDK 根据场景的连麦模式,内置了一对一、一对六、双人、三人、四宫格、七宫格、九宫格 7 种模式,同时支持自定义模式。

(合流布局示例)

连麦布局的难点和痛点

多人视频连麦时,我们需要实现以下功能:

主播端进行分流布局,并设置合流布局

合流视频中各麦位位置和响应点击事件

麦位管理,麦位信息同步/合流布局更新

行业普遍的解决方案,是使用 RTC SDK 提供的音视频流发布/订阅、音视频合流布局等底层技术进行二次开发。这个过程非常繁琐,而且需要开发者学习底层技术,难度很高。

融云直播 SDK

融云直播 SDK 基于融云 RTC 和融云 IM 实现连麦布局:通过融云 RTC 提供的视频流管理功能设置视频合流布局;通过融云 IM 实现麦位管理。SDK 分为三个模块:

房间管理:直播开启/结束、用户加入/离开、音视频流发布/订阅、房间属性设置等;

视图渲染:主播分流布局设置、观众合流布局设置等;

麦位管理:上下麦管理、视图事件响应、视图位置计算、麦位属性设置和同步等。

SDK 封装了房间、连麦、合流布局、麦位管理等复杂的逻辑,大大简化了视频直播功能的实现过程,节省开发成本。

融云直播 SDK 连麦布局方案

基于融云直播 SDK 实现连麦布局,只需要调用 setMixType:completion: 方法。连麦类型设置成功后,远端用户会接收到 roomMixTypeDidChange: 方法回调:

RCLiveVideoEngine.shared().setMixType(type) { code in
  /// TODO code
}

func roomMixTypeDidChange(_ mixType: RCLiveVideoMixType) {
  /// TODO mixType
}

SDK 根据连麦类型,分两种处理方式:内置连麦模式和自定义连麦模式。连麦模式 RCLiveVideoMixType 是枚举类型,包括 7 种内置模式和自定义模式,开发者可以根据业务场景选择合适的类型:

typedefNS_ENUM(NSInteger, RCLiveVideoMixType) {
  /// 默认模式
  RCLiveVideoMixTypeDefault = 0,
  /// 小窗模式
  RCLiveVideoMixTypeOneToOne,
  RCLiveVideoMixTypeOneToSix,
  /// 格子模式
  RCLiveVideoMixTypeGridTwo,
  RCLiveVideoMixTypeGridThree,
  RCLiveVideoMixTypeGridFour,
  RCLiveVideoMixTypeGridSeven,
  RCLiveVideoMixTypeGridNine,
  /// 自定义模式
  RCLiveVideoMixTypeCustom,
};

内置连麦模式

如果设置的连麦模式是内置类型,SDK 会根据连麦类型生成对应的麦位信息 NSArray,同时,调用 RCLiveVideoMixDelegate 中的 liveVideoDidLayout:withFrame: 方法对外同步麦位信息。

/// 自定义麦位视图
/// @param seat 麦位对象
 (void)liveVideoDidLayout:(RCLiveVideoSeat *)seat withFrame:(CGRect)frame;

自定义连麦模式

融云 RTC 提供了三种合流布局方式:自定义布局、悬浮布局和自适应布局。融云直播 SDK 选择自定义布局方式,更容易适配不同场景需求。

如下图所示,合流布局以像素方式定义视频输出尺寸。整体视频尺寸宽高 = 300 300;以整体作为画布,画布的原点(0,0)在左上角,那么三个连麦主播的窗口相对原点的位置及其宽度、高度值分别如图所示:


(自定义布局示意图)

布局模式为 RCLiveVideoMixTypeCustom 时,SDK 会通过 RCLiveVideoMixDataSource 的 liveVideoFrames 方法获取麦位信息。开发者根据业务需求,为每个 RCLiveVideoSeat 对象设置 frame 属性即可。

func liveVideoFrames() -> [NSValue] {
  return [
    NSValue(cgRect: CGRect(x: 0.0, y: 0.0, width: 0.5, height: 1.0)),
    NSValue(cgRect: CGRect(x: 0.5, y: 0.0, width: 0.5, height: 1.0)),
  ]
}

融云直播 SDK 音视频流的灵活控制

融云直播 SDK 封装了音视频流的发布和订阅,开发者可以通过麦位对象 RCLiveVideoSeat 控制音视频流。

音视频流的发布

用户调用 prepare 和 begin:completion: 接口开启直播,或者调用 joinLiveVideoAtIndex:completion: 接口开启连麦时,SDK 默认发布音视频流,并关联对应麦位 RCLiveVideoSeat,用户可设置麦位 userEnableAudio 和 userEnableVideo 属性控制是否发布音视频流:

/// 麦上用户是否开启音频
 (void)setUserEnableAudio:(BOOL)enable completion:(RCLVResultBlock)completion;

/// 麦上用户是否开启视频
 (void)setUserEnableVideo:(BOOL)enable completion:(RCLVResultBlock)completion;

音视频流的订阅

用户调用 joinRoom:completion: 进入视频直播房间后,SDK 通过两种方式订阅其他人已发布的资源:

在加入房间的成功时订阅;

在收到远端用户发布流的通知时订阅。

对于多人连麦的主播,如果远端用户发布的视频流开启了大小流功能,请根据性能优先级来选择订阅大流或小流(默认)。通过麦位 RCLiveVideoSeat 对象中的 enableTiny 属性,控制大小流订阅。

分流和合流

SDK 根据用户在当前房间的身份,订阅不同的音视频流:

主播:订阅 RCRTCRoom 中 remoteUsers 的分流;

观众:订阅 RCRTCRoom 中 getLiveStreams 或 getCDNStream 的合流。

观众端订阅合流可以减少设备性能的开销和网络带宽的负载,同时也降低了开发难度和流量费用。观众在加入房间时,可以选择订阅合流类型:低延迟和 CDN。订阅 CDN 流时,支持设置 CDN 分辨率和帧率。

/// 加入房间,观众订阅 RTC 流
/// @param roomId 房间id
/// @param completion 结果回调
 (void)joinRoom:(nonnull NSString *)roomId
      completion:(nonnull RCLVResultBlock)completion;

/// 加入房间,观众订阅 CDN 流
/// 如果 videoSizePreset 或 fps 大于视频流的最大值,则使用最大值
/// @param roomId 房间 id
/// @param videoSizePreset 视频分辨率
/// @param fps 视频帧率
/// @param completion 结果回调
 (void)joinCDNRoom:(nonnull NSString *)roomId
    videoSizePreset:(RCRTCVideoSizePreset)videoSizePreset
                FPS:(RCRTCVideoFPS)FPS
         completion:(nonnull RCLVResultBlock)completion;

融云直播 SDK 合流布局最佳实践

合流布局适配

场景问题:在多人连麦模式中,需要考虑合流画面在不同手机屏幕上的适配问题。区别于单主播直播,多人连麦直播时,如果合流视频长宽比与当前终端的不一致,就会出现画面部分被剪切,部分主播画面显示不完整。

解决方案:融云直播 SDK 在设置视频合流布局时,固定上、下、右边界,根据连麦模式视图宽高比剪切。开发者在自定义连麦模式,出现类似场景时,也应该按照这个规则设计。


(视频合流布局固定边界)

麦位事件响应

场景问题:观众点击麦上用户时,需要响应用户点击事件并展示用户的信息。

解决方案:观众订阅的合流是完整的画面,可以根据点击所在位置和各麦位相对位置获取目标用户。

根据主流场景,除了响应事件,在各麦位上需要展示每个用户信息或空麦位占位图。可以根据麦位信息创建自定义视图,覆盖在相对位置上,自定义视图可以接收点击事件,并根据麦上用户信息,设置自定义视图的内容显示。

融云直播 SDK 提供自定义各个麦位的视图,可以通过 RCLiveVideoMixDelegate 设置。

/// 自定义麦位视图
/// @param seat 麦位对象
 (void)liveVideoDidLayout:(RCLiveVideoSeat *)seat withFrame:(CGRect)frame;

主播掉线

场景问题:当麦位发生变化时,遵循“谁加入谁更新,谁离开谁更新”的原则更新合流布局。但是,在连麦期间,主播断网掉线或其它意外导致非正常退出直播时,麦位信息无法及时更新。

解决方案:需要终端配合 sever 共同完成:

融云 RTC server 会监听房间用户的连接状态,用户掉线且一分钟内没有上线,RTC server 会通知终端 server 该用户已下线;

终端 server 查询该用户所在房间的 KV,如果该用户处于连麦状态,终端 server 会强制清理该用户所在麦位的 KV 信息;

房间内的用户接收到 KV 更新后,更新麦位信息;掉线主播用户再次返回此房间,角色将会是观众。


(主播掉线处理时序图)

注意事项

麦位过多导致性能问题:融云视频直播最大连麦数为 16 个,在视频连麦直播时,主播端连麦过多时,会出现负载过高的情况:

主播端负责本地推流和远端拉流,上行和下行网络数据被占满,导致 CPU 负载超高;

主播端负责视频渲染,多路视频流需要分别渲染到指定的麦位,导致 GPU 负载超高;

主播端负责视频预处理,比如:美颜、贴纸、特效等,再次加重 GPU 负载。

因此,在连麦人数过多时,需要注意:
主播之间订阅分流时,使用小流的模式 enableTiny;
适当降低主播视频流的分辨率、帧率等参数。


融云RongCloud
82 声望1.2k 粉丝

因为专注,所以专业