屏幕共享的實現與應用

語言: CN / TW / HK

隨着音視頻的迅速發展,無論是在商用還是娛樂方面都有很多場景的實際應用,玩法也是越來越多了,隨之而來的就是對衍生功能要求的提高。

屏幕共享就是對於商用和娛樂場景最重要的功能之一。

簡介

屏幕共享包括屏幕採集和視頻流推送這兩部分功能。與音視頻互動不同,屏幕共享講究的是高清實時,對帶寬以及設備性能要求很高。本文的重點是 anyRTC 在屏幕共享上的調優以及實現步驟,開發者無需關注功能實現細節,只需要參透 API 調用順序即可。下面以 Windows SDK 平台為例,介紹 anyRTC 屏幕共享功能。

目前 Windows SDK 屏幕分享功能支持屏幕分享窗口分享以及區域採集分享三種類型,其中屏幕分享和區域採集分享可以合二為一,區域採集分享為選定的屏幕中進行區域指定分享,如果想整個屏幕分享,需要指定整個屏幕區域位置即可。這三種採集方式,都有自己特定的使用場景,開發者只需要根據自己的實際應用場景,選擇對應的分享類型即可。

anyRTC SDK 暫不提供方法獲取顯示器屏幕信息和 window ID,你需要通過 Windows 原生方法,例如 EnumDisplayMonitorsEnumWindows 獲取相應信息。

屏幕分享 & 區域採集分享

在 Windows 系統中,每個顯示器的屏幕都位於同一個虛擬屏幕上,通過 Windows 原生方法,獲取對應的屏幕信息和 window ID。

具體實現步驟如下:

  1. 獲取顯示器屏幕信息列表。

cpp void CArScreenCapture::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); }

  1. 通過待共享的顯示器屏幕在虛擬屏幕上的 Rectangle 座標以及待共享區域在顯示器屏幕上的 Rectangle 座標實現屏幕共享。

```cpp void CArScreenCapture::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 系統為每個窗口分配一個 windowId,數據類型為 HWND。該 ID 對應唯一的 Windows 窗口。為了兼容 x86 和 x64 系統,使用 view_t 類型。

通過獲取該 windowId,我們可以按如下步驟在 Windows 平台上實現窗口共享:

  1. 獲取想要共享窗口的 Window ID

cpp 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);

  1. 通過 Window ID 共享窗口

```cpp // 指定共享的屏幕或窗口 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(); ```

以上是 Windows 平台屏幕共享介紹,想了解更多平台如 Android iOS 的小夥伴可以點擊 anyRTC 文檔中心進行查看。

應用場景

上文是對屏幕共享的功能介紹,下面為大家介紹一下屏幕共享的具體應用場景。

在線教育:

適用於大班課、小班課等多種教育場景,老師端可以通過屏幕共享將上課需要的課件,資料共享給學生,讓教學變得更加高效,提高效率節省時間。

遊戲直播:

遊戲主播可以通過實時採集屏幕內容,以直播的方式共享給所有觀眾,讓觀眾能夠以主播同樣的視角體驗遊戲。這樣可以提高用户的觀看體驗,讓用户可以有身臨其境的感覺。使得用户觀看的代入感更強,增加用户的粘性。

視頻會議:

主持人可將電腦上的材料共享給遠端的與會方,所有人觀看屏幕的實時視頻流,達到信息共享的目的。主持人不必再提起分發文檔,因為參與者可以在演示者的屏幕上看到任何文檔或文件,甚至可以要求會議者通過屏幕共享工具的傳輸功能發送這些文檔和文件。

遠程演示:

在進行遠程協作或操作演示時,可以通過採集屏幕和窗口的內容,直觀演示具體操作步驟,幫助他人快速理解。屏幕共享允許的在線演示是組織與客户和客户互動的完美方法。藉助屏幕共享應用程序,不僅銷售人員可以展示他們的產品,而且他們還可以通過提供PC鍵盤或鼠標的遠程控制來邀請客户體驗軟件程序等項目。這是屏幕共享工具的最佳好處之一。

在線培訓:

通過在線培訓中使用屏幕共享工具,組織可以節省大量資金,因為他們不必設置整個投影儀設置併為外部講座付費。相反,講師的材料可以通過屏幕共享應用程序從他們的PC屏幕輕鬆共享,供所有與會者查看。

講師甚至可以使用這樣的屏幕共享功能作為白板或參與者指針來與學員互動,從而形成交互式和娛樂性的學習環境。

除了上述 Windows 的屏幕共享,anyRTC 已經實現了全平台的屏幕共享。Android 端支持屏幕共享採集H264格式的屏幕共享流,很大一定程度上優化了 Android 的性能;iOS 端無縫匹配 Replaykit ;Web 端除了區域採集分享,其他兩種分析功能都有對應的 API 調用,更多產品細節,關注 anyRTC。