As of v3.0.0, the Agora RTC SDK enables users to join an unlimited number of channels and to receive the audio and video streams of all those channels.
Agora provides the following open-source sample projects on GitHub. You can download them and refer to the source code.
AgoraRtcChannel
channel:AgoraRtcEngineKit
channel: Breakout Class (iOS)The SDK uses the AgoraRtcChannel
and AgoraRtcChannelDelegate
classes to support the multi-channel function.
You can call createRtcChannel
multiple times to create multiple AgoraRtcChannel
objects with different channelId
, and then call joinChannelByToken
in AgoraRtcChannel
to join the channel.
The following are the major steps of implementing the multi-channel function:
sharedEngineWithAppId
to create and initialize AgoraRtcEngineKit
.setChannelProfile
to set the channel profile as live streaming.createRtcChannel
to create an AgoraRtcChannel
object with a channelId
.setRtcChannelDelegate
of the AgoraRtcChannel
class to receive callbacks in this channel.setClientRole
of the AgoraRtcChannel
class to set the user role.joinChannelByToken
of the AgoraRtcChannel
class to join the channel. After joining a channel, the user publishes the local streams and automatically subscribes to the streams of all the other users in the channel by default. You can set the publishing and subscribing states in ChannelMediaOptions
when joining a channel, and you can change the publishing and subscribing states in the methods with prefixes muteLocal
and muteRemote
of the AgoraRtcChannel
class after joining a channel.Refer to the following API sequence to join multiple channels:
The following code demonstrates how to join an AgoraRtcChannel
channel, and then publish the local streams in the first channel.
Create and initialize AgoraRtcEngineKit
.
let config = AgoraRtcEngineConfig()
config.appId = KeyCenter.AppId
agoraKit = AgoraRtcEngineKit.sharedEngine(with: config, delegate: self)
Enable the video module.
agoraKit.enableVideo()
Set the channel profile as interactive live streaming.
agoraKit.setChannelProfile(.liveBroadcasting)
Create an AgoraRtcChannel1
object, and listen for events in this channel.
channel1 = agoraKit.createRtcChannel(channelName1)
channel1?.setRtcChannelDelegate(self)
Set the user role as a host.
channel1?.setClientRole(.broadcaster)
Pass in token
and channelId
to join the AgoraRtcChannel1
channel. The SDK publishes the local streams and automatically subscribes to the streams of all the other users in the channel by default.
let mediaOptions = AgoraRtcChannelMediaOptions()
mediaOptions.autoSubscribeAudio = YES
mediaOptions.autoSubscribeVideo = YES
mediaOptions.publishLocalAudio = YES
mediaOptions.publishLocalVideo = YES
channel1?.join(byToken: "Your token", info: nil, uid: 0, options: mediaOptions)
Create an AgoraRtcChannel2
object, and listen for events in this channel.
channel2 = agoraKit.createRtcChannel(channelName2)
channel2?.setRtcChannelDelegate(self)
Set the user role as an audience member. Note that audience members cannot publish local streams.
channel2?.setClientRole(.audience)
Pass in token
and channelId
to join the AgoraRtcChannel2
channel. You need to set publishLocalAudio
and publishLocalVideo
to NO
; otherwise, the user fails to join the channel.
let mediaOptions2 = AgoraRtcChannelMediaOptions()
mediaOptions2.autoSubscribeAudio = YES
mediaOptions2.autoSubscribeVideo = YES
mediaOptions2.publishLocalAudio = NO
mediaOptions2.publishLocalVideo = NO
channel2?.join(byToken: "Your token", info: nil, uid: 0, options: mediaOptions2)
Leave and destroy the AgoraRtcChannel2
channel.
channel2?.leave()
channel2?.destroy()
Leave and destroy the AgoraRtcChannel1
channel.
channel1?.leave()
channel1?.destroy()
Destroy the AgoraRtcEngineKit
object.
agoraKit.destroy()
joinChannelByToken
in the AgoraRtcChannel
class provides the media-subscription options (autoSubscribeAudio
and autoSubscribeVideo
) that determine whether to automatically subscribe to the remote streams after joining the channel. The default setting is to subscribe to all the streams automatically. After a user joins a channel, you can change the subscribing state by calling muteRemoteAudioStream
or muteRemoteVideoStream
.
If you need to subscribe to the streams of specified users after joining an AgoraRtcChannel
channel, refer to the following steps:
joinChannelByToken
and set autoSubscribeAudio = NO
or autoSubscribeVideo = NO
of ChannelMediaOptions
to unsubscribe from all remote users.muteRemoteAudioStream (uid,NO)
or muteRemoteVideoStream(uid,NO)
to subscribe to specified remote users.In video scenarios, if a remote user joins the channel using AgoraRtcChannel
, ensure that you specify the channel ID of the remote user in AgoraRtcVideoCanvas
when setting the remote video view.
// Swift
// Set the remote user's view in the didJoinedOfUid callback
func rtcChannel(_ rtcChannel: AgoraRtcChannel, didJoinedOfUid uid: UInt, elapsed: Int) {
LogUtils.log(message: "remote user join: \(uid) \(elapsed)ms", level: .info)
let videoCanvas = AgoraRtcVideoCanvas()
videoCanvas.uid = uid
// The view to bind to
videoCanvas.view = channel1 == rtcChannel ? channel1RemoteVideo.videoView : channel2RemoteVideo.videoView
videoCanvas.renderMode = .hidden
// Specify the channelId of the remote user
videoCanvas.channelId = rtcChannel.getId()
// Set the view for the remote user
agoraKit.setupRemoteVideo(videoCanvas)
}
The SDK supports publishing local streams to only one channel at a time. Agora recommends setting the user role as an audience when joining a channel where the user do not need to publish streams, and setting publishLocalAudio
and publishLocalVideo
in ChannelMediaOptions
to false
when joining the channel.
In the interactive live streaming profile, if a user joins the first channel as a host, the SDK publishes local streams in the first channel by default. If the user needs to join a second channel, you need to change the publishing state according to your actual scenario:
setClientRole(Audience)
).setClientRole(Audience)
) in the first channel and joining the second channel as a host (setClientRole(Broadcaster)
).If a user publishes local streams in a channel and you call the following methods in a second channel, the method call fails, and the SDK returns -5(AgoraErrorCodeRefused)
:
publishLocalAudio = YES
or publishLocalVideo = YES
when joining the second channel.muteLocalAudioStream(NO)
or muteLocalVideoStream(NO)
after joining the second channel.setClientRole(Broadcaster)
.As of v3.4.5, the AgoraRtcChannel
class changes as follows:
publish
and unpublish
, and adds muteLocalAudioStream
and muteLocalVideoStream
instead. After joining a channel, you can set the publishing state of the audio stream and video stream separately. muteLocalAudioStream
and muteLocalVideoStream
in the AgoraRtcEngineKit
and AgoraRtcChannel
classes control the publishing state of each channel in their respective classes only.publishLocalAudio
and publishLocalVideo
members in AgoraRtcChannelMediaOptions
. The default value is YES
. You can call joinChannelByToken
to join a channel and set the publishing state. If a user publishes streams in a channel, regardless of whether the user is a host or an audience member, they need to set publishLocalAudio
and publishLocalVideo
to NO
when joining other channels; otherwise, they fail to join the channel.setClientRole(Broadcaster)
, the local user publishes audio and video streams by default. You no longer need to call publish
.Earlier than v3.4.5:
muteLocalAudioStream(true)
or muteLocalVideoStream(true)
in AgoraRtcEngineKit
takes effect in channels created by both the AgoraRtcEngineKit
and AgoraRtcChannel
classes. muteLocalAudioStream
and muteLocalVideoStream
take effect when they are called before or after a user joins a channel.joinChannelByToken
cannot set the publishing state of local streams.setClientRole(Broadcaster)
of the AgoraRtcChannel
class does not publish local streams. You also need to call publish
.