You need to enable JavaScript to run this app.
导航

同一用户加入多个房间

最近更新时间2024.03.13 15:27:32

首次发布时间2023.03.21 14:36:57

同一个用户可以加入多个房间,分别订阅和接收这些房间中的音视频流,并在其中一个房间中发布音视频。也可以发送和接收实时消息

适用场景

  • 大班小组课:主讲老师在大班房间内讲课,学生在该房间内听讲,同时可以在小组房间交流提问,并由助教老师答疑。

  • 游戏场景:玩家可以在已加入的小队房间内和其他小队成员进行语音互动,同时能收听到世界房间内的广播音频。

  • 会议场景:云端会议过程中,主持人可以发起分组讨论。参会者无需离开原先的会议,即可在各自小组中进行音视频互动,不同讨论组互不干扰。

前提条件

你已经集成 RTC SDK v3.43 或更新的版本,实现了基本的音视频通话。
支持多房间功能的 SDK 详见API 及回调

功能实现

在集成 RTC SDK,并完成业务逻辑代码时,你已发现,音视频引擎类和房间类两个常用的主调类有明显的功能区分:

  • 通过使用音视频引擎类的方法,你可以启动音视频采集,并进行相关设置(如切换摄像头等);

  • 通过房间类的方法,你可以在房间内发布/订阅流,并进行相关设置(如用户自身在房间内的可见性等)。

要让一个用户加入多个房间,可以通过一个音视频引擎实例,创建多个房间实例,并为这些实例设置不同的房间 ID。同一个用户在多个房间中,可以订阅在这些房间中发布的音视频流。
本文以加入一个房间为例,你可以按照相同流程,让用户加入更多房间。

以下时序图以 Android SDK 中的 API 名称为例。不同端的 SDK 中 API 或回调名称可能略有不同,以 API 及回调为准。

alt

1. 创建引擎类

创建和初始化一个音视频引擎类。

参考 构建 RTC 应用 获取详细步骤。

// APP_ID: 已经在控制台申请的app_id
// videoEventHandler: 用于接收 RTCVideo 回调的接口实例
rtcVideo = RTCVideo.createRTCVideo(this, Constants.APP_ID, videoEventHandler, null, null);

2. 启动音视频采集

创建音视频引擎类后,你可以启动音视频采集,并设置渲染视图。

// 开启音视频采集
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);
}

3. 创建房间实例

创建房间实例后,你可以加入房间发布和订阅音视频流。建议设置房间回调接口,以便监听房间和音视频流的状态回调。
继续调用 createRTCRoom 并传入不同房间 ID,以创建多个房间实例,并分别加入这些房间。

// 创建房间1
rtcRoom1 = rtcVideo.createRTCRoom(roomID);
rtcRoom1.setRTCRoomEventHandler(firstRoomEventHandler);

// 创建房间2
rtcRoom2 = rtcVideo.createRTCRoom(roomID);
rtcRoom2.setRTCRoomEventHandler(secondRoomEventHandler);

4. 加入 RTC 房间

alt

  1. 加入每个房间时,默认自动订阅房间中的音视频流。
// 用户信息
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, "");
// room2不发流
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);
  1. 监听进房状态,处理进房失败。
public void onRoomStateChanged(String roomId, String uid, int state, String extraInfo) {
    if (state == 0) { //进房成功
    } else if (state == -1000) { //token错误
    } else {// .... 其他错误
    }
}
  1. 订阅端在接收到其他用户发布/取消发布音视频流回调时,设置渲染视图。
@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);
    });
}

5. 离开 RTC 房间

用户结束通话时,退出各个房间,并销毁本地房间实例。

rtcRoom.leaveRoom();
rtcRoom.destroy();
rtcRoom = null;

6. 销毁引擎类

在销毁所有房间实例后可销毁音视频引擎。

RTCVideo.destroyRTCVideo();

示例项目

参考以下项目获取完整代码。在示例项目中,本端用户加入了两个不同的 RTC 房间。你可以按照相同流程,让用户加入更多房间。

API 及回调

你可以根据上文的描述和示例,使用以下客户端 SDK,在不同的端上实现同一用户加入多房间功能。

说明:表格中的 macOS API 接口为 Objective-C,而示例项目中的 macOS 项目使用的是 Windows SDK 中的 API 接口。

平台AndroidiOSmacOSWindowsLinuxElectronFlutterUnity
音视频引擎类RTCVideoByteRTCVideoByteRTCVideoIRTCVideoIRTCVideoRTCVideoRTCVideoIRTCVideo
开启视频采集startVideoCapturestartVideoCapturestartVideoCapturestartVideoCapturestartVideoCapturestartVideoCapturestartVideoCaptureStartVideoCapture
开始音频采集startAudioCapturestartAudioCapturestartAudioCapturestartAudioCapturestartAudioCapturestartAudioCapturestartAudioCaptureStartAudioCapture
设置本地视图setLocalVideoCanvassetLocalVideoCanvas:withCanvas:setLocalVideoCanvas:withCanvas:setLocalVideoCanvassetLocalVideoCanvassetupLocalVideoRTCViewContextSetLocalVideoSink
创建房间createRTCRoomcreateRTCRoom:createRTCRoom:createRTCRoomcreateRTCRoomcreateRTCRoomcreateRTCRoomCreateRTCRoom
音视频房间类RTCRoomByteRTCRoomByteRTCRoomIRTCRoomIRTCRoomRTCRoomRTCRoomIRTCVideoRoom
设置房间回调setRTCRoomEventHandlersetRTCRoomDelegate:setRTCRoomDelegate:setRTCRoomEventHandlersetRTCRoomEventHandlersetRTCRoomEventHandler
加入房间joinRoomjoinRoom:userInfo:roomConfig:joinRoom:userInfo:roomConfig:joinRoomjoinRoomjoinRoomjoinRoomJoinRoom
房间状态回调onRoomStateChangedrtcRoom:onRoomStateChanged:withUid:state:extraInfo:rtcRoom:onRoomStateChanged:withUid:state:extraInfo:onRoomStateChangedonRoomStateChangedonRoomStateChangedonRoomStateChangedonRoomStateChanged
发布回调onUserPublishStreamrtcRoom:onUserPublishStream:type:rtcRoom:onUserPublishStream:type:onUserPublishStreamonUserPublishStreamonUserPublishStreamonUserPublishStreamOnUserPublishStreamEventHandler
取消发布回调onUserUnpublishStreamrtcRoom:onUserUnpublishStream:type:reason:rtcRoom:onUserUnpublishStream:type:reason:onUserUnpublishStreamonUserUnpublishStreamonUserUnpublishStreamonUserUnpublishStreamOnUserUnPublishStreamEventHandler
离开房间leaveRoomleaveRoomleaveRoomleaveRoomleaveRoomleaveRoomleaveRoomLeaveRoom
销毁房间destroydestroydestroydestroydestroydestroydestroyDestroy
销毁音视频引擎destroyRTCVideodestroyRTCVideodestroyRTCVideodestroyRTCVideodestroyRTCVideodestroyRTCVideodestroyRelease

常见问题

Q1: 同一用户如何在多个房间内同时发送音视频流?

A:对于一个音视频引擎实例,即使加入了多个房间,也仅能同时在其中的一个房间中发布音视频流。如果需要在多个房间中同时发布音视频流,参看 跨房间转发媒体流

Q2: 如何处理 Token 相关错误?

A:确保每个房间的 token 使用了对应的 roomId 生成。更多 Token 相关问题,参见 Token 使用常见问题