領域キャプチャ

W3C 作業草案

この文書についての詳細
このバージョン:
https://www.w3.org/TR/2023/WD-mediacapture-region-20230712/
最新公開バージョン:
https://www.w3.org/TR/mediacapture-region/
最新編集者草案:
https://w3c.github.io/mediacapture-region/
履歴:
https://www.w3.org/standards/history/mediacapture-region/
コミット履歴
編集者:
Elad Alon (Google)
フィードバック:
GitHub w3c/mediacapture-region (pull requests, 新しい課題, 未解決の課題)

概要

この文書は、現在のタブのディスプレイキャプチャから派生した ビデオトラックを切り抜くための API を紹介する。

この文書のステータス

この節は、この文書の公開時点における ステータスを説明する。現在の W3C 公開文書の一覧と、この技術報告の最新改訂版は、 https://www.w3.org/TR/ にある W3C 技術 報告索引で確認できる。

この最初の公開作業草案は、閲覧コンテキストの部分キャプチャという ユースケースを解決するために Web Real-Time Communications 作業グループが探求しようとしている方向性を示すものである。 作業グループは、この API の採用候補者から、この方向性が当該ユースケースに どの程度適合しているかについてのフィードバックに特に関心を持っている。

この文書は、Web Real-Time Communications Working Group により、 勧告トラックを用いた 作業草案として公開された。

作業草案としての公開は、 W3C およびその会員による支持を意味しない。

これは草案文書であり、いつでも他の文書によって更新、置換、または廃止される 可能性がある。この文書を進行中の作業以外のものとして引用することは 適切ではない。

この文書は、 W3C 特許 ポリシーの下で活動する グループによって作成された。 W3C は、 そのグループの成果物に関連して行われた 特許開示の公開リストを管理している。 そのページには、特許を開示するための 手順も含まれている。個人が、 必須クレームを含むとその個人が考える 特許について実際の知識を有する場合、 W3C 特許ポリシーの第 6 節に従って その情報を開示しなければならない。

この文書は、 2021年11月2日版 W3C プロセス文書に準拠する。

1. 適合性

非規範的と記された節と同様に、この仕様におけるすべての作成ガイドライン、図、例、および注記は非規範的である。この仕様のそれ以外のすべては規範的である。

この文書におけるキーワード MUST および MUST NOT は、 BCP 14 [RFC2119] [RFC8174] に記述されているように、かつここに示すようにすべて大文字で現れる場合に限り、解釈されるものとする。

2. 定義

この文書は、[SCREEN-CAPTURE] から、次の概念の定義を用いる: display-surface および browser display-surface

3. ユースケース

この節は非規範的である。

3.1 汎用的なユースケース

複雑なアプリケーションは、多くの場合、別個の 文書 を、同一の iframe 内の複数の 閲覧 コンテキスト 内に表示して構成される。そのようなアプリケーションを考える。 これらの文書の 1 つである CAPTURING-DOC が、getDisplayMedia() または getViewportMedia を用いて、現在の 閲覧 コンテキスト 全体をキャプチャすると仮定する。次にこの 文書が、協調する文書 CAPTURED-DOC の一部のサブセクション CAPTURE-TARGET の座標にビデオトラックを切り抜きたい場合、 CAPTURING-DOC はどのようにすれば高性能かつ信頼性高くそれを行えるか。特に、スクロール、ズーム、またはウィンドウのサイズ変更によるレイアウトの変化が追加の課題をもたらすことを思い出されたい。

3.2 実用的なユースケース

同一タブ内の異なる iframe にホストされる 2 つの主要な部分、すなわちビデオ会議アプリケーションと生産性スイート アプリケーションからなる複合アプリケーションを考える。ビデオ会議側が getDisplayMedia() および/または getViewportMedia などの既存/今後の API を用い、 タブ全体をキャプチャすると仮定する。今度は、生産性スイートの特定のセクション以外のすべてを切り抜いて除去する必要がある。 結果として得られる切り抜かれたビデオをリモートに送信する前に、自身のビデオ会議コンテンツ、発表者ノート、および生産性スイート内のその他の私的および/または無関係なコンテンツを切り抜いて除去する必要がある。

さらに、協調する 2 つのアプリケーションは互いにクロスオリジンである可能性が高いことを考慮する。それらはメッセージを投稿できるが、すべての通信は 非同期であり、かつそれらの間で情報を控えめに送信する方が容易で高性能である。 これは、フレーム全体を投稿する解決策や、レイアウトの変化(例: スクロール、ズーム、ウィンドウサイズの変更)への反応が遅すぎる 解決策を排除する。

ほとんどのアプリケーションは、そのようなシナリオでは getViewportMedia を使うことを好むであろう点は注目に値する。しかし、この執筆時点では、 getViewportMedia はまだ仕様化されておらず、実装もされていない。それには 採用にいくらかの時間と労力を要する、些細でない要件がある。そのため、多くの アプリケーションは、今後しばらくの間、getDisplayMedia() と Region Capture の組み合わせを使用する可能性が高い。

4. ソリューション概要

領域キャプチャ機構は 2 つの部分で構成される:

  1. CropTarget の生成: Element切り抜き機構の潜在的なターゲットとして タグ付けするための機構。
  2. 切り抜き機構: 以前に タグ付けされた Element の輪郭に合わせて ビデオトラックの切り抜きを開始するようユーザーエージェントに指示する、またはそのような切り抜きを停止してトラックをその 未切り抜き状態に戻すための機構。

ビデオトラックについて、2 つの 切り抜き状態、すなわち 切り抜き済み および 未切り抜き を定義する。トラックは 未切り抜きで開始し、 それらに対して cropTo が正常に呼び出されたとき、 切り抜き済みに変わりうる。

5. CropTarget の生成

5.1 CropTarget の動機

この文書で提示される 切り抜き機構 (cropTo) は、直接的なノード参照ではなく、 Crop-session Target に依存する。 これは二重の目的を果たす。

5.2 CropTarget の定義

CropTarget は、意図的に空で不透明な識別子である。その目的は、入力として cropTo に渡されることである。

WebIDL[Exposed=(Window,Worker), Serializable]
interface CropTarget {
  [Exposed=Window, SecureContext] static Promise<CropTarget> fromElement(Element element);
};
注記

fromElement をセキュアコンテキストを越えて公開すべきかどうかについては、 まだ合意がない。

fromElement()

サポートされる型の Element を指定して fromElement を呼び出すと、その ElementCropTarget に関連付けられる。この CropTarget は、 cropTo への入力として使用できる。 CropTarget.fromElement() の呼び出しによって返され、 かつまだ アクティブ文書 内にあるものを、 有効な CropTarget と定義する。

指定された elementfromElement が呼び出されたとき、ユーザー エージェントは element を入力として CropTarget を作成する。 ユーザーエージェントは Promise p を返さ MUST。 ユーザーエージェントは、新しい CropTarget に関連付けられた状態の必要な内部伝播をすべて完了した後に限って p を解決し MUST、その時点でユーザーエージェントは、新しい CropTargetcropTo への有効な パラメーターとして受け取る準備ができていなければ MUST ならない。

以前に fromElement が呼び出された Element をクローンする場合、 そのクローンはいかなる CropTarget とも関連付けられない。後でそのクローンに対して fromElement が呼び出された場合、 新しい CropTarget がそれに割り当てられる。

注記

CropTarget の生成を、 CropTarget.fromElement() のような非同期メソッドの呼び出しによって行うべきか、 それとも 入力として Element を受け取る CropTarget コンストラクターによって行うべきかについては、 まだ合意がない。これは issue #17 でさらに議論されている。

element を入力として CropTarget を作成するには、次の手順を実行する:

  1. cropTarget を、型 CropTarget の新しいオブジェクトとする。

  2. weakRefelement への弱参照とする。

    weakRef に初期化された cropTarget.[[Element]]作成する

    注記

    cropTarget は、それが表す要素への弱参照を保持する。言い換えると、 cropTarget はその要素のガベージコレクションを妨げない。

CropTarget オブジェクトはシリアライズ可能である。 valueserialized、および真偽値 forStorage が与えられたときの シリアライズ 手順は次のとおりである:

  1. forStoragetrue の場合、 name 属性の 値が "DataCloneError" である 新しい DOMException オブジェクトで例外を投げる。

  2. serialized.[[CropTargetElement]] を value.[[Element]] に設定する。

serialized および value が与えられたときの デシリアライズ 手順は次のとおりである:

  1. value.[[Element]]serialized.[[CropTargetElement]] に設定する。

6. 切り抜き機構

6.1 BrowserCaptureMediaStreamTrack

[SCREEN-CAPTURE] によれば、 getDisplayMedia() が呼び出されたとき、 それは Promise<MediaStream> を返し、 この MediaStream には、 型が MediaStreamTrack である ビデオトラックが正確に 1 つ含まれることを思い出されたい。

ユーザーが browser display-surface のキャプチャを選択した場合、ユーザー エージェントはビデオトラックを MediaStreamTrack、 または MediaStreamTrack の何らかの サブクラスとしてインスタンス化しなければ MUST ならず、 かつ cropTo はこのトラックで公開されなければ MUST ならない、と規定する。簡単のため、この文書では、ユーザーエージェントによって BrowserCaptureMediaStreamTrack と呼ばれるサブクラスが使用されると仮定する。

トラックは初期状態で 未切り抜きでなければ MUST ならない。

WebIDL[Exposed = Window]
interface BrowserCaptureMediaStreamTrack : MediaStreamTrack {
  Promise<undefined> cropTo(CropTarget? cropTarget);
  BrowserCaptureMediaStreamTrack clone();
};
cropTo()

このメソッドの呼び出しは、ビデオトラックを cropTarget.[[Element]] 境界クライアント矩形 に合わせて切り抜くことを開始/停止するようユーザーエージェントに指示する。トラックは display-surface の可視ビューポートに制限されるため、キャプチャされる 領域は、可視ビューポートと要素の境界クライアント矩形との交差部分になる。 cropTo が呼び出されるたびに、 ユーザーエージェントは次のアルゴリズムを実行しなければ MUST ならない:

  1. cropTarget有効な CropTarget でも null でもない場合、 ユーザーエージェントは UnknownError拒否された Promise を返さなければ MUST ならない。

  2. p を新しい Promise とする。
  3. 次の手順を並列に実行する:

    1. cropTargetundefined でも 有効な CropTarget でもない場合、 pNotAllowedError で拒否し、これらの手順を中止する。
    2. cropTargetundefined または 有効な CropTarget のいずれかである場合、 ユーザーエージェントは cropTarget に従って this ビデオトラックの 切り抜き状態を更新しなければ MUST ならない:

      • cropTargetundefined に設定された場合、 ユーザーエージェントは 切り抜きを停止しなければ MUST ならない。This ビデオトラックは 未切り抜き状態に戻る。
      • cropTarget有効な CropTarget である場合、ユーザーエージェントは this ビデオトラックを、この CropTarget によって参照される要素の輪郭に合わせて 切り抜き始めなければ MUST ならない。これは、 トラック上で生成される各新しいフレームについて、ユーザーエージェントがその要素に属するピクセルの境界ボックスを計算し、 この境界ボックスの座標に合わせてフレームを切り抜くことを意味する。
    3. このメソッド呼び出し前のトラックの状態を PRE-STATE と呼び、 このメソッド呼び出し後の状態を POST-STATE と呼ぶ。ユーザーエージェントは、 PRE-STATE に従って切り抜かれた(または未切り抜きの)フレームがそれ以上アプリケーションに配信されないこと、 およびアプリケーションに配信される追加のフレームがしたがって POST-STATE または それ以降の状態のいずれかに従って切り抜かれる(または未切り抜きになる)ことが保証されたとき、 p を解決しなければ MUST ならない。

      注記

      cropTo promise の解決タイミングおよびビデオフレームの実際の切り抜きタイミングは、 MediaStreamTrack transforms を通じて JavaScript から観測可能である。 最初の新たに切り抜かれたビデオフレームは、cropTo promise が解決された直後に MediaStreamTrack ReadableStream にキュー投入されることが期待される。

  4. p を返す。
clone()

BrowserCaptureMediaStreamTrack がクローンされるとき、ユーザーエージェントは、元のトラックの 切り抜き状態に関係なく、 初期状態で 未切り抜きであるトラックを生成しなければ MUST ならない。

6.2 Crop-Session の存続期間

6.2.1 Crop-Session の定義

fromElement の呼び出しを通じて CropTarget が生成された Element を、 潜在的な 切り抜きターゲット と定義する。

cropTo の正常な呼び出しによって ターゲットにされた 潜在的な切り抜きターゲットを、 crop-session target と定義する。

切り抜き済みビデオトラック上に生成されたフレームを考える。ユーザーエージェントは、 (i) 最上位 閲覧コンテキストのビューポートと、(ii) crop-session target に属するすべてのピクセルの境界 ボックスとの交差部分を計算する。この交差部分を、そのフレームにおける crop-session target の座標と定義する。

6.2.2 Crop-Session のエッジケース

指定された crop-session target TARGET に切り抜かれた ビデオトラック VT 切り抜き済みを考える。 TARGET が被る変化に直面した際の、VT の crop-session の動作を定義する。

6.2.2.1 空の Crop-Target

crop-session target が DOM に接続されているものの、 最上位 閲覧コンテキストのビューポート内に描画されるピクセルが 0 個である場合を、 空の crop-session target と定義する。

注記

これが起こりうる例には次のものが含まれる:

ユーザーエージェントは、空の crop-session target を持つトラック上で新しいフレームを生成しては MUST NOT ならない。そのようなトラックについて、トラックが 未切り抜きになるか、またはその crop-session targetでなくなった場合、ユーザーエージェントは フレームの生成を再開しなければ MUST ならない。

6.2.2.2 切断された Crop-Session Target

DOM から切り離された crop-session target を、 切断された crop-session target と定義する。

空の crop-session target切断された crop-session target の違いは、切断されたものは 到達不能になる可能性があり、 その場合は新しいフレームを生成しないことである。それにもかかわらず、ユーザーエージェントは 切断された crop-session target を、 空の crop-session target と同じように扱わなければ MUST ならない。アプリケーションは、 cropTo を トラックに対して undefined または 新しい CropTarget のいずれかで呼び出すことができ、それによりトラック上の フレーム生成を再開できる。

7. サンプルコード

キャプチャ対象内のコード:

const mainContentArea = navigator.getElementById('mainContentArea');
const cropTarget = await CropTarget.fromElement(mainContentArea);
sendCropTarget(cropTarget);

function sendCropTarget(cropTarget) {
  // postMessage() を使って、またはその他の任意の手段を使って、
  // このタブ内の別の文書に crop-target を送信できる。
  // 場合によっては他の文書がなく、これは単にローカルで消費される。
}

キャプチャ文書内のコード:

async function startCroppedCapture(cropTarget) {
  const stream = await navigator.mediaDevices.getDisplayMedia();
  const [track] = stream.getVideoTracks();
  if (!!track.cropTo) {
    handleError(stream);
    return;
  }
  await track.cropTo(cropTarget);
  transmitVideoRemotely(track);
}

A. 参考文献

A.1 規範的参考文献

[dom]
DOM Standard. Anne van Kesteren. WHATWG. Living Standard. URL: https://dom.spec.whatwg.org/
[HTML]
HTML Standard. Anne van Kesteren; Domenic Denicola; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[mediacapture-streams]
Media Capture and Streams. Cullen Jennings; Bernard Aboba; Jan-Ivar Bruaroey; Henrik Boström; youenn fablet. W3C. 2023年6月19日. W3C 候補勧告. URL: https://www.w3.org/TR/mediacapture-streams/
[RFC2119]
RFC において要求レベルを示すために用いる キーワード. S. Bradner. IETF. 1997年3月. 現時点での最良慣行. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC8174]
RFC 2119 キーワードにおける大文字と小文字の 曖昧性. B. Leiba. IETF. 2017年5月. 現時点での最良慣行. URL: https://www.rfc-editor.org/rfc/rfc8174
[SCREEN-CAPTURE]
Screen Capture. Jan-Ivar Bruaroey; Elad Alon. W3C. 2023年7月6日. W3C 作業草案. URL: https://www.w3.org/TR/screen-capture/
[WEBIDL]
Web IDL Standard. Edgar Chen; Timothy Gu. WHATWG. Living Standard. URL: https://webidl.spec.whatwg.org/