螢幕共享的實現與應用

語言: 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。