As of v3.0.0, the Agora RTC SDK enables users to join an unlimited number of channels at a time and to receive the audio and video streams of all the channels.
Agora provides the following open-source sample projects on GitHub. You can download them and refer to the source code.
The SDK uses the RtcChannel
and IRtcChannelEventHandler
classes to support the multi-channel function.
You can call createRtcChannel
multiple times to create multiple RtcChannel
objects with different channelId
, and then call joinChannel
in RtcChannel
to join the channel.
The following are the major steps of implementing the multi-channel function:
create
to create and initialize RtcEngine
.setChannelProfile
to set the channel profile as live streaming.createRtcChannel
to create an RtcChannel
object with channelId
.setRtcChannelEventHandler
of the RtcChannel
class to receive the callbacks in this channel.joinChannel
of the RtcChannel
class to join the channel.RtcEngine
channel: Call setClientRole
of the RtcEngine
class to set the user role as host, and then call joinChannel
to join the channel. The SDK automatically publishes the local stream after joining the channel. This method applies to scenarios where the local stream is published in a fixed channel.RtcChannel
channel: Call setClientRole
of the RtcChannel
class to set the user role as host, and then call publish
to publish the local stream. This method applies to scenarios where the local stream needs to be published to different channels.publish
of the RtcChannel
class, ensure that the user role is set as host by calling setClientRole
.RtcChannel
channel, and you must call unpublish
before publishing the local stream to another channel.Refer to the following API sequence to join multiple channels and publish the local stream in an RtcEngine
channel:
Refer to the following API sequence to join multiple channels and publish the local stream in an RtcChannel
channel:
The following code demonstrates how to join an RtcEngine
channel and an RtcChannel
channel, and publish the local stream in the RtcEngine
channel.
Create and initialize RtcEngine
.
engine = RtcEngine.create(context.getApplicationContext(), getString(R.string.agora_app_id), iRtcEngineEventHandler);
Enable the video module.
engine.enableVideo();
Set the channel profile as live streaming.
engine.setChannelProfile(Constants.CHANNEL_PROFILE_LIVE_BROADCASTING);
Set the usr role as host.
engine.setClientRole(IRtcEngineEventHandler.ClientRole.CLIENT_ROLE_BROADCASTER);
Pass in token
and channelId
to join the IRtcEngine
channel. The SDK automatically publishes the local stream after joining the channel.
engine.joinChannel(accessToken, channelId, "Extra Optional Data", 0);
Create and get an RtcChannel
object, and listen for events in this channel.
rtcChannel = engine.createRtcChannel(channel2);
rtcChannel.setRtcChannelEventHandler(new IRtcChannelEventHandler() {
@Override
// Listen for the onJoinChannelSuccess callback.
// This callback occurs when the local user successfully joins the channel.
public void onJoinChannelSuccess(RtcChannel rtcChannel, int uid, int elapsed) {
super.onJoinChannelSuccess(rtcChannel, uid, elapsed);
Log.i(TAG, String.format("onJoinChannelSuccess channel %s uid %d", channel2, uid));
}
@Override
// Listen for the onUserJoinedcallback.
// This callback occurs when a remote host joins a channel.
public void onUserJoined(RtcChannel rtcChannel, int uid, int elapsed) {
super.onUserJoined(rtcChannel, uid, elapsed);
Log.i(TAG, "onUserJoined->" + uid);
}
});
Join the RtcChannel
channel. The SDK subscribes to audio and video streams when the user joins the channel by default.
int ret = rtcChannel.joinChannel(null, "", 0, mediaOptions);
return (ret == 0);
Leave and destroy RtcChannel
.
rtcChannel.leaveChannel();
rtcChannel.destroy();
Leave the RtcEngine
channel, and destroy the RtcEngine
object.
engine.leaveChannel();``engine.destroy();
If you set autoSubscribeAudio
or autoSubscribeVideo
as false, the method call of muteRemoteAudioStream
or muteRemoteVideoStream
does not take effect after joining an RtcChannel
channel.
joinChannel
in the RtcChannel
class provides the media subscription options (autoSubscribeAudio
and autoSubscribeVideo
) to determine whether to susbcribe to the remote streams after joining the channel. The default setting is to subscribe to all the streams automatically.If you need to subscribe to streams of specified users after joining an RtcChannel
channel, refer to the following steps:
setDefaultMuteAllRemoteAudioStreams(true)
or setDefaultMuteAllRemoteVideoStreams(true)
in the RtcChannel
class to not receive any audio or video streams.joinChannel
with default media subscription options to join the channel.muteRemoteAudioStream(false)
or muteRemoteVideoStream(false)
to subscribe to streams of the specified users.In video scenarios, if the remote user joins the channel using RtcChannel
, ensure that you specify the channel ID of the remote user in VideoCanvas
when setting the remote video view.
// Set the remote user's view in the onUserJoined callback.
public void onUserJoined(RtcChannel rtcChannel, int uid, int elapsed) {
super.onUserJoined(rtcChannel, uid, elapsed);
Log.i(TAG, "onUserJoined->" + uid);
showLongToast(String.format("user %d joined!", uid));
Context context = getContext();
if (context == null) {
return;
}
handler.post(() ->
{
SurfaceView surfaceView = null;
if (fl_remote2.getChildCount() > 0) {
fl_remote2.removeAllViews();
}
// Create a SurfaceView object.
surfaceView = RtcEngine.CreateRendererView(context);
surfaceView.setZOrderMediaOverlay(true);
// Add the SurfaceView object to the layout of remote users.
fl_remote2.addView(surfaceView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
// Set the remote video view.
engine.setupRemoteVideo(new VideoCanvas(surfaceView, RENDER_MODE_FIT, channel2, uid));
});
}
The SDK supports publishing one stream to only one channel at a time, and the default behavior differs after the method call of joinChannel
in the RtcEngine
and RtcChannel
classes:
RtcEngine
class, the SDK publishes the local stream by default.RtcChannel
class, the SDK does not publish the local stream.You must meet the following requirements to implement the multi-channel function. Otherwise, the SDK returns ERR_REFUSED(5)
:
joinChannel
method in the RtcChannel
class: After calling publish
for Channel 1, you need to call unpublish
for Channel 1 before calling publish
for Channel 2.RtcEngine
and RtcChannel
classes:RtcEngine
class, and Channel 2 using the RtcChannel
class, you cannot call publish
in the RtcChannel
class.RtcEngine
class, and Channel 2 through the RtcChannel
class, you cannot call publish
in the RtcChannel
class.publish
method in the RtcChannel
class as an audience member.publish
in the RtcChannel
class, you need to call unpublish
in the RtcChannel
class. Otherwise, you cannot call joinChannel
in the RtcEngine
class.