跳到主要内容

跨房间连麦

流程说明

跨房间连麦功能中区分主房间和副房间。跨房间连麦前需要双方都已经加入自己的主房间,未加入主房间前无法进行连麦的邀请和被邀请。

主副房间定义如下:

  • 主房间:本端在最开始加入的房间,即:RCRTCRoom.h
  • 副房间:在接受邀请后加入的对方房间,即:RCRTCOtherRoom.h

两种房间的类都有对应的代理 RCRTCRoomEventDelegateRCRTCOtherRoomEventDelegate 用来区分不同类型房间的回调。

发起邀请

向指定用户发送跨房间连麦请求:

- (void)requestJoinOtherRoom:(NSString *)inviteeRoomId
userId:(NSString *)inviteeUserId
autoMix:(BOOL)autoMix
extra:(NSString *)extra
completion:(RCRTCOperationCallback)completion;

参数说明:

参数类型说明
inviteeRoomIdNSString被邀请人所在房间号
inviteeUserIdNSString被邀请人userId
autoMixBOOL是否将邀请人音视频资源发送到被邀请人房间中合流
extraNSString附加信息, 可随消息发送给被邀请人
completionRCRTCOperationCallback动作的回调

示例代码:

[self.mainRtcRoom.localUser requestJoinOtherRoom:otherRoomId
userId:otherRoomUserId
autoMix:YES
extra:@""
completion:^(BOOL isSuccess, RCRTCCode code) {

}];

取消邀请

取消向指定用户发送跨房间连麦请求:

- (void)cancelRequestJoinOtherRoom:(NSString *)inviteeRoomId
userId:(NSString *)inviteeUserId
extra:(NSString *)extra
completion:(RCRTCOperationCallback)completion;

参数说明:

参数类型说明
inviteeRoomIdNSString被邀请人所在房间号
inviteeUserIdNSString被邀请人userId
extraNSString附加信息, 可随消息发送给被邀请人
completionRCRTCOperationCallback动作的回调

示例代码:

[self.mainRtcRoom.localUser cancelRequestJoinOtherRoom:otherRoomId
userId:otherRoomUserId
extra:@""
completion:^(BOOL isSuccess, RCRTCCode code) {

}];

应答邀请

被邀请方响应邀请方发出的跨房间连麦请求。

- (void)responseJoinOtherRoom:(NSString *)inviterRoomId
userId:(NSString *)inviterUserId
agree:(BOOL)agree
autoMix:(BOOL)autoMix
extra:(NSString *)extra
completion:(RCRTCOperationCallback)completion;

参数说明:

参数类型说明
inviterRoomIdNSString邀请人所在房间号
inviterUserIdNSString邀请人userId
agreeBOOL是否同意加入副房间
autoMixBOOL是否将被邀请人音视频资源发送到邀请人房间中合流
extraNSString附加信息, 可随消息发送给被邀请人(选填)
completionRCRTCOperationCallback动作的回调

示例代码

[self.mainRtcRoom.localUser responseJoinOtherRoom:otherRoomId
userId:otherRoomuserId
agree:YES
autoMix:YES
extra:@""
completion:^(BOOL isSuccess, RCRTCCode code) {}];

加入副房间

邀请方与被邀请方连在麦邀请同意后加入副房间。

- (void)joinOtherRoom:(NSString *)roomId
completion:(void (^)(RCRTCOtherRoom * _Nullable room, RCRTCCode code))completion;

参数说明:

参数类型说明
roomIdNSString副房间 Id, 支持大小写英文字母、数字、部分特殊符号 + = - _ 的组合方式 最长 64 个字符
completionvoid (^)(RCRTCOtherRoom * _Nullable room, RCRTCCode code)加入副房间的回调

示例代码:

[[RCRTCEngine sharedInstance] joinOtherRoom:roomId
completion:^(RCRTCOtherRoom * _Nullable room, RCRTCCode code) {
room.delegate = self;
}];

订阅资源

订阅多路远端指定音视频流。

- (void)subscribeStream:(NSArray <RCRTCInputStream *> *)avStreams
tinyStreams:(NSArray <RCRTCInputStream *> *)tinyStreams
completion:(nonnull RCRTCOperationCallback)completion;

参数说明:

参数类型说明
avStreamsNSArray <RCRTCInputStream *>需要订阅的音频流和视频大流数组
tinyStreamsNSArray <RCRTCInputStream *>需要订阅的视频小流数组
completionRCRTCOperationCallback订阅完成的回调

示例代码:

[self.mainRTCRoom.localUser subscribeStream:streams
tinyStreams:@[]
completion:^(BOOL isSuccess, RCRTCCode code) {

}];

取消订阅

取消订阅多路远端指定音视频流,远端用户离开与自己离开主、副房间时 RongRTCLib 内部会取消订阅,不需要上层处理。

- (void)unsubscribeStreams:(nonnull NSArray <RCRTCInputStream *> *)streams
completion:(nonnull RCRTCOperationCallback)completion;

参数说明:

参数类型说明
streamsNSArray <RCRTCInputStream *>音视频流数组
completionRCRTCOperationCallbac取消订阅完成的回调

示例代码:

[self.mainRTCRoom.localUser unsubscribeStreams:streams
completion:^(BOOL isSuccess, RCRTCCode code) {
}];

离开副房间

- (void)leaveOtherRoom:(NSString *)roomId
notifyFinished:(BOOL)isNotify
completion:(nonnull RCRTCOperationCallback)completion;

参数说明:

参数类型说明
roomIdNSString副房间 Id
isNotifyBOOL是否通知所有连麦用户结束跨房间连麦
completionRCRTCOperationCallbac离开副房间完成的回调

示例代码:

[[RCRTCEngine sharedInstance] leaveOtherRoom:otherRoomId
notifyFinished:YES
completion:^(BOOL isSuccess, RCRTCCode code) {

}];

场景说明

邀请连麦流程

场景一:

邀请方发起邀请后,邀请方又取消邀请。

此场景中被邀请方未做任何操作,仅被动收到两次代理回调。

邀请方被邀请方
步骤1:调用 RCRTCLocalUser 类中的 requestJoinOtherRoom: userId: autoMix: extra: completion: 方法发起跨房间连麦邀请步骤2:在 RCRTCRoomEventDelegate 中收到 didRequestJoinOtherRoom: inviterUserId: extra: 邀请回调
步骤3:调用 RCRTCLocalUser 类中的 cancelRequestJoinOtherRoom: userId: extra: completion: 方法结束之前发起的邀请步骤4:在 RCRTCRoomEventDelegate 中收到 didCancelRequestOtherRoom: inviterUserId: extra: 取消受邀请的回调

场景二:

邀请方发起邀请后,被邀请方应答同意。

此场景中被邀请方应答同意,只有被邀请方不会收到应答的回调,包含邀请人在内两个房间的所有非观众用户都会收到代理回调。

邀请方被邀请方
步骤1:调用 RCRTCLocalUser 类中的 requestJoinOtherRoom: userId: autoMix: extra: completion: 方法发起跨房间连麦邀请步骤2:在 RCRTCRoomEventDelegate 中收到 didRequestJoinOtherRoom: inviterUserId: extra: 邀请回调
步骤4:包含邀请人在内两个房间的所有非观众用户,不包含被邀请方,会在 RCRTCRoomEventDelegate 中收到 didResponseJoinOtherRoom: inviterUserId: inviteeRoomId: inviteeUserId: extra: 应答回调步骤3:调用 RCRTCLocalUser 类中的 responseJoinOtherRoom: userId: agree: autoMix: extra: completion: 应答邀请,其中 agree 参数的值为 YES

场景三:

邀请方发起邀请后,被邀请方应答拒绝。

此场景中被邀请方应答拒绝,只有邀请方会收到应答拒绝的回调,其他所有用户都不会收到代理回调。

邀请方被邀请方
步骤1:调用 RCRTCLocalUser 类中的 requestJoinOtherRoom: userId: autoMix: extra: completion: 方法发起跨房间连麦邀请步骤2:在 RCRTCRoomEventDelegate 中收到 didRequestJoinOtherRoom: inviterUserId: extra: 邀请回调
步骤4:只有邀请方会收到应答拒绝的回调,其他所有用户都不会收到 RCRTCRoomEventDelegate 中的 didResponseJoinOtherRoom: inviterUserId: inviteeRoomId: inviteeUserId: extra: 应答回调步骤3:调用 RCRTCLocalUser 类中的 responseJoinOtherRoom: userId: agree: autoMix: extra: completion: 应答邀请,其中 agree 参数的值为 NO

加入副房间流程

场景四:

在 场景二 的前提下,

邀请方在收到应答同意的回调后,加入被邀请方的房间,即:邀请方加入的副房间。

被邀请方在调用应答同意后,加入邀请方的房间,即:被邀请方加入的副房间。

邀请方被邀请方
步骤2:在收到被邀请方同意代理回调后,调用 RCRTCEngine 中 joinOtherRoom: completion: 方法加入副房间步骤1:在应答邀请同意后,调用 RCRTCEngine 中 joinOtherRoom: completion: 方法加入副房间

场景五:

在加入主房间前,如果主房间的某用户已经与其他房间另一用户成功建立跨房间连麦。

可以通过加入主房间成功后得到的 RCRTCRoom 对象中检查 room.otherRoomIdArray 中是否存在房间中的用户已经加入的副房间。如果存在,可选择是否加入其他副房间。

/*!
主房间中主播已经加入的副房间Id列表
*/
@property (nonatomic, strong, readonly) NSArray *otherRoomIdArray;
邀请方
步骤1:调用 RCRTCEngine 中 joinRoom: completion: 方法加入主房间
步骤2:检查发现 room.otherRoomIdArray 中存在其他副房间
步骤3:调用 RCRTCEngine 中 joinOtherRoom: completion: 方法加入副房间

订阅流程

在 场景四 或 场景五 的前提下:

场景六:

订阅副房间用户已经发布的音视频资源方式一:加入副房间后,通过遍历取得副房间中所有远端用户中的 inputStream 列表,再调用 RCRTCLocalUser 中 subscribeStream: tinyStreams: completion: 方法订阅副房间中远端用户已经发布的音视频资源。

[[RCRTCEngine sharedInstance] joinOtherRoom:roomId
completion:^(RCRTCOtherRoom * _Nullable pkRoom, RCRTCCode code) {
pkRoom.delegate = self;

if (code == RCRTCCodeSuccess) {
NSMutableArray *streamArray = [NSMutableArray array];
for (RCRTCRemoteUser *user in pkRoom.remoteUsers) {
for (RCRTCInputStream *stream in user.remoteStreams) {
if (stream.mediaType == RTCMediaTypeVideo) {
RCRTCVideoInputStream *videoInputStream = (RCRTCVideoInputStream *)stream;
RCRTCRemoteVideoView *remoteVideoView = [[RCRTCRemoteVideoView alloc] initWithFrame:CGRectMake(0, 0, 90, 120)];
[需要显示到的View addSubView:remoteVideoView];
[videoInputStream setVideoView:remoteVideoView];
}
[streamArray addObject:stream];
}
}

if (streamArray.count > 0) {
[self.mainRTCRoom.localUser subscribeStream:streamArray
tinyStreams:@[]
completion:^(BOOL isSuccess, RCRTCCode desc) {
if (completion) {
completion(isSuccess, desc);
}
}];
}
}
}];

订阅副房间用户刚发布的音视频资源方式二:加入副房间后,当有副房间中远端用户发布资源时,会回调 RCRTCOtherRoomEventDelegate 中 room: didPublishStreams: 方法,调用 RCRTCLocalUser 中 subscribeStream: tinyStreams: completion: 方法,使用代理方法中的 streams 参数订阅副房间中远端用户刚发布的音视频资源。

- (void)room:(RCRTCBaseRoom *)room didPublishStreams:(NSArray <RCRTCInputStream *> *)streams {
for (RCRTCInputStream *stream in streams) {
if (stream.mediaType == RTCMediaTypeVideo) {
RCRTCVideoInputStream *videoInputStream = (RCRTCVideoInputStream *)stream;
RCRTCRemoteVideoView *remoteVideoView = [[RCRTCRemoteVideoView alloc] initWithFrame:CGRectMake(0, 0, 90, 120)];
[videoInputStream setVideoView:remoteVideoView];
}
}

[self.mainRTCRoom.localUser subscribeStream:streams
tinyStreams:@[]
completion:^(BOOL isSuccess, RCRTCCode code) {

}];
}

离开副房间流程

场景七:

已经加入副房间的用户,需要退出副房间时,可以调用 RCRTCEngine 中的 leaveOtherRoom: notifyFinished: completion: 方法。

此方法内部会取消订阅已经订阅的副房间所有用户音视频资源,上层无需自行取消订阅。

此方法中的 isNotify 参数为 NO 时,仅代表调用方离开副房间,其他用户会收到 RCRTCOtherRoomEventDelegate 中:

- (void)room:(RCRTCBaseRoom *)room didLeaveUser:(RCRTCRemoteUser *)user;

当 isNotify 参数为 YES 时,其他用户会首先收到 RCRTCOtherRoomEventDelegate 中:

- (void)room:(RCRTCBaseRoom *)room didLeaveUser:(RCRTCRemoteUser *)user;

回调方法,然后会收到 RCRTCRoomEventDelegate 中:

- (void)didFinishOtherRoom:(NSString *)roomId
userId:(NSString *)userId;

回调方法,用来通知跨房间连麦中的所有用户,可以退出副房间结束连麦。

被服务端踢出房间流程

通过调用服务端 API 可以将指定房间的指定用户踢出该房间。

在踢出某个用户之前,建议先通过服务下发消息让此客户端执行结束跨房间连麦 ,然后再从主房间踢出违禁用户。 被踢出的房间是该用户加入的主房间时,RongRTCLib 内部会调用 leaveRoom: 方法先退出已经加入的副房间,再退出主房间并销毁资源。UI 层无需再次调用离开主、副房间的方法,只处理上层逻辑即可。 被踢出的房间是该用户加入的副房间时,RongRTCLib 内部会调用 leaveOtherRoom: notifyFinished: completion: 方法仅退出指定的副房间,并取消订阅已经订阅的该副房间中用户的音视频资源,UI 层无需再次调用离开副房间的方法,只处理上层逻辑即可。

/*!
被服务端踢下线通知

@param room 离开的房间
@discussion
如果用户在房间内, 此时收到服务器封禁的通知, SDK 会关闭音视频连接, 释放资源,
将用户踢出房间, 回调通知用户

@remarks 代理
*/
- (void)didKickedByServer:(RCRTCBaseRoom *)room;