Region Capture を使用したタブ共有の改善

フランソワ ボーフォール
François Beaufort
Elad Alon 氏
Ead Alon

このウェブ プラットフォームでは、すでにウェブアプリで現在のタブの動画トラックをキャプチャできます。現在、こうした動画トラックを切り抜くメカニズムであるリージョン キャプチャも搭載されています。ウェブアプリは現在のタブの一部を関心領域として指定し、ブラウザはその領域外のすべてのピクセルを切り取ります。

ウェブアプリはこれまで、動画トラックを「手動で」切り抜くことがありました。つまり、ウェブアプリはすべてのフレームを直接操作することができました。これは堅牢性でもパフォーマンス性も高くありませんでした。リージョン キャプチャはこの欠点に対処します。これで、ウェブアプリからブラウザに代理で処理を行うよう指示できるようになります。

リージョン キャプチャについて

そこであなたは、Dynamic ContentTM を使用してウェブサイトを作成しました。これは、きわめて優れたウェブアプリであり、人々は協力関係にあることが多く、利用を止めることができません。次のステップとして、仮想会議機能の埋め込みがあります。これを採用することにしました。あなたは既存のビデオ会議サービス プロバイダと連携し、そのウェブアプリをクロスオリジンの iframe として埋め込みます。ビデオ会議ウェブアプリは、現在のタブを動画トラックとしてキャプチャし、リモートの参加者に送信します。

メイン コンテンツ領域とクロスオリジン iframe がハイライト表示されたウェブアプリが表示されたブラウザ ウィンドウのスクリーンショット。
メイン コンテンツ領域は青色、クロスオリジンの iframe は赤色で示されます。

処理速度が遅くなる不要な部分は削除することをおすすめします。これには、埋め込み iframe では、どのコンテンツがどこに表示されるかわからないため、適切に切り取られないと切り取られません。理論的には、目的の座標を渡すことができます。しかし、ユーザーがウィンドウのサイズを変更した場合はどうなるでしょうか。ビューポートをスクロールしますか?拡大または縮小しますか?レイアウトを変更するような方法でページとやり取りしていますか。新しい座標をキャプチャ iframe に送信しても、タイミングの問題によりフレームの誤切り抜きが発生することがあります。

リージョン キャプチャを使用しましょう。ページには Element<div> など)があり、そこにメイン コンテンツが含まれています。mainContentArea とします。ビデオ会議ウェブアプリで、この要素の境界ボックスで定義された領域をリモートでキャプチャして共有するようにします。そのため、mainContentArea から CropTarget を導出します。この CropTarget をビデオ会議ウェブアプリに渡します。この CropTarget を使用して動画トラックを切り抜くと、そのトラックのフレームは mainContentArea の境界ボックス内のピクセルのみで構成されます。mainContentArea でサイズ、形、または位置が変わっても、動画トラックが流れます。いずれのウェブアプリからの入力も必要ありません。

これらの手順をもう一度確認しましょう。

ウェブアプリで CropTarget を定義するには、任意の要素を入力として CropTarget.fromElement() を呼び出します。

// In the main web app, associate mainContentArea with a new CropTarget
const mainContentArea = document.querySelector("#mainContentArea");
const cropTarget = await CropTarget.fromElement(mainContentArea);

CropTarget をビデオ会議ウェブアプリに渡します。

// Send the CropTarget to the video conferencing web app.
const iframe = document.querySelector("#videoConferenceIframe");
iframe.contentWindow.postMessage(cropTarget);

ビデオ会議ウェブアプリは、メインのウェブアプリから受け取った切り抜きターゲットを使用して、セルフキャプチャ動画トラックで cropTo() を呼び出して、CropTarget で定義された領域でトラックを切り抜くようブラウザに指示します。

// In the embedded video conferencing web app, ask the user for permission
// to start capturing the current tab.
const stream = await navigator.mediaDevices.getDisplayMedia({
  preferCurrentTab: true,
});
const [track] = stream.getVideoTracks();

// Start cropping the self-capture video track using the CropTarget
// received over window.onmessage.
await track.cropTo(cropTarget);

// Enjoy! Transmit remotely the cropped video track with RTCPeerConnection.

これで完了です。これで設定は完了です。

詳細

特徴検出

CropTarget.fromElement() がサポートされているかどうかを確認するには、次のコマンドを使用します。

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

CropTarget の導出

mainContentArea という要素に注目してみましょう。CropTarget を導出するには、CropTarget.fromElement(mainContentArea) を呼び出します。返された Promise は、成功すると新しい CropTarget オブジェクトで解決されます。そうでない場合、不当な数の CropTarget オブジェクトを作成した場合、このオブジェクトは拒否されます。

const mainContentArea = document.querySelector("#mainContentArea");
const cropTarget = await CropTarget.fromElement(mainContentArea);

Element とは異なり、CropTarget オブジェクトはシリアル化可能です。たとえば、Window.postMessage() を使用して別のドキュメントに渡すことができます。

切り抜き

タブをキャプチャする際、動画トラックは MediaStreamTrack のサブクラスである BrowserCaptureMediaStreamTrack としてインスタンス化されます。このサブクラスは cropTo() を公開します。track.cropTo(cropTarget) を呼び出して、mainContentArea(cropTarget の導出元の要素)の輪郭までの切り抜きを開始します。

成功すると、Promise は、後続のすべての動画フレームが mainContentArea の境界ボックス内のピクセルで構成されることが保証された時点で解決されます。

失敗した場合、Promise は拒否されます。この処理は次のような場合に発生します。

  • CropTarget は別のタブで作成されました。(今のところ、今しばらくお待ちください)。
  • CropTarget が、もはや存在しない要素から取得されました。
  • トラックにクローンが含まれている。(問題 1509418 をご覧ください)。
  • 現在のトラックはセルフキャプチャ動画トラックではありません。下記をご覧ください。

cropTo() メソッドは、自己キャプチャだけでなく、タブキャプチャ動画トラックでも使用できます。そのため、トラックの切り抜きを行う前に、ユーザーが現在のタブを選択しているかどうかを確認することをおすすめします。これは、ハンドルをキャプチャを使用して行うことができます。preferCurrentTab を使用して、ユーザーに自己撮影を行うように促すこともできます。

// Start cropping the self-capture video track using the CropTarget.
await track.cropTo(cropTarget);

切り抜かれていない状態に戻すには、null を指定して cropTo() を呼び出します。

// Stop cropping.
await track.cropTo(null);

コンテンツの密閉性

リージョン キャプチャでは、ターゲットの位置とサイズのみが重要で、Z-Index は重要ではありません。ターゲットを遮るピクセルがキャプチャされます。ターゲットの隠れた部分はキャプチャされません。

これは必然的に、リージョン キャプチャによってトリミングが行われることになります。代替の 1 つとして、将来的に独自の API になる予定の要素レベル キャプチャがあります。つまり、オクルージョンに関係なく、ターゲットに関連付けられたピクセルのみをキャプチャします。このような API には、単純な切り抜きとは異なるセキュリティとプライバシー要件があります。

領域キャプチャと要素レベルのキャプチャ API のさまざまな結果を示す画像。
オクルージョン コンテンツに対するリージョン キャプチャの動作。

セキュリティとプライバシー

リージョン キャプチャを使用すると、すでにタブ内のすべてのピクセルを確認しているウェブアプリで、そうしたピクセルの一部を自発的に削除できます。新しい情報を取得できないため、特許の安全性が確保されています。

リージョン キャプチャを使用すると、リモートの参加者に送信される情報を制限できます。たとえば、スピーカー ノートは共有せずに、一部のスライドを共有する場合などです。

スライドとスピーカー ノートが表示されたブラウザ ウィンドウのスクリーンショット。
スライドとスピーカー ノートを含むウェブアプリ。
リモートでメモを共有することは、非常に望ましくありません。キューリージョンのキャプチャ。

ローカルでは、リージョン キャプチャによってセキュリティが保証されることはありません。トラックを別のドキュメントに引き渡す場合、受信側ドキュメントはトラックの切り抜きをアンクロップし、キャプチャされたタブのピクセルすべてにアクセスできます。

キャプチャしたタブの端に、青い枠線が描画されます。Chrome では通常、切り抜きの際、切り抜いた領域の周囲に青い枠線が描画されます。

デモ

Region Capture でプレイするには、Glitch のデモを実行します。ぜひソースコードをチェックしてください。

ブラウザ サポート

対応ブラウザ

  • 104
  • 104
  • x
  • x

リージョン キャプチャは、パソコンの Chrome 104 以降でのみご利用いただけます。

次のステップ

ウェブ上の画面共有機能の改善について、近々ご紹介します。

  • リージョン キャプチャは、他のタブのキャプチャもサポートします。
  • 条件付きフォーカスを使用すると、キャプチャ ウェブアプリから、キャプチャしたディスプレイ サーフェスにフォーカスを切り替えるか、そのようなフォーカス変更を回避するようにブラウザに指示できます。
  • 要素レベルのキャプチャ API が提供される場合があります。

フィードバック

Chrome チームとウェブ標準コミュニティでは、Region Capture の使用経験を募集しています。

デザインについてお聞かせください

リージョン キャプチャについて、ご期待に沿えない点はございませんか?あるいは、アイデアを実装するために必要なメソッドやプロパティが不足しているか?セキュリティ モデルについてご質問やご意見がある場合

実装に問題がある場合

Chrome の実装にバグが見つかりましたか?あるいは、実装が仕様と異なるのでしょうか?

  • https://new.crbug.com でバグを報告します。できるだけ詳しい情報と、再現するための簡単な手順を記載してください。Glitch は、再現をすばやく簡単に行うのに最適です。

サポートを示す

リージョン キャプチャを使用する予定はありますか?公開サポートによって、Chrome チームは機能の優先順位付けを行うことができ、サポートがいかに重要であるかを他のブラウザ ベンダーに示すことができます。

@ChromiumDev 宛てのツイートで、この機能をどこでどのように使っているかを教えてください。

謝辞

この記事をレビューしてくれた Joe Medley に感謝します。