跨房间连麦
跨房间连麦中需要区分主房间和副房间概念。主副房间是相对概念,定义如下:
- 主房间:本端在最开始加入的房间,即 RCRTCRoom。
- 副房间:在连麦邀请被接受后,双方均需要加入对方房间。对方房间即:RCRTCOtherRoom。
跨房间连麦前需要双方都已经加入自己的主房间,未加入主房间前无法进行连麦的邀请和被邀请。
两种房间的类都有对应的代理 IRCRTCRoomEventsListener 和 IRCRTCOtherRoomEventsListener 用来区分不同类型房间的回调。
主流程
发起邀请
向指定用户发送跨房间连麦请求,使用加入房 间成功回调返回的 RCRTCRoom
类获取 RCRTCLocalUser
对象,调用 requestJoinOtherRoom
方法。
-
代码示例:
/**
* 向指定用户发送跨房间连麦请求
* <P>
* 1: inviterAutoMix为true时:
*
* 1.1:如果被邀请方在加入邀请方房间之前发布了资源,当被邀请方加入邀请者房间成功后,服务器会把被邀请方流资源合并到邀请方视图 ·(默认仅悬浮布局合流)上。
*
* 1.2:如果被邀请方在加入邀请方房间之前没有发布过资源,将会在被邀请方发布资源成功后,服务器会把被邀请方流资源合并 到邀请方视图(默认仅悬浮布局合流)上。
*
* 2:无论为true或false,双方都可以使用{@link RCRTCLiveInfo#setMixConfig(RCRTCMixConfig, IRCRTCResultCallback)} 方法主动设置合流布局。一旦主动设置过合流布局,后续音视频直播过程中设置的自动合流参数将失效。
* <P/>
*/
RCRTCRoom.getLocalUser().requestJoinOtherRoom(inviteeRoomId, inviteeUserId, inviterAutoMix, "extra", new IRCRTCResultCallback() {
@Override
public void onSuccess() {
}
@Override
public void onFailed(RTCErrorCode errorCode) {
}
}); -
API 参考:
取消邀请
收到其他房间主播连麦邀请后,如果不打算加入,则调用 RCRTCLocalUser
中的 cancelRequestJoinOtherRoom
来取消正在进行中的跨房间连麦请求。
-
代码示例:
RCRTCRoom.getLocalUser().cancelRequestJoinOtherRoom(inviteeRoomId, inviteeUserId, "extra", new IRCRTCResultCallback() {
@Override
public void onSuccess() {
}
@Override
public void onFailed(RTCErrorCode errorCode) {
}
}); -
API 参考:
应答邀请
收到其他房间主播连麦邀请后,如果打算加入,则需要先调用 RCRTCLocalUser
中的 responseJoinOtherRoom
来响应跨房间麦连麦邀请,再调用 joinOtherRoom
加入副房间。
-
代码示例:
/**
* <P>
* 1:inviteeAutoMix 为true时:
*
* 1.1:如果邀请方在发送连麦请求之前发布了资源,当被邀请方加入邀请者房间成功后,服务器会把邀请方流资源合并到被邀请方视图(默认仅悬浮布局合流)上。
*
* 1.2:如果邀请方在发送连麦请求之前没有发布资源,将会在邀请方发布资源成功后,服务器才会把邀请方的资源合并到被邀请方视图(默认仅悬浮布局合流)上。
*
* 2: 无论为true或false,双方都可以使用{@link RCRTCLiveInfo#setMixConfig(RCRTCMixConfig, IRCRTCResultCallback)} 方法主动设置合流布局。一旦主动设置过合流布局, 后续音视频直播过程中设置的自动合流参数将失效。
*
* <P/>
*/
RCRTCRoom.getLocalUser().responseJoinOtherRoom(inviterRoomId, inviterUserId, agree, inviteeAutoMix, "extra", new IRCRTCResultCallback() {
@Override
public void onSuccess() {
}
@Override
public void onFailed(RTCErrorCode errorCode) {
}
}); -
API 参考:
加入副房间
-
代码示例:
RCRTCEngine.getInstance().joinOtherRoom(roomId, new IRCRTCResultDataCallback<RCRTCOtherRoom>() {
@Override
public void onSuccess(RCRTCOtherRoom rcrtcOtherRoom) {
}
@Override
public void onFailed(RTCErrorCode rtcErrorCode) {
}
}); -
API 参考:
注册其他房间事件监听
-
在加入其他房间成功后的回调中,可以得到
RCRTCOtherRoom
对象,调用其中的registerOtherRoomEventsListener
即可注册其他房间事件监听。当有其他房间主播加入、离开、发布资源后会触发此监听回调,在回调中订阅用户音视频资源,可进行音视频通话。 -
在不使用或退出房间之前需取消注册
RCRTCOtherRoom.unregisterOtherRoomEventsListener
。RCRTCOtherRoom.registerOtherRoomEventsListener(new IRCRTCOtherRoomEventsListener() {
/**
* 其他房间内用户发布资源
*
* @param rcrtcOtherRoom 加入的其他房间对象
* @param rcrtcRemoteUser 远端用户
* @param list 发布的资源
*/
@Override
public void onRemoteUserPublishResource(RCRTCOtherRoom rcrtcOtherRoom, RCRTCRemoteUser rcrtcRemoteUser, List<RCRTCInputStream> list) {}
/**
* 其他房间用户发布的音频资源静音或者取消静音
*
* @param rcrtcOtherRoom 加入的其他房间对象
* @param rcrtcRemoteUser 远端用户
* @param rcrtcInputStream 音频流
* @param mute true表示静音,false表示取消静音
*/
@Override
public void onRemoteUserMuteAudio(RCRTCOtherRoom rcrtcOtherRoom, RCRTCRemoteUser rcrtcRemoteUser, RCRTCInputStream rcrtcInputStream, boolean mute) {}
/**
* 远端用户打开或关闭发布的视频流。 例如用户开启或者关闭摄像头
*
* @param rcrtcOtherRoom 加入的其他房间对象
* @param rcrtcRemoteUser 远端用户
* @param rcrtcInputStream 视频流
* @param mute true表示关闭,false表示打开
*/
@Override
public void onRemoteUserMuteVideo(RCRTCOtherRoom rcrtcOtherRoom, RCRTCRemoteUser rcrtcRemoteUser, RCRTCInputStream rcrtcInputStream, boolean mute) {}
/**
* 房间内用户取消发布资源
*
* @param rcrtcOtherRoom 加入的其他房间对象
* @param rcrtcRemoteUser 远端用户
* @param list 远端用户取消发布的资源
*/
@Override
public void onRemoteUserUnpublishResource(RCRTCOtherRoom rcrtcOtherRoom, RCRTCRemoteUser rcrtcRemoteUser, List<RCRTCInputStream> list) {}
/**
* 用户加入房间
*
* @param rcrtcOtherRoom 加入的其他房间对象
* @param rcrtcRemoteUser 远端用户
*/
@Override
public void onUserJoined(RCRTCOtherRoom rcrtcOtherRoom, RCRTCRemoteUser rcrtcRemoteUser) {}
/**
* 用户离开房间
*
* @param rcrtcOtherRoom 加入的其他房间对象
* @param rcrtcRemoteUser 远端用户
*/
@Override
public void onUserLeft(RCRTCOtherRoom rcrtcOtherRoom, RCRTCRemoteUser rcrtcRemoteUser) {}
/**
* 用户离线
*
* @param rcrtcOtherRoom 加入的其他房间对象
* @param rcrtcRemoteUser 远端用户
*/
@Override
public void onUserOffline(RCRTCOtherRoom rcrtcOtherRoom, RCRTCRemoteUser rcrtcRemoteUser) {}
/**
* 自己退出其他房间。 例如断网退出等
*
* @param rcrtcOtherRoom 加入的其他房间对象
* @param reasonCode 状态码
*/
@Override
public void onLeaveRoom(RCRTCOtherRoom rcrtcOtherRoom, int reasonCode) {}
});
离开副房间
当需要结束跨房间连麦时,调用 RCRTCEngine
中的 leaveOtherRoom
离开副房间。
-
代码示例:
RCRTCEngine.getInstance().leaveOtherRoom(roomId, notifyFinished, new IRCRTCResultCallback() {
@Override
public void onSuccess() {
}
@Override
public void onFailed(RTCErrorCode rtcErrorCode) {
}
}); -
API 参考:
邀请连麦流程
-
场景一,邀请方发起邀请后,邀请方又取消邀请。
提示此场景中被邀请方未做任何操作,仅被动收到两次代理回调。
邀请方 | 被邀请方 |
---|---|
步骤1:调用 RCRTCLocalUser 类中的 requestJoinOtherRoom 方法发起跨房间连麦邀请 | 步骤2:在 IRCRTCRoomEventsListener 中收到 onRequestJoinOtherRoom 邀请回调 |
步骤3:调用 RCRTCLocalUser 类中的 cancelRequestJoinOtherRoom 方法结束之前发起的邀请 | 步骤4:在 IRCRTCRoomEventsListener 中收到 onCancelRequestOtherRoom 取消受邀请的回调 |
-
场景二,邀请方发起邀请后,被邀请方应答同意。
提示此场景中被邀请方应答同意,只有被邀请方不会收到应答的回调,包含邀请人在内两个房间的所有非观众用户都会收到代理回调。
邀请方 | 被邀请方 |
---|---|
步骤1:调用 RCRTCLocalUser 类中的 requestJoinOtherRoom 方法发起跨房间连麦邀请 | 步骤2:在 IRCRTCRoomEventsListener 中收到 onRequestJoinOtherRoom 邀请回调 |
步骤4:包含邀请人在内两个房间的所有非观众用户,不包含被邀请方,会在 IRCRTCRoomEventsListener 中收到 onResponseJoinOtherRoom 应答回调 | 步骤3:调用 RCRTCLocalUser 类中的 responseJoinOtherRoom 应答邀请,其中,agree 参数的值为 true |
-
场景三,邀请方发起邀请后,被邀请方应答拒绝。
提示此场景中被邀请方应答拒绝,只有邀请方会收到应答拒绝的回调,其他所有用户都不会收到代理回调。
邀请方 | 被邀请方 |
---|---|
步骤1:调用 RCRTCLocalUser 类中的 requestJoinOtherRoom 方法发起跨房间连麦邀请 | 步骤2:在 IRCRTCRoomEventsListener 中收到 onRequestJoinOtherRoom 邀请回调 |
步骤4:只有邀请方会收到应答拒绝的回调,其他所有用户都不会收 到 IRCRTCRoomEventsListener 中的 onResponseJoinOtherRoom 应答回调 | 步骤3:调用 RCRTCLocalUser 类中的 responseJoinOtherRoom 应答邀请,其中,agree 参数的值为 false |
加入副房间流程
-
场景四,在 场景二 的前提下,邀请方在收到应答同意的回调后,加入被邀请方的房间,即:邀请方加入的副房间。
被邀请方在调用应答同意后,加入邀请方的房间,即:被邀请方加入的副房间。
邀请方 被邀请方 步骤2:在收到被邀请方同意代理回调后,调用 RCRTCEngine 中 joinOtherRoom
方法加入副房间步骤1:在应答邀请同意后,调用 RCRTCEngine 中 joinOtherRoom
方法加入副房间 -
场景五,在加入主房间前,如果主房间的某用户已经与其他房间另一用户成功建立跨房间连麦。
可以通过 加入主房间成功后得到的 RCRTCRoom 对象中检查
getOtherRoomIds()
中是否存在房间中的用户已经加入的副房间。如果存在,可选择是否加入其他副房间/**
* 主房间中主播已经加入的副房间Id列表
*/
List<String> getOtherRoomIds();跨房间连麦成功后加入主房间的用户 步骤1:调用 RCRTCEngine 中 joinRoom
方法加入主房间步骤2:检查发现 getOtherRoomIds()
中存在其他副房间步骤3:调用 RCRTCEngine
中joinOtherRoom
方法加入副房间
订阅流程
在 场景四 或 场景五 的前提下。
-
场景六,订阅副房间用户已经发布的音视频资源方式一:加入副房间后,通过遍历取得副房间中所有远端用户中的 RCRTCInputStream 列表,再调用 RCRTCLocalUser 中
subscribeStreams
方法订阅副房间中远端用户已经发布的音视频资源。RCRTCEngine.getInstance().joinOtherRoom(roomId, new IRCRTCResultDataCallback<RCRTCOtherRoom>() {
@Override
public void onSuccess(RCRTCOtherRoom rcrtcOtherRoom) {
List<RCRTCInputStream> inputStreamList=new ArrayList<>();
//遍历远端用户列表
for (int i = 0; i < rcrtcOtherRoom.getRemoteUsers().size(); i++) {
//遍历远端用户发布的资源列表
for (RCRTCInputStream stream : rcrtcOtherRoom.getRemoteUsers().get(i).getStreams()) {
if(stream.getMediaType()== RCRTCMediaType.VIDEO){
//如果远端用户发布的是视频流,创建显示视图RCRTCVideoView,并添加到布局中显示
RCRTCVideoView remoteView = new RCRTCVideoView(MainActivity.this);
((RCRTCVideoInputStream)stream).setVideoView(remoteView);
//todo 本demo只演示添加1个远端用户的视图
frameyout_remote.removeAllViews();
frameyout_remote.addView(remoteView);
}
//如果要订阅所有远端用户的流。将其保存,方便后面统一订阅
inputStreamList.add(stream);
}
}
//开始订阅资源
RCRTCRoom.getLocalUser().subscribeStreams(inputStreamList, new IRCRTCResultDataCallback<List<RCRTCInputStream>>() {
@Override
public void onSuccess() {
}
@Override
// 如果 SDK ≧ 5.3.4,您可以使用 IRCRTCResultDataCallback,onFailed 方法会返回订阅失败的流列表和错误码。
// 如果 SDK < 5.3.4,仅 支持使用 IRCRTCResultCallback,onFailed 方法仅返回错误码。
public void onFailed(List<RCRTCInputStream> failedStreams, RTCErrorCode errorCode) {
}
});
}
@Override
public void onFailed(RTCErrorCode rtcErrorCode) {
}
}); -
订阅副房间用户刚发布的音视频资源方式二:加入副房间后,当有副房间中远端用户发布资源时,会回调 IRCRTCOtherRoomEventsListener 中
onRemoteUserPublishResource
方法,调用 RCRTCLocalUser 中subscribeStreams
方法订阅副房间中远端用户刚发布的音视频资源。@Override
public void onRemoteUserPublishResource(RCRTCOtherRoom rcrtcOtherRoom, RCRTCRemoteUser rcrtcRemoteUser, List<RCRTCInputStream> list) {
//遍历远端用户发布的资源列表
for (RCRTCInputStream stream : list) {
if(stream.getMediaType()== RCRTCMediaType.VIDEO){
//如果远端用户发布的是视频流,创建显示视图RCRTCVideoView,并添加到布局中显示
RCRTCVideoView remoteView = new RCRTCVideoView(MainActivity.this);
((RCRTCVideoInputStream)stream).setVideoView(remoteView);
frameyout_remote.removeAllViews();
frameyout_remote.addView(remoteView);
}
}
//开始订阅资源
RCRTCRoom.getLocalUser().subscribeStreams(list, new IRCRTCResultDataCallback<List<RCRTCInputStream>>() {
@Override
public void onSuccess() {
}
@Override
// 如果 SDK ≧ 5.3.4,您可以使用 IRCRTCResultDataCallback,onFailed 方法会返回订阅失败的流列表和错误码。
// 如果 SDK < 5.3.4,仅支持使用 IRCRTCResultCallback,onFailed 方法仅返回错误码。
public void onFailed(List<RCRTCInputStream> failedStreams, RTCErrorCode errorCode) {
}
});
}
离开副房间流程
-
场景七,已经加入副房间的用户,需要退出副房间时,可以调用 RCRTCEngine 中的
leaveOtherRoom(String roomId, boolean notifyFinished, IRCRTCResultCallback callBack)
方法。提示此方法内部会取消订阅已经订阅的副房间所有用户音视频资源,上层无需自行取消订阅。 此方法中的
notifyFinished
参数为false
时,仅代表调用方离开副房间,其他用户会收到 IRCRTCOtherRoomEventsListener 中onUserLeft
回调。
@Override
public void onUserLeft(RCRTCOtherRoom rcrtcBaseRoom, RCRTCRemoteUser rcrtcRemoteUser) {
}
-
当
notifyFinished
参数为true
时,其他用户会收到 IRCRTCOtherRoomEventsListener 中onUserLeft
和在 IRCRTCRoomEventsListener 中onFinishOtherRoom
回调。/**
* 用户离开房间
*
* @param rcrtcBaseRoom 加入的其他房间对象
* @param rcrtcRemoteUser 远端用户
*/
@Override
public void onUserLeft(RCRTCOtherRoom rcrtcBaseRoom, RCRTCRemoteUser rcrtcRemoteUser) {
}/**
* 收到结束跨房间连麦的通知
*
* @param roomId 结束连麦的房间 Id
* @param userId 发起结束连麦的用户 id
*/
@Override
public void onFinishOtherRoom(String roomId, String userId) {
super.onFinishOtherRoom(roomId, userId);
}
被服务端踢出房间流程
通过调用服务端 API 可以将指定房间的指定用户踢出该房间。
-
在踢出某个用户之前 ,建议先通过服务下发消息让此客户端执行结束跨房间连麦 ,然后再从主房间踢出违禁用户。
-
被踢出的房间是该用户加入的主房间时,RongRTCLib 内部会调用
RCRTCEngine.getInstance().leaveRoom
方法先退出已经加入的副房间,再退出主房间并销毁资源。UI 层无需再次调用离开主、副房间的方法,只处理上层逻辑即可。 -
被踢出的房间是该用户加入的副房间时,RongRTCLib 内部会调用 IRCRTCOtherRoomEventsListener 中
onKickedByServer(RCRTCOtherRoom rcrtcBaseRoom)
方法仅退出指定的副房间,并取消订阅已经订阅的该副房间中用户的音视频资源,UI 层无需再次调用离开副房间的方法,只处理上层逻辑即可。/**
* 被服务端踢下线
* <p>如果用户在房间内, 此时收到服务器封禁的通知, SDK 会关闭音视频连接, 释放资源,
* 将用户踢出房间, 回调通知用户</p>
*
* @param rcrtcBaseRoom 加入的其他房间对象
*/
@Override
public void onKickedByServer(RCRTCOtherRoom rcrtcBaseRoom) {
super.onKickedByServer(rcrtcBaseRoom);
}