During a video call or interactive streaming, sharing the screen enhances communication by displaying the speaker's screen on the display of other speakers or audience members in the channel.
Screen sharing is applied in the following scenarios:
Refer to the sample project on GitHub to learn how to share a screen or window with the Agora SDK.
Ensure that you implement a video call or interactive streaming in your project. For details, see Start a Video Call or Start Interactive Video Streaming.
From v2.4.0, Agora supports the following screen sharing functions on Windows:
screenRect
or specifying displayId
.windowId
.startScreenCaptureByDisplayId
to start sharing with displayId
instead of using startScreenCaptureByScreenRect
to start sharing with screenRect
.displayId
.Call getScreenCaptureSources
and get the display ID of the screen to be shared from the returned sourceId
, which identifies each screen.
SIZE size;
size.cx = 100;
size.cy = 100;
IScreenCaptureSourceList* infos = m_rtcEngine->getScreenCaptureSources(size, size, true);
int count = 0;
for (size_t i = 0; i < infos->getCount(); i++) {
ScreenCaptureSourceInfo info = infos->getSourceInfo(i);
if (info.type == ScreenCaptureSourceType_Screen) {
m_cmbScreenRegion.InsertString(i, utf82cs(info.sourceName));
count++;
}
}
Call startScreenCaptureByDisplayId
, pass in the display ID, and set the screen-sharing configuration to enable screen sharing.
IScreenCaptureSourceList* infos = m_rtcEngine->getScreenCaptureSources(size, size, true);
ScreenCaptureSourceInfo info = infos->getSourceInfo(sel);
ScreenCaptureParameters capParam;
m_rtcEngine->startScreenCaptureByDisplayId((int)info.sourceId, regionRect, capParam);
Windows lays all its screen displays on a virtual screen. You need the following parameters to share a screen:
Take the following steps to share a screen by specifying screenRect:
Get a list of monitor display information.
// Get a list of monitor display information
void CAgoraScreenCapture::InitMonitorInfos()
{
// m_monitors is an instance of CMonitors. Refer to the sample project for the implementation of the CMonitors class
// m_monitors calls EnumMonitor to get a list of monitor information
m_monitors.EnumMonitor();
// Define the infos vector to store the list
std::vector<CMonitors::MonitorInformation> infos = m_monitors.GetMonitors();
CString str = _T("");
// Get the Rectangle coordinates of each display 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);
}
EnumMonitor
method in the sample code calls EnumDisplayMonitors to list monitor information. See the demo project for the implementation of EnumMonitor
.Share the screen by the Rectangle coordinates of the display screen to share on the virtual screen and that of the area to share on the display screen.
void CAgoraScreenCapture::OnBnClickedButtonStartShareScreen()
{
m_screenShare = !m_screenShare;
if (m_screenShare) {
// Get the selected display 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 area to share on the display screen.
// See the sample project for the detailed implementation of GetMonitorRectangle
regionRect = m_monitors.GetMonitorRectangle(sel);
// Get the Rectangle coordinate of the display screen on the virtual screen.
// See the sample project for the implementation of GetScreenRect
screenRegion = m_monitors.GetScreenRect();
m_monitors.GetScreenRect();
// Set the encoding configurations for screen sharing
ScreenCaptureParameters capParam;
// Start screen sharing
m_rtcEngine->startScreenCaptureByScreenRect(screenRegion, regionRect, capParam);
m_btnShareScreen.SetWindowText(screenShareCtrlStopShare);
m_btnStartCap.EnableWindow(FALSE);
}
else {
// Stop screen sharing
m_rtcEngine->stopScreenCapture();
m_btnShareScreen.SetWindowText(screenShareCtrlShareSCreen);
m_btnStartCap.EnableWindow(TRUE);
}
}
Windows assigns a unique window identifier (windowId) for each window with a data type of HWND. To achieve compatibility with the x86 and x64 operating systems, it is in the format of view_t. With this window ID, we can implement window sharing on Windows with the following steps:
Get a list of IDs of all top-level windows.
// Get the HWND of all top-level windows and store them 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;
// ID of the window to share
hWnd = m_listWnd.GetAt(m_listWnd.FindIndex(m_cmbScreenCap.GetCurSel()));
int ret = 0;
m_windowShare = !m_windowShare;
if (m_windowShare)
{
// Set captureParameters, which includes encoding parameters for screen sharing
ScreenCaptureParameters capParam;
GetCaptureParameterFromCtrl(capParam);
// Set regionRect, which is the Rectangle coordinate of the area to share on the display window
CRect rcWnd = { 0 };
::GetClientRect(hWnd, &rcWnd);
agora::rtc::Rectangle rcCapWnd = { rcWnd.left, rcWnd.top, rcWnd.right - rcWnd.left, rcWnd.bottom - rcWnd.top };
// Start screen sharing
ret = m_rtcEngine->startScreenCaptureByWindowId(hWnd, rcCapWnd, capParam);
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 {
// Stop 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);
}
}
getScreenCaptureSources
startScreenCaptureByDisplayId
startScreenCaptureByWindowId
startScreenCaptureByScreenRect
updateScreenCaptureParameters
setScreenCaptureContentHint
updateScreenCaptureRegion
stopScreenCapture
We provide an open-source Agora-Screen-Sharing-Windows demo project on GitHub that implements screen sharing and publishing the local video stream. You can download it and refer to the source code.
startScreenCapture
method. It is still functional, but Agora no longer recommends it.AgoraScreenCaptureParameters
may affect your communication chargers. As of v2.4.1, if you set the dimendions
parameter as default, Agora uses 1920 x 1080 to calculate the charges.