Use this guide to quickly start a basic video call with the Agora Video SDK for Windows.
The following figure shows the workflow to integrate into your app in order to add Video Call functionality.
As shown in the figure, the workflow for adding Video Call in your project is as follows:
Retrieve a token
A token is the credential that authenticates a user when your app client joins a channel. In a test or production environment, your app client retrieves tokens from a server in your security infrastructure.
Join a channel
Call joinChannel
to create and join a channel. App clients that pass the same channel name join the same channel.
Publish and subscribe to audio and video in the channel
After joining a channel, the app client automatically publishes and subscribes to audio and video in the channel.
For an app client to join a channel, you need the following information:
We provide the open-source sample projects that implement the video call on GitHub:
Before implementing a video call, you can download the sample projects and refer to the source code.
In this section, we will create a Windows project and integrate the SDK into the project.
Now, let's build a Windows project from scratch. Skip to Integrate the SDK if a Windows project already exists.
Follow these steps to integrate the Agora Video SDK into your project.
1. Configure the project files
2. Configure the project properties
Right-click the project name in the Solution Explorer window, click Properties to configure the following project properties, and click OK.
This section introduces how to use the Agora SDK to make a video call. The following figure shows the API call sequence of a basic one-to-one video call.
Create the user interface (UI) for the one-to-one video call in your project. Skip to Initialize IRtcEngine if you already have a UI in your project.
If you are implementing a video call, we recommend adding the following elements into the UI:
When you use the UI setting of the demo project, you can see the following interface:
Create and initialize the IRtcEngine
object before calling any other Agora APIs.
In this step, you need to use the App ID of your project. Refer to Get Started With Agora to create an Agora project and get the App ID in Console.
Call the createAgoraRtcEngine
method and the initialize
method, and pass in the App ID to initialize the IRtcEngine object.
You can also listen for callback events, such as when the local user joins or leaves the channel.
CAgoraObject *CAgoraObject::GetAgoraObject(LPCTSTR lpAppId)
{
if (m_lpAgoraObject == NULL)
m_lpAgoraObject = new CAgoraObject();
if (m_lpAgoraEngine == NULL)
// Create the instance.
m_lpAgoraEngine = (IRtcEngine *)createAgoraRtcEngine();
if (lpAppId == NULL)
return m_lpAgoraObject;
RtcEngineContext ctx;
// Add the register events and callbacks.
ctx.eventHandler = &m_EngineEventHandler;
#ifdef UNICODE
char szAppId[128];
::WideCharToMultiByte(CP_ACP, 0, lpAppId, -1, szAppId, 128, NULL, NULL);
// Input your App ID.
ctx.appId = szAppId;
#else
ctx.appId = lpAppId;
#endif
// Initialize the IRtcEngine object.
m_lpAgoraEngine->initialize(ctx);
return m_lpAgoraObject;
}
// Inherit the events and callbacks of IRtcEngineEventHandler.
class CAGEngineEventHandler :
public IRtcEngineEventHandler
{
public:
CAGEngineEventHandler(void);
~CAGEngineEventHandler(void);
void SetMsgReceiver(HWND hWnd = NULL);
HWND GetMsgReceiver() {return m_hMainWnd;};
// Listen for the onJoinChannelSuccess callback.
// This callback occurs when the local user successfully joins the channel.
virtual void onJoinChannelSuccess(const char* channel, uid_t uid, int elapsed);
// Listen for the onLeaveChannel callback.
// This callback occurs when the local user successfully leaves the channel.
virtual void onLeaveChannel(const RtcStats& stat);
// Listen for the onUserJoined callback.
// This callback occurs when the remote user successfully joins the channel.
// After receiving this callback, immediately call setupRemoteVideo to set the remote video view.
virtual void onUserJoined(uid_t uid, int elapsed) override;
// Listen for the onUserOffline callback.
// This callback occurs when the remote user leaves the channel or drops offline.
virtual void onUserOffline(uid_t uid, USER_OFFLINE_REASON_TYPE reason);
private:
HWND m_hMainWnd;
};
After initializing the IRtcEngine
object, set the local video view before joining the channel so that you can see yourself in the call. Follow these steps to configure the local video view:
enableVideo
method to enable the video module. setupLocalVideo
method to configure the local video display settings. // Enable the video module.
m_lpAgoraObject->GetEngine()->enableVideo();
VideoCanvas vc;
vc.uid = 0;
vc.view = m_wndLocal.GetSafeHwnd();
vc.renderMode = RENDER_MODE_FIT;
// Set the local video view.
m_lpAgoraObject->GetEngine()->setupLocalVideo(vc);
After initializing the IRtcEngine object and setting the local video view, you can call the joinChannel
method to join a channel. In this method, set the following parameters:
channelName
: Specify the channel name that you want to join.
token
: Pass a token that identifies the role and privilege of the user. You can set it as one of the following values:
uid
is the same with those you use to generate the token.token
as "".uid
: ID of the local user that is an integer and should be unique. If you set uid
as 0, the SDK assigns a user ID for the local user and returns it in the onJoinChannelSuccess
callback.
mute
methods accordingly.For more details on the parameter settings, see joinChannel.
BOOL CAgoraObject::JoinChannel(LPCTSTR lpChannelName, UINT nUID,LPCTSTR lpToken)
{
int nRet = 0;
#ifdef UNICODE
CHAR szChannelName[128];
::WideCharToMultiByte(CP_UTF8, 0, lpChannelName, -1, szChannelName, 128, NULL, NULL);
char szToken[128];
::WideCharToMultiByte(CP_UTF8, 0, lpToken, -1, szToken, 128, NULL, NULL);
if(0 == _tcslen(lpToken))
nRet = m_lpAgoraEngine->joinChannel(NULL, szChannelName, NULL, nUID);
else
// Join a channel with a token.
nRet = m_lpAgoraEngine->joinChannel(szToken, szChannelName, NULL, nUID);
#else
if(0 == _tcslen(lpToken))
nRet = m_lpAgoraEngine->joinChannel(NULL, lpChannelName, NULL, nUID);
else
nRet = m_lpAgoraEngine->joinChannel(lpToken, lpChannelName, NULL, nUID);
#endif
if (nRet == 0)
m_strChannelName = lpChannelName;
return nRet == 0 ? TRUE : FALSE;
}
In a video call, you should be able to see other users too. This is achieved by calling the setupRemoteVideo
method after joining the channel.
Shortly after a remote user joins the channel, the SDK gets the remote user's ID in the onUserJoined
callback. Call the setupRemoteVideo
method in the callback, and pass in the uid
to set the video view of the remote user.
// Listen for the onUserJoined callback.
// After receiving this callback, immediately call setupRemoteVideo to set the remote video view.
LRESULT CAgoraTutorialDlg::OnEIDUserJoined(WPARAM wParam, LPARAM lParam)
{
LPAGE_USER_JOINED lpData = (LPAGE_USER_JOINED)wParam;
VideoCanvas vc;
vc.renderMode = RENDER_MODE_FIT;
vc.uid = lpData->uid;
vc.view = m_wndRemote.GetSafeHwnd();
// Set the remote video view.
m_lpAgoraObject->GetEngine()->setupRemoteVideo(vc);
delete lpData;
return 0;
}
Call the leaveChannel
method to leave the current call according to your scenario, for example, when the call ends, when you need to close the app, or when your app runs in the background.
BOOL CAgoraObject::LeaveChannel()
{
m_lpAgoraEngine->stopPreview();
// Leave the current channel.
int nRet = m_lpAgoraEngine->leaveChannel();
return nRet == 0 ? TRUE : FALSE;
}
void CAgoraObject::CloseAgoraObject()
{
if(m_lpAgoraEngine != NULL)
// Release the IRtcEngine object.
m_lpAgoraEngine->release();
if(m_lpAgoraObject != NULL)
delete m_lpAgoraObject;
m_lpAgoraEngine = NULL;
m_lpAgoraObject = NULL;
}
Run the project on your Windows device. You can see both the local and remote video views when you successfully start a one-to-one video call in your app.