在视频通话或互动直播中进行屏幕共享,可以将说话人或主播的屏幕内容,以视频的方式分享给其他说话人或观众观看,以提高沟通效率。
屏幕共享在如下场景中应用广泛:
我们在 GitHub 提供一个开源的示例项目。你可以前往下载体验。
在实现屏幕共享前,请确保已在你的项目中实现基本的实时音视频功能。详见开始音视频通话或开始互动直播。
Agora 在 v2.4.0 对屏幕共享相关接口进行梳理,目前在 Windows 平台上支持:
在 Windows 系统中,每个显示器的屏幕都位于同一个虚拟屏幕上。为了共享指定屏幕区域,你必须获取以下参数:
具体实现步骤如下:
// 获取显示器屏幕信息列表
void CAgoraScreenCapture::InitMonitorInfos()
{
// m_monitors 是 CMonitors 类的实例。CMonitors 类的具体实现参考示例项目。
// m_monitors 调用 EnumMonitor 获取显示器屏幕信息列表。EnumMonitor 方法的具体实现参考示例项目。
m_monitors.EnumMonitor();
// 定义 infos 向量,用于存储显示器屏幕信息列表。
std::vector<CMonitors::MonitorInformation> infos = m_monitors.GetMonitors();
CString str = _T("");
// 获取每个显示器屏幕在虚拟屏幕上的 Rectangle 坐标
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);
}
void CAgoraScreenCapture::OnBnClickedButtonStartShareScreen()
{
m_screenShare = !m_screenShare;
if (m_screenShare) {
// 获取选择的显示器屏幕
int sel = m_cmbScreenRegion.GetCurSel();
agora::rtc::Rectangle regionRect = { 0,0,0,0 }, screenRegion = {0,0,0,0};
// 获取指定的待共享区域在整个显示器屏幕中的 Rectangle 坐标。
// GetMonitorRectangle 方法的具体实现详见示例项目。
regionRect = m_monitors.GetMonitorRectangle(sel);
// 获取显示器屏幕在虚拟屏幕中的 Rectangle 坐标。GetScreenRect 方法的实现详见示例项目。
screenRegion = m_monitors.GetScreenRect();
m_monitors.GetScreenRect();
// 屏幕共享的编码参数配置
ScreenCaptureParameters capParam;
// 开始屏幕共享
m_rtcEngine->startScreenCaptureByScreenRect(screenRegion, regionRect, capParam);
m_btnShareScreen.SetWindowText(screenShareCtrlStopShare);
m_btnStartCap.EnableWindow(FALSE);
}
else {
// 停止屏幕共享
m_rtcEngine->stopScreenCapture();
m_btnShareScreen.SetWindowText(screenShareCtrlShareSCreen);
m_btnStartCap.EnableWindow(TRUE);
}
}
Windows 系统为每个窗口分配一个 Window ID,数据类型为 HWND。该 ID 对应唯一的 Windows 窗口。为了兼容 x86 和 x64 系统,API 参数使用 view_t
类型。
通过获取该 Window ID,我们可以按如下步骤在 Windows 平台上实现窗口共享:
// 获取所有最新顶层窗口的 HWND 并储存在 m_listWnd 中
int CAgoraScreenCapture::RefreshWndInfo()
{
m_listWnd.RemoveAll();
::EnumWindows(&CAgoraScreenCapture::WndEnumProc, (LPARAM)&m_listWnd);
return static_cast<int>(m_listWnd.GetCount());
}
void CAgoraScreenCapture::OnBnClickedButtonStartShareScreen()
{
m_screenShare = !m_screenShare;
if (m_screenShare) {
// 获取选择的显示器屏幕
int sel = m_cmbScreenRegion.GetCurSel();
agora::rtc::Rectangle regionRect = { 0,0,0,0 }, screenRegion = {0,0,0,0};
// 获取指定的待共享区域在整个显示器屏幕中的 Rectangle 坐标。
// GetMonitorRectangle 方法的具体实现详见示例项目。
regionRect = m_monitors.GetMonitorRectangle(sel);
// 获取显示器屏幕在虚拟屏幕中的 Rectangle 坐标。GetScreenRect 方法的实现详见示例项目。
screenRegion = m_monitors.GetScreenRect();
m_monitors.GetScreenRect();
// 屏幕共享的编码参数配置
ScreenCaptureParameters capParam;
// 开始屏幕共享
m_rtcEngine->startScreenCaptureByScreenRect(screenRegion, regionRect, capParam);
m_btnShareScreen.SetWindowText(screenShareCtrlStopShare);
m_btnStartCap.EnableWindow(FALSE);
}
else {
// 停止屏幕共享
m_rtcEngine->stopScreenCapture();
m_btnShareScreen.SetWindowText(screenShareCtrlShareSCreen);
m_btnStartCap.EnableWindow(TRUE);
}
}
startScreenCaptureByWindowId
startScreenCaptureByScreenRect
updateScreenCaptureParameters
setScreenCaptureContentHint
updateScreenCaptureRegion
stopScreenCapture
我们在 GitHub 提供一个实现同时发布屏幕共享流和用户视频流功能的开源示例项目。你可以前往 Agora-Screen-Sharing-Windows 下载体验。
startScreenCapture
接口。你可以继续使用,但 Agora 不再推荐。ScreenCaptureParameters
类中各参数的设置可能会影响计费。从 v2.4.1 版本起,如果你将 dimensions
参数设为默认值,则 Agora 使用 1920 x 1080 进行计费。