直播场景下主播端使用 4.x 版本与观众使用 5.X 版本 SDK 的兼容方案

问题描述

在直播场景下,最新的 RTCLib 5.1.0及以上版本优化了观众订阅主播音视频资源的方式,导致与 RTCLib 5.1.0(不包含5.1.0) 以下版本观众订阅资源方式存在差异。

背景

  • 4.x 版本的的观众没有加房间的功能,只能通过订阅 liveUrl 来订阅合流;
  • 5.x(5.1.0 及之后的版本)的观众会先加入房间,拿到房间内的合流来订阅;

假设 4.x 版本的主播和 5.x 版本(5.1.0 及之后的版本)的观众进行直播互动。

  • 5.x 观众只能事先知道是 4.x 主播在当前房间,使用订阅 liveUrl 的方式观看直播;
  • 5.x 观众如果事先知道是 5.x 主播在当前房间,应该加入房间去拿到直播合流订阅观看;

加入房间

连接 IM 服务成功后,观众端首先调用 RCRTCEngine 的 joinRoom:config:completion: 方法创建一个直播类型房间。加入房间成功后,调用 RCRTCRoom 新增的 getLiveStreams 拿到直播的合流进行订阅,如代码所示。

示例代码

- (void)joinLiveRoom {
    RCRTCRoomConfig *config = [[RCRTCRoomConfig alloc] init];
    config.roomType = RCRTCRoomTypeLive; //房间类型
    config.liveType = RCRTCLiveTypeAudioVideo; //直播类型
    config.roleType = RCRTCLiveRoleTypeAudience; //观众角色

    [[RCRTCEngine sharedInstance] joinRoom:@"房间号"
                                  config:config
                              completion:^(RCRTCRoom * _Nullable room, RCRTCCode code) {
        if (code != RCRTCCodeSuccess) {
            // 错误处理
            return;
        }
        // 设置房间事件代理
        self.room = room;
        self.room.delegate = self;

        // 加入房间时存在live合流,可以直接订阅
        NSArray *liveStreams = [room getLiveStreams];
        if (liveStreams.count) {
            // 从房间拿到合流去订阅
            [room.localUser subscribeStream:liveStreams tinyStreams:nil completion:^(BOOL isSuccess, RCRTCCode desc) {
                // to do something
            }];
        }else{
            // 拿不到合流,直接使用传递过来的 liveUrl 进行订阅
            [room.localUser subscribeLiveUrl:self.liveUrl streamType:RCRTCAVStreamTypeAudioVideo completion:^(RCRTCCode code, NSArray<RCRTCInputStream *> * _Nullable inputStreams) {
                // to do something
            }];
        }
    }];
}

订阅资源

假设上述操作的房间内只存在 4.x 主播,通过 getLiveStreams方法是拿不到主播合流的,这时候就可以使用新增 RCRTCLocalUser 的 subscribeLiveUrl:streamType:completion: 进行订阅,代码如图所示。

示例代码

    if (liveStreams.count) {
        // 从房间拿到合流去订阅
        [room.localUser subscribeStream:liveStreams tinyStreams:nil completion:^(BOOL isSuccess, RCRTCCode desc) {
            // to do something
        }];
    }else{
        // 拿不到合流,直接使用传递过来的 liveUrl 进行订阅
        [room.localUser subscribeLiveUrl:self.liveUrl streamType:RCRTCAVStreamTypeAudioVideo completion:^(RCRTCCode code, NSArray<RCRTCInputStream *> * _Nullable inputStreams) {
            // to do something
        }];
    }
/*!
 观众订阅合流资源

 @param liveUrl 主播直播的 liveUrl (针对 4x版本的主播兼容方案)
 @param streamType 需要具体订阅的媒体类型
 @param completion  完成的回调, 会依次回调合流的 RCRTCInputStream, 根据 streamType 区分是音频流还是视频流, 如主播发布了音视频流, 此回调会回调两次, 分别为音频的 RCRTCInputStream,  和视频的 RCRTCInputStream 。
 @discussion
 仅直播模式可用,  作为观众, 直接观看主播的直播, 通过传入主播的 url, 仅观众端可用,此接口可具体订阅音频流或视频流或大小流
 Added from 5.1.2

 @remarks 媒体流操作
 */
- (void)subscribeLiveUrl:(nonnull NSString *)liveUrl
              streamType:(RCRTCAVStreamType)streamType
              completion:(nullable RCRTCLiveUrlCallback)completion;

关于 liveUrl

任何版本的主播在发布资源的时候会从回调的里面的 RCRTCLiveInfo 对象中获取 liveUrl。推荐开发者可以通过 App server 或者融云的 IM 聊天室设置 kv 的方式给到观众端。

示例代码

@interface RCRTCLiveInfo : NSObject


/**
 当前的直播地址
 @discussion 新版观众加房间,直接可以拿到直播合流, 单个主播流,使用常规方式订阅即可
 */
@property (nonatomic, copy, readonly) NSString *liveUrl
 // 发布本地流到房间
    [self.room.localUser publishDefaultLiveStreams:^(BOOL isSuccess, RCRTCCode desc, RCRTCLiveInfo * _Nullable liveInfo) {
        if (desc == RCRTCCodeSuccess) {
            self.liveInfo = liveInfo; 
           //获取 liveUrl
            self.liveUrl = liveInfo.liveUrl;
        }else {
            [UIAlertController alertWithString:@"本地流发布失败" inCurrentVC:nil];
        }
    }];