Use this guide to quickly start the interactive live video streaming with the Agora Video SDK for Windows.
The following figure shows the workflow to integrate into your app in order to add Interactive Live Streaming Standard functionality.
As shown in the figure, the workflow for adding Interactive Live Streaming Standard in your project is as follows:
Set the client role and latency level
Each user in an Interactive Live Streaming Standard channel is either a host or an audience member. Hosts publish streams to the channel, and the audience subscribe to the streams. When a user is an audience member, you can control the delay the user receives host streams using ClientRoleOptions
.
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, app clients with the role of the host can publish audio and video. For an auidence memeber to send audio and video, call setClientRole
to switch the client role.
For an app client to join a channel, you need the following information:
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
Go to SDK Downloads, download the latest version of the Agora SDK for Windows, and unzip the downloaded SDK package.
Copy the x86 or x86_64 folder of the downloaded SDK package to your project files according to your development environment.
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.
Go to the C/C++ > General > Additional Include Directories menu, click Edit, and input $(SolutionDir)include in the pop-up window.
Go to the Linker > General > Additional Library Directories menu, click Edit, and input $(SolutionDir) in the pop-up window.
Go to the Linker > Input > Additional Dependencies menu, click Edit, and input agora_rtc_sdk.lib in the pop-up window.
This section introduces how to use the Agora SDK to start the interactive live video streaming. The following figure shows the API call sequence of the interactive live video streaming.
Create the user interface (UI) for the interactive video streaming in your project. Skip to Initialize IRtcEngine if you already have a UI in your project.
If you are implementing the interactive video streaming, we recommend adding the following elements into the UI:
When you use the UI setting of the sample 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.
// Create the instance.
m_lpAgoraEngine = createAgoraRtcEngine();
RtcEngineContext ctx;
// Add the register events and callbacks.
ctx.eventHandler = &m_engineEventHandler;
// Input your App ID.
ctx.appId = "YourAppID";
// Initialize the IRtcEngine object.
m_lpAgoraEngine->initialize(ctx);
// Inherit the events and callbacks of IRtcEngineEventHandler.
class CAGEngineEventHandler :
public IRtcEngineEventHandler
{
public:
CAGEngineEventHandler();
~CAGEngineEventHandler();
void setMainWnd(HWND wnd);
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 host 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 host 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, call the setChannelProfile
method to set the channel profile as LIVE_BROADCASTING
.
One IRtcEngine
object uses one profile only. If you want to switch to another profile, release the current IRtcEngine
object with the release
method and create a new one before calling the setChannelProfile
method.
m_lpAgoraEngine->setChannelProfile(CHANNEL_PROFILE_LIVE_BROADCASTING);
In a live-streaming channel, you need to set the role and level of a user:
You may use the following steps to set the user role and level in your app:
Allow the end user to set the role as host or audience.
Call the setClientRole
method and set the role
and options
parameters according to the user's choice:
role
as CLIENT_ROLE_BROADCASTER
, set options
as null
. The latency between two hosts is < 400 ms.role
as CLIENT_ROLE_AUDIENCE
, set the audienceLatencyLevel
parameter in options
as AUDIENCE_LATENCY_LEVEL_LOW_LATENCY
. The latency from the host's client to the audience's client is 1500 ms - 2000 ms.AUDIENCE_LATENCY_LEVEL_LOW_LATENCY
to AUDIENCE_LATENCY_LEVEL_ULTRA_LOW_LATENCY
, in essence, you switch from Interactive Live Streaming Standard to Interactive Live Streaming Premium and the latency from the host's client to the audience's client changes to 400 ms - 800 ms.CLIENT_ROLE_AUDIENCE
to CLIENT_ROLE_BROADCASTER
, in essence, you switch from Interactive Live Streaming Standard to Interactive Live Streaming Premium and the latency between two hosts is < 400 ms.AUDIENCE_LATENCY_LEVEL_LOW_LATENCY
, the jitterBufferDelay
property in RemoteAudioStats
does not take effect.Audience:
ClientRoleOptions role_options;
role_options.audienceLatencyLevel = AUDIENCE_LATENCY_LEVEL_LOW_LATENCY;
m_lpAgoraEngine->setClientRole(CLIENT_ROLE_AUDIENCE, role_options);
Host:
m_lpAgoraEngine->setClientRole(CLIENT_ROLE_BROADCASTER, NULL);
After setting the channel profile and client role, set the local video view before joining the channel so that the host can see the local video in the interactive streaming. 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_lpAgoraEngine->enableVideo();
// Set the local video view.
VideoCanvas vc;
vc.uid = 0;
vc.view = hVideoWnd;
vc.renderMode = RENDER_MODE_TYPE::RENDER_MODE_HIDDEN;
m_lpAgoraEngine->setupLocalVideo(vc);
After setting the client role and 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.
// Join a channel with a token.
BOOL CAgoraObject::JoinChannel(LPCTSTR lpChannelName, UINT nUID, LPCSTR lpDynamicKey)
{
int nRet = 0;
LPCSTR lpStreamInfo = "{\"owner\":true,\"width\":640,\"height\":480,\"bitrate\":500}";
#ifdef UNICODE
CHAR szChannelName[128];
::WideCharToMultiByte(CP_ACP, 0, lpChannelName, -1, szChannelName, 128, NULL, NULL);
nRet = m_lpAgoraEngine->joinChannel(lpDynamicKey, szChannelName, lpStreamInfo, nUID);
#else
nRet = m_lpAgoraEngine->joinChannel(lpDynamicKey, lpChannelName, lpStreamInfo, nUID);
#endif
if (nRet == 0)
m_strChannelName = lpChannelName;
return nRet == 0 ? TRUE : FALSE;
}
In the interactive video streaming, you should also be able to see all the hosts, regardless of your role. This is achieved by calling the setupRemoteVideo
method after joining the channel.
Shortly after a remote host joins the channel, the SDK gets the host's user ID in the onUserJoined
callback. Call the setupRemoteVideo
method in the callback and pass in the uid
to set the video view of the host.
// Listen for the onUserJoined callback.
// After receiving this callback, immediately call setupRemoteVideo to set the remote video view.
void CAGEngineEventHandler::onUserJoined(uid_t uid, int elapsed)
{
LPAGE_USER_JOINED lpData = new AGE_USER_JOINED;
lpData->uid = uid;
lpData->elapsed = elapsed;
if(m_hMainWnd != NULL)
::PostMessage(m_hMainWnd, WM_MSGID(EID_USER_JOINED), (WPARAM)lpData, 0);
}
VideoCanvas canvas;
canvas.renderMode = RENDER_MODE_FIT;
POSITION pos = m_listWndInfo.GetHeadPosition();
......
AGVIDEO_WNDINFO &agvWndInfo = m_listWndInfo.GetNext(pos);
canvas.uid = agvWndInfo.nUID;
canvas.view = m_wndVideo[nIndex].GetSafeHwnd();
agvWndInfo.nIndex = nIndex;
// Set the remote video view.
CAgoraObject::GetEngine()->setupRemoteVideo(canvas);
Call the leaveChannel
method to leave the current channel according to your scenario, for example, when the interactive streaming ends, when you need to close the app, or when your app runs in the background.
BOOL CAgoraObject::LeaveCahnnel()
{
m_lpAgoraEngine->stopPreview();
// Leave the current channel.
int nRet = m_lpAgoraEngine->leaveChannel();
m_nSelfUID = 0;
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. When you set the role as the host and successfully start the interactive video streaming, you can see the video view of yourself in the app. When you set the role as the audience and successfully join the interactive video streaming, you can see the video view of the host in the app.