As of v3.0.1, the Agora Unity 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.
This feature can be applied to a multiplayer game scenario: All players are in one channel, and they can interact with each other in real time. When players are on separate teams, members on the same team can communicate with each other in real time.
The Agora Unity SDK uses the AgoraChannel
class to support the multi-channel function. To implement this function in your project, choose either of the following approaches:
Follow these steps to implement the multi-channel function in your project:
CreateChannel
of the IRtcEngine
class to create an AgoraChannel
object with channelId
.JoinChannel
of the AgoraChannel
class to join the created channel.AgoraChannel
objects, and call the JoinChannel
method of each object to join these channels.This approach applies to scenarios where you need to frequently switch between channels and publish audio or video streams.
API call sequence
Refer to the following API sequence to implement the multi-channel function in your project with the AgoraChannel
class.
Sample code
You can also refer to the following sample code.
void Start ()
{
// 1. Initializes the IRtcEngine instance.
mRtcEngine = IRtcEngine.GetEngine(APP_ID);
// To receive and render multi-channel videos, calls SetMultiChannelWant before joining a channel
mRtcEngine.SetMultiChannelWant(true);
// 2. Creates an AgoraChannel object.
mRtcchannel = mRtcEngine.CreateChannel(channelName);
// 3. Listens for callbacks which report a user joins or leaves a channel successfully.
mRtcchannel.ChannelOnJoinChannelSuccess = ChannelOnJoinChannelSuccessHandler;
mRtcchannel.ChannelOnLeaveChannel = ChannelOnLeaveChannelHandler;
// 4. Joins a channel.
mRtcchannel.JoinChannel("", "", 0, new ChannelMediaOptions(true, true));
// Publish audio or video streams.
mRtcchannel.Publish();
}
void OnApplicationQuit()
{
if (mRtcEngine != null)
{
// 5. Leaves a channel.
mRtcchannel.LeaveChannel();
// 6. Releases all AgoraChannel objects.
mRtcchannel.ReleaseChannel();
// 7. Destroys the IRtcEngine instance.
IRtcEngine.Destroy();
}
}
// Occurs when a user joins a channel.
void ChannelOnJoinChannelSuccessHandler(string channelId, uint uid, int elapsed)
{
makeVideoView(channelId ,0);
}
// Occurs when a user leaves a channel.
void ChannelOnLeaveChannelHandler(string channelId, RtcStats rtcStats)
{
}
void makeVideoView(string channelId, uint uid)
{
GameObject go = GameObject.Find(uid.ToString());
if (!ReferenceEquals(go, null))
{
return;
}
// Creates a GameObject and binds the object to the VideoSurface.
VideoSurface videoSurface = makeImageSurface(uid.ToString());
if (!ReferenceEquals(videoSurface, null))
{
// Sets up the local or remote video view.
videoSurface.SetForMultiChannelUser(channelId, uid);
}
}
VideoSurface makeImageSurface(string goName)
{
GameObject go = new GameObject();
go.name = goName;
go.AddComponent<RawImage>();
GameObject canvas = GameObject.Find("VideoCanvas");
if (canvas != null)
{
go.transform.parent = canvas.transform;
}
go.transform.Rotate(0f, 0.0f, 180.0f);
float xPos = Random.Range(Offset - Screen.width / 2f, Screen.width / 2f - Offset);
float yPos = Random.Range(Offset, Screen.height / 2f - Offset);
go.transform.localPosition = new Vector3(xPos, yPos, 0f);
go.transform.localScale = new Vector3(3f, 4f, 1f);
VideoSurface videoSurface = go.AddComponent<VideoSurface>();
return videoSurface;
}
Follow these steps to implement the multi-channel function in your project:
JoinChannelByKey
of the IRtcEngine
class to join the first channel.CreateChannel
of the IRtcEngine
class to create an AgoraChannel
object with channelId
.JoinChannel
of the AgoraChannel
class to join the second channel.AgoraChannel
objects, and call the JoinChannel
method of each object to join these channels.This approach applies to scenarios where you publish streams only to the IRtcEngine
channel. If you have implemented RTC functions with an earlier version of our SDK, this approach does not require any change to your existing code.
API call sequence
Refer to the following API sequence to implement the multi-channel function in your project with the IRtcEngine
and AgoraChannel
classes.
CreateChannel
AgoraChannel
classWhen joining a channel by calling JoinChannel
in the AgoraChannel
class, if you set autoSubscribeAudio
or autoSubscribeVideo
as false, you cannot resume receiving the audio or video stream of a specified user by calling MuteRemoteAudioStream(false)
or MuteRemoteVideoStream(false)
.
To resume receiving a specified stream, take the following steps:
SetDefaultMuteAllRemoteAudioStreams(true)
or SetDefaultMuteAllRemoteVideoStreams(true)
before joining the channel.MuteRemoteAudioStream(false)
or MuteRemoteVideoStream(false)
, and specify the user whose stream you want to resume receiving.In video scenarios, to receive multi-channel video streams, you need to call SetMultiChannelWant
before joining the channel. To render the remote video view, you need to call SetForMultiChannelUser
before binding VideoSurface.cs
, and specify the remote user’s uid
and the channelId
of their channel.
v3.0.1 supports publishing one stream to only one channel at a time. In other words, if you are already publishing a stream to a channel, you cannot publish that stream to a different channel.
You must meet the following requirements to implement the multi-channel function. Otherwise, the SDK returns ERR_REFUSED(-5)
:
AgoraChannel
class:Publish
method in Channel 1, you need to call the Unpublish
method in Channel 1 before calling the Publish
method in Channel 2.IRtcEngine
and AgoraChannel
classes:COMMUNICATION
or LIVE_BROADCASTING
profile, if you join Channel 1 using the IRtcEngine
class, and Channel 2 using the AgoraChannel
class, you cannot call Publish
in the AgoraChannel
class.LIVE_BROADCASTING
profile, after joining multiple channels, you cannot call the Publish
method in the AgoraChannel
class as an audience member.Publish
in the AgoraChannel
class, you need to call Unpublish
in the AgoraChannel
class. Otherwise, you cannot call JoinChannelByKey
in the IRtcEngine
class.