Quickstart
This page provides a step-by-step guide on how to create a basic Video Calling app using the Agora Video SDK.
Understand the tech
To start a Video Calling session, implement the following steps in your app:
-
Initialize the Agora Engine: Before calling other APIs, create and initialize an Agora Engine instance.
-
Join a channel: Call methods to create and join a channel.
- Send and receive audio and video: All users can publish streams to the channel and subscribe to audio and video streams published by other users in the channel.
Prerequisites
-
Unity Hub and Unity Editor 2018.4.0 or higher
-
A suitable operating system and compiler for your development platform:
Development platform Operating system version Compiler version Android Android 4.1 or later Android Studio 4.1 or later iOS iOS 10.15 or later Xcode 9.0 or later macOS macOS 10.15 or later Xcode 9.0 or later Windows Windows 7 or later Microsoft Visual Studio 2017 or later
- A camera and a microphone
- A valid Agora account and project. Please refer to Agora account management for details.
Set up your project
This section shows you how to set up your Unity project and install the Agora Video SDK.
- Create a new project
- Add to an existing project
Refer to the following steps or the Official Unity documentation to create a Unity project.
-
Open Unity and click New.
-
Enter the following details:
- Project name : The name of the project.
- Location : Project storage path.
- Template : The project type. Select 3D.
-
Click Create project.
To open your existing project:
-
In the Projects window, click the Open button in the top-right corner.
-
Browse your file manager and select the folder of the project you want to open.
-
Confirm your selection to add the project to the Projects window and open it in the Unity Editor.
Install the SDK
-
Go to the Download SDKs page and download the latest version of the Unity SDK.
-
In Unity Editor, navigate to Assets > Import Package > Custom Package, and select the unzipped SDK.
All plugins are selected by default. Deselect any plugins you don't need, then click Import.
Implement Video Calling
This section guides you through the implementation of basic real-time audio and video interaction in your game.
The following figure illustrates the essential steps:
Quick start sequence
This guide includes complete sample code that demonstrates implementing basic real-time interaction. To understand the core API calls in the sample code, review the following implementation steps.
Before proceeding, create and set up a script to implement Video Calling and bind the script to the canvas.
Steps to set up a script
-
Create a new script and import the UI library.
-
In the Project tab, navigate to Assets > Agora-Unity-RTC-SDK > Code > Rtc, right-click and select Create > C# Script. A new file named
NewBehaviourScript.cs
appears in your Assets. -
Rename the file to
JoinChannel.cs
and open it. -
Import the Unity namespaces to access UI components by adding the following code at the top of the file:
-
-
Bind the script to the canvas.
In
Assets/Agora-Unity-RTC-SDK/Code/Rtc
, select theJoinChannel.cs
file, and drag it to the Canvas. In the Inspector panel, ensure that the file is bound to the Canvas.
Import Agora classes
Import the Agora.Rtc
namespace, which contains various classes and interfaces required to implement real-time audio and video functions.
Initialize the engine
For real-time communication, create an IRtcEngine
instance using RtcEngine.CreateAgoraRtcEngine()
. Then, configure it using Initialize(context)
with an RtcEngineContext
, specifying the application context, App ID, and channel profile. In your JoinChannel.cs
file, add the following code:
Join a channel
To join a channel, call JoinChannel
with the following parameters:
-
Channel name: The name of the channel to join. Clients that pass the same channel name join the same channel. If a channel with the specified name does not exist, it is created when the first user joins.
-
Authentication token: A dynamic key that authenticates a user when the client joins a channel. In a production environment, you obtain a token from a token server in your security infrastructure. For the purpose of this guide Generate a temporary token.
-
User ID: A 32-bit signed integer that identifies a user in the channel. You can specify a unique user ID for each user yourself. If you set the user ID to
0
when joining a channel, the SDK generates a random number for the user ID and returns the value in theOnJoinChannelSuccess
callback. -
Channel media options: Configure
ChannelMediaOptions
to define publishing and subscription settings, optimize performance for your specific use-case, and set optional parameters.
For Video Calling, set the channelProfile
to CHANNEL_PROFILE_COMMUNICATION
and the clientRoleType
to CLIENT_ROLE_BROADCASTER
.
Subscribe to Video SDK events
Create an instance of the UserEventHandler
class and set it as the engine event handler. Override the callbacks based on your use-case.
Create an instance of the user callback class and call InitEventHandler
to register the event handler.
To ensure that you receive all Video SDK events, register the event handler before joining a channel.
Display the local video
Use the following code to set up the local video view:
Display remote video
When a remote user joins the channel, the OnUserJoined
callback is triggered. Call SetForUser
to set the remote video display and call SetEnable(true)
to render the video.
Leave the channel
Call LeaveChannel
to leave the current channel.
Handle permissions
To access the camera and microphone, add device permissions to your project according to your target platform.
- Android
- iOS and macOS
Since version 2018.3, Unity does not actively obtain device permissions from the user. Call CheckPermission
to check for and obtain the necessary permissions.
-
Include the
UnityEngine.Android
namespace, which contains Android-specific classes for interacting with Android devices from Unity: -
Create a list of permissions to be obtained.
-
Check if the required permissions have been granted. If not, prompt the user to grant the necessary permissions.
For iOS and macOS platforms, the Video SDK includes a post-build script named BL_BuildPostProcess.cs
. When you build and export your Unity project as an iOS project, this script automatically inserts camera and microphone permission entries into the Info.plist
file, eliminating the need for manual updates.
Start and stop your game
-
When the game starts, ensure that device permissions have been granted.
-
To start Video Calling, initialize the engine and set up the event handler.
-
To clean up all session-related resources when a user exits the game, call the
Dispose
method of theIRtcEngine
.infoAfter calling
Dispose
, you can no longer use any methods or callbacks of the SDK. To use Video Calling features again, create a new engine instance.
Complete sample code
A complete code sample demonstrating the basic process of real-time interaction is provided for your reference. To quickly implement the basic functions of real-time Video Calling, copy the following sample code into your project:
Sample code to implement Video Calling in your game
using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.UI;using Agora.Rtc;#if (UNITY_2018_3_OR_NEWER && UNITY_ANDROID)using UnityEngine.Android;#endifpublic class JoinChannelVideo : MonoBehaviour{ // Fill in your app ID private string _appID= ""; // Fill in your channel name private string _channelName = ""; // Fill in your Token private string _token = ""; internal VideoSurface LocalView; internal VideoSurface RemoteView; internal IRtcEngine RtcEngine; #if (UNITY_2018_3_OR_NEWER && UNITY_ANDROID) private ArrayList permissionList = new ArrayList() { Permission.Camera, Permission.Microphone }; #endif void Start() { SetupVideoSDKEngine(); InitEventHandler(); SetupUI(); PreviewSelf(); } void Update() { CheckPermissions(); } void OnApplicationQuit() { if (RtcEngine != null) { Leave(); // Destroy IRtcEngine RtcEngine.Dispose(); RtcEngine = null; } } private void CheckPermissions() { #if (UNITY_2018_3_OR_NEWER && UNITY_ANDROID) foreach (string permission in permissionList) { if (!Permission.HasUserAuthorizedPermission(permission)) { Permission.RequestUserPermission(permission); } } #endif } private void PreviewSelf() { // Enable video module RtcEngine.EnableVideo(); // Start local video preview RtcEngine.StartPreview(); // Set local video display LocalView.SetForUser(0, ""); // Start rendering video LocalView.SetEnable(true); } private void SetupUI() { GameObject go = GameObject.Find("LocalView"); LocalView = go.AddComponent<VideoSurface>(); go.transform.Rotate(0.0f, 0.0f, -180.0f); go = GameObject.Find("RemoteView"); RemoteView = go.AddComponent<VideoSurface>(); go.transform.Rotate(0.0f, 0.0f, -180.0f); go = GameObject.Find("Leave"); go.GetComponent<Button>().onClick.AddListener(Leave); go = GameObject.Find("Join"); go.GetComponent<Button>().onClick.AddListener(Join); } private void SetupVideoSDKEngine() { // Create IRtcEngine instance RtcEngine = Agora.Rtc.RtcEngine.CreateAgoraRtcEngine(); RtcEngineContext context = new RtcEngineContext(); context.appId = _appID; context.channelProfile = CHANNEL_PROFILE_TYPE.CHANNEL_PROFILE_LIVE_BROADCASTING; context.audioScenario = AUDIO_SCENARIO_TYPE.AUDIO_SCENARIO_DEFAULT; // Initialize IRtcEngine RtcEngine.Initialize(context); } // Create an instance of the user callback class and set the callback private void InitEventHandler() { UserEventHandler handler = new UserEventHandler(this); RtcEngine.InitEventHandler(handler); } public void Join() { // Set channel media options ChannelMediaOptions options = new ChannelMediaOptions(); // Start video rendering LocalView.SetEnable(true); // Publish microphone audio stream options.publishMicrophoneTrack.SetValue(true); // Publish camera video stream options.publishCameraTrack.SetValue(true); // Automatically subscribe to all audio streams options.autoSubscribeAudio.SetValue(true); // Automatically subscribe to all video streams options.autoSubscribeVideo.SetValue(true); // Set the channel profile to live broadcasting options.channelProfile.SetValue(CHANNEL_PROFILE_TYPE.CHANNEL_PROFILE_LIVE_BROADCASTING); // Set the user role to broadcaster options.clientRoleType.SetValue(CLIENT_ROLE_TYPE.CLIENT_ROLE_BROADCASTER); // Join the channel RtcEngine.JoinChannel(_token, _channelName, 0, options); } public void Leave() { Debug.Log("Leaving _channelName"); // Disable video module RtcEngine.StopPreview(); // Leave the channel RtcEngine.LeaveChannel(); // Stop remote video rendering RemoteView.SetEnable(false); } // Implement your own callback class by inheriting from the IRtcEngineEventHandler interface class internal class UserEventHandler : IRtcEngineEventHandler { private readonly JoinChannelVideo _videoSample; internal UserEventHandler(JoinChannelVideo videoSample) { _videoSample = videoSample; } // Callback triggered when an error occurs public override void OnError(int err, string msg) { } // Callback triggered when the local user successfully joins the channel public override void OnJoinChannelSuccess(RtcConnection connection, int elapsed) { } // OnUserJoined callback is triggered when the SDK receives and successfully decodes the first frame of remote video public override void OnUserJoined(RtcConnection connection, uint uid, int elapsed) { // Set remote video display _videoSample.RemoteView.SetForUser(uid, connection.channelId, VIDEO_SOURCE_TYPE.VIDEO_SOURCE_REMOTE); // Start video rendering _videoSample.RemoteView.SetEnable(true); Debug.Log("Remote user joined"); } // Callback triggered when a remote user leaves the current channel public override void OnUserOffline(RtcConnection connection, uint uid, USER_OFFLINE_REASON_TYPE reason) { _videoSample.RemoteView.SetEnable(false); Debug.Log("Remote user offline"); } }}
Create a user interface
Follow these steps to set up a basic UI for your project or to integrate essential UI elements into your existing interface. A basic UI consists of the following components:
- Local view window
- Remote view window
- Buttons to join and leave the channel
Create a basic UI
-
Create buttons to join and leave channel
-
In your Unity project, right-click the Sample Scene and select Game Object > UI > Button. You see a button on the scene canvas.
-
In the Inspector panel, rename the button to
Join
and adjust the position coordinates as needed. For example:- Pos X:
-329
- Pos Y:
-172
- Pos X:
-
Select the Text control of the Join button , and change the text to
Join
in the Inspector panel. -
Repeat the steps to create a Leave button, using the following positions:
- Pos X:
329
- Pos Y:
-172
- Pos X:
-
-
Create local and remote view windows
-
Right-click the Canvas and select UI > Raw Image.
-
In the Inspector panel, rename
Raw Image
toLocalView
and adjust its size and position on the canvas. For example:- PosX:
-250
- Pos Y:
0
- Width:
250
- Height:
250
- PosX:
-
Repeat the above steps to create a remote view window, name it
RemoteView
, and adjust its position on the canvas:- PosX:
250
- Pos Y:
0
- Width:
250
- Height:
250
Save the changes.
- PosX:
-
At this point your UI looks similar to the following:
Test the sample code
Take the following steps to test the sample code:
-
Obtain a temporary token from Agora Console.
-
In
JoinChannel.cs
, update_appID
,_channelName
, and_token
with the app ID, channel name, and temporary token for your project. -
In Unity Editor, click Play to run your project.
-
Click Join to join a channel.
-
Invite a friend to run the demo game on a second device. Use the same
_appID_
,_token
, and_channelName
to join. Alternatively, use the Web demo to join the same channel.After your friend joins successfully, you can hear and see each other.
Reference
This section contains content that completes the information on this page, or points you to documentation that explains other aspects to this product.
- If a firewall is deployed in your network environment, refer to Connect with Cloud Proxy to use Agora services normally.
Next steps
After implementing the quickstart sample, read the following documents to learn more:
- To ensure communication security in a test or production environment, best practice is to obtain and use a token from an authentication server. For details, see Secure authentication with tokens.
Sample project
Agora provides open source sample projects on GitHub for your reference. Download or view the JoinChannelVideo project for a more detailed example.
API reference
-
JoinChannel
-
EnableVideo
-
CreateAgoraRtcEngine
-
InitEventHandler
-
SetClientRole
-
LeaveChannel
-
DisableVideo