從任何元素擷取影片串流

法蘭索瓦博福
François Beaufort
艾倫 (Elad Alon)
Elad Alon

使用 Screen Capture API 可擷取目前的整個分頁,Element Capture API 可讓您擷取及記錄特定 HTML 元素。它會將整個分頁的擷取內容轉換為特定 DOM 子樹狀結構的擷取 (僅擷取目標元素的直接子系)。也就是說,它會裁剪及移除遮蔽和遮蔽的內容。

使用元素擷取功能的好處

思考視訊會議應用程式的需求條件,有助於瞭解 Element Capture 的實用之處。如果您的視訊會議應用程式可讓您將第三方應用程式嵌入 iframe 中,有時可能需要擷取該 iframe 做為影片,並傳輸給遠端參與者。

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

呼叫 getDisplayMedia() 並讓使用者選擇目前的分頁會傳輸整個目前的分頁。因此可能會將人們的影片傳輸給他們。您也可以使用區域擷取功能來裁剪相關資訊。

但是,如果簡報者使用視訊會議應用程式,部分內容 (例如下拉式清單) 會在想要拍攝的內容上方繪圖嗎?

下拉式清單螢幕截圖,顯示要擷取的內容。
系統會在要擷取的內容上方顯示下拉式清單。

但區域擷取功能無法助你一臂之力。遠端參與者的螢幕上可能會顯示下拉式清單的部分內容。

已擷取下拉式清單的螢幕截圖。
Elad 的下拉式清單會顯示在 François 收到的內容頂端。

區域擷取功能以這種方式擷取部分元素 (稱為「收錄內容」) 會產生多個問題:

  • 隱藏內容可能會擋住使用者欲分享的內容。
  • 隱藏的內容可能有私人資訊 (例如即時通訊通知)。
  • 隱藏內容可能會造成混淆。(舉例來說,重新調整應用程式的版面配置可暫時將遠端參與者自己的影片移到擷取的目標上)。

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

然後使用 RestrictionTarget 做為輸入內容,在視訊軌上呼叫 restrictTo()。一旦最後一個 promise 解決,所有後續影格都會受到限制。

// 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)。如果成功,傳回的 Promise 會使用新的 RestrictionTarget 物件解決。否則,假如您遇到了不合理的 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() 方法會顯示在任何分頁擷取影片軌上,而不只是用於自行拍攝的影片。但「Element Capture」功能目前僅供自行拍攝。因此,建議先檢查使用者是否選取目前的分頁,再嘗試限製曲目。您可以使用擷取帳號代碼完成這項操作。您也可以使用 preferCurrentTab,要求瀏覽器提醒使用者自行拍攝。

資訊公開

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

  • 實際顏色可能不同。移除 Alpha 通道時,覆蓋在淺色背景上的部分透明目標元素可能會變暗,而在深色背景上繪製的元素可能會較淺。
  • 設定 Alpha 通道時,使用者看不到或無法察覺的顏色,會在 Alpha 管道移除後顯示。舉例來說,如果透明區段的 RGBA 代碼為 rgba(0, 0, 0, 0),可能會導致擷取的影格中出現非預期的黑色區域。
非矩形透明拍攝目標的結果螢幕截圖。
非矩形透明擷取目標影片串流 (右側) 是包含不透明藍色圓圈的黑色背景矩形。

不符資格的擷取目標

您隨時可以開始將追蹤範圍限制在任何有效的擷取目標中。不過,如果元素或祖係是 display:none,系統就不會在特定條件下產生影格。基本原因就是限制僅適用於單一元素,亦即包含單一、連貫、二維矩形區域的元素,其中的像素可透過邏輯方式與任何父項或同層級元素區隔開來。

為確保元素符合限制資格,重要的考量因素是,該元素必須建立專屬的「堆疊內容」。如要確保這種情況,您可以指定「隔離」CSS 屬性,並設為 isolate

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

請注意,即使應用程式變更其 CSS 屬性,目標元素隨時可以將目標元素切換為符合限制資格,不符合限制條件。應用程式可採用合理的擷取目標,並避免意外變更其屬性。如果目標元素不符合資格,則除非該目標元素再次符合限制資格,否則系統不會在軌道發出新的影格。

啟用元素擷取

Chrome 電腦版的 Element Capture API 還提供 Element Capture API,您可以前往 chrome://flags/#element-capture 啟用這個 API。

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

安全性和隱私權

如要瞭解安全性的優缺點,請參閱「Element Capture」規格的「隱私權和安全性考量」一節。

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

示範模式

你可以在 Glitch 上執行示範,使用 Element Capture 功能。請務必查看原始碼

意見回饋:

Chrome 團隊和網路標準社群想瞭解你的 Element Capture 使用體驗。

介紹設計

哪些區域擷取功能無法正常運作?還是缺少實作提案所需的方法或屬性?對安全模型有任何疑問或意見嗎?

  • GitHub 存放區中提交規格問題,或是在現有問題中新增想法。

執行時遇到問題嗎?

您在導入 Chrome 時發現錯誤嗎?還是實作方式與規格不同?

  • 前往 https://new.crbug.com 回報錯誤。請務必盡可能提供詳細資訊,並且提供重現問題的簡單操作說明。Glitch 適合用於分享快速簡便的重新提交內容。

認證

Paul Skorupskas 提供 Unsplash 網站上分享的相片