このウェブ プラットフォームではすでに、ウェブアプリで現在のタブの動画トラックをキャプチャできます。これらの動画トラックを切り抜くメカニズムである Region Capture が付属しています。ウェブアプリは現在のタブの一部を対象領域として指定し、ブラウザはその領域外のピクセルをすべてトリミングします。
以前は、ウェブアプリが動画トラックを「手動で切り抜く」ことができました。つまり、ウェブアプリはすべてのフレームを直接操作できます。これは堅牢でもパフォーマンスも高くありませんでした。Region Capture はこうした欠点を補うものです。これで、ウェブアプリはブラウザに代わって作業を行うように指示できます。
Region Capture について
Dynamic ContentTM を使ってウェブサイトを作成できました。史上最高のウェブアプリであり、使い続けると、しばしば協力して使用できます。次のステップとして、仮想会議機能の組み込みが考えられます。あなたはそれを使うことにしました。あなたは既存のビデオ会議サービス プロバイダと提携し、ウェブアプリをクロスオリジンの iframe として埋め込むことにしました。ビデオ会議ウェブアプリは現在のタブを動画トラックとしてキャプチャし、リモート参加者に送信します。
<ph type="x-smartling-placeholder">それほど速くない場合、自分の動画を送信したくないということでしょうか?その部分を切り抜いた方がよいでしょう。これには、埋め込み iframe は、どのコンテンツをどこで公開するのかを認識しないため、ヘルプなしでは切り抜くことができません。理論上は、目的の座標を渡すことができます。しかし、ユーザーがウィンドウのサイズを変更した場合はどうなるでしょうか。ビューポートをスクロールしますか?ズームインまたはズームアウトしますか?レイアウトが変更されるような形でページを操作する新しい座標をキャプチャ用 iframe に送信しても、タイミングの問題によってフレームの切り抜きが発生する可能性があります。
Region Capture を使ってみましょう。ページに 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 の派生要素)の輪郭に合わせて切り抜きを開始します。
成功すると、後続のすべての動画フレームが mainContentArea
の境界ボックス内にあるピクセルで構成されていることが保証されると、Promise は解決されます。
失敗した場合、Promise は拒否されます。これは次の場合に発生します。
CropTarget
は別のタブに作成されました。(現時点では、今後の情報にご注目ください)。CropTarget
は、存在しない要素から派生しています。- トラックにクローンが含まれている。(問題 1509418 をご覧ください)。
- 現在のトラックがセルフキャプチャ動画トラックではない。以下を参照してください。
cropTo()
メソッドは、セルフ キャプチャだけでなく、すべてのタブキャプチャ動画トラックで公開されます。そのため、トラックを切り抜く前に、ユーザーが現在のタブを選択したかどうかを確認することをおすすめします。そのためには、[Capture Handle] を使用します。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 には適用されません。ターゲットを遮るピクセルをキャプチャします。ターゲットの不完全な部分はキャプチャされません。
これは、リージョン キャプチャが基本的にトリミングされることによるものです。これに代わる選択肢の一つとして、今後独自の API が追加される予定で、要素レベルのキャプチャがあります。つまり、オクルージョンに関係なく、ターゲットに関連するピクセルのみをキャプチャします。このような API では、単純な切り抜きとはセキュリティとプライバシーの要件が異なります。
<ph type="x-smartling-placeholder">セキュリティとプライバシー
Region Capture を使用すると、すでにタブ内のすべてのピクセルを監視しているウェブアプリで、それらのピクセルの一部を自発的に削除できます。新たな情報は得られないため、特許技術によって保護されます。
Region Capture を使用すると、リモート参加者に送信する情報を制限できます。たとえば、スピーカー ノートではなくスライドを共有したい場合、
<ph type="x-smartling-placeholder">ローカルでは、Region Capture によってセキュリティの保証が追加されることはありません。トラックを別のドキュメントに渡した場合も、受信側ドキュメントはトラックの切り抜きを元に戻し、キャプチャしたタブのすべてのピクセルにアクセスできます。
キャプチャしたタブの端の周囲に青い枠線が描画されます。切り抜かれた部分の周囲に青い枠線が描画されます。
デモ
Glitch でデモを実行すると、Region Capture を試してみることができます。行動 ソースコードをご確認ください。
ブラウザ サポート
対応ブラウザ
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
地域キャプチャは、Chrome 104 のパソコンでのみご利用いただけます。
次のステップ
ウェブでの画面共有が今後予定されている機能の一部をご紹介します。
- 領域キャプチャで、他のタブのキャプチャがサポートされます。
- 条件付きフォーカスを使用すると、キャプチャ用ウェブアプリは、キャプチャされたディスプレイ サーフェスにフォーカスを切り替えるか、そのようなフォーカスの変更を回避するかをブラウザに指示できるようになります。
- Element-level Capture API が提供されることがあります。
フィードバック
Chrome チームとウェブ標準コミュニティは、Region Capture の使用体験についてご意見をお聞かせください。
デザインについて教えてください
「Region Capture」について、想定どおりに機能していないものはありますか?あるいは、アイデアを実装するために不足しているメソッドやプロパティがないでしょうか。セキュリティ モデルについて質問や意見がある場合は、
- GitHub リポジトリで仕様に関する問題を報告するか、既存の問題にご意見をお寄せください。
実装に問題がある場合
Chrome の実装にバグは見つかりましたか?または、実装が仕様と異なっていますか?
- https://new.crbug.com でバグを報告します。できるだけ多くの詳細と、再現するための簡単な手順を含めてください。Glitch は、すばやく簡単に再現を共有するのに最適です。
サポートの気持ちを伝える
Region Capture を使用する予定はありますか?皆様の公開サポートは、Chrome チームが機能の優先度を判断したり、他のブラウザ ベンダーにそれらのサポートがいかに重要であるかを示すのに役立ちます。
@ChromiumDev にツイートを送信して、どこでどのように使用しているかをお知らせください。
関連情報
謝辞
この記事をレビューしてくれた Joe Medley に感謝します。