Screen sharing enables a host of an interactive live streaming broadcast or a user in a video call to display what is on their screen to other users in the channel.
This technology has many advantages for communicating information such as the following:
To share the screen on Windows, you need to use Windows native APIs and Agora APIs together. The following two screen-sharing methods are supported:
The following diagrams show the two methods of the API call sequence: This page takes the first method as an example.
Before proceeding, ensure that you have implemented the basic real-time engagement function. See Start a Call or Start Interactive Live Streaming.
This section shows you how to implement screen sharing.
Get the screen list
// Get the screen list
void CAgoraScreenCapture::InitMonitorInfos()
{
// m_monitors is an object of the CMonitors Class. For the implementation of the CMonitors Class, see the sample project.
// m_monitors calls EnumMonitor to get the screen list. For the implementation of the EnumMonitor method, see the sample project.
m_monitors.EnumMonitor();
// Define infos vector to store the screen list.
std::vector<CMonitors::MonitorInformation> infos = m_monitors.GetMonitors();
CString str = _T("");
// Get the Rectangle coordinate of each screen on the virtual screen.
for (size_t i = 0; i < infos.size(); i++) {
RECT rcMonitor = infos[i].monitorInfo.rcMonitor;
CString strInfo;
strInfo.Format(_T("Screen%d: rect = {%d, %d, %d, %d} ")
, i + 1, rcMonitor.left, rcMonitor.top, rcMonitor.right, rcMonitor.bottom);
}
str += strInfo;
m_cmbScreenRegion.InsertString(i, utf82cs(infos[i].monitorName));
}
m_cmbScreenRegion.InsertString(infos.size(), _T("Select Window Hwnd Rect Area"));
m_staScreenInfo.SetWindowText(str);
m_cmbScreenRegion.SetCurSel(0);
}
To share the screen by specifying the Rectangle
coordinates of the screen on the virtual screen and the Rectangle
coordinates of the region on the screen.
void CAgoraScreenCapture::OnBnClickedButtonStartShareScreen()
{
m_screenShare = !m_screenShare;
if (m_screenShare) {
// Get the chosen screen.
int sel = m_cmbScreenRegion.GetCurSel();
agora::rtc::Rectangle regionRect = { 0,0,0,0 }, screenRegion = {0,0,0,0};
// Get the Rectangle coordinate of the region on the whole screen.
// For the GetMonitorRectangle method, see the sample project.
regionRect = m_monitors.GetMonitorRectangle(sel);
// Get the Rectangle coordinate of each screen on the virtual screen.
screenRegion = m_monitors.GetScreenRect();
m_monitors.GetScreenRect();
// The screen-sharing encoding parameters.
ScreenCaptureParameters capParam;
// To start the screen sharing.
m_rtcEngine->startScreenCaptureByScreenRect(screenRegion, regionRect, capParam);
m_btnShareScreen.SetWindowText(screenShareCtrlStopShare);
// To start the video preview.
m_rtcEngine->startPreview();
m_btnStartCap.EnableWindow(FALSE);
m_screenShare = true;
}
else {
// To stop the screen sharing.
m_rtcEngine->stopScreenCapture();
m_btnShareScreen.SetWindowText(screenShareCtrlShareSCreen);
m_btnStartCap.EnableWindow(TRUE);
m_screenShare = false;
}
}
Join the channel, and publish the screen-sharing stream.
If you only need to publish the screen-sharing stream, see the following codes:
ChannelMediaOptions option;
option.publishScreenTrack = true;
option.publishCameraTrack = false;
if (0 == m_rtcEngine->joinChannel(APP_TOKEN, szChannelId.c_str(), 0, option)) {
strInfo.Format(_T("join channel %s, use ChannelMediaOption"), getCurrentTime());
m_btnJoinChannel.EnableWindow(FALSE);
}
If you need to publish the screen-sharing stream and the video stream captured by the local camera, see the following codes:
// Join the channel and publish the video stream captured by the local camera
ChannelMediaOptions option;
option.publishScreenTrack = false;
option.publishCameraTrack = true;
if (0 == m_rtcEngine->joinChannel(APP_TOKEN, szChannelId.c_str(), 0, option)) {
strInfo.Format(_T("join channel %s, use ChannelMediaOption"), getCurrentTime());
m_btnJoinChannel.EnableWindow(FALSE);
}
// Join the same channel and publish the screen-sharing stream
ChannelMediaOptions options;
options.publishScreenTrack = true;
options.autoSubscribeAudio = false;
options.autoSubscribeVideo = false;
options.publishCameraTrack = false;
CAgoraMultiVideoSourceEventHandler * p = new CAgoraMultiVideoSourceEventHandler;
p->SetChannelId(m_vecVidoeSourceEventHandler.size());
p->SetMsgReceiver(GetSafeHwnd());
m_vecVidoeSourceEventHandler.push_back(p);
if (0 == m_rtcEngine->joinChannelEx(APP_TOKEN,connection, options, p))
{
m_btnJoinChannel.EnableWindow(FALSE);
}
Windows assigns a unique Window ID for each window with a data type of HWND. To achieve compatibility with the x86 and the x64 operating systems, the API parameter is in the format of view_t
.
Call Windows native API EnumWindows
get the Window ID list.
// Get HWND of all the latest top windows and restore it in m_listWnd.
int CAgoraScreenCapture::RefreshWndInfo()
{
m_listWnd.RemoveAll();
::EnumWindows(&CAgoraScreenCapture::WndEnumProc, (LPARAM)&m_listWnd);
return static_cast<int>(m_listWnd.GetCount());
}
Share the window by specifying the Window ID.
void CAgoraScreenCapture::OnBnClickedButtonStartShare()
{
if (!m_rtcEngine || !m_initialize)
return;
HWND hWnd = NULL;
// The Window ID to be shared.
hWnd = m_listWnd.GetAt(m_listWnd.FindIndex(m_cmbScreenCap.GetCurSel()));
int ret = 0;
m_windowShare = !m_windowShare;
if (m_windowShare)
{
// Set captureParameters.
ScreenCaptureParameters capParam;
GetCaptureParameterFromCtrl(capParam);
// Set regionRect.
CRect rcWnd = { 0 };
::GetClientRect(hWnd, &rcWnd);
agora::rtc::Rectangle rcCapWnd = { rcWnd.left, rcWnd.top, rcWnd.right - rcWnd.left, rcWnd.bottom - rcWnd.top };
// To start the screen sharing.
ret = m_rtcEngine->startScreenCaptureByWindowId(hWnd, rcCapWnd, capParam);
// To start the video preview.
m_rtcEngine->startPreview();
m_lstInfo.InsertString(m_lstInfo.GetCount(), _T("startPreview"));
if (ret == 0)
m_lstInfo.InsertString(m_lstInfo.GetCount(), _T("Succees!"));
else
m_lstInfo.InsertString(m_lstInfo.GetCount(), _T("Failed!"));
m_btnStartCap.SetWindowText(screenShareCtrlEndCap);
m_btnShareScreen.EnableWindow(FALSE);
}
else {
// To stop the screen sharing.
ret = m_rtcEngine->stopScreenCapture();
if (ret == 0)
m_lstInfo.InsertString(m_lstInfo.GetCount(), _T("Success!"));
else
m_lstInfo.InsertString(m_lstInfo.GetCount(), _T("Failed!"));
m_btnStartCap.SetWindowText(screenShareCtrlStartCap);
m_btnShareScreen.EnableWindow(TRUE);
}
}
Join the channel, and publish the screen-sharing stream.
If you only need to publish the screen-sharing stream, see the following codes:
ChannelMediaOptions option;
option.publishScreenTrack = true;
option.publishCameraTrack = false;
if (0 == m_rtcEngine->joinChannel(APP_TOKEN, szChannelId.c_str(), 0, option)) {
strInfo.Format(_T("join channel %s, use ChannelMediaOption"), getCurrentTime());
m_btnJoinChannel.EnableWindow(FALSE);
}
If you need to publish the screen-sharing stream and the video stream captured by the local camera, see the following codes:
// Join the channel and publish the video stream captured by the local camera
ChannelMediaOptions option;
option.publishScreenTrack = false;
option.publishCameraTrack = true;
if (0 == m_rtcEngine->joinChannel(APP_TOKEN, szChannelId.c_str(), 0, option)) {
strInfo.Format(_T("join channel %s, use ChannelMediaOption"), getCurrentTime());
m_btnJoinChannel.EnableWindow(FALSE);
}
// Join the same channel and publish the screen-sharing stream
ChannelMediaOptions options;
options.publishScreenTrack = true;
options.autoSubscribeAudio = false;
options.autoSubscribeVideo = false;
options.publishCameraTrack = false;
CAgoraMultiVideoSourceEventHandler * p = new CAgoraMultiVideoSourceEventHandler;
p->SetChannelId(m_vecVidoeSourceEventHandler.size());
p->SetMsgReceiver(GetSafeHwnd());
m_vecVidoeSourceEventHandler.push_back(p);
if (0 == m_rtcEngine->joinChannelEx(APP_TOKEN,connection, options, p))
{
m_btnJoinChannel.EnableWindow(FALSE);
}
This section provides reference information for managing the channel connection state.
ScreenCaptureParameters
may affect your communication usage chargers. If you set the dimensions
parameter as default, Agora uses 1920 x 1080 to calculate your usage charges.Agora provides an open-source sample project on GitHub. You can download the project to try it out.
Windows native API
Agora API