Skip to main content

You are looking at Interactive Live Streaming v3.x Docs. The newest version is  Interactive Live Streaming 4.x

Android
iOS
macOS
Windows C++
Windows C#
Unity
Flutter
React Native
Electron
Cocos Creator
Cocos2d-x

Join Multiple Channels

Introduction

As of v3.0.0, the Agora Video SDK enables users to join an unlimited number of channels and to receive the audio and video streams of all those channels.

  • This feature applies to the live streaming channel profile. Do not use it for the communication profile.
  • As of v3.4.5, Agora optimizes the publishing logic in the multichannel scenario. If you have upgraded the SDK from an earlier version to v3.4.5 or later, Agora recommends that you adjust your publishing settings by referring to API changes to avoid any impact on your business functions.
  • Sample project

    Agora provides the following open-source sample projects on GitHub. You can download them and refer to the source code.

    Implementation

    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:

    1. Call sharedEngineWithAppId to create and initialize AgoraRtcEngineKit.
    2. Call setChannelProfile to set the channel profile as live streaming.
    3. Call createRtcChannel to create an AgoraRtcChannel object with a channelId.
    4. Call setRtcChannelDelegate of the AgoraRtcChannel class to receive callbacks in this channel.
    5. Call setClientRole of the AgoraRtcChannel class to set the user role.
    6. Call 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 muteLocaland muteRemote of the AgoraRtcChannel class after joining a channel.
    7. Repeat steps 3, 4, 5, and 6 to join more channels.
  • Ensure that each channel you join has a unique channel name.
  • A user can publish local streams in only one channel at a time. Agora recommends joining a channel as a host when the user needs to publish local streams or as an audience member when the user does not need to publish local streams.
  • API call sequence

    Refer to the following API sequence to join multiple channels:

    1624445956430

    Sample code

    The following code demonstrates how to join an AgoraRtcChannel channel, and then publish the local streams in the first channel.

    1. Create and initialize AgoraRtcEngineKit.
    let config = AgoraRtcEngineConfig()
    config.appId = KeyCenter.AppId
    agoraKit = AgoraRtcEngineKit.sharedEngine(with: config, delegate: self)
    Copy
    1. Enable the video module.
    agoraKit.enableVideo()
    Copy
    1. Set the channel profile as interactive live streaming.
    agoraKit.setChannelProfile(.liveBroadcasting)
    Copy
    1. Create an AgoraRtcChannel1 object, and listen for events in this channel.
    channel1 = agoraKit.createRtcChannel(channelName1)
    channel1?.setRtcChannelDelegate(self)
    Copy
    1. Set the user role as a host.
    channel1?.setClientRole(.broadcaster)
    Copy
    1. 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)
    Copy
    1. Create an AgoraRtcChannel2 object, and listen for events in this channel.
    channel2 = agoraKit.createRtcChannel(channelName2)
    channel2?.setRtcChannelDelegate(self)
    Copy
    1. Set the user role as an audience member. Note that audience members cannot publish local streams.
    channel2?.setClientRole(.audience)
    Copy
    1. 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)
    Copy
    1. Leave and destroy the AgoraRtcChannel2 channel.
    channel2?.leave()
    channel2?.destroy()
    Copy
    1. Leave and destroy the AgoraRtcChannel1 channel.
    channel1?.leave()
    channel1?.destroy()
    Copy
    1. Destroy the AgoraRtcEngineKit object.
    agoraKit.destroy()
    Copy

    API reference

    Considerations

    Subscribing limits

    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:

    1. Call joinChannelByToken and set autoSubscribeAudio = NO or autoSubscribeVideo = NO of ChannelMediaOptions to unsubscribe from all remote users.
    2. In the channel, call muteRemoteAudioStream (uid,NO) or muteRemoteVideoStream(uid,NO) to subscribe to specified remote users.

    Set the remote video view

    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)
    }
    Copy

    Publishing limits

    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 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:

    • If the user does not need to publish local streams in the second channel, Agora recommends joining the second channel as an audience member (setClientRole(Audience)).
    • If the user needs to publish local streams in the second channel, the user needs to stop publishing in the current channel before joining the second channel. Agora recommends setting the user role as an audience member (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):

    • Set publishLocalAudio = YES or publishLocalVideo = YES when joining the second channel.
    • Call muteLocalAudioStream(NO) or muteLocalVideoStream(NO) after joining the second channel.
    • Call setClientRole(Broadcaster).

    API changes

    As of v3.4.5, the AgoraRtcChannel class changes as follows:

    • Deprecates 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.
    • Adds the 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.
    • After calling setClientRole(Broadcaster), the local user publishes audio and video streams by default. You no longer need to call publish.

    Earlier than v3.4.5:

    • Calling 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.
    • Calling setClientRole(Broadcaster) of the AgoraRtcChannel class does not publish local streams. You also need to call publish.

    Interactive Live Streaming