在 WebRTC 應用中,透過 Capture Handle 識別共享標籤頁

我一直不太贊同在演示的同時共享螢幕。大家進入影片會議應用程式,跟大家打招呼,然後開始分享自己在另一個標籤或視窗的ppt。那你要看什麼呢?ppt嗎?但我更想面對觀眾並與其互動。確實,有些工具可以讓你預覽所分享的內容,但你仍然需要來回滑動每張ppt。理應採用一個更好的辦法,那就是capture handle。

Capture Handle是origin trial中一個用於螢幕共享(getDisplayMedia)的新的API。它可以讓螢幕共享app識別,與使用者選擇的標籤相協調。

Elad Alon是一位對接webrtc。org團隊的谷歌員工。他負責整理capture handle規範,並推動其透過W3C的標準化過程。

在這篇文章中,Elad向我們介紹了capture handle,並列舉了一些關於防止“鏡室 (hall of mirrors)效應”的例子。另外他也回答了我在文章開頭所說,螢幕共享時切換幻燈片的問題。capture handle也有很多其他用途。下面會對此進行詳述。

在 WebRTC 應用中,透過 Capture Handle 識別共享標籤頁

在過去的一年裡,螢幕共享逐漸成為大家生活中必不可少的一部分。其原因自然不言而喻。對於基於Web的產品,該操作通常是透過呼叫getDisplayMedia來實現的。一旦getDisplayMedia被呼叫,瀏覽器就會向用戶展示他們自己的媒體選擇器。

在 WebRTC 應用中,透過 Capture Handle 識別共享標籤頁

不同瀏覽器中,getDisplayMedia示例頁面上的螢幕共享選擇器

目前,該API允許捕獲三種不同的介面展示選項——螢幕、視窗或標籤。使用者擁有該選擇權。(這種選擇可能受到使用者選擇的瀏覽器的限制。比如Firefox還不支援標籤捕捉,而Safari只提供全屏捕捉。)

getDisplayMedia返回一個Promise。當用戶做出選擇後,Promise被解決,應用程式可以開始使用返回的MediaStream,該stream有一個影片軌道,可能還有一個音訊軌道。但是,應用程式還能較容易地發現捕獲介面的哪些內容呢?為什麼需要應用程式這樣做呢?讓我們來解決這兩個問題。

識別捕獲的顯示介面

以前,應用程式只能區分螢幕/視窗/標籤捕獲。

對於Safari來說確實是這樣,因為它只支援螢幕捕捉。

Chrome允許透過MediaTrackSettings。displaySurface查詢捕獲街面。

Firefox以MediaStreamTrack。label的形式公開了捕獲視窗的標題。螢幕捕捉會指定一個特殊的字串,比如“Primary Monitor”。

所以,並沒有標準的方法來真正識別捕獲的web應用。被捕獲的標籤是一個YouTube影片?還是一個簡報?如果是簡報的話,它又來自哪個應用呢?如果捕獲的應用程式和被捕獲的應用程式甚至不能識別對方,那麼它們如何進行協作?是否應該透過嵌入二維碼的方式進行隱寫?

輸入“Capture Handle”。讓我們看幾個示例來說明Capture Handle如何工作。

檢測自我抓取

我們可以從最簡單的Capture Handle示例講起——一個單一標籤(應用程式裡預期是兩個)。設想現在有一個將捕獲的影片呈現給本地使用者的應用程式。自我捕獲會導致鏡廳效應。

在 WebRTC 應用中,透過 Capture Handle 識別共享標籤頁

顯示被捕獲螢幕時出現的鏡室效應

如果web應用能夠檢測到這一點,它就可以避免將影片回放給本地使用者,從而避免令人不適的這種效果。

const TOTALLY_RANDOM_ID = “42”; // Or actually randomize。。。const ownId = TOTALLY_RANDOM_ID;// Set the capture handle of the web application。navigator。mediaDevices。setCaptureHandleConfig( { handle: ownId, permittedOrigins: [“*”] });// 。。。const stream = await navigator。mediaDevices。getDisplayMedia();const [track] = stream。getVideoTracks();// Check to see if the captured tab has the same handle。const isSelfCapture = track。getCaptureHandle && track。getCaptureHandle() && track。getCaptureHandle()。handle == ownId;// Then mitigate the hall-of-mirrors as you see fit,// e。g。 hide the element using CSS。

在這種情況下,Web應用程式可以很輕易地在當前標籤上設定一個ID。然後這個captureHandle()。handle可以用來檢查使用者是否在螢幕共享選擇器中選擇了他們自己的標籤。

點選此處,你可以看到這個概念的完整演示。

引導協作

如果一個應用程式可以識別它正在捕獲的應用程式,它就可以與之協作。它們之間無論使用多傳統的方法,都可以進行訊息交流,並新增包括任何種類的語義。例如,一個VC應用可以遠端控制幻燈片。

在 WebRTC 應用中,透過 Capture Handle 識別共享標籤頁

如需觀看演示請點選此處。請注意,它是由一個C++開發人員製作的,並不是一個web開發人員。TL;DR是指,被捕獲的應用程式設定一個handle,而捕獲的應用程式從中提取會話ID。可以想象一個名為Slides 3000的幻燈片web應用程式:

////////////////////////////////////////// Captured application (Slides 3000) //////////////////////////////////////////function getLoonySessionId() { 。。。 // Returns some ID which is meaningful using loonyAPI。}function onPageLoaded() { // Expose and add info as you like, including the origin。 。。。 setCaptureHandleConfig({ exposeOrigin: true, handle: JSON。stringify({ description: “See slides-3000。com for our API。”, protocol: “loonyAPI”, version: “1。983”, sessionId: getLoonySessionId(), }), permittedOrigins = [‘*’] }); 。。。}

和一個名為VC-MAX的影片通話web應用:

////////////////////////////////////// Capturing application (VC-MAX) //////////////////////////////////////async function startCapture() { // 。。。 const stream = await navigator。mediaDevices。getDisplayMedia(); const [track] = stream。getVideoTracks(); if (track。getCaptureHandle) { // Feature detection。 // Subscribe to notifications of the capture-handle changing。 track。oncapturehandlechange = (event) => { onNewCaptureHandle(event。captureHandle()); }; // Read the current capture-handle。 onNewCaptureHandle(track。getCaptureHandle()); } 。。。}function onNewCaptureHandle(captureHandle) { if (captureHandle。origin == ‘slides-3000。com’) { const parsed = JSON。parse(captureHandle。handle); onNewSlides300Session(parsed。protocol, parsed。version, parsed。sessionId); }}function onNewSlides300Session(protocol, version, sessionId) { if (protocol != “loonyAPI” || version > “2。02”) { return; } // Exposes prev/next buttons to the user。 When clicked, these send // a message to some REST API, where |sessionId| indicates that the // message has to be relayed to the Slides 3000 session in question。 ExposeSlides300Controls(sessionId);}

選擇你自己的信令

capture handle可以提供識別,但並不提供通訊。它並不涉及兩個標籤之間如何交換訊息。你可以設想是BroadcastChannel,或者共享雲基礎設施被啟用,即信令伺服器(在比通常使用WebRTC情景更廣泛的情況裡)。所有合理的通訊手段都有一個共同特點——它們要求捕獲者知道被捕獲的應用程式的ID,而這正是capture handle所能提供的。

這為開發者實現其應用提供了方式上的靈活性。比如,如果使用者開啟多個幻燈片標籤,多個標籤是否都會被指示翻到下一張幻燈片呢?不可思議!

使用capture handle最佳化capture引數

假設有兩個使用者,一個使用者正在和朋友分享一個1080p的預告片,提議大家一起看這部電影。另一個使用者正在向同事們展示一個基本都是靜態的檔案。這兩個使用者都使用了同一種影片通話應用程式來分享另一個標籤。那麼在這兩個capture場景中,是否應該使用相同的幀率和解析度呢?

將來,可以直接提示內容型別的機制才是主流。但作為現在的一種權宜之計,Capture Handle能幫助使用者檢查標籤的來源是否是已知的影片服務網站、已知的生產力套裝等。然後,應用程式就可以設定幀速率、解析度屬性以及contentHint了。

Capture Handle何時能用?

從M92版開始,Chrome進行Capture Handle origin trial。

M92版和M93版相比,API有細微差別:

在 WebRTC 應用中,透過 Capture Handle 識別共享標籤頁

除此之外,Chrome目前沒有計劃進行額外的修改。如果有,我們可以在變更日誌中找到。然而,我們確實在計劃進行一項擴充套件,將該API擴充套件到視窗級capture。

Chrome瀏覽器正在收集公共web開發人員的支援意見,以說服其他瀏覽器供應商瞭解這一功能的重要性。