anyRTC 为您提供屏幕分享使用的接口方法,通过本文档您可以了解实现的具体调用流程。
功能简介
目前Windows SDK屏幕分享功能支持屏幕分享和窗口分享两种类型,其中屏幕分享还支持指定区域进行分享,应用侧可根据业务场景设置分享内容并推流。
屏幕分享
anyRTC对屏幕分享相关接口进行梳理,目前在 Windows 平台上支持:
- 通过
screenRect
共享指定屏幕,或指定屏幕的部分区域 - 通过
windowId
共享指定窗口,或指定窗口的部分区域
Windows 系统的所有屏幕(display)都画在一整张 virtual screen 上。对用户来说,只有拿到该屏幕在整张 virtual screen 上的相对位置,才能获得该屏幕的画面。通过获取该画面的 screenRect
,我们可以按如下步骤在 Windows 平台上实现屏幕共享:
- 获取想要共享窗口的
screenRect
bool result = true;
int index;
for (index = 0;; index++) {
DISPLAY_DEVICE device;
device.cb = sizeof(device);
result = EnumDisplayDevices(NULL, index, &device, 0);
if (!result) break;
if (!(device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) {
continue;
}
DEVMODE device_mode;
device_mode.dmSize = sizeof(DEVMODE);
device_mode.dmDriverExtra = 0;
EnumDisplaySettingsEx(device.DeviceName, ENUM_CURRENT_SETTINGS, &device_mode, 0);
printf("device name:%ls\n", device.DeviceName);
printf("x: %d\n", device_mode.dmPosition.x);
printf("y: %d\n", device_mode.dmPosition.y);
printf("w: %d\n", device_mode.dmPelsWidth);
printf("h: %d\n", device_mode.dmPelsHeight);
}
更多关于 screenRect 的详情,请参考 Microsoft EnumDisplayDevicesA 说明。
-
通过
screenRect
共享屏幕// 指定共享的屏幕或窗口 RECT rc; ar::rtc::Rectangle rcCap; ar::rtc::Rectangle screenRegion = { rc.left, rc.right, rc.right - rc.left, rc.bottom - rc.top }; capParam.dimensions.width = rc.right - rc.left; capParam.dimensions.height = rc.bottom - rc.top; ::GetWindowRect(hWnd, &rc); ScreenCaptureParameters capParam; capParam.dimensions.width = rc.right - rc.left; capParam.dimensions.height = rc.bottom - rc.top; VideoContentHint contentHint; ar::rtc::Rect rt; // 开始共享屏幕 ret = m_lpAREngine->startScreenCaptureByScreenRect(screenRegion, rcCap, capParam); // 更新屏幕共享编码参数 m_lpAREngine->updateScreenCaptureParameters(capParam); // 更新屏幕共享区域 m_lpAREngine->updateScreenCaptureRegion(screenRegion); // 设置屏幕共享内容类型 m_lpAREngine->setScreenCaptureContentHint(contentHint); // 停止屏幕共享 m_lpAREngine->stopScreenCapture();
窗口分享
Windows 系统为每个窗口分配一个 windowId,数据类型为 HWND。该 ID 对应唯一的 Windows 窗口。为了兼容 x86 和 x64 系统,使用 view_t 类型。
通过获取该 windowId,我们可以按如下步骤在 Windows 平台上实现窗口共享:
- 获取想要共享窗口的 Window ID
BOOL CALLBACK EnumProc(HWND hWnd, LPARAM IParam)
{
// 仅获取可视窗口 ID,忽略弹出窗口及目录窗口
LONG IStyle = ::GetWindowLong(hWnd, GWL_STYLE);
if ((IStyle&WS_VISIBLE) != 0 && (IStyle&(WAS_POPUP | WA_SYSMENU)) != 0) {
HWND window_id = hWnd;
}
return TRUE;
}
EnumWindows(&EnumProc, NULL);
更多关于 windowId 的详情,请参考 Microsoft EnumWindows 说明。
-
通过 Window ID 共享窗口
// 指定共享的屏幕或窗口 RECT rc; ar::rtc::Rectangle rcCap; ar::rtc::Rectangle screenRegion = { rc.left, rc.right, rc.right - rc.left, rc.bottom - rc.top }; capParam.dimensions.width = rc.right - rc.left; capParam.dimensions.height = rc.bottom - rc.top; ::GetWindowRect(hWnd, &rc); ScreenCaptureParameters capParam; capParam.dimensions.width = rc.right - rc.left; capParam.dimensions.height = rc.bottom - rc.top; VideoContentHint contentHint; ar::rtc::Rect rt; // 开始共享窗口 ret = m_lpAREngine->startScreenCaptureByWindowId(hWnd, rcCap, capParam); // 更新屏幕共享编码参数 m_lpAREngine->updateScreenCaptureParameters(capParam); // 更新屏幕共享区域 m_lpAREngine->updateScreenCaptureRegion(screenRegion); // 设置屏幕共享内容类型 m_lpAREngine->setScreenCaptureContentHint(contentHint); // 停止屏幕共享 m_lpAREngine->stopScreenCapture();
API 参考
startScreenCaptureByWindowId
startScreenCaptureByScreenRect
updateScreenCaptureParameters
setScreenCaptureContentHint
updateScreenCaptureRegion
stopScreenCapture
开发注意事项
- 视频共享编码属性
ScreenCaptureParameters
类中各参数的设置可能会影响计费。如果你将dimensions
参数设为默认值,则 anyRTC 使用 1920 x 1080 进行计费。 - 屏幕共享的媒体流的用户 ID 默认为 "share666",单个频道中只能有一个共享通道。单个频道支持多个共享的话,需要设定屏幕共享的 ID,请在调用开始共享 API 前使用私有方法:
m_lpAREngine->setParameters("{\"Cmd\":\"SetScreenCastUId\", \"UId\": \"screen888\"}");
- 在 Windows 平台上进行屏幕共享时,如果共享的是 QQ 聊天窗口会导致共享窗口黑屏。