跨房间连麦
流程说明
跨房间连麦功能中区分主房间和副房间。 主副房间定义如下:
- 主房间:本端在最开始加入的房间,即:
RCRTCRoom.h - 副房间:在接受邀请后加入的对方房间,即:
RCRTCOtherRoom.h
- 跨房间连麦前需要双方都已经加入自己的主房间,未加入主房间前无法进行连麦的邀请和被邀请。
- 两种房间的类都有对应的代理 RCRTCRoomEventDelegate 和 RCRTCOtherRoomEventDelegate 用来区分不同类型房间的回调。

发起邀请
向指定用户发送跨房间连麦请求。
接口原型
- (void)requestRoomPK:(nullable NSString *)inviteeRoomId
userId:(nullable NSString *)inviteeUserId
autoMix:(BOOL)autoMix
extra:(nullable NSString *)extra
completion:(nullable RCRTCOperationCallback)completion;
参数说明
| 参数 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
| inviteeRoomId | NSString | 否 | 被邀请人所在房间号 |
| inviteeUserId | NSString | 否 | 被邀请人userId |
| autoMix | BOOL | 是 | 是否将邀请人音视频资源发送到被邀请人房间中合流 |
| extra | NSString | 否 | 附加信息,可随消息发送给被邀请人 |
| completion | RCRTCOperationCallback | 否 | 动作的回调 |
代码示例
[self.mainRtcRoom.localUser requestRoomPK:otherRoomId
userId:otherRoomUserId
autoMix:YES
extra:@""
completion:^(BOOL isSuccess, RCRTCCode code) {
// 处理邀请结果
}];
取消邀请
取消向指定用户发送跨房间连麦请求。
接口原型
- (void)cancelRequestJoinPK:(nullable NSString *)inviteeRoomId
userId:(nullable NSString *)inviteeUserId
extra:(nullable NSString *)extra
completion:(nullable RCRTCOperationCallback)completion;
参数说明
| 参数 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
| inviteeRoomId | NSString | 否 | 被邀请人所在房间号 |
| inviteeUserId | NSString | 否 | 被邀请人userId |
| extra | NSString | 否 | 附加信息,可随消息发送给被邀请人 |
| completion | RCRTCOperationCallback | 否 | 动作的回调 |
代码示例
[self.mainRtcRoom.localUser cancelRequestJoinPK:otherRoomId
userId:otherRoomUserId
extra:@""
completion:^(BOOL isSuccess, RCRTCCode code) {
// 处理取消结果
}];
应答邀请
被邀请方响应邀请方发出的跨房间连麦请求。
接口原型
- (void)responseRoomPK:(nullable NSString *)inviterRoomId
userId:(nullable NSString *)inviterUserId
agree:(BOOL)agree
autoMix:(BOOL)autoMix
extra:(nullable NSString *)extra
completion:(nullable RCRTCOperationCallback)completion;
参数说明
| 参数 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
| inviterRoomId | NSString | 否 | 邀请人所在房间号 |
| inviterUserId | NSString | 否 | 邀请人userId |
| agree | BOOL | 是 | 是否同意加入副房间 |
| autoMix | BOOL | 是 | 是否将被邀请人音视频资源发送到邀请人房间中合流 |
| extra | NSString | 否 | 附加信息,可随消息发送给被 邀请人 |
| completion | RCRTCOperationCallback | 否 | 动作的回调 |
代码示例
[self.mainRtcRoom.localUser responseRoomPK:otherRoomId
userId:otherRoomUserId
agree:YES
autoMix:YES
extra:@""
completion:^(BOOL isSuccess, RCRTCCode code) {
// 处理应答结果
}];
加入副房间
邀请方与被邀请方在连麦邀请同意后加入副房间。
接口原型
- (void)joinOtherRoom:(NSString *)roomId
completion:(nullable void (^)(RCRTCOtherRoom * _Nullable room, RCRTCCode code))completion;
参数说明
| 参数 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
| roomId | NSString | 是 | 副房间 Id,支持大小写英文字母、数字、部分特殊符号 + = - _ 的组合方式 最长 64 个字符 |
| completion | void (^)(RCRTCOtherRoom * _Nullable room, RCRTCCode code) | 否 | 加入副房间的回调 |
代码示例
[[RCRTCEngine sharedInstance] joinOtherRoom:roomId
completion:^(RCRTCOtherRoom * _Nullable room, RCRTCCode code) {
room.delegate = self;
// 处理加入副房间结果
}];
订阅资源
订阅多路远端指定音视频流。
接口原型
- (void)subscribeStream:(nullable NSArray<RCRTCInputStream *> *)avStreams
tinyStreams:(nullable NSArray<RCRTCInputStream *> *)tinyStreams
completion:(nullable RCRTCOperationCallback)completion;
参数说明
| 参数 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
| avStreams | NSArray<RCRTCInputStream *> | 否 | 需要订阅的音频流和视频大流数组 |
| tinyStreams | NSArray<RCRTCInputStream *> | 否 | 需要订阅的视频小流数组 |
| completion | RCRTCOperationCallback | 否 | 订阅完成的回调 |
代码示例
[self.mainRTCRoom.localUser subscribeStream:streams
tinyStreams:@[]
completion:^(BOOL isSuccess, RCRTCCode code) {
// 处理订阅结果
}];
取消订阅
取消订阅多路远端指定音视频流,远端用户离开与自己离开主、副房间时 RongRTCLib 内部会取消订阅,不需要上层处理。
接口原型
- (void)unsubscribeStreams:(nullable NSArray<RCRTCInputStream *> *)streams
completion:(nullable RCRTCOperationCallback)completion;
参数说明
| 参数 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
| streams | NSArray<RCRTCInputStream *> | 否 | 音视频流数组 |
| completion | RCRTCOperationCallback | 否 | 取消订阅完成的回调 |
代码示例
[self.mainRTCRoom.localUser unsubscribeStreams:streams
completion:^(BOOL isSuccess, RCRTCCode code) {
// 处理取消订阅结果
}];
离开副房间
离开指定的副房间。
接口原型
- (void)leaveOtherRoom:(NSString *)roomId
completion:(nullable RCRTCOperationCallback)completion;
参数说明
| 参数 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
| roomId | NSString | 是 | 副房间 Id |
| completion | RCRTCOperationCallback | 否 | 离开副房间完成的回调 |
代码示例
[[RCRTCEngine sharedInstance] leaveOtherRoom:otherRoomId
completion:^(BOOL isSuccess, RCRTCCode code) {
// 处理离开副房间结果
}];
场景说明
邀请连麦流程
场景一:
邀请方发起邀请后,邀请方又取消邀请。
此场景中被邀请方未做任何操作,仅被动收到两次代理回调。
| 邀请方 | 被邀请方 |
|---|---|
| 步骤1:调用 RCRTCLocalUser 类中的 requestRoomPK: userId: autoMix: extra: completion: 方法发起跨房间连麦邀请 | 步骤2:在 RCRTCRoomEventDelegate 中收到 didRequestJoinOtherRoom: inviterUserId: extra: 邀请回调 |
| 步骤3:调用 RCRTCLocalUser 类中的 cancelRequestJoinPK: userId: extra: completion: 方法结束之前发起的邀请 | 步骤4:在 RCRTCRoomEventDelegate 中收到 didCancelRequestOtherRoom: inviterUserId: extra: 取消受邀请的回调 |
场景二:
邀请方发起邀请后,被邀请方应答同意。
此场景中被邀请方应答同意,只有被邀请方不会收到应答的回调,包含邀请人在内两个房间的所有非观众用户都会收到代理回调。
| 邀请方 | 被邀请方 |
|---|---|
| 步骤1:调用 RCRTCLocalUser 类中的 requestRoomPK: userId: autoMix: extra: completion: 方法发起跨房间连麦邀请 | 步骤2:在 RCRTCRoomEventDelegate 中收到 didRequestJoinOtherRoom: inviterUserId: extra: 邀请回调 |
| 步骤4:包含邀请人在内两个房间的所有非观众用户,不包含被邀请方,会在 RCRTCRoomEventDelegate 中收到 didResponseJoinOtherRoom: inviterUserId: inviteeRoomId: inviteeUserId: extra: 应答回调 | 步骤3:调用 RCRTCLocalUser 类中的 responseRoomPK: userId: agree: autoMix: extra: completion: 应答邀请,其中 agree 参数的值为 YES |
场景三:
邀请方发起邀请后,被邀请方应答拒绝。
此场景中被邀请方应答拒绝,只有邀请方会收到应答拒绝的回调,其他所有用户都不会收到代理回调。
| 邀请方 | 被邀请方 |
|---|---|
| 步骤1:调用 RCRTCLocalUser 类中的 requestRoomPK: userId: autoMix: extra: completion: 方法发起跨房间连麦邀请 | 步骤2:在 RCRTCRoomEventDelegate 中收到 didRequestJoinOtherRoom: inviterUserId: extra: 邀请回调 |
| 步骤4:只有邀请方会收到应答拒绝的回调,其他所有用户都不会收到 RCRTCRoomEventDelegate 中的 didResponseJoinOtherRoom: inviterUserId: inviteeRoomId: inviteeUserId: extra: 应答回调 | 步骤3:调用 RCRTCLocalUser 类中的 responseRoomPK: userId: agree: autoMix: extra: completion: 应答邀请,其中 agree 参数的值为 NO |
加入副房间流程
场景四:
在 场景二 的前提下,
邀请方在收到应答同意的回调后,加入被邀请方的房间,即:邀请方加入的副房间。
被邀请方在调用应答同意后,加入邀请方的房间,即:被邀请方加入的副房间。
| 邀请方 | 被邀请方 |
|---|---|
| 步骤2:在收到被邀请方同意代理回调后,调用 RCRTCEngine 中 joinOtherRoom: completion: 方法加入副房间 | 步骤1:在应答邀请同意后,调用 RCRTCEngine 中 joinOtherRoom: completion: 方法加入副房间 |
场景五:
在加入主房间前,如果主房间的某用户已经与其他房间另一用户成功建立跨房间连麦。
可以通过加入主房间成功后得到的 RCRTCRoom 对象中检查 room.otherRoomIdArray 中是否存在房间中的用户已经加入的副房间。如果存在,可选择是否加入其他副房间。
@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)];
[self.view addSubview:remoteVideoView];
[videoInputStream setVideoView:remoteVideoView];
}
[streamArray addObject:stream];
}
}
if (streamArray.count > 0) {
[self.mainRTCRoom.localUser subscribeStream:streamArray
tinyStreams:@[]
completion:^(BOOL isSuccess, RCRTCCode 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)];
[self.view addSubview:remoteVideoView];
[videoInputStream setVideoView:remoteVideoView];
}
}
[self.mainRTCRoom.localUser subscribeStream:streams
tinyStreams:@[]
completion:^(BOOL isSuccess, RCRTCCode code) {
// 处理订阅结果
}];
}
离开副房间流程
场景七:
已经加入副房间的用户,需要退出副房间时,可以调用 RCRTCEngine 中的 leaveOtherRoom: completion: 方法。
此方法内部会取消订阅已经订阅的副房间所有用户音视频资源,上层无需自行取消订阅。
当用户离开副房间时,其他用户会收到 RCRTCOtherRoomEventDelegate 中的回调:
- (void)room:(RCRTCBaseRoom *)room didLeaveUser:(RCRTCRemoteUser *)user;
被服务端踢出房间流程
通过调用服务端 API 可以将指定房间的指定用户踢出该房间。
在踢出某个用户之前,建议先通过服务下发消息让此客户端执行结束跨房间连麦 ,然后再从主房间踢出违禁用户。 被踢出的房间是该用户加入的主房间时,RongRTCLib 内部会调用 leaveRoom: 方法先退出已经加入的副房间,再退出主房间并销毁资源。UI 层无需再次调用离开主、副房间的方法,只处理上层逻辑即可。 被踢出的房间是该用户加入的副房间时,RongRTCLib 内部会调用 leaveOtherRoom: completion: 方法仅退出指定的副房间,并取消订阅已经订阅的该副房间中用户的音视频资源,UI 层无需再次调用离开副房间的方法,只处理上层逻辑即可。
- (void)didKickedByServer:(RCRTCBaseRoom *)room;