從任何元素擷取影片串流

François Beaufort
François Beaufort

只要使用螢幕畫面擷取 API,即可擷取整個分頁。Element Capture API 可讓您擷取並記錄特定的 HTML 元素。它會將整個分頁的擷取轉換為特定 DOM 子樹狀結構的擷取內容,只擷取 target 元素的直接子系。換句話說,這項功能會裁剪及移除遭到遮蓋和遮住的內容。

使用元素擷取的好處

考量視訊會議應用程式的需求條件,可協助你瞭解「元素擷取」功能的實用性。如果您有視訊會議應用程式可讓您將第三方應用程式嵌入 iframe,有時可能會想以影片形式擷取該 iframe,並傳送給遠端參與者。

Chrome 中視訊會議通話的螢幕截圖。
Elad 透過第三方應用程式和 François 進行視訊會議。

呼叫 getDisplayMedia() 並讓使用者選擇目前的分頁,就會傳送目前的分頁。這很有可能會將人們自己的影片傳回給他們。您可以使用區域拍攝功能裁剪掉該區域。

不過,如果簡報者與視訊會議應用程式互動,且部分內容 (例如下拉式清單) 出現於即將擷取的內容上方,會發生什麼事?

下拉式清單的螢幕截圖,涵蓋要擷取的內容。
系統會在要擷取的內容頂端顯示下拉式清單。

區域擷取功能無法為你提供協助。遠端參與者的螢幕畫面上可能會顯示下拉式清單的部分內容。

已擷取下拉式清單的螢幕截圖。
Elad 的下拉式清單顯示在法屬法人所收到內容之上。

區域擷取功能會以這種方式擷取元素的一部分 (稱為「遮蔽內容」),會導致多個問題:

  • 這些內容可能會擋住使用者要分享的內容。
  • 某些內容可能會遭遮蓋,例如即時通訊通知。
  • 但遭遮蓋的內容可能會造成混淆。(舉例來說,應用程式的重新版面配置可以短暫提供遠端參與者的影片,而不是擷取的目標)。

Element Capture API 能讓您指定要分享的元素,藉此解決上述所有問題。

目標元素螢幕截圖 (檢視畫面中沒有下拉式選單)。
François 並未看到 Elad 的下拉式清單。

如何使用元素擷取?

captureTarget 是網頁上的元素,其中包含使用者要擷取的內容。你希望視訊會議網頁應用程式擷取captureTarget並分享給遠端參與者。因此從 captureTarget 衍生 RestrictionTarget。使用這個 RestrictionTarget 限制視訊軌後,該視訊軌的影格現在只會包含 captureTarget 及其直接 DOM 子系中的像素。

如果 captureTarget 會變更大小、形狀或位置,視訊軌就會跟著播放,您不需要透過任一網頁應用程式另外輸入。只要擋掉顯示、消失或移動的內容,同樣不需要特殊處理。

請再次檢查這些步驟:

第一步是讓使用者擷取目前的分頁。

// Ask the user for permission to start capturing the current tab.
const stream = await navigator.mediaDevices.getDisplayMedia({
 preferCurrentTab: true,
});
const [track] = stream.getVideoTracks();

使用您選擇的元素做為輸入內容,呼叫 RestrictionTarget.fromElement() 即可定義 RestrictionTarget

// Associate captureTarget with a new RestrictionTarget
const captureTarget = document.querySelector("#captureTarget");
const restrictionTarget = await RestrictionTarget.fromElement(captureTarget);

接著,呼叫視訊軌上的 restrictTo(),並使用 RestrictionTarget 做為輸入內容。一旦最後一個承諾值解決,所有後續影格都會受到限制。

// Start restricting the self-capture video track using the RestrictionTarget.
await track.restrictTo(restrictionTarget);

// Enjoy! Transmit remotely.

深入探索

特徵偵測

如要檢查系統是否支援 RestrictionTarget.fromElement(),請使用:

if ("RestrictionTarget" in self && "fromElement" in RestrictionTarget) {
  // Deriving a restriction target is supported.
}

擷取 RestrictionTarget

聚焦在名為 captureTarget元素。如要從該來源衍生 RestrictionTarget,請呼叫 RestrictionTarget.fromElement(captureTarget)。如果成功,系統會用新的 RestrictionTarget 物件解析傳回的 Promise。否則,如果計算出的 RestrictionTarget 物件數量不合理,該物件就會遭拒。

const captureTarget = document.querySelector("#captureTarget");
const restrictionTarget = await RestrictionTarget.fromElement(captureTarget);

與元素不同,RestrictionTarget 物件「可序列化」。舉例來說,您可以使用 Window.postMessage() 將傳遞訊息傳送至其他文件。

受限

擷取分頁時,視訊軌會顯示 restrictTo()。擷取目前的分頁時,可透過 null 或從目前分頁內的元素衍生的任何 RestrictionTarget 呼叫 restrictTo()

呼叫 restrictTo(restrictionTarget) 會將影片軌變更為 captureTarget 的擷取,就像是自行繪製,與 DOM 的其餘部分一樣。也會擷取 captureTarget 的所有子系。系統會從擷取作業中排除 captureTarget 的同層。因此,在軌跡上提交的任何影格看起來都像是裁剪為 captureTarget 的輪廓,並移除所有遮蔽和遭遮蔽的內容。

// Start restricting the self-capture video track using the RestrictionTarget.
await track.restrictTo(restrictionTarget);

呼叫 restrictTo(null) 會將測試群組還原為原始狀態。

// Stop restricting.
await track.restrictTo(null);

如果呼叫 restrictTo() 成功,傳回的 Promise 就會自動解決,但可以保證所有後續影片影格都僅限 captureTarget 使用。

如果失敗,Promise 就會遭到拒絕。無法撥打 restrictTo() 的可能原因如下:

  • 如果在非擷取的分頁中建立 restrictionTarget。(請注意,點選 [改為分享此分頁] 按鈕,使用者可以隨時變更要擷取的分頁)。
  • restrictionTarget 衍生自已不存在的元素。
  • 如果音軌有本機副本,(詳情請參閱問題 1509418)。
  • 如果目前的曲目不是自行擷取的音軌,
  • 如果衍生 restrictionTarget 的元素不符合限制資格。

自我拍攝注意事項

當應用程式呼叫 getDisplayMedia() 時,使用者選擇擷取應用程式本身的分頁,稱為「自行擷取」。

所有分頁擷取視訊軌都會揭露 restrictTo() 方法,而不只是用於自行拍攝。不過元素擷取功能目前僅供自行拍攝。因此,建議您在限制測試群組前,先檢查使用者是否選取了目前的分頁。可以使用「擷取控點」完成此操作。也可以要求瀏覽器使用 preferCurrentTab 提醒使用者自行擷取。

透明度

應用程式透過 getDisplayMedia() 取得的影片影格不含 Alpha 頻道。如果應用程式設定了部分透明的擷取目標,則刪除 Alpha 管道可能會產生某些後果:

  • 實際顏色可能會改變。移除 Alpha 頻道時,在淺色背景上繪製的部分透明目標元素可能會變暗,而在深色背景上繪製的元素則可能較淺。
  • 將 Alpha 版本移除後,使用者看不到或無法看到的顏色。舉例來說,如果透明部分具有 RGBA 代碼 rgba(0, 0, 0, 0),這可能會導致擷取的影格出現非預期的黑色區域。
非矩形透明擷取目標的結果螢幕截圖。
非矩形透明擷取目標影片串流 (右側) 是黑色背景矩形,內含不透明藍色圓圈。

不符資格的擷取目標

您可以開始將測試群組限制為任何有效的擷取目標。不過,如果特定條件 (例如元素或祖系為 display:none),系統就不會產生影格。一般原因在於,限制僅適用於由單一、連貫、二維長方形區域的元素組成的,而其像素可以在邏輯上與任何父項或同層級元素分開決定。

確保元素符合限制資格的其中一項重要考量是,必須建立專屬的堆疊背景資訊。確認無誤後,您可以指定 isolation CSS 屬性,並將其設為 isolate

<div id="captureTarget" style="isolation: isolate;"></iframe>

請注意,目標元素隨時可以切換是否符合資格和不符合限制資格,例如當應用程式變更 CSS 屬性時。應用程式必須採用合理的擷取目標,並避免無預警地變更其屬性。如果目標元素不再符合資格,則除非目標元素再次符合限制資格,否則系統不會在音軌發出新的影格。

啟用元素擷取功能

電腦版 Chrome 支援 Element Capture API (元素擷取標記後方),使用者可在 chrome://flags/#element-capture 啟用 Element Capture API。

這項功能也正在進入 Chrome 121 電腦版的來源試用。這項功能可讓開發人員啟用這項功能,讓網站訪客收集實際使用者的資料。如要進一步瞭解來源試用,請參閱「開始使用來源試用」一文。

安全性和隱私權

如要瞭解安全性的取捨,請參閱元素擷取規格的「隱私權和安全性考量」一節。

Chrome 瀏覽器會在已擷取的分頁邊緣周圍繪製藍色框線。

操作示範

如要使用元素擷取功能,請在 Glitch 上執行示範。請務必檢查原始碼

意見回饋:

Chrome 團隊和網路標準社群歡迎分享你對 Element Capture 的感想。

請與我們分享設計

區域擷取功能是否未如預期運作?或是你還需要實現創意的方法或屬性嗎?對安全性模型有任何疑問或意見嗎?

  • GitHub 存放區上提交規格問題,或將你的想法新增至現有問題。

無法導入嗎?

您發現 Chrome 實作錯誤嗎?還是採用與規格不同?

  • 前往 https://new.crbug.com 回報錯誤。請盡可能提供所有細節,以及簡單的重製說明。Glitch 有便捷的報復工具,

特別銘謝

相片來源:Paul Skorupskas 提供的 Unsplash 網站上