同一个用户可以加入多个房间,分别订阅和接收这些房间中的音视频流,并在其中一个房间中发布音视频。也可以发送和接收实时消息。
大班小组课:主讲老师在大班房间内讲课,学生在该房间内听讲,同时可以在小组房间交流提问,并由助教老师答疑。
游戏场景:玩家可以在已加入的小队房间内和其他小队成员进行语音互动,同时能收听到世界房间内的广播音频。
会议场景:云端会议过程中,主持人可以发起分组讨论。参会者无需离开原先的会议,即可在各自小组中进行音视频互动,不同讨论组互不干扰。
你已经集成 RTC SDK v3.43 或更新的版本,实现了基本的音视频通话。
支持多房间功能的 SDK 详见API 及回调。
在集成 RTC SDK,并完成业务逻辑代码时,你已发现,音视频引擎类和房间类两个常用的主调类有明显的功能区分:
通过使用音视频引擎类的方法,你可以启动音视频采集,并进行相关设置(如切换摄像头等);
通过房间类的方法,你可以在房间内发布/订阅流,并进行相关设置(如用户自身在房间内的可见性等)。
要让一个用户加入多个房间,可以通过一个音视频引擎实例,创建多个房间实例,并为这些实例设置不同的房间 ID。同一个用户在多个房间中,可以订阅在这些房间中发布的音视频流。
本文以加入两个房间为例,你可以按照相同流程,让用户加入更多房间。
以下时序图以 Android SDK 中的 API 名称为例。不同端的 SDK 中 API 或回调名称可能略有不同,以 API 及回调为准。
创建和初始化一个音视频引擎类。
参考 构建 RTC 应用 获取详细步骤。
// APP_ID: 已经在控制台申请的app_id
// videoEventHandler: 用于接收 RTCVideo 回调的接口实例
rtcVideo = RTCVideo.createRTCVideo(this, Constants.APP_ID, videoEventHandler, null, null);
创建音视频引擎类后,你可以启动音视频采集,并设置渲染视图。
// 开启音视频采集
rtcVideo.startAudioCapture();
rtcVideo.startVideoCapture();
// 设置本地渲染视图,支持 TextureView 和 SurfaceView
private void setLocalRenderView() {
VideoCanvas videoCanvas = new VideoCanvas();
videoCanvas.renderView = localView;
videoCanvas.renderMode = VideoCanvas.RENDER_MODE_HIDDEN;
rtcVideo.setLocalVideoCanvas(StreamIndex.STREAM_INDEX_MAIN, videoCanvas);
}
创建房间实例后,你可以加入房间发布和订阅音视频流。建议设置房间回调接口,以便监听房间和音视频流的状态回调。
继续调用 createRTCRoom 并传入不同房间 ID,以创建多个房间实例,并分别加入这些房间。
// 创建房间1
rtcRoom1 = rtcVideo.createRTCRoom(roomID);
rtcRoom1.setRTCRoomEventHandler(firstRoomEventHandler);
// 创建房间2
rtcRoom2 = rtcVideo.createRTCRoom(roomID);
rtcRoom2.setRTCRoomEventHandler(secondRoomEventHandler);
// 用户信息
UserInfo userInfo = new UserInfo(localUid, "");
// 房间配置
boolean isAutoPublish = true;
boolean isAutoSubscribeAudio = true;
boolean isAutoSubscribeVideo = true;
RTCRoomConfig roomConfig = new RTCRoomConfig(ChannelProfile.CHANNEL_PROFILE_CHAT_ROOM, isAutoPublish, isAutoSubscribeAudio, isAutoSubscribeVideo);
// 加入房间
rtcRoom1.joinRoom(token, userInfo, roomConfig);
// 用户信息
UserInfo userInfo = new UserInfo(localUid, "");
// 一个用户只能在一个房间中发布视频流。
boolean isAutoPublish = false;
boolean isAutoSubscribeAudio = true;
boolean isAutoSubscribeVideo = true;
RTCRoomConfig roomConfig = new RTCRoomConfig(ChannelProfile.CHANNEL_PROFILE_CHAT_ROOM, isAutoPublish, isAutoSubscribeAudio, isAutoSubscribeVideo);
// 加入房间
rtcRoom2.joinRoom(token, userInfo, roomConfig);
public void onRoomStateChanged(String roomId, String uid, int state, String extraInfo) {
if (state == 0) { //进房成功
} else if (state == -1000) { //token错误
} else {// .... 其他错误
}
}
@Override
public void onUserPublishStream(String uid, MediaStreamType type) {
super.onUserPublishStream(uid, type);
runOnUiThread(() -> {
// 设置远端视频渲染视图
RemoteStreamKey remoteStreamKey = new RemoteStreamKey(roomID1, uid, StreamIndex.STREAM_INDEX_MAIN);
VideoCanvas videoCanvas = new VideoCanvas();
videoCanvas.renderView = firstRoomRemoteView;
videoCanvas.renderMode = VideoCanvas.RENDER_MODE_HIDDEN;
rtcVideo.setRemoteVideoCanvas(remoteStreamKey, videoCanvas);
});
}
@Override
public void onUserUnpublishStream(String uid, MediaStreamType type, StreamRemoveReason reason) {
super.onUserUnpublishStream(uid, type, reason);
runOnUiThread(() -> {
// 解除远端视频渲染视图绑定
RemoteStreamKey remoteStreamKey = new RemoteStreamKey(roomID1, uid, StreamIndex.STREAM_INDEX_MAIN);
rtcVideo.setRemoteVideoCanvas(remoteStreamKey, null);
});
}
用户结束通话时,退出各个房间,并销毁本地房间实例。
rtcRoom.leaveRoom();
rtcRoom.destroy();
rtcRoom = null;
在销毁所有房间实例后可销毁音视频引擎。
RTCVideo.destroyRTCVideo();
参考以下项目获取完整代码。在示例项目中,本端用户加入了两个不同的 RTC 房间。你可以按照相同流程,让用户加入更多房间。
你可以根据上文的描述和示例,使用以下客户端 SDK,在不同的端上实现同一用户加入多房间功能。
说明:表格中的 macOS API 接口为 Objective-C,而示例项目中的 macOS 项目使用的是 Windows SDK 中的 API 接口。
A:对于一个音视频引擎实例,即使加入了多个房间,也仅能同时在其中的一个房间中发布音视频流。如果需要在多个房间中同时发布音视频流,参看 跨房间转发媒体流 。
A:确保每个房间的 token 使用了对应的 roomId 生成。更多 Token 相关问题,参见 Token 使用常见问题