メディアキャプチャとストリーム

W3C 候補勧告草案

このドキュメントの詳細
このバージョン:
https://www.w3.org/TR/2025/CRD-mediacapture-streams-20251009/
最新公開バージョン:
https://www.w3.org/TR/mediacapture-streams/
最新エディタ草案:
https://w3c.github.io/mediacapture-main/
履歴:
https://www.w3.org/standards/history/mediacapture-streams/
コミット履歴
実装レポート:
https://wpt.fyi/mediacapture-streams
編集者:
Cullen Jennings (Cisco)
Jan-Ivar Bruaroey (Mozilla)
Henrik Boström (Google)
Youenn Fablet (Apple)
以前の編集者:
Daniel C. Burnett (招待 エキスパート) - まで
Adam Bergkvist (Ericsson) - まで
Anant Narayanan (Mozilla) - まで
Bernard Aboba (Microsoft Corporation)
フィードバック:
GitHub w3c/mediacapture-main (プルリクエスト, 新しい課題, オープン課題)
public-webrtc@w3.org 件名 [mediacapture-streams] … メッセージトピック … (アーカイブ)
参加
メーリングリスト
ブラウザサポート:
Chromeロゴ53
Edgeロゴ12
Firefoxロゴ36
Safariロゴ11
デスクトップ
Android Chrome ロゴ141
Android Firefox ロゴ143
Android UC ロゴ15.5
iOS Safari ロゴ11.0
Samsung Internet ロゴ6.2
モバイル
詳細情報

概要

このドキュメントは、音声や映像などのローカルメディアをプラットフォームから取得できるJavaScript APIのセットを定義します。

この文書のステータス

このセクションは、公開時点でのこの文書のステータスについて説明しています。現在のW3Cの出版物一覧やこの技術レポートの最新版は、 W3C 標準およびドラフト一覧 で確認できます。

この文書は完成していません。このAPIはWHATWGでの予備的な作業に基づいています。

この文書が勧告案(Proposed Recommendation)に進む前に、WebRTCワーキンググループは 広範なレビューから生じた課題 に対応する予定です。

この文書は Webリアルタイムコミュニケーションズワーキンググループ によって、勧告プロセスを使用して 勧告候補ドラフトとして公開されました。

勧告候補として公開されても、W3Cおよびそのメンバーによる支持を意味するものではありません。勧告候補ドラフトは、ワーキンググループが次回の勧告候補スナップショットに含める予定の、前回の勧告候補からの変更を統合したものです。

これはドラフト文書であり、随時更新・置換・廃止される場合があります。進行中の作業以外の目的でこの文書を引用することは適切ではありません。

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

この文書は 2025年8月18日 W3Cプロセス文書 に準拠しています。

1. はじめに

このセクションは規定ではありません。

このドキュメントは、マイクやビデオカメラなどのローカルマルチメディアデバイスへのアクセスを要求するためのAPIを定義します。

また、本ドキュメントでは、マルチメディアストリームデータがどこで消費されるかを制御する手段や、メディアを生成するデバイスの一部制御を提供するMediaStream APIについても定義しています。さらに、メディアのキャプチャやレンダリングが可能なデバイスの情報も公開されます。

2. 適合性

規定ではないと記載されたセクションだけでなく、この仕様におけるすべての著者向けガイドライン、図、例、および注意事項も規定ではありません。それ以外のすべてが規定です。

このドキュメントにおけるキーワード MAYMUSTMUST NOTNOT REQUIREDSHOULD は、 BCP 14 [RFC2119] [RFC8174] に記載された通り、すべて大文字で現れる場合のみ、その意味で解釈されます。

この仕様は、含まれるインターフェースを実装する単一製品、すなわち ユーザーエージェント に適合性基準を定義します。

アルゴリズムや特定の手順として表現された適合要件は、最終的な結果が同等であれば、どのような方法で実装しても構いません。(特に、この仕様で定義されるアルゴリズムは理解しやすくするためのものであり、パフォーマンスを意図したものではありません。)

この仕様で定義されるAPIをECMAScript [ECMA-262] で実装する場合、Web IDL仕様 [WEBIDL] で定義されたECMAScriptバインディングおよび用語と一致させなければなりません。本仕様はその仕様と用語を使用しています。

3. 用語

ソース

ソースとは、メディアストリームトラックの元となる「もの」です。ソースはメディア自体を送信します。ソースは物理的なウェブカメラ、マイク、ユーザーのハードディスク上のローカルビデオや音声ファイル、ネットワークリソース、静止画像などがありえます。なお、このドキュメントではマイクやカメラタイプのソースのみを扱い、他のソースタイプについては他の文書で説明されています。

ソースに関して事前の認可がないアプリケーションには、利用可能なソースの数、種類、および他のデバイスとの関係のみが提供されます。ソースを利用する認可をアプリケーションが得た場合、追加情報が利用可能になります(9.2.1 アクセス制御モデル参照)。

ソースは制約を持ちません — トラックが制約を持ちます。ソースがトラックに接続されると、そのトラックにある制約に準拠するメディアを生成しなければなりません。複数のトラックが同じソースに接続可能です。ユーザーエージェント による処理(例:ダウンサンプリング)は、すべてのトラックが適切なメディアを持つようにするために MAY です。

ソースは制約可能なプロパティを持ち、能力設定がトラック上で公開されます。制約可能プロパティはソースが「所有」しますが、ソースは同時に複数の要求に対応できる場合があります。このため、能力は同じソースを使う(複数の)すべてのトラックで共通ですが、設定はトラックごとに異なる場合があります(例えば、同じソースにバインドされた2つの異なるトラックオブジェクトが能力・設定情報を取得すると、能力は同じですが、それぞれの制約に合わせた設定は異なる可能性があります)。

設定(ソース設定)

設定は、ソースの制約可能プロパティの即時かつ現在の値を指します。設定は常に読み取り専用です。

ソースの状態が動的に変化する場合(例:カメラが低照度で低フレームレートに切り替わる場合)、関連するトラックが設定された制約を満たさなくなることがあります。プラットフォームはそのような逸脱を可能な限り最小限に抑える SHOULD ですが、制約を満たせない一時的または恒久的な状態でもメディアの提供は継続されます。

設定はソースのプロパティですが、ソースに接続されたトラックを介してのみアプリケーションに公開されます。これはConstrainablePatternインターフェースを通じて公開されます。

能力

各制約可能プロパティには、そのプロパティがソースでサポートされているか、またサポート範囲がどの値かを示す能力があります。設定と同様、能力はConstrainablePatternインターフェースを介してアプリケーションへ公開されます。

サポートされる能力の値は、この仕様で定義された範囲や列挙型に正規化されなければなりません。

getCapabilities() をトラックで呼び出すと、そのソースに接続されたすべてのトラックで同じ能力情報が返されます。

このAPIは意図的に簡素化されています。能力は異なる値同士の相互作用を記述することはできません。たとえば、高解像度映像は低フレームレート、低解像度では高フレームレートが可能なカメラの能力を正確に表現することはできません。能力は各値の完全な範囲のみを記述します。制約同士の相互作用は制約の適用時に公開されます。

制約

制約は、アプリケーションがトラックに適切なソースを選択し、選択後にソースの動作に影響を与えるための一般的な制御面を提供します。

制約は、ソースがトラックのメディアを提供する際に利用できる動作モードの範囲を制限します。トラックの制約がなければ、実装はソースの能力範囲から任意の設定を選択できます。実装は、適用されたすべての制約の範囲内であれば、いつでもソース設定を調整できます。

getUserMedia()は、 トラックに適切なソースを選択し設定するのに制約を使用します。また、トラック上のConstrainablePatternインターフェースは、 後からトラックの制約を動的に変更するAPIを提供します。

getUserMedia()で 初期制約が満たせない場合、トラックはソースに接続されません。ただし、トラックの制約を満たす能力は時間とともに変化し得ますし、制約も変更可能です。状況が変化して制約が満たせなくなった場合、ConstrainablePatternインターフェースは アプリケーションへ適切なエラーを通知します。5. モデル:ソース・シンク・制約・設定で制約の相互作用について詳しく説明しています。

各制約可能プロパティには、関連するソース設定名および能力名に対応する名前を持つ制約が存在します。

制約は、その制約構造内の位置に応じて3つのグループに分けられます。グループは以下の通りです:

  • 必須制約は、すべての非高度制約で、 requiredです。
  • オプション基本制約は、残りの非高度制約です。
  • 高度制約は、advanced キーワードで指定されたすべての制約です。

一般的に、ユーザーエージェントは、制約が少ないほどメディアストリーミング体験を最適化する柔軟性が高くなるため、アプリケーション作者は必須制約の使用を控えめにすることが強く推奨されます。

4. MediaStream API

4.1 はじめに

MediaStream APIの主な構成要素は MediaStreamTrackMediaStreamインターフェースです。 MediaStreamTrackオブジェクトは、ユーザーエージェント内のひとつのメディアソースから発生する単一タイプのメディア(例:ウェブカメラによるビデオ)を表します。 MediaStreamは、複数の MediaStreamTrackオブジェクトを 1つの単位にまとめ、記録やメディア要素でレンダリングできるようにします。

MediaStreamは、0個以上の MediaStreamTrackオブジェクトを含むことができます。 MediaStream内のすべてのトラックはレンダリング時に同期されることが意図されていますが、異なるクロックを持つソースからのトラックは同期できない場合もあります。異なる MediaStream同士は同期する必要はありません。

本来はトラックの同期が意図されていますが、状況によっては同期を失うことを許容したほうがよい場合もあります。特に、トラックがリモートソースかつリアルタイム [WEBRTC] の場合は、同期の喪失を許容するほうが遅延蓄積やグリッチ等のリスクを回避できる場合があります。実装は再生同期の選択がユーザー体験にどう影響するか理解していることが期待されます。

ひとつのMediaStreamTrackは、ステレオや5.1音声、立体映像など、複数チャンネルのコンテンツを表現できます。チャンネル同士は明確な関係があり、情報は他のAPI(例:[WEBAUDIO])で公開される場合がありますが、本仕様ではチャンネルへの直接アクセスは提供しません。

MediaStreamオブジェクトは、すべてのトラックの入力と出力を統合した入力・出力を持ちます。 MediaStreamの出力は、そのオブジェクトのレンダリング方法(例:ファイルへ録画する場合の保存内容や、 video 要素で表示する内容)を制御します。 ひとつのMediaStreamオブジェクトは、同時に複数の異なる出力へ接続可能です。

新しいMediaStreamオブジェクトは、既存のメディアストリームやトラックから MediaStream()コンストラクタで作成できます。 コンストラクタ引数は既存のMediaStreamオブジェクト、または MediaStreamTrackオブジェクトの配列です。後者の場合、異なるソースストリームからストリームを構成できます。

MediaStreamおよび MediaStreamTrackオブジェクトは、クローン可能です。 クローンされたMediaStreamは、元のストリームのすべてのトラックのクローンを含みます。 クローンされたMediaStreamTrackは、 独立した制約セットを持ち、元インスタンスとは独立して制約を適用できるため、同じソースのメディアに異なる制約をそれぞれの消費者に対して与えることが可能です。 MediaStreamオブジェクトは getUserMedia以外の文脈(例:[WEBRTC])でも利用されます。

MediaStreamのconstructorは、既存のトラックから新しいストリームを構成します。引数には MediaStream型、または MediaStreamTrackオブジェクトの配列を指定できます。コンストラクターが呼び出された場合、ユーザーエージェントは次の手順を実行しなければなりません:

  1. streamを新しく構築された MediaStreamオブジェクトとする。

  2. stream.id属性を新たに生成した値で初期化する。

  3. コンストラクターの引数が存在する場合、以下の手順を実施する:

    1. 引数の型に基づき、トラック集合tracksを構成する:

    2. tracks内の各MediaStreamTracktrack)について、以下を実施する:

      1. もしtrackが既にstreamトラックセットに存在する場合は、 trackをスキップする。

      2. そうでなければ、trackstreamトラックセットに追加する。

  4. streamを返す。

MediaStream のトラックは トラック集合に格納されます。トラック集合には、ストリームのトラックに対応する MediaStreamTrack オブジェクトが必須で含まれる必要があります。集合内のトラックの順序はユーザーエージェント定義であり、APIは順序に関して何も要求しません。 集合内の特定の MediaStreamTrack オブジェクトを見つける正しい方法は、その id によって検索することです。

MediaStream の出力からデータを読み取るオブジェクトは MediaStreamコンシューマと呼ばれます。現在の MediaStreamコンシューマのリストには、メディア要素(videoaudioなど)[HTML]、Web Real-Time Communications (WebRTC; RTCPeerConnection) [WEBRTC]、メディア録音 (MediaRecorder) [mediastream-recording]、画像キャプチャ (ImageCapture) [image-capture]、Web Audio (MediaStreamAudioSourceNode) [WEBAUDIO]が含まれます。

注記

MediaStreamのコンシューマは、トラックが追加・削除されることへの対応ができなければなりません。この動作はコンシューマごとに規定されます。

MediaStream オブジェクトは、1つ以上の MediaStreamTrack終了していない場合、 アクティブであると言います。 MediaStream がトラックを持たない場合、またはすべてのトラックが 終了している場合は、 非アクティブです。

MediaStream オブジェクトは、MediaStreamTrack[[Kind]]"audio" で、かつ 終了していないものが1つ以上ある場合、可聴であると言います。 MediaStream に音声トラックが1つもない、またはすべての音声トラックが 終了している場合は、非可聴です。

ユーザーエージェントは外部イベントなどに応じて、MediaStreamトラック集合を更新する場合があります。本仕様はこれらのケースを規定しませんが、MediaStream APIを利用する他仕様が規定する場合があります。例えば、WebRTC 1.0 [WEBRTC]仕様では、他ピアから受信したMediaStreamトラック集合がメディアセッションの変更により更新されることがあります。

MediaStream streamトラック追加 track をするには、ユーザーエージェントは以下の手順を必須で実行してください:

  1. もしtrackが既にstreamトラックセットに存在する場合は、これらの手順を中止する。

  2. trackstreamトラックセットに追加する。

  3. trackイベントaddtrackとして trackstreamで発火する。

トラック削除操作で trackMediaStreamstreamから削除するには、 ユーザーエージェントは次の手順を実施しなければなりません:

  1. もしtrackstreamトラックセットに存在しない場合は、これらの手順を中止する。

  2. Remove trackstreamトラックセットから削除する。

  3. trackイベントremovetrackとして trackstreamで発火する。

WebIDL[Exposed=Window]
interface MediaStream : EventTarget {
  constructor();
  constructor(MediaStream stream);
  constructor(sequence<MediaStreamTrack> tracks);
  readonly attribute DOMString id;
  sequence<MediaStreamTrack> getAudioTracks();
  sequence<MediaStreamTrack> getVideoTracks();
  sequence<MediaStreamTrack> getTracks();
  MediaStreamTrack? getTrackById(DOMString trackId);
  undefined addTrack(MediaStreamTrack track);
  undefined removeTrack(MediaStreamTrack track);
  MediaStream clone();
  readonly attribute boolean active;
  attribute EventHandler onaddtrack;
  attribute EventHandler onremovetrack;
};

コンストラクター

MediaStream

MediaStream コンストラクターアルゴリズムを参照してください

パラメーターなし。
MediaStream

MediaStream コンストラクターアルゴリズムを参照してください

MediaStream

MediaStream コンストラクターアルゴリズムを参照してください

属性

idDOMString, 読み取り専用

id属性は、オブジェクトが作成されたときに初期化された値を 返さなければなりません

MediaStream が作成される際、ユーザーエージェントは識別子文字列を生成し、 オブジェクトのid 属性をその文字列で初期化しなければなりません。 ただし、ストリームIDの初期化方法を定めた特別なアルゴリズムの一部としてオブジェクトが作成される場合は除きます。 UUID [rfc4122](標準形式で36文字)が推奨されます。 フィンガープリント防止のため、実装はRFC 4122の4.4または4.5の形式を使うべきです。

ストリームID初期化方法を指定するアルゴリズムの例として、ネットワークコンポーネントと MediaStreamオブジェクトを関連付ける方法があります。[WEBRTC]

activeboolean, 読み取り専用

active 属性は、このMediaStreamアクティブならtrue、 そうでなければfalseを返さなければなりません。

onaddtrackEventHandler

このイベントハンドラのイベントタイプはaddtrackです。

onremovetrackEventHandler

このイベントハンドラのイベントタイプはremovetrackです。

メソッド

getAudioTracks()

このストリーム内の音声トラックを表す MediaStreamTrack オブジェクトのシーケンスを返します。

getAudioTracks メソッドは、ストリームのトラックセット内の [[Kind]]"audio"である MediaStreamTrack オブジェクトのスナップショットを表すシーケンスを返さなければなりません。 シーケンスへの変換はユーザーエージェント定義であり、呼び出しごとに順序は安定している必要はありません。

getVideoTracks()

このストリーム内の映像トラックを表す MediaStreamTrack オブジェクトのシーケンスを返します。

getVideoTracks メソッドは、ストリームのトラックセット内の [[Kind]]"video"である MediaStreamTrack オブジェクトのスナップショットを表すシーケンスを返さなければなりません。 シーケンスへの変換はユーザーエージェント定義であり、呼び出しごとに順序は安定している必要はありません。

getTracks()

このストリーム内のすべてのトラックを表す MediaStreamTrack オブジェクトのシーケンスを返します。

getTracksメソッドは、 トラックセット内の MediaStreamTrack オブジェクトすべてのスナップショットを表すシーケンスを返さなければなりません[[Kind]]の値は問わない)。シーケンスへの変換はユーザーエージェント定義であり、呼び出しごとに順序は安定している必要はありません。

getTrackById()

getTrackByIdメソッドは、 トラックセット内で [[Id]]trackIdと一致するMediaStreamTrack オブジェクトを返さなければなりません。該当トラックがなければnullを返します。

addTrack()

指定されたMediaStreamTrackをこの MediaStream に追加します。

addTrackメソッドが呼び出されたとき、 ユーザーエージェントは次の手順を実施しなければなりません:

  1. 引数trackと、メソッドが呼ばれた MediaStream オブジェクトstreamとする。

  2. もしtrackstreamトラックセットに存在する場合は、手順を中止する。

  3. 追加操作で trackstreamトラックセットに追加する。

removeTrack()

指定されたMediaStreamTrackオブジェクトを このMediaStream から削除します。

removeTrack メソッドが呼び出されたとき、 ユーザーエージェントは以下を実施しなければなりません:

  1. 引数trackと、メソッドが呼ばれた MediaStream オブジェクトstreamとする。

  2. もしtrackstreamトラックセットに存在しない場合は、手順を中止する。

  3. 削除操作でtrackstreamトラックセットから除去する。

clone()

指定されたMediaStreamおよび そのすべてのトラックをクローンします。

clone()メソッドが呼び出されたとき、ユーザーエージェントは次の手順を実施しなければなりません:

  1. streamCloneを新しく構築された MediaStreamオブジェクトとする。

  2. streamClone.MediaStream.idを新たに生成した値で初期化する。

  3. このMediaStreamオブジェクトの各トラックをクローンし、 streamCloneトラックセットに追加する。

  4. streamCloneを返す。

ガベージコレクション

addtrackまたはremovetrackイベントを発火することを期待するユーザーエージェントコードは、対象となるMediaStreamオブジェクトへの参照を他のオブジェクトから保持して生存させることが期待されます。 addtrack/removetrackイベントリスナーの存在は、MediaStreamオブジェクトのガベージコレクションを検討する際に考慮する必要はありません。

MediaStreamTrackオブジェクトは、ユーザーエージェント内のメディアソースを表します。ソースの例としては、ユーザーエージェントに接続されたデバイスがあります。他の仕様では、ここで定義された動作を上書きするMediaStreamTrack用のソースが定義される場合があります。複数のMediaStreamTrackオブジェクトが同じメディアソースを表すこともあり、例えば、ユーザーがUIで同じカメラを2回連続してgetUserMedia()を呼び出した場合などです。

MediaStreamTrackのソースは、以下のプロパティを定義します:

  1. ソースはMediaStreamTrackソース型を持ちます。 これはMediaStreamTrackまたはそのサブタイプに設定されます。 デフォルトではMediaStreamTrackとなります。
  2. ソースにはMediaStreamTrackソース固有の構築手順があり、 ソースからMediaStreamTrackを作成する際に実行されます。 手順は新しく作成されたMediaStreamTrackを入力とします。デフォルトでは手順は空です。
  3. ソースにはMediaStreamTrackソース固有のクローン手順があり、 指定されたソースのMediaStreamTrackをクローンする際に実行されます。 手順はソースと複製先のMediaStreamTrackを入力とします。デフォルトでは手順は空です。

MediaStreamTrackオブジェクトからのデータは、必ずしも標準的なバイナリ形式を持つとは限りません。例えば「ユーザーのビデオカメラから現在送られている映像」などです。これにより、ユーザーエージェントはプラットフォームに最適な方法でメディアを操作できます。

スクリプトは、MediaStreamTrackオブジェクトがソースを必要としなくなったことを、stop()メソッドで示すことができます。ソースを利用しているすべてのトラックが停止または他の方法で終了された場合、ソースは停止状態となります。ソースがgetUserMedia()によって公開されるデバイスの場合、ソースが停止された時、ユーザーエージェントは以下の手順を実行しなければなりません:

  1. mediaDevicesを対象となるMediaDevicesオブジェクトとする。

  2. deviceIdをソースデバイスのdeviceIdとする。

  3. mediaDevices.[[devicesLiveMap]][deviceId] を falseに設定する。

  4. デバイスのkindとdeviceIdに関連するパーミッションのパーミッション状態が、 mediaDevices関連設定オブジェクトにおいて "granted"でない場合、 mediaDevices.[[devicesAccessibleMap]][deviceId] をfalseに設定する。

MediaStreamTrackを作成するために、基礎となるsourcemediaDevicesToTieSourceToを指定して、以下の手順を実行します:

  1. tracksourceMediaStreamTrackソース型の新規オブジェクトとする。

    trackの内部スロットを以下のように初期化する:

    • [[Source]]sourceで初期化。

    • [[Id]]、 新しく生成した一意の識別子文字列で初期化。生成方法についてはMediaStream.id属性のガイドラインを参照。

    • [[Kind]]sourceが音声ソースなら"audio"sourceが映像ソースなら"video"で初期化。

    • [[Label]]、 ユーザーエージェントが提供する場合はsourceのラベルで、なければ""で初期化。 ユーザーエージェントは音声・映像ソースにラベル(例:"内部マイク"や"外部USBウェブカメラ")を付与してもよい(MAY)。

    • [[ReadyState]]、 "live"で初期化。

    • [[Enabled]]trueで初期化。

    • [[Muted]]sourceミュートされていればtrue、そうでなければfalseで初期化。

    • [[Capabilities]][[Constraints]][[Settings]]は、 ConstrainablePatternに従い初期化。

    • [[Restrictable]]falseで初期化。

  2. mediaDevicesToTieSourceTonullでない場合、trackソースとMediaDevicesを紐付ける手順をsourcemediaDevicesToTieSourceToで実行する。

  3. sourceMediaStreamTrackソース固有の構築手順trackで実行する。

  4. trackを返す。

基礎となるソースを初期化するには、 tracksourceで初期化するため、以下の手順を実行します:

  1. track.[[Source]]sourceで初期化する。

  2. track[[Capabilities]][[Constraints]][[Settings]]ConstrainablePatternに従い初期化する。

trackソースをMediaDevicesに紐付けるには、 sourcemediaDevicesを指定し、以下の手順を実行します:

  1. sourcemediaDevices.[[mediaStreamTrackSources]]に追加する。

全ソースを停止するには、グローバルオブジェクトglobalObject)について、 ユーザーエージェントは以下の手順を実行しなければなりません:

  1. MediaStreamTrack オブジェクトtrack関連グローバルオブジェクトglobalObjectであるものについて、 track[[ReadyState]]を "ended"に設定する。

  2. もしglobalObjectWindowなら、 globalObject関連MediaDevices.[[mediaStreamTrackSources]]内の 各sourceについて、停止手順を実行する。

ユーザーエージェントは、以下の場合にglobalObject全ソースを停止する必要があります(MUST):

  1. もしglobalObjectWindow オブジェクトで、アンロード時のドキュメントクリーンアップ手順が、 関連ドキュメントに対して実行される場合。

  2. もしglobalObjectWorkerGlobalScope オブジェクトで、closing フラグがtrueの場合。

実装は、ソースごとに参照カウントを用いてソースの利用状況を管理してもよいですが、具体的な方法は本仕様の範囲外です。

トラックをクローンするには、ユーザーエージェントは以下の手順を実行しなければなりません(MUST):

  1. 複製元のMediaStreamTrack オブジェクトtrackとする。

  2. sourcetrack[[Source]]とする。

  3. trackCloneMediaStreamTrackを作成する手順によって、 sourcenullを引数として生成する。

  4. trackClone[[ReadyState]]track[[ReadyState]]の値に設定する。

  5. trackClone[[Capabilities]]track[[Capabilities]]のクローンに設定する。

  6. trackClone[[Constraints]]track[[Constraints]]のクローンに設定する。

  7. trackClone[[Settings]]track[[Settings]]のクローンに設定する。

  8. sourceMediaStreamTrackソース固有のクローン手順を、tracktrackCloneで実行する。

  9. trackCloneを返す。

4.3.1 メディアフローとライフサイクル

4.3.1.1 メディアフロー

"live"なMediaStreamTrackについて、メディアフローには2つの側面があります:ミュート/非ミュート、そして有効/無効です。

ミュートは、MediaStreamTrackへの入力を指します。MediaStreamTrackは、ソースがミュート(一時的にデータが供給できない状態)であるときにミュートされます。 Liveサンプルは、ミュート状態のMediaStreamTrackに対して提供されてはなりません。

ミュート状態はウェブアプリケーションから制御できませんが、muted属性の読み取りや、関連イベントmuteunmuteを監視することで観測できます。MediaStreamTrackがミュートされる理由は、そのソースによって定義されます。

カメラやマイクのソースにおいて、ミュートされる理由は実装定義です。 これにより、ユーザーがマイクの物理的なミュートボタンを押す、ノートPCの蓋を閉じる、OSのコントロールを切り替える、ユーザーエージェントのUIでミュートボタンをクリックする、ユーザーエージェントがユーザーの代わりにミュートする等のプライバシー対策が可能です。

一部OSでは、他の高優先度のアプリケーションがマイクアクセスを奪う場合(例えばモバイルOSで着信時)、ユーザーエージェントはこの情報をmuted属性および関連イベントとしてウェブアプリケーションへ提供するべきです(SHOULD)。

カメラやマイクソースに対して、ユーザーエージェントがそのような実装定義の変更を開始する場合、ユーザー操作タスクソースを使って、ユーザーが望む状態にトラックのミュート状態を設定するタスクをキューしなければなりません(MUST)。

これは他仕様で定義されたソースには適用されません。他仕様で必要なら独自のミュート状態設定手順を定義する必要があります。

トラックのミュート状態を設定するnewStateを指定した場合、ユーザーエージェントは以下の手順を実行しなければなりません(MUST):

  1. trackを対象のMediaStreamTrackとする。

  2. もしtrack.[[Muted]]がすでにnewStateなら、手順を中止する。

  3. track.[[Muted]]newStateに設定する。

  4. もしnewStatetrueならeventNamemuteに、そうでなければunmuteに設定する。

  5. eventを発火し、名前はeventName、対象はtrack

有効/無効は、アプリケーションがenabled属性経由で制御・観測できます。

コンシューマー側から見ると、MediaStreamTrackがミュートまたは無効(または両方)ならゼロ情報コンテンツ(音声は無音、映像は黒フレーム)となります。つまり、ソースからメディアが流れるのは、MediaStreamTrackオブジェクトがミュートされておらず、かつ有効な場合のみです。例えば、音声・映像トラックがすべてミュートまたは無効なMediaStreamをソースにしたvideo要素の場合、再生はされるが、無音・黒フレームがレンダリングされます。

新しく生成されたMediaStreamTrackオブジェクトについては、特に指定がなければ常に有効であり(例:クローン時除く)、ミュート状態は生成時のソースの状態を反映します。

4.3.1.2 ライフサイクル

MediaStreamTrackはライフサイクルとして2つの状態(live, ended)を持ちます。新しく生成されたMediaStreamTrackは、生成方法によってどちらの状態にもなり得ます(例:endedなトラックをクローンすると新しいendedトラックになる)。現在の状態はreadyState属性で反映されます。

live状態ではトラックはアクティブであり、メディア(またはMediaStreamTrackミュートまたは無効の場合はゼロ情報コンテンツ)がコンシューマーで利用できます。

ソースがnavigator.mediaDevices.getUserMedia()で公開されたデバイスの場合、トラックがミュートまたは無効になり、これによりそのデバイスに接続されているすべてのトラックがミュート・無効・停止状態になった際、UAは任意で(MAY)、デバイスのdeviceIddeviceId)を使ってnavigator.mediaDevices.[[devicesLiveMap]][deviceId]をfalseに設定できます。ただし、未停止トラックがミュート解除または有効になったときすぐtrueに戻す必要があります。

デバイス由来の「live」かつミュート解除・有効なトラックがミュートまたは無効になることで、そのデバイスに接続されたすべてのトラック(UAが操作する全てのnavigableを含む)がミュート・無効・停止となった場合、UAは推奨で(SHOULD)デバイスを解放すべきです(3秒以内、ユーザーが遷移に気付く程度の猶予を持たせる)。また、デバイス由来のliveトラックが再度ミュート解除かつ有効になったら、UAはデバイスの再取得を試みるべきです(SHOULD)。ただし、そのトラックの関連グローバルオブジェクト関連Documentがその時点で表示中である場合のみ。もし表示中でない場合、UAは推奨で(SHOULD)タスクキューにトラックをミュートする(unmuteは表示されるまでしない)。デバイス再取得に失敗した場合、UAは必須で(MUST)トラックを終了する(物理的なデバイスの取り外し等問題を検知した場合は早期終了も可)。

ユーザーに物理カメラ・マイクのハードウェアライトが消灯していることでプライバシー確保の安心感を与えるため、物理・論理の“プライバシーインジケーター”を合わせる意図です(少なくとも本ドキュメントがデバイスの唯一利用者である間)。

他アプリや他ドキュメントが同時にデバイスを使っている場合はこの意図が妨げられる場合もありますが、ここで定めたルールには影響しません。

MediaStreamTrackオブジェクトは、トラックのソースが切断されるか、枯渇したとき終了したとみなされます。

同じソースを利用しているすべてのMediaStreamTrack終了すると、ソースは停止されます。

アプリケーションがstop()メソッドを呼び出した場合、またはソースがトラックへのライブサンプル供給を永久に終了した場合(早い方)、MediaStreamTrack終了状態とみなされます。

カメラ・マイクソースの場合、stop()以外のソース終了理由は実装定義です(例:ユーザーがページの利用許可を取り消す、UAが何らかの理由でトラック終了を指示する等)。

MediaStreamTracktrackstop()以外の理由で終了した場合ユーザーエージェントは以下の手順を実行するタスクをキューしなければなりません(MUST):

  1. もしtrack[[ReadyState]] が"ended"なら、手順を中止。

  2. track[[ReadyState]] を"ended"に設定。

  3. track[[Source]]に、track終了したことを通知し、他に依存するMediaStreamTrackオブジェクトがなければ、ソースを停止する。

  4. eventを発火し、名前はended、対象はそのオブジェクト。

ユーザー操作によってトラックが終了した場合、このイベントのソースはユーザー操作イベントソースです。

デバイス権限取り消しアルゴリズムpermissionNameで呼び出すには、以下の手順を実施:

  1. この種のトラック("camera""microphone")に関連する権限がpermissionNameに一致する、現在"live"なMediaStreamTrackの全セットtracksを取得。

  2. tracks内の各trackについて、終了させる。

4.3.2 トラックと制約

MediaStreamTrackは、制約可能オブジェクトであり、これは制約可能パターンセクションで定義されています。 制約はトラックに設定され、ソースに影響を与える場合があります。

トラック初期化時に Constraints が提供された場合や、後から実行時に設定が必要な場合でも、 ConstrainablePatternインターフェースで定義されたAPIにより、トラックで現在設定されている制約を取得・操作できます。

トラックが終了した後も、 固有制約可能トラックプロパティの一覧 を公開し続けます。 この一覧にはdeviceIdfacingModegroupIdが含まれます。

4.3.3 インターフェース定義

WebIDL[Exposed=Window]
interface MediaStreamTrack : EventTarget {
  readonly attribute DOMString kind;
  readonly attribute DOMString id;
  readonly attribute DOMString label;
  attribute boolean enabled;
  readonly attribute boolean muted;
  attribute EventHandler onmute;
  attribute EventHandler onunmute;
  readonly attribute MediaStreamTrackState readyState;
  attribute EventHandler onended;
  MediaStreamTrack clone();
  undefined stop();
  MediaTrackCapabilities getCapabilities();
  MediaTrackConstraints getConstraints();
  MediaTrackSettings getSettings();
  Promise<undefined> applyConstraints(optional MediaTrackConstraints constraints = {});
};
属性
kindDOMString, 読み取り専用

kind属性は必ず this.[[Kind]]を返します。

idDOMString, 読み取り専用

id属性は必ず this.[[Id]]を返します。

labelDOMString, 読み取り専用

label属性は必ず this.[[Label]]を返します。

enabledboolean

enabled 属性は、オブジェクトの有効状態を制御します。

取得時は this.[[Enabled]]必ず返します。 設定時は this.[[Enabled]]に新しい値を必ずセットします。

したがって、 MediaStreamTrack終了した後でも、enabled 属性の値は設定時に変化します(ただし新しい値に対して何も実行されません)。

mutedboolean, 読み取り専用

muted属性は、トラックがミュートされているかどうかを反映します。 必ず this.[[Muted]]を返します。

onmuteEventHandler

このイベントハンドラーのイベントタイプはmuteです。

onunmuteEventHandler

このイベントハンドラーのイベントタイプはunmuteです。

readyStateMediaStreamTrackState, 読み取り専用

取得時、readyState属性は必ず this.[[ReadyState]]を返します。

onendedEventHandler

このイベントハンドラーのイベントタイプはendedです。

メソッド
clone

clone() メソッドが呼び出されたとき、ユーザーエージェント必ずトラックをクローンする手順の結果を返します(引数はthis)。

stop

MediaStreamTrackオブジェクトの stop() メソッドが呼び出された場合、ユーザーエージェントは以下の手順を実行します(MUST):

  1. trackを現在の MediaStreamTrack オブジェクトとする。

  2. もしtrack[[ReadyState]] が"ended"なら、手順を中止。

  3. trackのソースに、track終了したことを通知する。

    トラック終了が通知されたソースは、他に依存する MediaStreamTrack オブジェクトがなければ停止されます。

  4. track[[ReadyState]]を "ended"に設定する。

getCapabilities

この MediaStreamTrack制約可能オブジェクト)が表すソースのcapabilitiesを返します。

このメソッドの定義はConstrainablePatternインターフェースを参照してください。

このメソッドは基礎デバイスに関する永続的かつクロスオリジンな情報を与えるため、デバイスのフィンガープリントベクトルを増やします。(This is a fingerprinting vector.)

getConstraints

このメソッドの定義はConstrainablePatternインターフェースを参照してください。

getSettings

MediaStreamTrackオブジェクトの MediaStreamTrack.getSettings() メソッドが呼び出された場合、ユーザーエージェントは以下の手順を実行します(MUST):

  1. trackを現在のMediaStreamTrackオブジェクトとする。

  2. もしtrack[[ReadyState]] が"ended"なら、以下を実行:

    1. settingsを新しいMediaTrackSettings辞書とする。

    2. 固有制約可能トラックプロパティの一覧の各propertyについて、 track終了時にそのプロパティが存在していた場合は、その値でsettingsに対応するプロパティを追加する。

    3. settingsを返す。

  3. それ以外の場合、ConstrainablePatternインターフェースで定義されるトラックの現在の設定を返す。

applyConstraints

MediaStreamTrackオブジェクトの applyConstraints() メソッドが呼び出された場合、ユーザーエージェントは以下の手順を実行します(MUST):

  1. trackを現在の MediaStreamTrackオブジェクトとする。

  2. もしtrack[[ReadyState]] が"ended"なら、以下を実行:

    1. pを新しいPromiseとする。

    2. resolve pundefinedで解決する。

    3. pを返す。

  3. applyConstraintsテンプレートメソッドの結果を返す(以下の通り):

WebIDLenum MediaStreamTrackState {
  "live",
  "ended"
};
MediaStreamTrackState列挙型説明
列挙値 説明
live

トラックはアクティブ(トラックの基礎メディアソースがリアルタイムでデータを提供するよう最善を尽くしている状態)です。

"live"状態のトラックの出力は、enabled 属性でオン・オフできます。

ended

トラックが終了した状態(トラックの基礎メディアソースがもはやデータを提供せず、今後もこのトラックにデータを提供しない状態)。一度この状態になったトラックは、二度とこの状態を抜けません。

例えば、MediaStream内のビデオトラックは、ユーザーがUSBウェブカメラ(トラックのメディアソース)を抜いたときに終了します。

4.3.4 MediaTrackSupportedConstraints

MediaTrackSupportedConstraintsは、 ユーザーエージェントCapabilitiesを制御するために認識する制約リストを MediaStreamTrackオブジェクトに対して表します。 このdictionaryは関数の返り値として使われ、操作の引数として使われることはありません。

将来の仕様は、部分的なdictionaryを定義し、型がbooleanである dictionaryメンバーを追加することで MediaTrackSupportedConstraintsを拡張できます。

この仕様で指定されている制約は、特に他の仕様で明記されていない限り、 MediaDevices.getUserMedia()で生成された MediaStreamTrackインスタンスにのみ適用されます。

WebIDLdictionary MediaTrackSupportedConstraints {
  boolean width = true;
  boolean height = true;
  boolean aspectRatio = true;
  boolean frameRate = true;
  boolean facingMode = true;
  boolean resizeMode = true;
  boolean sampleRate = true;
  boolean sampleSize = true;
  boolean echoCancellation = true;
  boolean autoGainControl = true;
  boolean noiseSuppression = true;
  boolean latency = true;
  boolean channelCount = true;
  boolean deviceId = true;
  boolean groupId = true;
  boolean backgroundBlur = true;
};
Dictionary MediaTrackSupportedConstraints メンバー
widthboolean, デフォルト値 true
詳細はwidthを参照。
heightboolean, デフォルト値 true
詳細はheightを参照。
aspectRatioboolean, デフォルト値 true
詳細はaspectRatioを参照。
frameRateboolean, デフォルト値 true
詳細はframeRateを参照。
facingModeboolean, デフォルト値 true
詳細はfacingModeを参照。
resizeModeboolean, デフォルト値 true
詳細はresizeModeを参照。
sampleRateboolean, デフォルト値 true
詳細はsampleRateを参照。
sampleSizeboolean, デフォルト値 true
詳細はsampleSizeを参照。
echoCancellationboolean, デフォルト値 true
詳細はechoCancellationを参照。
autoGainControlboolean, デフォルト値 true
詳細はautoGainControlを参照。
noiseSuppressionboolean, デフォルト値 true
詳細はnoiseSuppressionを参照。
latencyboolean, デフォルト値 true
詳細はlatencyを参照。
channelCountboolean, デフォルト値 true
詳細はchannelCountを参照。
deviceIdboolean, デフォルト値 true
詳細はdeviceIdを参照。
groupIdboolean, デフォルト値 true
詳細はgroupIdを参照。
backgroundBlurboolean, デフォルト値 true
詳細はbackgroundBlurを参照。

4.3.5 MediaTrackCapabilities

MediaTrackCapabilitiesは、 CapabilitiesMediaStreamTrack オブジェクトに対して表します。

将来の仕様は、適切な型のdictionaryメンバーを持つ部分的なdictionaryを定義することで MediaTrackCapabilitiesを拡張できます。

WebIDLdictionary MediaTrackCapabilities {
  ULongRange width;
  ULongRange height;
  DoubleRange aspectRatio;
  DoubleRange frameRate;
  sequence<DOMString> facingMode;
  sequence<DOMString> resizeMode;
  ULongRange sampleRate;
  ULongRange sampleSize;
  sequence<(boolean or DOMString)> echoCancellation;
  sequence<boolean> autoGainControl;
  sequence<boolean> noiseSuppression;
  DoubleRange latency;
  ULongRange channelCount;
  DOMString deviceId;
  DOMString groupId;
  sequence<boolean> backgroundBlur;
};

歴史的な理由により、deviceIdgroupIdDOMString型ですが、 ConstrainablePatternCapabilities で期待される sequence<DOMString>型とは異なります。

Dictionary MediaTrackCapabilities メンバー
widthULongRange
詳細はwidthを参照。
heightULongRange
詳細はheightを参照。
aspectRatioDoubleRange
詳細はaspectRatioを参照。
frameRateDoubleRange
詳細はframeRateを参照。
facingModesequence<DOMString>

カメラは複数のfacing modeを報告できます。例えば、ユーザー向きに複数カメラがある高性能テレプレゼンス環境では、ユーザーの左側のカメラが"left"や"user"の両方を報告できます。詳細はfacingModeを参照。

resizeModesequence<DOMString>

ユーザーエージェントは、クロッピングやダウンサンプリングを用いて、 このカメラが本来出力できる以上の解像度選択肢を提供してもよい(MAY)。 報告されるsequenceには、UAがこのカメラの解像度選択肢を導出するために利用可能な全手段を必ず含めること(MUST)。 "none"は必須であり、UAによるクロッピング・ダウンサンプリングを禁止できることを示します。詳細はresizeMode参照。

sampleRateULongRange
詳細はsampleRate参照。
sampleSizeULongRange
詳細はsampleSize参照。
echoCancellationsequence<boolean>

ソースがエコーキャンセル非対応の場合、falseのみのリストでなければなりません(MUST)。対応していればtrueを含めること必須。スクリプトで制御できる場合は、リストにtruefalseの両方を必須で含めること。さらに、ソースがどの音声ソースをキャンセルするか制御できる場合は、EchoCancellationModeEnumのサポート値を含める。truefalseが含まれる場合は、EchoCancellationModeEnum値の前に配置すること。詳細はechoCancellation参照。

autoGainControlsequence<boolean>

ソースがオートゲインコントロール非対応の場合はfalseのみを返す。オフにできない場合はtrueのみ。スクリプトで制御可能ならtruefalse両方をリストで返す。詳細はautoGainControl参照。

noiseSuppressionsequence<boolean>

ソースがノイズ抑制非対応ならfalseのみ。オフにできない場合はtrueのみ。スクリプト制御可能ならtruefalse両方を返す。詳細はnoiseSuppression参照。

latencyDoubleRange
詳細はlatency参照。
channelCountULongRange
詳細はchannelCount参照。
deviceIdDOMString
詳細はdeviceId参照。
groupIdDOMString
詳細はgroupId参照。
backgroundBlursequence<boolean>
ソースに背景ぼかし機能がなければfalseのみ。オフにできない場合はtrueのみ。スクリプトで制御可能ならtruefalse両方を返す。詳細はbackgroundBlur参照。

4.3.6 MediaTrackConstraints

WebIDLdictionary MediaTrackConstraints : MediaTrackConstraintSet {
  sequence<MediaTrackConstraintSet> advanced;
};
辞書 MediaTrackConstraints メンバー
advancedsequence<MediaTrackConstraintSet>

この要素の定義については、Constraints and ConstraintSet を参照してください。

将来の仕様は、適切な型の辞書メンバーを持つ部分辞書を定義することで MediaTrackConstraintSet 辞書を拡張できます。

WebIDLdictionary MediaTrackConstraintSet {
  ConstrainULong width;
  ConstrainULong height;
  ConstrainDouble aspectRatio;
  ConstrainDouble frameRate;
  ConstrainDOMString facingMode;
  ConstrainDOMString resizeMode;
  ConstrainULong sampleRate;
  ConstrainULong sampleSize;
  ConstrainBooleanOrDOMString echoCancellation;
  ConstrainBoolean autoGainControl;
  ConstrainBoolean noiseSuppression;
  ConstrainDouble latency;
  ConstrainULong channelCount;
  ConstrainDOMString deviceId;
  ConstrainDOMString groupId;
  ConstrainBoolean backgroundBlur;
};
辞書 MediaTrackConstraintSet メンバー
widthConstrainULong
詳細は width を参照してください。
heightConstrainULong
詳細は height を参照してください。
aspectRatioConstrainDouble
詳細は aspectRatio を参照してください。
frameRateConstrainDouble
詳細は frameRate を参照してください。
facingModeConstrainDOMString
詳細は facingMode を参照してください。
resizeModeConstrainDOMString
詳細は resizeMode を参照してください。
sampleRateConstrainULong
詳細は sampleRate を参照してください。
sampleSizeConstrainULong
詳細は sampleSize を参照してください。
echoCancellationConstrainBooleanOrDOMString
詳細は echoCancellation を参照してください。
autoGainControlConstrainBoolean
詳細は autoGainControl を参照してください。
noiseSuppressionConstrainBoolean
詳細は noiseSuppression を参照してください。
latencyConstrainDouble
詳細は latency を参照してください。
channelCountConstrainULong
詳細は channelCount を参照してください。
deviceIdConstrainDOMString
詳細は deviceId を参照してください。
groupIdConstrainDOMString
詳細は groupId を参照してください。
backgroundBlurConstrainBoolean
詳細は backgroundBlur を参照してください。

4.3.7 MediaTrackSettings

MediaTrackSettings設定MediaStreamTrack オブジェクトに対応させます。

将来の仕様は、適切な型の辞書メンバーを持つ部分辞書を定義することで MediaTrackSettings 辞書を拡張できます。

WebIDLdictionary MediaTrackSettings {
  unsigned long width;
  unsigned long height;
  double aspectRatio;
  double frameRate;
  DOMString facingMode;
  DOMString resizeMode;
  unsigned long sampleRate;
  unsigned long sampleSize;
  (boolean or DOMString) echoCancellation;
  boolean autoGainControl;
  boolean noiseSuppression;
  double latency;
  unsigned long channelCount;
  DOMString deviceId;
  DOMString groupId;
  boolean backgroundBlur;
};
辞書 MediaTrackSettings メンバー
widthunsigned long
詳細は width を参照してください。
heightunsigned long
詳細は height を参照してください。
aspectRatiodouble
詳細は aspectRatio を参照してください。
frameRatedouble
詳細は frameRate を参照してください。
facingModeDOMString
詳細は facingMode を参照してください。
resizeModeDOMString
詳細は resizeMode を参照してください。
sampleRateunsigned long
詳細は sampleRate を参照してください。
sampleSizeunsigned long
詳細は sampleSize を参照してください。
echoCancellationboolean または DOMString
詳細は echoCancellation を参照してください。
autoGainControlboolean
詳細は autoGainControl を参照してください。
noiseSuppressionboolean
詳細は noiseSuppression を参照してください。
latencydouble
詳細は latency を参照してください。
channelCountunsigned long
詳細は channelCount を参照してください。
deviceIdDOMString
詳細は deviceId を参照してください。
groupIdDOMString
詳細は groupId を参照してください。
backgroundBlurboolean、 デフォルト値は true
詳細は backgroundBlur を参照してください。

4.3.8 制約可能プロパティ

MediaStreamTrack の初期セットの制約可能プロパティの名前は以下で定義されます。

以下の制約可能プロパティは、ビデオおよびオーディオMediaStreamTrackオブジェクトの両方に適用されます:

プロパティ名 備考
deviceId DOMString MediaStreamTrackの内容を生成するデバイスの識別子です。これは MediaDeviceInfo.deviceIdの定義に準拠します。 このプロパティの設定は、MediaStreamTrackにアタッチされたソースによって一意に決定されます。特に、 getCapabilities() は deviceId の単一値のみを返します。このプロパティは getUserMedia() による初期メディア選択には使用できますが、 applyConstraints() による後続のメディア制御には役立ちません。異なる値をセットしようとしても、 ConstraintSetが満たされない結果となります。 長さ0の文字列を deviceId の値制約として getUserMedia() で使用した場合、制約が指定されていないかのように解釈される場合があります (任意)。
groupId DOMString document固有のグループ識別子で、 MediaStreamTrackの内容を生成する デバイスに対応します。これは MediaDeviceInfo.groupIdの定義に準拠します。 このプロパティの設定は、MediaStreamTrackにアタッチされたソースによって一意に決定されます。特に、 getCapabilities() は groupId の単一値のみを返します。このプロパティはブラウジングセッション間で安定していないため、 getUserMedia() による初期メディア選択には限定的に役立ちます。後続の applyConstraints() で異なる値をセットしようとしても、 ConstraintSetが満たされない結果となります。

以下の制約可能プロパティは、ビデオMediaStreamTrackオブジェクトのみに適用されます:

プロパティ名 備考
width unsigned long 幅(ピクセル単位)。ケイパビリティとしては、有効範囲はビデオソースの事前設定された幅値の範囲にまたがり、 最小値は1、最大値は最大の幅となります。ユーザーエージェントは、最小幅からネイティブ解像度幅までの任意の値へのダウンサンプリングを 必須でサポートしなければなりません。
height unsigned long 高さ(ピクセル単位)。ケイパビリティとしては、有効範囲はビデオソースの事前設定された高さ値の範囲にまたがり、 最小値は1、最大値は最大の高さとなります。ユーザーエージェントは、最小高さからネイティブ解像度高さまでの任意の値へのダウンサンプリングを 必須でサポートしなければなりません。
frameRate double

フレームレート(毎秒フレーム数)。 ビデオソースの事前設定でフレームレートが決定できる場合、ケイパビリティとしては有効範囲は事前設定されたフレームレート値の範囲にまたがり、 最小値は0、最大値は最大のフレームレートとなります。 ユーザーエージェントは、ネイティブ解像度フレームレートの整数除算で得られる フレームレートを必須でサポートしなければなりません。 フレームレートが決定できない場合(例:ソースがネイティブにフレームレートを提供しない、またはソースストリームからフレームレートが決定できない場合)、 ケイパビリティ値は必須ユーザーエージェントの vsync 表示レートを参照しなければなりません。

設定値としては、この値は設定されたフレームレートを表します。 デシメーションが使用されている場合は、ネイティブフレームレートではなくその値となります。例えば、 デシメーションで25fpsに設定し、カメラのネイティブフレームレートが30fpsだが照明条件のため20fpsが実現されているなら、 frameRateは設定値である25fpsを報告します。

aspectRatio double 正確なアスペクト比(幅÷高さ、10桁小数で丸めた double)またはアスペクト比の範囲。
facingMode DOMString この文字列はVideoFacingModeEnumのメンバーのいずれかです。 メンバーはユーザーの視点からカメラの向きを示します。 getConstraints は、この enum にない文字列の場合、同じ文字列を返さない場合があります。 これは将来の WebIDL enum の利用可能性を保つためです。
resizeMode DOMString この文字列は VideoResizeModeEnumのメンバーのいずれかです。 メンバーは UA が解像度を導出する方法を示します。つまり、UA がカメラ出力に対してクロッピングやダウンサンプリングを使用できるかどうかを示します。

UA は、カメラが他のアプリケーションで同時利用されている場合に限り、「none」が使われているときにダウンサンプリング、アップサンプリング、クロッピングなどを使ってネイティブ解像度を模倣することで、同時使用を偽装 してもよいですが、これはユーザーエージェント外でのみです。(これはフィンガープリントベクトルです)

なお、 getConstraints は、この enum にない文字列の場合、同じ文字列を返さない場合があります。 これは将来の WebIDL enum の利用可能性を保つためです。
backgroundBlur boolean 一部のプラットフォームやユーザーエージェントは、特にカメラの動画ストリームに対して、動画フレームの背景ぼかしをビルトインでサポートする場合があります。Webアプリケーションは、背景ぼかしがソースレベルで適用されているかどうかを制御したり、少なくとも認識したい場合があります。例えば、アプリケーションの UI を更新したり、独自に背景ぼかしを適用しないようにすることができます。

システムによっては、環境要因に応じてキャプチャされた動画の X 軸および Y 軸を自動的に反転させることが望ましい場合があります。その際、 widthheightaspectRatio の制約およびケイパビリティはすべてのアルゴリズムで影響を受けず、主方向のみで考慮されます。ただし、 getSettings() アルゴリズムについては、キャプチャされた動画の返却時の寸法に合わせて必要に応じてこれらの制約可能プロパティの設定を反転する 必須があります。

主方向は、キャプチャされた動画の X 軸および Y 軸の反転をサポートするシステムにおいて、そのシステムごとにユーザーエージェントが定義します。

注記

自動的にランドスケープモードとポートレートモードを切り替えられるシステムでは、ユーザーエージェントはランドスケープモードを主方向にすることが推奨されます。

WebIDLenum VideoFacingModeEnum {
  "user",
  "environment",
  "left",
  "right"
};
VideoFacingModeEnum 列挙型説明
列挙値 説明
user

ソースはユーザーの方を向いています(セルフビューカメラ)。

environment

ソースはユーザーから離れた方向(周囲の環境)を向いています。

left

ソースはユーザーの左側を向いています。

right

ソースはユーザーの右側を向いています。

以下はユーザーに対するビデオの向きを図示したものです。
ユーザーに対するビデオの向きの図解

WebIDLenum VideoResizeModeEnum {
  "none",
  "crop-and-scale"
};
VideoResizeModeEnum 列挙型説明
列挙値 説明
none

この解像度とフレームレートはカメラ、ドライバー、またはOSによって提供されます。

注記: UAは、他の ナビゲーション対象でカメラが使用されている場合のみ、同時利用を偽装するためにこの値を報告 してもよいです。(これはフィンガープリントベクトルです)

crop-and-scale

この解像度はユーザーエージェントによって、より高いカメラ解像度からダウンサンプリングやクロップされるか、 フレームレートがユーザーエージェントによって間引かれます。メディアは、下記の例外を除き、 アップスケール、ストレッチ、または入力ソースに存在しない偽のデータを生成してはなりません

注記: UAは、他のアプリケーションがユーザーエージェント外でカメラを使用している場合のみ、同時利用を偽装するためにアップスケール してもよいです。(これはフィンガープリントベクトルです)

以下の制約可能プロパティは、オーディオMediaStreamTrackオブジェクトのみに適用されます:

プロパティ名 備考
sampleRate unsigned long オーディオデータのサンプルレート(毎秒サンプル数)。
sampleSize unsigned long 線形サンプルサイズ(ビット単位)。制約としては、線形サンプルを生成するオーディオデバイスでのみ満たすことができます。
echoCancellation boolean または DOMString これは falsetrue、または EchoCancellationModeEnum のいずれかのメンバーです。 複数のマイクで様々な音声ストリームが再生されている場合、マイクで録音された入力信号から再生されている音を除去しようとすることが望ましい場合がよくあります。これがエコーキャンセル(echo cancellation)と呼ばれます。不要な場合もあり、音声アーティファクトが発生しないようにオフにすることが望ましいこともあります。このプロパティによって、アプリケーションがこの動作を制御できます。
autoGainControl boolean 自動ゲイン制御は、マイクで録音した入力信号に対して望まれることが多いです。不要な場合はオフにしてオーディオが変化しないようにすることも望ましいです。これによりアプリケーションはこの動作を制御できます。
noiseSuppression boolean ノイズ抑制は、マイクで録音した入力信号に対して望まれることが多いです。不要な場合はオフにしてオーディオが変化しないようにすることも望ましいです。これによりアプリケーションはこの動作を制御できます。
latency double レイテンシまたはレイテンシ範囲(秒単位)。レイテンシは処理の開始(例:現実世界で音が発生したタイミング)から次の処理ステップでデータが利用可能になるまでの時間です。低レイテンシは一部のアプリケーションにとって重要です。高レイテンシは他のアプリケーションでは許容されることもあり、電力制約への対応になります。数値は構成の目標レイテンシを表しますが、実際のレイテンシは多少変動する場合があります。
channelCount unsigned long オーディオデータが含む独立した音声チャンネルの数(サンプルフレームあたりのオーディオサンプル数)。
WebIDLenum EchoCancellationModeEnum {
  "all",
  "remote-only"
};
EchoCancellationModeEnum 列挙型説明
列挙値 説明
"all"

システムは、システムによって再生されるすべての音をマイクの入力信号から除去する 必須です。

このオプションは最大限のプライバシーを提供することを目的としており、通知やスクリーンリーダーなどのローカルオーディオの送信を防ぎます。

"remote-only"

システムは、WebRTC RTCPeerConnectionからソースされた MediaStreamTrackの 入力音声のみを除去する 必須です。

このオプションはローカルで再生された音声を送信したい場合に便利です。例えば、リモート音楽教室で生徒がローカルアプリケーションの伴奏と一緒に楽器を演奏する場合、リモート参加者(先生)からの音声だけエコーを除去し、伴奏は除去せずに演奏音とともに送信する必要があります。

UAは、どの RTCPeerConnection をキャンセルするか決定しますが、マイクをキャプチャしているブラウジングコンテキストで再生されているものは 推奨でキャンセル対象とするべきです。

EchoCancellationModeEnum の値に加えて、 echoCancellation 制約プロパティは true および false の値も受け付けます。 false はエコーキャンセルが行われないことを意味します。 true はUAがマイクで録音された信号からどの音声を除去するかを決定することを意味します。 true は少なくとも「remote-only」と同等以上のキャンセルを試みる 必要があります。 さらに「all」と同等のキャンセルも試みる べきです

4.3.9 ガベージコレクション

MediaStreamTrack オブジェクトは ガベージコレクトされてはならない、もし ended でなく、 muteunmuteまたは endedイベントのイベントリスナーが登録されている場合。 各ソースタイプはさらにガベージコレクションのルールを細かく定義でき、特定のイベントを発火しない場合もある。

注記
著者は MediaStreamTrack の stop() を呼び出すことが推奨されます。特にキャプチャトラックの場合、基盤となるリソースが高コストであり、ユーザーに提示されるプライバシーインジケーターにも影響があり得ます。

addtrack および removetrackイベントは、 MediaStreamTrackEvent インターフェイスを使用します。

addtrackおよびremovetrackイベントは、 スクリプトにtrack setMediaStreamユーザーエージェントにより更新されたことを通知します。

イベント名eのトラックイベントを発火するとは、 MediaStreamTrack trackで、バブルせず(特記なければ)、キャンセル不可(特記なければ)、インターフェイスは MediaStreamTrackEvent を使い、属性 tracktrack に設定されたイベントが生成・ディスパッチ されなければならないことを意味します。

WebIDL[Exposed=Window]
interface MediaStreamTrackEvent : Event {
  constructor(DOMString type, MediaStreamTrackEventInit eventInitDict);
  [SameObject] readonly attribute MediaStreamTrack track;
};

コンストラクタ

constructor()

新しいMediaStreamTrackEvent を生成します。

属性

trackMediaStreamTrack、readonly

track 属性は、イベントに関連付けられたMediaStreamTrackオブジェクトを表します。

WebIDLdictionary MediaStreamTrackEventInit : EventInit {
  required MediaStreamTrack track;
};

辞書 MediaStreamTrackEventInit メンバー

trackMediaStreamTrack、required

5. モデル:ソース、シンク、制約、および設定

このセクションは規範的ではありません。

ユーザーエージェントは、ソースからシンクへのメディアパイプラインを提供します。ユーザーエージェントでは、 シンクは <img>、 <video>、 および <audio> タグです。 従来のソースには、ストリームされたコンテンツ、ファイル、ウェブリソースが含まれます。これらのソースが生成するメディアは通常時間とともに変化しません―これらのソースは静的と見なすことができます。

これらのソースをユーザーに表示するシンク(実際のタグ自体)は、ソースコンテンツを操作するためのさまざまなコントロールを持っています。 例えば、 <img> タグは、 1600x1200 ピクセルの巨大なソース画像を width="400" および height="300" で定義された矩形に収めるために縮小します。

ソースには寿命があります。デフォルトでは、ソースの寿命はそれを作成したコンテキストに紐付けられます。例えば、MediaDevices.getUserMedia()によって作成されたソースは、 navigator.mediaDevicesコンテキストによって作成されたものとみなされます。 同様に、RTCRtpReceiverオブジェクトのソースは RTCPeerConnection自体に紐付けられ、 それが作成されたコンテキストに紐付けられます。 特定のソース定義で明示的に述べられていない限り、 ソースは常に、その作成コンテキストが消失したときに停止されます。 異なるコンテキストの2つのソースが同じキャプチャデバイスを同時に使用する場合があることにも注意が必要です。 1つのソースは他方とは独立して停止することができます。

getUserMedia APIは、マイクやカメラなどの動的ソースを追加します―これらのソースの特性はアプリケーションの要件に応じて変化します。これらのソースは本質的に動的と考えられます。 動的ソースからメディアを表示する <video> 要素は、スケーリングを行うか、メディアパイプラインにフィードバック情報を渡して、表示により適したコンテンツをソース側で生成させることができます。

注記

注記: この種のフィードバックループは明らかに「最適化」を可能にしますが、これは些細な利得ではありません。この最適化によりバッテリー消費を抑えたり、ネットワーク輻輳の軽減などが可能です。

MediaStreamのシンク(例えば <video>、 <audio>、 さらには RTCPeerConnection)は、 本仕様で記述されている設定ケイパビリティ制約を超えて ソースストリームをさらに変換する仕組みを持ち続けます(シンクの変換オプション、特に RTCPeerConnectionのものは本仕様の対象外です)。

トラックの制約を変更・適用する行為は、そのソースを共有するすべてのトラックの設定に影響を与え、 それを使用しているすべての下流のシンクにも結果的に影響します。多くのシンクはこの変化に対応できますが、 <video> 要素やRTCPeerConnectionなどです。 Recorder APIのようなものは、ソースの設定変更により失敗する場合もあります。

RTCPeerConnectionは興味深いオブジェクトです。なぜなら、 ネットワーク越しのストリームに対してシンクでありかつソースとして同時に動作するからです。シンクとしてはソース変換機能(例:ビットレートの低減、解像度の上下、フレームレートの調整など)を持ち、ソースとしてはトラックソースによって設定変更される可能性があります。

あるソースへの変更がさまざまなシンクにどのような影響を与えるかを図示するために、以下の例を示します。この例ではwidthとheightのみを扱いますが、 本仕様で公開されている設定すべてに同じ原則が当てはまります。最初の図ではホームクライアントがローカルビデオカメラからビデオソースを取得しています。 ソースの幅と高さの設定はそれぞれ800ピクセルと600ピクセルです。ホームクライアント上の3つの MediaStreamオブジェクトは、この同じ <deviceIdを使うトラックを保持しています。3つのメディアストリームは3つの異なるシンクに接続されています: <video> 要素A、別の <video> 要素B、ピア接続Cです。ピア接続はソースビデオをリモートクライアントにストリームしています。リモートクライアントには、ピア接続をソースにするトラックを持つ2つのメディアストリームがあり、これら2つのメディアストリームは2つの <video> 要素シンク(YとZ)に接続されています。

メディアストリームソース変更の効果:要求前

この時点で、ホームクライアント上のすべてのシンクは元のソースの寸法設定に変換を適用する必要があります。Bはビデオを縮小し、Aは拡大(画質低下)、Cもネットワーク送信のためにわずかに拡大しています。リモートクライアントでは、シンクYはビデオを大幅に縮小し、シンクZはスケーリングを適用していません。

applyConstraints() が呼び出された結果、トラックの1つがホームクライアントのビデオソースにより高い解像度(1920x1200ピクセル)を要求します。

メディアストリームソース変更の効果:要求後

ソース変更はホームクライアント上のすべてのトラックとシンクに即座に影響しますが、リモートクライアント上のシンク(やソース)には影響しません。ホームクライアントのソースビデオ寸法が増加したことで、シンクAはスケーリング不要となり、シンクBは以前よりさらに縮小が必要となります。シンクC(ピア接続)は、リモートクライアントへの送信を一定に保つためにビデオを縮小する必要があります。

ここでは図示していませんが、リモートクライアント側でも同様に有効な設定変更要求を行うことができます。これは、YおよびZのシンクにA、B、Cと同様の影響を与えるだけでなく、ホームクライアントのピア接続との再ネゴシエーションを促し、ホームクライアントのビデオソースに対する変換を変更することにつながる場合があります。このような変更は必須ではありませんが、シンクAやB、ホームクライアントのビデオソースに関する何かを変更する必要はありません。

本仕様は、リモートクライアントのビデオソース変更が自動的にホームクライアントのビデオソースの変更を引き起こす仕組みを定義していません。実装は、アプリケーションで定められた制約内でのみ、例示のようなソースからシンクへの最適化を選択的に行うことが可能です。

あるソースの変更がシンクの消費者に影響することは明白ですが、場合によってはシンク側の変更がソースの設定を調整することにつながることもあります。以下の図で説明します。最初の図では、ホームクライアントのビデオソースが1920x1200ピクセルのストリームを送信しています。ソースは制約されておらず、アプリケーション的にはソース寸法は自由です。2つの MediaStreamオブジェクトは同じ deviceIdを持つトラックを保持し、これらのMediaStreamは 2つの異なる <video> 要素シンクAおよびBに接続されています。シンクAはwidth="1920"height="1200"に設定され、ソースのビデオコンテンツを変換なしで表示しています。シンクBはより小さく設定されており、結果として320x200ピクセルの矩形に収めるためにビデオを縮小しています。

メディアストリームシンク変更の効果:要求前

アプリケーションがシンクAの寸法を小さく変更した場合(1920から1024ピクセル幅、1200から768ピクセル高さ)、ユーザーエージェントのメディアパイプラインは、いずれのシンクも高いソース解像度を必要としていないと認識し、ソースとシンクAで無駄な処理が行われていることに気づくかもしれません。この場合、他に制約がなければ、メディアパイプラインはソース解像度を変更してもよいです:

メディアストリームシンク変更の効果:要求後

上記の図では、ホームクライアントのビデオソース解像度は再生の最適化のためにAおよびBのうち大きい方に変更されました。ここでは示されていませんが、同様の動作はピア接続や他のシンクにも適用できます。

制約が、そのソースが満たせないトラックに適用されることもあり得ます。これは、ソース自体が制約を満たせない場合や、既に矛盾する制約を満たしている場合です。この場合、applyConstraints() から返される promise は拒否され、新しい制約は一切適用されません。この場合は制約の変更が発生しないため、ソース自体にも何も変更はありません。以下はこの動作の例です。

この例では、2つのメディアストリームがそれぞれ同じソースを共有するビデオトラックを持っています。最初のトラックには制約がありません。これはシンクNに接続されています。シンクNは800x600ピクセルの解像度で、ソースの1024x768から縮小して表示しています。もう一方のトラックには、ソースのフィルライトをオフにする必須制約があり、シンクPに接続されています。シンクPの幅と高さはソースと同じです。

過剰な制約の適用例

この時点で、最初のトラックがフィルライトをオンにする必須制約を追加します。この時点で両方の必須制約はソースによって満たすことができません(フィルライトを同時にオンとオフにはできません)。この状態が最初のトラックの競合する制約適用によって発生したため、制約適用は失敗し、ソースの設定や両トラックの制約には何も変更がありません。

6. メディア要素におけるMediaStreams

MediaStreamは、メディア要素に割り当てることができます。 MediaStreamはプリロード不可・シーク不可であり、 単純かつ潜在的に無限な線形 メディアタイムラインを表します。タイムラインは0から始まり、 メディア要素が再生可能状態である間、 実時間で線形に増加します。MediaStreamの再生が一時停止中は、タイムラインは増加しません。

ユーザーエージェントは、本仕様をサポートする場合、必須srcObject 属性を HTMLMediaElement インターフェイスでサポートしなければなりません([HTML]現行標準)。これには MediaStream オブジェクトの再生サポートも含まれます。

[HTML]現行標準文書は、 HTMLMediaElementメディアプロバイダーオブジェクトとしてどのように動作するかを説明しています。以下は メディアプロバイダーオブジェクトMediaStreamである場合の内容です:

MediaStreamの性質により、関連する HTMLMediaElement の属性の挙動や、以下に示すような操作に制約が生じます:

属性名 属性型 MediaStream提供時のセッター/ゲッター挙動 追加考慮事項
preload DOMString 取得時: none。設定時: 無視。 MediaStreamはプリロードできません。
buffered TimeRanges buffered.length必ず0を返す。 MediaStreamはプリロードできないため、 バッファ済み量は常に空のタイムレンジ。
currentTime double 任意の非負整数。初期値は0で、要素が再生可能状態の間、 実時間で線形に増加する。 値は公式再生位置 (秒単位)。変更しようとした場合は必ず無視される。
seeking boolean false MediaStreamはシーク不可。そのため 必ずfalseを返す。
defaultPlaybackRate double 取得時: 1.0。設定時: 無視。 MediaStreamはシーク不可。そのため 必ず1.0を返し、変更も必ず無視される。 これによりratechange イベントは発火しない。
playbackRate double 取得時: 1.0。設定時: 無視。 MediaStreamはシーク不可。そのため 必ず1.0を返し、変更も必ず無視される。 これによりratechange イベントは発火しない。
played TimeRanges played.length必ず1を返す。
played.start(0)必ず0を返す。
played.end(0)必ず最後に取得したcurrentTimeを返す。
MediaStreamのタイムラインは常に1つの範囲(0からcurrentTimeまで)となる。
seekable TimeRanges seekable.length必ず0を返す。 MediaStreamはシーク不可。
loop boolean truefalse loop 属性を設定しても効果はありません。MediaStreamは終了が定義されていないためループできません。

上記のセッターは、HTMLMediaElementの内部状態を変更しないため、 一度MediaStreamが 要素の割り当てられたメディアプロバイダーオブジェクトでなくなると、 上記の属性はストリームを割り当てる前の値に戻るように見えます。

注記

MediaStreamが 要素の割り当てられたメディアプロバイダーオブジェクトでなくなるのは、 srcObjectnullか非ストリームオブジェクトが割り当てられた時であり、 メディア要素読込アルゴリズムの直前です。 その結果、playbackRate および defaultPlaybackRate がストリーム割り当て前と異なる場合、ratechange イベントが(ステップ7で)発火する可能性があります。

7. エラー処理

一部の操作は OverconstrainedError をthrowまたは発火します。これはDOMExceptionの拡張であり、制約失敗に関連する追加情報を保持します。

7.1 OverconstrainedError インターフェイス

WebIDL[Exposed=Window]
interface OverconstrainedError : DOMException {
  constructor(DOMString constraint, optional DOMString message = "");
  readonly attribute DOMString constraint;
};

7.1.1 コンストラクタ

OverconstrainedError

次の手順を実行します:

  1. constraint をコンストラクタの第1引数とする。

  2. message をコンストラクタの第2引数とする。

  3. e を新しい OverconstrainedError オブジェクトとする。

  4. emessage 引数に message を、name 引数に "OverconstrainedError" をセットして DOMException コンストラクタを呼び出す。

    注記

    この name はレガシーコードへの対応がないため、ecode 属性は 0 を返します。

  5. e.constraintconstraint をセットする。

  6. e を返す。

7.1.2 属性

constraintDOMString、readonly

このエラーに関連付けられる制約名、または特定の制約名が公開されていない場合は ""

8. イベント一覧

このセクションは規範的ではありません。

以下のイベントがMediaStream オブジェクト上で発火します:

イベント名 インターフェイス 発火条件
addtrack MediaStreamTrackEvent 新しい MediaStreamTrack がこのストリームに追加されたとき。スクリプトが直接 MediaStream のトラックを変更した場合は発火しません。
removetrack MediaStreamTrackEvent MediaStreamTrack がこのストリームから削除されたとき。スクリプトが直接 MediaStream のトラックを変更した場合は発火しません。

以下のイベントがMediaStreamTrack オブジェクト上で発火します:

イベント名 インターフェイス 発火条件
mute Event MediaStreamTrack オブジェクトのソースが一時的にデータを提供できなくなったとき。
unmute Event MediaStreamTrack オブジェクトのソースが一時的にデータを提供できない状態から復帰し、再びライブになったとき。
ended Event

MediaStreamTrack オブジェクトのソースが データの提供を永久に終了したとき(例:ユーザーが権限を取り消した、ソースデバイスが取り外された、リモートピアがデータ送信を永久に停止した場合など)。

以下のイベントがMediaDevices オブジェクト上で発火します:

イベント名 インターフェイス 発火条件
devicechange DeviceChangeEvent ユーザーエージェントが利用可能な メディアデバイスのセットが変更されたとき。現在のデバイス一覧は devices 属性で取得可能。

9. ローカルメディアデバイスの列挙

このセクションでは、スクリプトがユーザーエージェントに接続されたメディア入力・出力デバイス(例:ウェブカメラやヘッドセット)について問い合わせるためのAPIを説明します。

MediaDevices オブジェクトは、ユーザーエージェントが利用可能なメディアデバイスを調べたりアクセスするためのAPIへのエントリポイントです。

MediaDevicesを作成するオブジェクトをrealmで作成するには、以下の手順を実行します:

  1. mediaDevicesを新しいMediaDevicesオブジェクト(realm内)として生成し、以下の内部スロットで初期化する:

    • [[devicesLiveMap]]: 空のmapで初期化。

    • [[devicesAccessibleMap]]: 空のmapで初期化。

    • [[kindsAccessibleMap]]: 空のmapで初期化。

    • [[storedDeviceList]]listで初期化(ユーザーエージェントが利用可能な全てのメディア入力・出力デバイス)。

    • [[canExposeCameraInfo]]falseで初期化。

    • [[canExposeMicrophoneInfo]]falseで初期化。

    • [[mediaStreamTrackSources]]:空のsetで初期化。

  2. settingsmediaDevices関連する設定オブジェクトとする。

  3. 各デバイス種別kindについて、MediaDevices.getUserMedia() が公開する場合、以下を行う:

    1. mediaDevices.[[kindsAccessibleMap]][kind] を、kindに関連するパーミッション状態 (例:"camera""microphone")がsettingsにおいて "granted"ならtrue、 そうでなければfalseにセットする。

  4. 各個別デバイス(deviceId=deviceId)について、MediaDevices.getUserMedia() が公開する場合、以下を行う:

    1. mediaDevices.[[devicesLiveMap]][deviceId]falseにセットし、mediaDevices.[[devicesAccessibleMap]][deviceId] を、そのデバイス種別とdeviceIdに関連するパーミッション状態がsettingsにおいて "granted"ならtrue、 そうでなければfalseにセットする。

  5. mediaDevicesを返す。

各デバイス種別kindについて、getUserMedia()が公開する場合、 パーミッション状態が変化するたびに、以下の手順を実行する:

  1. 変化が他の値から"granted"になった場合、 mediaDevices.[[kindsAccessibleMap]][kind]trueにセットする。

  2. 変化が"granted"から他の値になった場合、 mediaDevices.[[kindsAccessibleMap]][kind]falseにセットする。

各デバイスについて、getUserMedia()が公開する場合、 デバイス種別とdeviceId=deviceIdに関連するパーミッション状態が変化するたびに、以下の手順を実行する:

  1. 変化が他の値から"granted"になった場合、 mediaDevices.[[devicesAccessibleMap]][deviceId]trueに(まだtrueでなければ)セットする。

  2. 変化が"granted"から他の値になり、 かつ、デバイスが現在停止状態なら、 mediaDevices.[[devicesAccessibleMap]][deviceId]falseにセットする。

新しいメディア入力/出力デバイスがユーザーエージェントで利用可能になった場合、あるいは利用可能な入力/出力デバイスが利用不可になった場合、あるいは MediaDeviceKindのシステムデフォルトが変更された場合、 ユーザーエージェントデバイス変更通知手順を、MediaDevices オブジェクトmediaDevicesごとに(デバイス列挙が可能trueであるもののみ)、他のMediaDevicesには実行せず、実行する必須があります:

  1. lastExposedDevicesを、デバイス情報オブジェクトのリスト作成(引数はmediaDevicesmediaDevices.[[storedDeviceList]])の結果とする。

  2. deviceListを、ユーザーエージェントが利用可能な全てのメディア入力/出力デバイスのリストとする。

  3. newExposedDevicesを、デバイス情報オブジェクトのリスト作成(引数はmediaDevicesdeviceList)の結果とする。

  4. newExposedDevices内のMediaDeviceInfo オブジェクトがlastExposedDevicesと一致し、順序も同じなら、これらの手順を中断する。

    注記

    上記の手順は、enumerateDevices アルゴリズムのため、devicechangeイベントの発火を、 特定のMediaDeviceKindのデバイス列挙が許可されたドキュメントのみに制限します。

  5. mediaDevices.[[storedDeviceList]]deviceListにセットする。

  6. タスクをキューし、イベント発火(イベント名はdevicechangeDeviceChangeEvent コンストラクタで devicesnewExposedDevicesで初期化してmediaDevicesで発火)。 ユーザーエージェントは、複数のイベントが同時に起きる場合や複数デバイスが同時に追加・削除される場合(例:カメラ+マイク)、イベント発火をまとめて一つにしてもよいです。

さらに、以前は走査されたMediaDevicesオブジェクトが 後でデバイス列挙が可能条件を満たすようになった場合(例:ビューに入った)、その時点でユーザーエージェントは そのMediaDevicesオブジェクトに対して デバイス変更通知手順必須で実行します。

注記

これらのイベントは、異なるオリジンのドキュメントで同時にトリガーされる可能性があります。 ユーザーエージェントは、 クロスオリジンのアクティビティ相関を避けるためにイベントタイミングにファジングを加えてもよいです。(これはフィンガープリントベクトルです)

WebIDL[Exposed=Window, SecureContext]
interface MediaDevices : EventTarget {
  attribute EventHandler ondevicechange;
  Promise<sequence<MediaDeviceInfo>> enumerateDevices();
};

属性

ondevicechangeEventHandler

このイベントハンドラのイベントタイプは devicechange です。

メソッド

enumerateDevices

ユーザーエージェントが利用可能なメディア入力・出力デバイスの情報を収集します。

このメソッドはpromiseを返します。promiseは fulfilled時、 MediaDeviceInfoオブジェクトのシーケンス( ユーザーエージェントが利用可能なメディア入力・出力デバイスを表す)で解決されます。

このシーケンスの要素のうち、入力デバイスを表すものは InputDeviceInfo型(MediaDeviceInfoを継承)です。

カメラとマイクのソースは推奨で列挙可能であるべきです。追加のソースタイプを加える仕様は、そのタイプが列挙されるべきかどうかの推奨を提供します。

enumerateDevices() メソッドが呼ばれると、ユーザーエージェントは以下の手順を実行します:

  1. p を新しいpromiseとする。

  2. proceedデバイス列挙が可能か(引数は this)の結果とする。

  3. mediaDevicesthisとする。

  4. 次の手順を並行して実行:

    1. proceedfalseの間は、ユーザーエージェント 必須でタスクキューを待機し、proceedデバイス列挙が可能か(引数はmediaDevices)の結果でtrueになるまで先へ進まない。

    2. resultListデバイス情報オブジェクトのリスト作成(引数はmediaDevicesmediaDevices.[[storedDeviceList]])の結果とする。

    3. resolve presultListで)。

  5. pを返す。

デバイス情報オブジェクトのリスト作成(引数mediaDevicesdeviceList)は以下の手順を実行:

  1. resultListを空リストとする。

  2. microphoneListcameraListotherDeviceListを空リストとする。

  3. documentmediaDevices関連グローバルオブジェクト関連付けられたDocumentとする。

  4. deviceListの各デバイスdeviceについて以下のサブ手順を実行:

    1. deviceがマイクでない、またはdocument機能使用許可"microphone"でない場合、 サブ手順中断・次のデバイスへ。

    2. deviceInfoデバイス情報オブジェクト作成devicemediaDevices)の結果とする。

    3. deviceがシステムデフォルトマイクならmicrophoneListdeviceInfoを先頭に、 そうでなければ末尾に追加する。

  5. deviceListの各デバイスdeviceについて以下のサブ手順を実行:

    1. deviceがカメラでない、またはdocument機能使用許可"camera"でない場合、 サブ手順中断・次のデバイスへ。

    2. deviceInfoデバイス情報オブジェクト作成devicemediaDevices)の結果とする。

    3. deviceがシステムデフォルトカメラならcameraListdeviceInfoを先頭に、 そうでなければ末尾に追加する。

  6. マイク情報公開可mediaDevicesfalseなら、 microphoneListを先頭1件に切り詰める。

  7. カメラ情報公開可mediaDevicesfalseなら、 cameraListを先頭1件に切り詰める。

  8. deviceListの各デバイスdeviceについて以下のサブ手順を実行:

    1. deviceがマイクまたはカメラならサブ手順を中断し次のデバイスへ。

    2. カメラ・マイク以外のデバイス公開判定アルゴリズムdevicemicrophoneListcameraListmediaDevices)を実行し、その結果がfalseなら中断し次のデバイスへ。

    3. deviceInfoデバイス情報オブジェクト作成devicemediaDevices)の結果とする。

    4. deviceInfootherDeviceList に追加する。

    5. もし device がシステムのデフォルトオーディオ出力である場合は、以下のサブステップを実行する:

      1. defaultAudioOutputInfodevice を表す device info object の作成 の結果とし、mediaDevices を用いる。

      2. defaultAudioOutputInfodeviceId を "default" に設定する。

      3. ユーザーエージェントは SHOULD defaultAudioOutputInfolabel を、これがシステムデフォルトのオーディオ出力であることを明示するように更新すべきである。

      4. defaultAudioOutputInfootherDeviceList の先頭に追加する。

  9. microphoneList のすべてのデバイスを順番に resultList に追加する。

  10. cameraList のすべてのデバイスを順番に resultList に追加する。

  11. otherDeviceList のすべてのデバイスを順番に resultList に追加する。

  12. resultList を返す。

このメソッドは、キャプチャデバイスの有無という形でブラウジングセッションやオリジンをまたいで永続情報を返すため、 ユーザーエージェントによるフィンガープリント面を拡大します。(これはフィンガープリントベクトルです)

関連グローバルオブジェクトの 関連付けられたDocumentがキャプチャしていない限り、このメソッドは「カメラがあるか」「マイクがあるか」の2ビットしか公開しません。 ユーザーエージェントは (例えばgetUserMedia()で妥当な制約が来るまで)システムにカメラ・マイクがあると偽装してもよいです。(これはフィンガープリントベクトルです)

関連グローバルオブジェクトの 関連付けられたDocumentがキャプチャを開始した後は、全キャプチャデバイスのリスト(グループ・ラベル含む)によってさらに永続的なクロスオリジン情報を公開するため、フィンガープリント面が拡大します。(これはフィンガープリントベクトルです)

ユーザーエージェントは、デバイスラベルをサニタイズして公開範囲を制限してもよいです。例えば、ラベル内のユーザー名は削除し、メーカー名やモデル情報は残すなど。ただし、サニタイズ後もユーザーがデバイス識別可能であることが重要です。(これはフィンガープリントベクトルです)

9.2.1 アクセス制御モデル

上記のアルゴリズムは、メディアデバイス情報へのアクセスが、関連グローバルオブジェクト関連付けられた Documentがキャプチャしたかどうかに依存することを意味します。

カメラとマイクデバイスの場合、関連グローバルオブジェクト関連付けられた Documentがキャプチャしていない時 (つまりgetUserMedia()が呼ばれていない、または呼ばれても解決していない場合)、 MediaDeviceInfoオブジェクトはkindには有効な値を持ちますが、 deviceIdlabelgroupIdは空文字列となります。 また、各kindごとに最大1つのみが enumerateDevices() の結果にリストされます。

それ以外の場合、 MediaDeviceInfoオブジェクトは deviceIdkindlabelgroupIdに意味のある値を持ちます。 利用可能なすべてのデバイスが enumerateDevices() の結果にリストされます。

デバイス情報オブジェクト作成 を実行して発見されたデバイスdeviceを表すには、mediaDevicesを元に以下の手順を実行します:

  1. deviceInfoを新しいMediaDeviceInfoオブジェクトとして生成し、 deviceを表す。

  2. deviceInfo.kinddeviceに対して初期化する。

  3. deviceInfo.kindが "videoinput"で、 カメラ情報公開可mediaDevicesfalseなら、deviceInfoを返す。

  4. deviceInfo.kindが "audioinput"で、 マイク情報公開可mediaDevicesfalseなら、deviceInfoを返す。

  5. deviceInfo.labeldeviceに対して初期化する。

  6. 格納されたdeviceIddeviceに存在する場合は、 deviceInfo.deviceIdをその値で初期化する。 それ以外の場合は、deviceInfo.deviceIddeviceId項で述べたように新規生成された一意識別子で初期化する。

  7. devicedocumentですでに表現されているデバイスと同じ物理デバイスに属する場合は、 deviceInfo.groupIdを 既存のgroupId値で初期化する。 それ以外の場合は、deviceInfo.groupIdgroupId項で述べたように新規生成された一意識別子で初期化する。

  8. deviceInfoを返す。

9.2.2 デバイス情報の公開

デバイス列挙が可能かチェックを mediaDevicesで実行するには、以下の手順を実行:

  1. ユーザーエージェントは、 デバイス情報公開可mediaDevicestrueなら、 trueを返してもよい

  2. ビューに入っているかmediaDevicesで実行した結果を返す。

デバイス情報公開可 チェックをmediaDevicesで実行するには、以下の手順を実行:

  1. カメラ情報公開可mediaDevicestrueなら、trueを返す。

  2. マイク情報公開可mediaDevicestrueなら、trueを返す。

  3. falseを返す。

カメラ情報公開可 チェックをmediaDevicesで実行するには、以下の手順を実行:

  1. ローカルデバイスのうち"videoinput"種別のものが、 mediaDevices関連グローバルオブジェクト関連付けられた DocumentでライブなMediaStreamTrackに接続されていれば、 trueを返す。

  2. mediaDevices.[[canExposeCameraInfo]]を返す。

マイク情報公開可 チェックをmediaDevicesで実行するには、以下の手順を実行:

  1. ローカルデバイスのうち"audioinput"種別のものが、 MediaStreamTrackとして mediaDevices関連グローバルオブジェクト関連付けられた Documentでライブに接続されていれば、trueを返す。

  2. mediaDevices.[[canExposeMicrophoneInfo]]を返す。

ビューに入っているかのチェックをmediaDevicesで実行するには、以下の手順:

  1. mediaDevices関連グローバルオブジェクト関連付けられた Document完全にアクティブで、 可視状態"visible"ならtrueを返す。そうでなければfalseを返す。

システムフォーカスありチェックをmediaDevicesで実行するには、以下の手順:

  1. mediaDevices関連グローバルオブジェクトナビゲーション対象最上位トラバーサブルシステムフォーカスを持っていればtrue、 そうでなければfalseを返す。

デバイス公開を拡張できるかチェックをdeviceTypeで実行するには、以下の手順:

  1. permissionを、名前がdeviceTypeであるディスクリプタの パーミッション状態の値で取得する。

  2. permissionが"granted"なら、 trueを返す。

  3. permissionが"prompt"のとき、 そのオリジンで以前にdeviceTypeアクセスが許可されたことをユーザーエージェントが知っていれば、 よいとしてtrueを返す。

  4. falseを返す。

9.2.3 デバイス情報公開の設定

set the device information exposuremediaDevicesに対して、requestedTypes setと、boolean型のvalueを指定して実行するには、以下の手順を実行する:

  1. "video"requestedTypesに含まれている場合、以下のサブ手順を実行:

    1. mediaDevices.[[canExposeCameraInfo]]valueをセットする。

    2. valuetrueであり、かつdevice exposure can be extended("microphone"指定)がtrueの場合、 mediaDevices.[[canExposeMicrophoneInfo]]trueをセットする。

  2. "audio"requestedTypesに含まれている場合、以下のサブ手順を実行:

    1. mediaDevices.[[canExposeMicrophoneInfo]]valueをセットする。

    2. valuetrueであり、かつdevice exposure can be extended("camera"指定)がtrueの場合、 mediaDevices.[[canExposeCameraInfo]]trueをセットする。

注記

ユーザーエージェントは、任意のタイミングでデバイス情報公開をfalseに戻してもよい。例えばユーザーエージェントが特定のDocumentでデバイスアクセスを撤回すると判断した場合など。

9.2.4 カメラ・マイク以外のデバイス公開判定アルゴリズム

カメラ・マイク以外のデバイス公開判定アルゴリズム は、devicemicrophoneListcameraListmediaDevicesを入力として、 deviceの情報をウェブページに公開するかどうかを決定するboolean値を返す。

デフォルトではfalseを返す。

他の仕様で特定のデバイス種別用のアルゴリズムを定義してもよい。

9.2.5 コンテキストのキャプチャ状態

context is capturing チェックを globalObjectに対して実行するには、以下の手順を実行する:

  1. globalObjectWindowでない場合、falseを返す。

  2. mediaDevicesglobalObject関連付けられたMediaDevicesとする。

  3. mediaDevices.[[mediaStreamTrackSources]] の各sourceについて以下のサブ手順を実行:

    1. source停止またはミュートなら、これらの手順を中断する。

    2. deviceIdsourceのデバイスのdeviceIdとする。

    3. mediaDevices.[[devicesLiveMap]][deviceId] がtrueなら、trueを返す。

  4. falseを返す。

注記

このアルゴリズムは、マイク・カメラ・画面共有などすべてのキャプチャトラックを対象とする。

9.3 デバイス情報

WebIDL[Exposed=Window, SecureContext]
interface MediaDeviceInfo {
  readonly attribute DOMString deviceId;
  readonly attribute MediaDeviceKind kind;
  readonly attribute DOMString label;
  readonly attribute DOMString groupId;
  [Default] object toJSON();
};

属性

deviceIdDOMString, readonly

表現されるデバイスの識別子。このデバイスは識別子とkindによって一意に識別されなければならない

保存された識別子を認識するため、識別子はDocument同一オリジントップレベルトラバーサブル間で同一でなければならない。 子ナビゲーションでは、 識別子がドキュメント間で同一かどうかの判断は、ユーザーエージェントのストレージ分割ルール(例:localStorage) に従わなければならない。識別子がユーザーを一意に識別できる場合、他のオリジンのドキュメントでは識別子が推測できないようにしなければならない(クロスオリジン関連付け回避)。ユーザーに紐付かず、他の手段(例:User-Agent文字列)で推測可能ならオリジン間で再利用可能。

ローカルデバイスがこのオリジンのページでライブなMediaStreamTrackにアタッチされた場合や、このオリジンにローカルデバイスへの保存された許可がある場合、この識別子は必ず永続化される(後述の例外を除く)。一意かつ安定した識別子により、アプリケーションは複数回アクセス時に特定ソースの保存・利用可否判定・直接リクエストが可能となる。

ただし、ローカルデバイスがこのオリジンのページでライブなMediaStreamTrackにアタッチされておらず、また保存された許可もない場合、ユーザーエージェントはこの識別子を最後のセッション終了時にクリアしてもよい。クリアしない場合は必ずユーザーが識別子を目視・削除できる手段(例:Cookie同様)を提供しなければならない

deviceIdはセッションをまたいで残る場合があり、フィンガープリント防止のため、deviceIdはCookie等と同様に扱う。ユーザーエージェントはCookie利用不可サイトには識別子を永続化してはならない、他の永続ストレージをクリアした際は必ずオリジンごと識別子をローテーションしなければならない(これはフィンガープリントベクトルです)

kindMediaDeviceKind、readonly

表現されるデバイスの種別。

labelDOMString、readonly

このデバイスの説明用ラベル(例:"External USB Webcam")。ユーザーがデバイスを区別できるよう設計されているが、アプリケーションはラベル内容(デバイスタイプや型番等)を仮定してはならない。ラベルがない場合は空文字列を返す必須

groupIdDOMString、readonly

表現されるデバイスのグループ識別子。同じ物理デバイスに属する場合は同じグループIDとなる(例:同じヘッドセットのスピーカーとマイク)。

グループ識別子は各documentごとに一意に生成必須

メソッド

toJSON
呼び出し時、[WEBIDL]の既定のtoJSON手順を実行する。
WebIDLenum MediaDeviceKind {
  "audioinput",
  "audiooutput",
  "videoinput"
};
MediaDeviceKind 列挙型説明
audioinput

音声入力デバイス(例:マイク)を表す。

audiooutput

音声出力デバイス(例:ヘッドホン)を表す。

videoinput

映像入力デバイス(例:ウェブカメラ)を表す。

9.4 入力専用デバイス情報

InputDeviceInfo インターフェイスは、対応する入力デバイスのケイパビリティへアクセスする。

WebIDL[Exposed=Window, SecureContext]
interface InputDeviceInfo : MediaDeviceInfo {
  MediaTrackCapabilities getCapabilities();
};

メソッド

getCapabilities

デバイスの主トラック(MediaStream内で kind値に応じた音声または映像トラック)の MediaTrackCapabilitiesオブジェクトを返す(ユーザー指定制約なしの場合)。 これらのケイパビリティは、getUserMedia({deviceId: id})で取得された MediaStreamTrackの最初の MediaStreamdeviceId属性がidgetCapabilities() を呼んだ場合と同一でなければならない

ローカルデバイスへのアクセス許可がなく、この InputDeviceInfoが一意情報でフィルタ済みの場合(enumerateDevices()の説明参照)、 このメソッドは空の辞書を返す。

devicechange イベントは DeviceChangeEvent インターフェイスを使用します。

WebIDL[Exposed=Window]
interface DeviceChangeEvent : Event {
  constructor(DOMString type, optional DeviceChangeEventInit eventInitDict = {});
  [SameObject] readonly attribute FrozenArray<MediaDeviceInfo> devices;
  [SameObject] readonly attribute FrozenArray<MediaDeviceInfo> userInsertedDevices;
};

コンストラクタ

constructor()

this.deviceseventInitDict.devicesから frozen arrayを作成した結果で初期化します。

属性

devicesFrozenArray<MediaDeviceInfo>, readonly

devices 属性は、 利用可能なデバイス一覧を表す MediaDeviceInfo オブジェクトの配列を返します。

userInsertedDevicesFrozenArray<MediaDeviceInfo>, readonly

userInsertedDevices 属性は、 MediaDeviceInfo オブジェクトのうち devices 配列の中から、 ユーザーが物理的に挿入・有効化したばかりで、今回イベントで新たに公開されたもののみを含む配列を返します。 それ以外の場合は空リストを返します。

ユーザーエージェント任意で、 getUserMedia()呼び出し前に ユーザーが挿入・有効化したデバイスを含めてもよい。ただしこのイベントが初公開となり、 ユーザーが getUserMedia()でそのデバイスを選択していない場合のみ。

MediaDeviceInfo オブジェクトが含まれる場合、 必ず devicesにも同じオブジェクトが存在していなければならない。

注記

通話中(または直前)にユーザーがデバイスを挿入することは、そのデバイスをすぐ使いたいという強い意志のシグナルになり得ます。

アプリケーションは、この属性を頼りに、デバイス情報公開の違いによる devices の変化と区別することを推奨します。

注記
この属性が存在しない場合は、このUAがまだ本仕様のこのバージョンに対応していないことを意味します。
WebIDLdictionary DeviceChangeEventInit : EventInit {
  sequence<MediaDeviceInfo> devices = [];
};

辞書 DeviceChangeEventInit メンバー

devicessequence<MediaDeviceInfo>, 既定値 []

devices メンバーは、 利用可能なデバイスを表す MediaDeviceInfo オブジェクトの配列です。

10. ローカルマルチメディアコンテンツの取得

このセクションでは Navigator および MediaDevices を拡張し、 ユーザーエージェントが利用可能なメディア入力デバイスへのアクセス許可をリクエストするAPIを提供します。

また、ローカルの MediaStream は video要素など特定のDOM要素からキャプチャすることも可能です [mediacapture-fromelement]。これは自動テスト等で便利です。

10.1 MediaDevices インターフェイス拡張

注記
このセクションに定義される getUserMedia() の定義は、 Navigator で長らく存在していたメソッド定義から2つの大きな変更点が反映されています。

第一に、getUserMedia() メソッドの正式な定義は、 開発者が利用を推奨されるものとして、ここで定義される MediaDevices 上のものとなりました。 この決定は、元のAPIが後方互換性のため Navigator.getUserMedia として Navigator オブジェクトに残っている間、コンセンサスを反映しています。 ワーキンググループは、これらのAPIの初期ユーザーが getUserMedia を "var getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;" のように定義することが推奨されていたことを認識しており、 公式実装の前後でコードが動作するようにしていました。 機能的同等性を保証するため、Navigator 上の getUserMedia() メソッドはここで定義されたものに基づいて定義されています。

第二に、ここで定義されるメソッドはPromiseベースですが、 Navigator 上のものは現在もコールバックベースです。 Navigator上でgetUserMedia()を探す開発者は、そちらの詳細な注記も読むことを強く推奨します。

getSupportedConstraints メソッドは、 アプリケーションが ユーザーエージェントが認識する制約一覧を取得できるように提供されています。 アプリケーションは、必須制約を確実に使うためや、 高度な制約の組み合わせロジックから予測可能な結果を得るために、この情報が必要となる場合があります。

WebIDLpartial interface MediaDevices {
  MediaTrackSupportedConstraints getSupportedConstraints();
  Promise<MediaStream> getUserMedia(optional MediaStreamConstraints constraints = {});
};

メソッド

getSupportedConstraints

現行標準におけるユーザーエージェントが認識している 制約可能プロパティをメンバーとするディクショナリを返します。サポートされている制約可能プロパティは必須で 表現される必要があり、サポートされていない制約可能プロパティは ユーザーエージェントから 絶対に返されてはなりません。返される値は ユーザーエージェント が実装している内容を示し、ブラウジングセッション中は変化しません。

getUserMedia

ユーザーにWebカメラやその他のビデオ・オーディオ入力の利用許可を求めます。

constraints引数はMediaStreamConstraints型のディクショナリです。

このメソッドはpromiseを返します。promiseは fulfilled時、 下記の通り有効なトラックが許可された場合、適切な MediaStream オブジェクトで解決されます。

promiseは、下記の通り有効なトラックが見つからない場合やユーザーが許可しない場合は rejectedとなります。

getUserMedia() メソッドが呼び出されたとき、 ユーザーエージェント必須で以下の手順を実行します:

  1. constraintsをメソッドの第1引数とする。

  2. requestedMediaTypesconstraints内で ディクショナリ値またはtrue値を持つメディアタイプ集合とする。

  3. requestedMediaTypesが空集合の場合、 rejectedなpromiseをTypeErrorで返す。 WebIDL上"optional"と記載されているが、引数は必須でなければ成功しない。

  4. document関連グローバルオブジェクト関連付けられたDocumentとする。

  5. document完全にアクティブ でない場合、promiseはInvalidStateErrorDOMExceptionrejectedとなる。

  6. requestedMediaTypesが"audio"を含み、 documentが "microphone"権限名で識別される機能の 使用許可 を持たない場合、下記Permission Failure手順へジャンプ。

  7. requestedMediaTypesが"video"を含み、 documentが "camera"権限名で識別される機能の 使用許可 を持たない場合、下記Permission Failure手順へジャンプ。

  8. mediaDevicesthisとする。

  9. isInViewビューに入っているかアルゴリズムの結果とする。

  10. pを新しいpromiseとする。

  11. 以下の手順を並行して実行:

    1. isInViewfalseの間、 ユーザーエージェント 必須で、isInViewビューに入っているか アルゴリズムの結果でtrueになるまで、次へ進まない。

    2. finalSetを初期値空集合として用意。

    3. requestedMediaTypesの各メディアタイプkindについて以下の手順を実行:

      1. 各種kindソースデバイスの全構成パターンについて、candidate(デバイスとその設定ディクショナリを保持する MediaStreamTrack のプレースホルダー)を考える。

        この候補集合をcandidateSetとする。

        candidateSetが空なら下記NotFound Failure手順へジャンプ。

      2. constraintskind値がtrueならCSを制約なし(空セット)に設定、そうでなければconstraintskind値でCSを設定。
      3. CS内の制約可能プロパティで、kind型の MediaStreamTrack に定義されていないものは除外する(音声専用制約がvideoに、映像専用制約がaudioに含まれていても無視され、OverconstrainedErrorにはならない)。
      4. CS必須制約があり、その名前が デバイス選択に許可された必須制約 リストに存在しない場合、pTypeErrorrejectし、以降を中断。

      5. 全候補についてSelectSettingsアルゴリズムをCS制約セットで実行。アルゴリズムがundefinedを返す候補はcandidateSetから除外。制約を満たせないデバイスは除外される。

        candidateSetが空なら、failedConstraint必須制約のうち fitness distanceが全て無限大だったもの(なければ"")にし、下記Constraint Failure手順へジャンプ。

        このエラーは、ユーザーがデバイスに許可を与える前に、デバイスが何を生成できないかという情報を提供するため、フィンガープリント面となる可能性があります。(これはフィンガープリントベクトルです)

      6. 現行の パーミッション状態 を、現ドキュメントでライブな MediaStreamTrack にアタッチされていない全候補デバイスについて取得。パーミッション状態が"denied"の候補はcandidateSetから除外。

        この時点でcandidateSetが空(全デバイス"denied")なら、下記PermissionFailure手順へジャンプ。

      7. ユーザープリファレンスやセキュリティ、プラットフォーム制約等で任意にPermission Failureへジャンプしてもよい。

      8. candidateSetの全候補をfinalSetに追加。

    4. streamを新規・空の MediaStreamオブジェクトとする。

    5. requestedMediaTypesの各kindについて、できれば同時に以下のサブ手順を実行:

      注記

      ユーザーエージェントは複数種メディアの同時リクエストを 一つのユーザー向け許可プロンプトにまとめることが推奨されます。

      1. 利用許可リクエストPermissionDescriptornamekindに対応する権限名(例:"camera""video"用、"microphone""audio"用)で指定して実行。 現ドキュメントでライブかつ同一許可MediaStreamTrackに アタッチされた全デバイスは"granted"とみなす。得られるメディア集合を「provided media」とする。 同一許可とは、取得時に同じレベルの権限(例:隔離されていない)を必要とした MediaStreamTrackを指す。

        ユーザーに許可を求める際、ユーザーエージェントは 許可は選択したデバイスのみに与えられるか、 kindの全デバイスに与えられるかを明示必須

        注記

        ユーザーが応答しなければ、このアルゴリズムはこのステップで停止します。

      2. リクエスト結果が"denied"なら下記Permission Failureへジャンプ。

    6. hasSystemFocusfalseにする。

    7. hasSystemFocusfalseの間、 ユーザーエージェント 必須で、hasSystemFocusシステムフォーカスあり アルゴリズムの結果でtrueになるまで、次へ進まない。

    8. デバイス情報公開の設定mediaDevicesに対しrequestedMediaTypestrueで実行。

    9. requestedMediaTypesの各kindについて以下のサブ手順を実行:

      1. finalCandidate を提供されたメディアとし、これは finalSet から kind 型の candidate が正確に1つ必須です。どの candidate を finalSet から選ぶかは完全にユーザーエージェントの裁量であり、ユーザーに選択させても構いません。

        ユーザーエージェントは、計算されたfitness distanceSelectSettings アルゴリズムの入力の1つとして推奨で利用すべきです。ただし、ユーザーの好みなどデバイスに関する他の内部情報を使ってもよいです。

        これは、必須ではない制約値は保証されないことを意味します。

        ユーザーエージェントは、可能ならkindについてユーザーの主デバイスまたはシステム既定デバイスを使うことをデフォルトとすることが推奨されます。ユーザーエージェントは、ユーザーが任意のメディアソース(録画済みファイル等も含む)を使うことを許可しても構いません。

      2. リクエストの結果は "granted" です。OSやプログラム、ウェブページのロックなどハードウェアエラーでアクセスできない場合は、該当 candidate を finalSet から除外してください。finalSetkind 型の candidate が1つもなければ、reject p を新規 DOMException オブジェクト(属性 name が "NotReadableError")でrejectし、これらの手順を中止してください。それ以外の場合は、更新された finalSet でこれらのサブ手順を再実行してください。

        デバイスアクセスが上記以外の理由で失敗した場合も、該当 candidate を finalSet から除外してください。finalSetkind 型の candidate がなければ、reject p を新規 DOMException(属性 name が "AbortError")でrejectし、手順を中止してください。それ以外の場合は、更新された finalSet でこれらのサブ手順を再実行してください。

      3. grantedDevicefinalCandidate のソースデバイスとする。

      4. grantedDevice の deviceId(deviceId)を使い、mediaDevices.[[devicesLiveMap]][deviceId] を true(すでに true でなければ)にし、mediaDevices.[[devicesAccessibleMap]][deviceId] も true(すでに true でなければ)にしてください。

      5. trackMediaStreamTrack作成(引数 grantedDevicemediaDevices)の結果としてください。MediaStreamTrack のソースは変更してはなりません

      6. trackstream のトラック集合に追加してください。

    10. 全トラックに対してApplyConstraintsアルゴリズムを適用。結果がundefined以外ならfailedConstraintにセットし、下記Constraint Failureへジャンプ。

    11. trackについて トラックソースをMediaDevicesに紐付けtrack.[[Source]]mediaDevices)。

    12. resolve pstreamで)し、手順中断。

    13. NotFound Failure:

      1. getUserMedia 固有失敗許可requestedMediaTypes)がfalseなら、下記Permission Failureへジャンプ。

      2. reject p(name値は"NotFoundError"の DOMException)で返す。

    14. Constraint Failure:

      1. getUserMedia 固有失敗許可requestedMediaTypes)がfalseなら、下記Permission Failureへジャンプ。

      2. messageundefinedまたは説明用文字列とし、constraintfailedConstraintデバイス情報公開可trueならそれ、そうでなければ"")とする。

      3. reject pOverconstrainedError(constraint, message)で作成した新規OverconstrainedError)で返す。

    15. Permission Failure: reject p(name値は"NotAllowedError"の DOMException)で返す。

  12. pを返す。

getUserMedia 固有失敗許可を確認するには、 requestedMediaTypesを指定して以下の手順を実行する:

  1. requestedMediaTypesに"audio"が含まれていれば、名前が"microphone"のディスクリプタのパーミッション状態を読み取る。そのリクエスト結果が "denied" なら、falseを返す。

  2. requestedMediaTypesに"video"が含まれていれば、名前が"camera"のディスクリプタのパーミッション状態を読み取る。そのリクエスト結果が "denied" なら、falseを返す。

  3. trueを返す。

注記

上記のアルゴリズムでは、制約がデバイス選択時とアクセス承認後の2回チェックされます。その間に時間が経過するため、選択したデバイスが適さなくなっている可能性があります。この場合、NotReadableErrorが発生します。

デバイス選択に許可された必須制約 には、以下の制約名が含まれます: width, height, aspectRatio, frameRate, facingMode, resizeMode, sampleRate, sampleSize, echoCancellation, autoGainControl, noiseSuppression, latency, channelCount, deviceId, groupId.

MediaStreamConstraints 辞書は、 ユーザーエージェントMediaStreamTrack をどのように MediaStreamgetUserMedia()で返される)に含めるか指示するためのものです。

WebIDLdictionary MediaStreamConstraints {
  (boolean or MediaTrackConstraints) video = false;
  (boolean or MediaTrackConstraints) audio = false;
};

Dictionary MediaStreamConstraints メンバー

video(boolean または MediaTrackConstraints)、既定値はfalse

trueの場合、返される MediaStreamに 映像トラックを含めるよう要求します。Constraints 構造が指定されていれば、さらに映像トラックの性質や設定を指定できます。falseの場合、 MediaStreamには 映像トラックを絶対に含めてはなりません。

audio(boolean または MediaTrackConstraints)、既定値はfalse

trueの場合、返される MediaStreamに 音声トラックを含めるよう要求します。 Constraints構造が指定されていれば、 さらに音声トラックの性質や設定を指定できます。falseの場合、 MediaStreamには 音声トラックを絶対に含めてはなりません。

10.3 旧GetUserMediaインターフェイス

このセクションは規範的ではありません。

注記

本セクションのgetUserMedia()定義は、元々提案された呼び出し形式を反映したもので、後方互換性維持が必要なブラウザ向けにのみ記載されています。推奨インターフェイスとは2点異なります。

第一に、getUserMedia()メソッドの公式定義および開発者が利用を推奨されるものは、現在MediaDevices上にあります。この決定は、元のAPIがNavigatorオブジェクト下に後方互換性のため残る限り、コンセンサスを反映しています。ワーキンググループは、これらのAPIの初期ユーザーが getUserMedia を "var getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;" と定義することが推奨されていたことを認識しており、公式実装の前後両方でコードが動作するようにしていました。機能的同等性を保証するため、Navigator上のgetUserMedia()メソッドはMediaDevices下のメソッドに基づいて定義されています。

第二に、仕様上の他のコールバックベースメソッドがPromiseベースに変更されたため、navigator.getUserMedia()定義も navigator.mediaDevices.getUserMedia() を利用する形となりました。navigator.getUserMedia()は本仕様で唯一残っているコールバックベースメソッドであり、仕様上残すべきか、また残すなら構文をコールバックベースのままにするかPromise型などに変更すべきか、現在も議論が続いています。現行実装を利用している開発者からの意見を歓迎します。

他のメソッドがコールバックベースからPromiseベースに変わった際は、広く実装されていなかったためレガシー利用を考慮する必要はありませんでした。

本インターフェイスを実装しなくても適合実装とみなされます。

10.3.1 インターフェイス定義

WebIDLpartial interface Navigator {
  [SecureContext] undefined getUserMedia(MediaStreamConstraints constraints,
                                    NavigatorUserMediaSuccessCallback successCallback,
                                    NavigatorUserMediaErrorCallback errorCallback);
};
メソッド
getUserMedia

ユーザーにWebカメラやその他のビデオ・オーディオ入力利用許可を求めます。

constraints引数はMediaStreamConstraints型のディクショナリです。

successCallbackは、ユーザーが有効なトラックを許可した場合、MediaStream オブジェクトを引数として呼び出されます(詳細はgetUserMedia() in MediaDevices 参照)。

errorCallbackは、有効なトラックが見つからない場合やユーザーが許可しない場合に呼び出されます(詳細はgetUserMedia() in MediaDevices 参照)。

getUserMedia() メソッドが呼ばれたら、 ユーザーエージェントは必須で以下の手順を実行する:

  1. constraintsを第1引数とする。

  2. successCallbackを第2引数のコールバックとする。

  3. errorCallbackを第3引数のコールバックとする。

  4. getUserMedia() アルゴリズムの手順をconstraintsを引数として実行し、pを得る。

  5. fulfilled時、 pの値streamについて以下を実行:

    1. successCallbackstreamで呼び出す。

  6. rejected時、 pの理由rについて以下を実行:

    1. errorCallbackrで呼び出す。

10.4 実装上の提案

このセクションは規範的ではありません。

Best Practice 1: リソース予約

ユーザーエージェントgetUserMedia() の呼び出しが成功することを判定した時点で リソースを予約することが推奨されます。promiseがresolveされる前にリソースを予約するのが望ましいです。 以降の getUserMedia() (同一ページや他ページ)呼び出しでは、既に割り当て済みリソースや他アプリが保持するリソースを 「使用中」とみなし、ユーザーが指定しない限り現ページのソースとして提供しないことが望ましいです。 任意で、ユーザーエージェントは 使用中ソースを同一オリジンのページにのみストリームとして提供してもよいです。

本仕様は、許可ダイアログやデバイス選択画面(存在する場合)で 利用可能なハードウェアをユーザーがどれでも選択可能にすることを推奨します (リソースが指定の必須制約を満たせる場合)。なお、特に推奨はしませんが 一部ユーザーエージェントは ローカルファイルや他メディアで映像・音声ソースを代替可能です。ファイルピッカーなどでこの機能を提供できます。

さらに、現在使用中のリソース(同じページや他の生存中ページで getUserMedia()により確保済み)を 一覧で表示し、ユーザーがそのストリームを終了して現ページでリソース利用できるようにすることも推奨されます。 OS環境によっては、他アプリで保持中のリソースも同様に提示・処理できるようにするとよいです。 ユーザーがこの選択肢を選んだ場合、影響を受けたストリームの該当リソースのトラックはページから削除しなければなりません。

Best Practice 2: 保存された許可

デバイスの許可が要求された際、 ユーザーエージェントは 同じオリジンで後から使うために許可を保存することができます。 これによりユーザーは後で再度許可を与える必要がなくなります。 どの単位で許可を保存するか(デバイスごと、クラスごと、全デバイス)は ユーザーエージェントの判断ですが、 その選択がユーザーに分かりやすく示されている必要があり、 保存する範囲のすべてに対して許可が与えられている必要があります。 例えば全カメラに対して許可を保存するには、1台だけでなく全カメラに許可が必要です。

本仕様は、許可付与が保存された許可になるかどうかは規定しません。 許可が保存されない場合、許可はそのデバイス由来のMediaStreamTrackが全停止するまで有効です。

Best Practice 3: 複数デバイスの取り扱い

MediaStreamは 複数のビデオ・オーディオトラックを含むことができます。 例えば複数Webカメラの映像を1つのストリームに含めることも可能です。 ただし現在のAPIでは、独立した複数ビデオストリームの要求は表現できません。

同じページから複数回 getUserMedia() を呼び出して、 別々のビデオ/オーディオストリームをリクエストする方法が推奨されます。

また、1ページで複数回 getUserMedia() を実行した場合、 リソース要求や完了の順序は本仕様では制約しません。

1回の getUserMedia() 呼び出しで オーディオは0または1トラック、ビデオも0または1トラックのみ返されます。 スクリプトが複数回 getUserMedia() を安定状態前に呼ぶ場合、 UI設計者は許可ダイアログを統合し、複数カメラやメディアソースに一度で許可できるようにするのが望ましいです。 各getUserMedia呼び出しの制約で、どのストリームがどのメディアソースを使うかを決定できます。

Best Practice 4: deviceId生成

deviceId生成の効率的な方法は、 プライベートキー+(オリジンまたはオリジン+トップレベルオリジン、ユーザーエージェントの分割規則による)+ソルト+ドライバ内のデバイス固有ID を暗号学的ハッシュし、英数字文字列として提示することです。 衝突リスクを避けるため、ハッシュは32ビット以下が推奨ですがあまり小さくしないようにします。

より低エントロピーでストレージ消費の多い代替案として、 各オリジン(またはオリジン+トップレベルオリジン、ユーザーエージェントの分割規則による)ごとに 新しいデバイスごとに0〜255の番号をランダムに割り当て、 枠が足りなくなったら最も長く使われていない番号を廃止する方法もあります。

Best Practice 5: ユーザーエージェントによるデバイスミュート

カメラやマイクからソースされたトラックは、ユーザーのプライバシー保護のため、ミュートユーザーエージェントがいつでも強制的に実行できます。ただし、この操作はウェブ互換性の問題やユーザーの活動に関する情報漏洩を引き起こす可能性があるため、注意が必要です。

ベストプラクティスとして、以下の状況で ミュートが推奨されます:

  • OSレベルのイベント(メディア再生がグローバルに一時停止されるがJavaScriptは停止しない)で、 ユーザーが意図的に設定しない限り、録画が継続すると驚く可能性があるため。 OSイベントですでにトラックのフレームが止まるなら、追加的なユーザー活動情報は漏れません。 そうでない場合でも、録画終了を通知する方が、ユーザーの意図に反する録画継続よりプライバシー上望ましいです。

  • Webページがビュー外で そのソース由来の全トラックが無効化された状態で トラックが再有効化された場合。 ページがビュー内になるまで録画再開を遅延するため。

ベストプラクティスとして、以下の場合に アンミュート(以前ミュートしたトラック)を推奨:

  • OSレベルのイベントでメディア再生がグローバルに再開され、かつページがユーザーに可視状態の場合(例:ロック画面中でない)。 ユーザーエージェントは 以前の録画セッション認知に重大な時間経過があった場合はアンミュートを遅延してもよいです。

  • Webページがビュー内になり、 有効化かつミュート状態のトラックが1つ以上ある場合。

11. Constrainableパターン

Constrainableパターンは、これを実装するオブジェクト(constrainableオブジェクト)のプロパティをアプリケーションが検査・調整できるようにします。他仕様から参照できるよう定義群が分離されています。コア概念はCapability(ケイパビリティ)で、オブジェクトの制約可能プロパティと、その値の集合(範囲または列挙)からなります。例えば、カメラはフレームレート(プロパティ)が20~50fps(範囲)に対応、向き(プロパティ)がユーザー方向・反対・左・右(列挙)に対応可能です。アプリケーションはgetCapabilities()アクセサで制約可能プロパティの対応ケイパビリティを調べられます。

アプリケーションは、基本または高度なConstraintSetおよびapplyConstraints()メソッドによって、オブジェクトのケイパビリティに対して望む(範囲の)値を選択できます。ConstraintSetは、オブジェクトの1つ以上のプロパティ名+各プロパティに対する希望値(または範囲)からなり、各プロパティ/値の組は個別制約とみなせます。例えば、ConstraintSetでカメラのフレームレートを30~40fps(範囲)、向きをユーザー方向(値)に設定することができます。個別制約の挙動は、基本Constraint構造('advanced'プロパティ付ConstraintSet)にあるか、高度リストのConstraintSet内にあるかで異なります。挙動は以下の通り:基本Constraint構造の全ての'min'・'max'・'exact'制約は必須制約として同時に満たせなければユーザーエージェント必須でpromiseをrejectしなければなりません。同時に満たせれば必須制約を適用。その後、advancedリスト内の各ConstraintSetを順番に全ての制約を同時に満たせる場合だけ適用・満たせない場合だけスキップ。次にユーザーエージェントは'ideal'制約やプロパティへの値指定(基本オプション制約)を個別にできるだけ多数満たす(順不同)。最後にユーザーエージェントはpromiseを必須resolveする。

注記
このAPIで指定した制約は、該当の制約可能プロパティがユーザーエージェントにサポートされている場合のみ考慮されます。JavaScriptアプリケーションはgetSupportedConstraints()で使用するプロパティ名がサポートされているか事前に確認するのが期待されます。これはWebIDLが未サポート名を制約ディクショナリから除去し、ユーザーエージェントが認識せず無視されるためです。アプリ側は制約を指定しているつもりでもユーザーエージェントが無視するため、混乱の元です。名前は認識しているが満たせない場合はエラーを返しますが、プロパティ自体非対応の場合はエラーになりません。

以下の例で制約の動作を説明します。最初は基本Constraint構造の例。3つの制約があり、ユーザーエージェントはそれぞれ個別に満たそうとします。カメラの解像度次第では3つ同時に満たせない場合もあり、その場合は2つ、さらに不可能なら1つだけ満たします。同時満足できない場合、どの組み合わせ2つを満たすか複数選択肢があればユーザーエージェントが選択します。

const stream = await navigator.mediaDevices.getUserMedia({
  video: {
    width: 1280,
    height: 720,
    aspectRatio: 3/2
  }
});

次の例は少し複雑です。widthとheightに理想値(ideal)を指定しつつ、各値の最小値とframeRateの最小値も指定します。frameRate・width・heightのいずれか最小値を満たせなければpromiseはrejectされます。それ以外ならwidth・height・aspectRatioの目標値も満たすよう試み、resolveされます。

try {
  const stream = await navigator.mediaDevices.getUserMedia({
    video: {
      width: {min: 640, ideal: 1280},
      height: {min: 480, ideal: 720},
      aspectRatio: 3/2,
      frameRate: {min: 20}
    }
  });
} catch (error) {
  if (error.name != "OverconstrainedError") {
    throw error;
  }
  // Overconstrained. Try again with a different combination (no prompt was shown)
}

この例では、Constraints構造の'advanced'プロパティで制御の幅を広げています。必須制約の扱いは同じですが、理想値を満たす前に'advanced'リストを処理します。この例の'advanced'リストには2つのConstraintSetがあり、1つ目はwidth・height制約、2つ目はaspectRatio制約です。高度リスト内の値は'exact'として扱われます。例の意味は「ビデオは横幅640px以上・高さ480px以上が必須。理想は1920x1280だが、無理ならaspectRatio=4:3が望ましい。それも無理なら1280x720に近いものがほしい」です。

try {
  const stream = await navigator.mediaDevices.getUserMedia({
    video: {
      width: {min: 640, ideal: 1280},
      height: {min: 480, ideal: 720},
      frameRate: {min: 30},
      advanced: [
        {width: 1920, height: 1280},
        {aspectRatio: 4/3},
        {frameRate: {min: 50}},
        {frameRate: {min: 40}}
      ]
    }
  });
} catch (error) {
  if (error.name != "OverconstrainedError") {
    throw error;
  }
  // Overconstrained. Try again with a different combination (no prompt was shown)
}

高度ConstraintSetの順序は重要です。上記例では1920x1280と4:3の両方同時に満たすことは不可能ですが、先に1920x1280があるためユーザーエージェントはまずそちらを満たそうとします。アプリ作者は同じプロパティに複数高度ConstraintSetを指定してバックオフ戦略を実装可能です。さらに2つの高度ConstraintSet(frameRate>50, frameRate>40)も指定。ユーザーエージェントが50以上対応ならそれを使い、次のConstraintSetは自動的に満たされます。50以上不可ならスキップして40以上に挑戦。それも不可なら基本ConstraintSetの'min'値(30)が下限を主張。つまりユーザーエージェントは30以上が得られなければ失敗、得られるなら50以上を優先、次に40以上を試します。

基本制約と異なり、高度リストのConstraintSet内の制約は全て同時に満たすかスキップするかです。{width: 1920, height: 1280}はその解像度を要求しており、横幅/高さどちらかではありません。基本制約は個々の制約の「非排他的or」要求、高度ConstraintSetはセット内すべての「and」要求と言えます。アプリはgetConstraints()アクセサで現在有効な制約集合を調査可能です。

ユーザーエージェントが制約可能プロパティの値として選択する具体値はSetting(設定値)と呼びます。例えばframeRateが30~40fpsでConstraintSetを適用した場合、設定値は32・35・37fpsなど中間値も可です。アプリはgetSettings()アクセサでオブジェクトの制約可能プロパティの現在値を問い合わせできます。

11.1 インターフェイス定義

本仕様は ConstrainablePattern をWebIDLインターフェイスとして形式的に定義していますが、実際には他インターフェイス向けのテンプレート・パターンであり、直接継承はできません(メソッドの返り値を拡張する必要がありWebIDLでは不可)。このため、本機能を使いたいインターフェイスはここに示す関数やインターフェイスのWebIDLを個別に用意する必要があります。ただし意味論はここを参照できます(変更されません)。例は MediaStreamTrack インターフェイス定義 参照。

このパターンは constrainableオブジェクト が3つの内部スロットを定義することに依存します:

  1. [[Capabilities]] 内部スロット。初期値は Capabilities辞書(公開する各制約可能プロパティについて許容値の集合。詳細は Capabilities 参照)またはプロパティがなければ空辞書。

  2. [[Constraints]] 内部スロット。初期値は空の Constraints辞書。

  3. [[Settings]] 内部スロット。初期値は Settings辞書(公開する各制約可能プロパティについて現在有効な設定値。詳細は Settings 参照)またはプロパティがなければ空辞書。

テンプレート:
WebIDL[Exposed=Window]
interface ConstrainablePattern {
  Capabilities  getCapabilities();
  Constraints   getConstraints();
  Settings      getSettings();
  Promise<undefined> applyConstraints(optional Constraints constraints = {});
};

メソッド

getCapabilities

getCapabilities() メソッドは、そのオブジェクトがサポートする制約可能プロパティ名の辞書を返します。呼び出し時、ユーザーエージェント 必須[[Capabilities]]内部スロットの値を返します。

注記

基盤ハードウェアが制約可能プロパティの範囲に厳密に一致しない場合もあり得ます。そうした場合、対応方法(変換・スケール)を定義することが推奨です。例えば仮のfluxCapacitanceプロパティが-10~10の範囲でも、ハードは"off" "medium" "full"しか対応しない場合、定義で-10→"off"、10→"full"、0→"medium"と対応付けること。ConstraintSetで厳密値3が来た場合は"medium"を設定し、getSettings()は0を返す("medium"に対応する値)。

getConstraints

getConstraints() メソッドは、 直近で成功した ApplyConstraints algorithm の引数だったConstraintsを順序保持して返します。高度ConstraintSetの一部は現状満たされていない可能性もあるので、現状有効なConstraintSetの確認には getSettings を使うこと。UAは上記内容と同じ効果のConstraintSetを返してもよいです。呼び出し時、ユーザーエージェント 必須[[Constraints]]内部スロットの値を返します。

getSettings

getSettings() メソッドは、 そのオブジェクトの制約可能プロパティすべての現設定値(プラットフォーム既定値またはApplyConstraints algorithmで設定した値)を返します。設定値は制約を満たすターゲット値であり、実際の計測値と異なる場合もあります。呼び出し時、ユーザーエージェント必須[[Settings]] 内部スロットの値を返します。

applyConstraints

applyConstraintsテンプレートメソッドが呼ばれた場合、 ユーザーエージェント必須で以下を実行します:

  1. object:このメソッドが呼ばれたオブジェクト

  2. newConstraints:このメソッドの引数

  3. p:新規promise

  4. 以下を並行実行(多重呼び出し時は順序保持):

    1. failedConstraintApplyConstraints algorithm(引数newConstraints)の結果

    2. successfulSettings=上記アルゴリズム終了後のobjectの現設定値

    3. 以下をタスクキューに登録:

      1. failedConstraintundefinedでなければ、messageundefinedまたは説明文字列)を用い、OverconstrainedError(failedConstraint, message)で新規OverconstrainedErrorを生成しpをrejectして中断。既存制約は有効のまま。

      2. object[[Constraints]] 内部スロットにnewConstraintsまたは同効果のConstraints辞書を設定。

      3. object[[Settings]] 内部スロットにsuccessfulSettingsを設定。

      4. resolve pundefinedで)。

  5. pを返す。

制約適用用ApplyConstraints algorithmは以下。まず用語定義:

settings dictionary(設定値辞書)は、 オブジェクトに設定しうる値の集合。

文字列値制約では「==」はシーケンス内どれかが比較値と完全一致ならtrue。

settings dictionaryと制約セットCS間の fitness distanceは、 CSに存在する各(constraintName, constraintValue)ペアについて以下の値の合計:

  1. constraintNameユーザーエージェントによってサポートされていない場合、適合度距離は0となる。

  2. 制約がrequiredconstraintValueが「min」「max」「exact」いずれかのメンバーを1つ以上含む場合、またはadvanced ConstraintSet内で値のみの場合)であり、settings dictionaryconstraintNameメンバーの値が制約を満たさない、または存在しない場合、適合度距離は正の無限大となる。

  3. この型のオブジェクトに制約が適用されない場合、適合度距離は0(つまり、その制約は適合度距離に影響しない)。

  4. constraintValueが真偽値だが、制約可能なプロパティが真偽値でない場合、適合度距離はsettings dictionaryconstraintNameメンバーが存在するかどうかによって、次の式で決まる:

    (constraintValue == exists) ? 0 : 1
  5. settings dictionaryconstraintNameメンバーが存在しない場合、適合度距離は1となる。

  6. 理想値が指定されていない場合(constraintValueに「ideal」メンバーがなく、または値のみの場合に「ideal」とみなされない場合)、適合度距離は0となる。
  7. 全ての正の数値制約(height, width, frameRate, aspectRatio, sampleRate, sampleSizeなど)については、適合度距離は以下の式による:
    (actual == ideal) ? 0 : |actual - ideal| / max(|actual|, |ideal|)
  8. 全ての文字列・列挙型・真偽値の制約(deviceId, groupId, facingMode, resizeMode, echoCancellationなど)については、適合度距離は以下の式による:
    (actual == ideal) ? 0 : 1

用語補足:

  • ConstraintSetの各要素('advanced'以外)は「制約」と呼ぶ。Capabilityで指定された値集合から、指定値/範囲に絞る。
  • 「有効ケイパビリティ」Cは、getCapabilitiesで得られる値集合の環境制限・他制約による部分集合。例えばaspectRatio, height, widthに制約をかけると、2つの値で3つ目の有効ケイパビリティが制限される。プラットフォーム依存。
  • settings dictionaryがConstraintSet CSを満たすとは、fitness distanceが∞未満であること。
  • ConstraintSets CS1...CSn(n≥1)が同時に満たせるとは、Oのsettings dictionaryで全部同時に満たせるものがあること。
  • ConstraintSets CS1...CSnをOに適用するとは、それらを満たす値列を選び、Oのプロパティ設定値とすること。

SelectSettingsアルゴリズムは以下:

  1. 制約は、そのプロパティの1つ以上の値(または値の範囲)を指定します。プロパティは「advanced」ConstraintSetのリスト内に複数回現れてもよいです。制約値として空リストが指定された場合、それは制約が指定されていないものと必須でみなされます(つまり、空制約=制約なし)。

    未知のプロパティはWebIDLで破棄されるため、未知・非対応のrequired制約は黙って消えます。これによる意外性を避けるため、アプリケーション作者は下記例のようにまずgetSupportedConstraints()メソッドの利用が期待されます。

  2. object をこのアルゴリズムが適用される ConstrainablePattern オブジェクトとする。copyobject の非制約コピー(すなわち全ConstraintSetを除去した状態で object のように振る舞う)とする。
  3. copy の可能なすべてのsettings dictionaryについて、そのfitness distanceを計算し、プロパティの値が裸値の場合は理想値として扱う。candidates を、fitness distance が有限となるsettings dictionaryの集合とする。

  4. candidatesが空なら、SelectSettingsアルゴリズムの結果としてundefinedを返す。

  5. newConstraintsの「advanced」ConstraintSetを指定順に繰り返す。各ConstraintSetについて:
    1. それとcandidates内の各settings dictionaryとのfitness distanceを計算し、プロパティの裸値は厳密値として扱う。

    2. fitness distanceが有限のsettings dictionaryがcandidatesに1つ以上ある場合、それらのみcandidatesに残し、他は除外する。

      すべてのsettings dictionaryでfitness distanceが無限なら、このConstraintSetは無視する。

  6. candidatesから1つsettings dictionaryを選び、SelectSettingsアルゴリズムの結果として返す。ユーザーエージェントはstep3で計算されたfitness distanceが最小のものを必須で使うこと。最小fitness distanceが複数ある場合、ユーザーエージェントはシステム既定プロパティ値やユーザーエージェント既定プロパティ値に基づきその中から1つを選択する。

選択デバイスにシステム既定値がある場合、互換性あれば既定値を推奨で使う(例:sampleRate, sampleSize)。echoCancellation, resizeMode等は既定値がなくUA独自既定値となる。既定値選択はメディア生成に影響するため慎重に。

注記

現実装を参考に意味のある既定値を選ぶことが推奨。既定値はデスクトップ/モバイル等システム依存で異なる場合あり。執筆時点でUAはRTCPeerConnection用途に次を既定値としている場合が多い:

  1. width=640

  2. height=480

  3. frameRate=30

  4. echoCancellation=true

ApplyConstraints algorithmobjectnewConstraintsを引数で適用するには、ユーザーエージェント必須で以下を実行:

  1. successfulSettings を、newConstraints を制約セットとして SelectSettings アルゴリズムを実行した結果とする。

  2. もし successfulSettingsundefined であれば、failedConstraint を、必須制約 の中で SelectSettings アルゴリズムの実行中に調べられたすべての設定ディクショナリについて、フィットネス距離が無限大であったもののいずれかとする。該当するものがなければ "" とし、その後 failedConstraint を返してこれらの手順を中止する。

  3. 1つの操作で、object から既存の制約を削除し、newConstraints を適用し、successfulSettings を現在の設定として適用する。
  4. undefined を返す。
注記

UAがデバイス解放(例:トラックがミュート)した場合は、設定適用はデバイス構成変更を意味しません。代わりに、トラックがアンミュート等で再取得する時点でトラック設定に合わせて構成します。

注記

上記アルゴリズムと同じ結果になる実装はすべて許容されます。例えば、設定値の全候補値ではなく、制約下でOKな最大・最小値だけを追跡する実装でもよいです。

注記

settings dictionary選択時、UAは取得可能なあらゆる情報を使えます。例:getUserMediaのデバイス選択時かどうか、カメラの消費電力の違い、設定値によるドライバでリサンプリングが発生するか等。

ユーザーエージェントは任意のタイミングで制約可能プロパティの新設定値を選択してもよい。選択時は必ず現制約を満たすよう上記アルゴリズム通りに処理し、successfulSettings新値で以下をタスクキューに登録:

  1. object:新設定値変更対象のConstrainablePatternオブジェクト

  2. object[[Settings]]内部スロットにsuccessfulSettingsを設定。

以下は applyConstraints() に渡すことも、 constraints の値として返すこともできるConstraintsの例です。 カメラソースの制約可能プロパティを使っています。 この例ではすべての制約が理想値(ideal)なので、結果はユーザーのカメラに応じて「ベストエフォート」となります:

await track.applyConstraints({
  width: 1920,
  height: 1080,
  frameRate: 30,
});
const {width, height, frameRate} = track.getSettings();

console.log(`${width}x${height}x${frameRate}`); // 1920x1080x30, ただしベストエフォートで例:1280x720x30等もあり得る

より細かな制御をしたい場合、アプリケーションは厳密一致(exact)を要求することもできますが、その場合失敗時の処理も必要です:

try {
  await track.applyConstraints({
    width: {exact: 1920},
    height: {exact: 1080},
    frameRate: {min: 25, ideal: 30, max: 30},
  });
  const {width, height, frameRate} = track.getSettings();

  console.log(`${width}x${height}x${frameRate}`); // 1920x1080x25-30!

} catch (error) {
  if (error.name != "OverconstrainedError") {
    throw error;
  }
  console.log(`このカメラは要求された ${error.constraint} に対応できません。`);
}

Constraintsは getUserMedia に渡すこともでき、初期化のためだけでなく、デバイス選択に影響を与える目的でも使えます。 この場合は 固有制約 も利用可能です。

以下は、前回の訪問で使用した特定のカメラ・マイクを優先し、寸法やステレオ希望を要求し、許可されたら適用し、希望デバイスが使えない場合(または一部UAでユーザーが上書きした場合)でも代替デバイスを探すサポートをする例です。

try {
  const stream = await navigator.mediaDevices.getUserMedia({
    video: {
      deviceId: localStorage.camId,
      width: {min: 800, ideal: 1024, max: 1280},
      height: {min: 600}
    },
    audio: {
      deviceId: localStorage.micId,
      channelCount: 2
    }
  });

  // 許可された場合、デバイスIDを次回用に保存
  localStorage.camId = stream.getVideoTracks()[0].getSettings().deviceId;
  localStorage.micId = stream.getAudioTracks()[0].getSettings().deviceId;

} catch (error) {
  if (error.name != "OverconstrainedError") {
    throw error;
  }
  // Overconstrained. 条件に合う代替デバイスが見つからない
}

上記の例では、{exact: deviceId} を使用せず、ブラウザーがデバイスに関する内部情報(ユーザーの好みやデバイスの不在など)を、提供された deviceId よりも優先して利用できるようにしています。

また、この例では、deviceId が新たな選択肢を表す場合に備えて、すべての許可時に deviceId を保存しています。

対照的に、コンテンツ内カメラピッカーを実装する場合の例です。この場合は exact を使い、ユーザーが選択リストから選んだ deviceId のみ頼りにします:

async function switchCameraTrack(freshlyChosenDeviceId, oldTrack) {
  if (isMobile) {
    oldTrack.stop(); // 一部プラットフォームは同時に1つのカメラしか開けない
  }
  const stream = await navigator.mediaDevices.getUserMedia({
    video: {
      deviceId: {exact: freshlyChosenDeviceId}
    }
  });
  const [track] = stream.getVideoTracks();
  localStorage.camId = track.getSettings().deviceId;
  return track;
}

次は、スマートフォンの背面カメラで理想的には720p、近い値なら何でも許容、という要求例です。寸法制約は横向き(ランドスケープ)で指定しています:

async function getBackCamera() {
  return await navigator.mediaDevices.getUserMedia({
    video: {
      facingMode: {exact: 'environment'},
      width: 1280,
      height: 720
    }
  });
}

「16:9のネイティブ解像度で720p近傍が欲しいが、フレームレートは非ネイティブでも10を厳密指定したい」場合の例です。2段階処理が必要:まずネイティブモードを取得し、次にカスタムフレームレートを適用。この例は現在の設定値から制約を導出する方法も示しています(回転している場合も考慮):

async function nativeResolutionButDecimatedFrameRate() {
  const stream = await navigator.mediaDevices.getUserMedia({
    video: {
      resizeMode: 'none', // ネイティブ解像度・フレームレート
      width: 1280,
      height: 720,
      aspectRatio: 16 / 9 // aspectRatioは厳密一致でない場合あり
    }
  });
  const [track] = stream.getVideoTracks();
  const {width, height, aspectRatio} = track.getSettings();

  // 制約はランドスケープ、設定値は回転(ポートレート)している場合も
  if (width < height) {
    [width, height] = [height, width];
    aspectRatio = 1 / aspectRatio;
  }

  await track.applyConstraints({
    resizeMode: 'crop-and-scale',
    width: {exact: width},
    height: {exact: height},
    frameRate: {exact: 10},
    aspectRatio,
  });

  return stream;
}
注記
上記例は主方向がランドスケープであることを前提としています。

次は getSupportedConstraints の活用例です。UAで未対応の制約が無視されるのをアプリが許容しない場合に使います:

async function getFrontCameraRes() {
  const supports = navigator.mediaDevices.getSupportedConstraints();

  for (const constraint of ["facingMode", "aspectRatio", "resizeMode"]) {
    if (!(constraint in supports) {
      throw new OverconstrainedError(constraint, "未対応");
    }
  }
  return await navigator.mediaDevices.getUserMedia({
    video: {
      facingMode: {exact: 'user'},
      advanced: [
        {aspectRatio: 16/9, height: 1080, resizeMode: "none"},
        {aspectRatio: 4/3, width: 1280, resizeMode: "none"}
      ]
    }
  });
}

11.2 制約型

有効入力集合の仕様の構文は値の型によって異なります。標準の原子型(boolean, long, double, DOMString)に加え、原子型のリストや、下記で定義されるmin-max範囲も有効値になります。

リスト値は必須で論理和(disjunction)として解釈されます。例えばカメラのプロパティ'facingMode'が["left", "right", "user", "environment"]の有効値なら、'facingMode'は"left", "right", "environment", "user"のいずれでも可。同様にConstraintsで'facingMode'を["user", "left", "right"]に制限すると、ユーザーエージェントはカメラ(または可能なら向き)を"user", "left", "right"のいずれかにするべきです。この制約はカメラがユーザーと逆向きでないよう要求しますが、他方向の選択はユーザーエージェントがユーザーに委ねても構いません。

WebIDLdictionary DoubleRange {
  double max;
  double min;
};

辞書 DoubleRange メンバー

maxdouble

このプロパティの最大有効値。

mindouble

このプロパティの最小値。

WebIDLdictionary ConstrainDoubleRange : DoubleRange {
  double exact;
  double ideal;
};

辞書 ConstrainDoubleRange メンバー

exactdouble

このプロパティの厳密指定値。

idealdouble

このプロパティの理想(目標)値。

WebIDLdictionary ULongRange {
  [Clamp] unsigned long max;
  [Clamp] unsigned long min;
};

辞書 ULongRange メンバー

maxunsigned long

このプロパティの最大有効値。

minunsigned long

このプロパティの最小値。

WebIDLdictionary ConstrainULongRange : ULongRange {
  [Clamp] unsigned long exact;
  [Clamp] unsigned long ideal;
};

辞書 ConstrainULongRange メンバー

exactunsigned long

このプロパティの厳密指定値。

idealunsigned long

このプロパティの理想(目標)値。

WebIDLdictionary ConstrainBooleanParameters {
  boolean exact;
  boolean ideal;
};

辞書 ConstrainBooleanParameters メンバー

exactboolean

このプロパティの厳密指定値。

idealboolean

このプロパティの理想(目標)値。

WebIDLdictionary ConstrainDOMStringParameters {
  (DOMString or sequence<DOMString>) exact;
  (DOMString or sequence<DOMString>) ideal;
};

辞書 ConstrainDOMStringParameters メンバー

exact(DOMString または sequence<DOMString>)

このプロパティの厳密指定値。

ideal(DOMString または sequence<DOMString>)

このプロパティの理想(目標)値。

WebIDLdictionary ConstrainBooleanOrDOMStringParameters {
  (boolean or DOMString) exact;
  (boolean or DOMString) ideal;
};

辞書 ConstrainBooleanOrDOMStringParameters メンバー

exact 型 (boolean または DOMString)

このプロパティの厳密指定値。

ideal 型 (boolean または DOMString)

このプロパティの理想(目標)値。

WebIDLtypedef ([Clamp] unsigned long or ConstrainULongRange) ConstrainULong;
本仕様全体で、識別子 ConstrainULong([Clamp] unsigned long または ConstrainULongRange)型を指します。
WebIDLtypedef (double or ConstrainDoubleRange) ConstrainDouble;
本仕様全体で、識別子 ConstrainDouble(double または ConstrainDoubleRange)型を指します。
WebIDLtypedef (boolean or ConstrainBooleanParameters) ConstrainBoolean;
本仕様全体で、識別子 ConstrainBoolean(boolean または ConstrainBooleanParameters)型を指します。
WebIDLtypedef (DOMString or
         sequence<DOMString> or
         ConstrainDOMStringParameters) ConstrainDOMString;
本仕様全体で、識別子 ConstrainDOMString(DOMString または sequence<DOMString> または ConstrainDOMStringParameters)型を指します。
WebIDLtypedef (boolean or DOMString or ConstrainBooleanOrDOMStringParameters) ConstrainBooleanOrDOMString;
本仕様全体で、識別子 ConstrainBooleanOrDOMString(boolean または DOMString または ConstrainBooleanOrDOMStringParameters) 型を指します。

11.3 ケイパビリティ

Capabilitiesは1つ以上のキー・値ペアからなる辞書です。各キーは必須で制約可能プロパティであり、各値はそのプロパティに許可された値集合の部分集合でなければなりません。値の表現の正確な構文はプロパティの型によって異なります。Capabilities辞書は、constrainableオブジェクトに制約として適用できる制約可能プロパティを指定します。constrainableオブジェクトのCapabilitiesは、Webプラットフォームで定義されたプロパティの部分集合かつ値集合の部分集合であってよいことに注意してください。Capabilitiesはユーザーエージェントからアプリケーションへ返され、アプリケーションが指定することはできません。ただしアプリケーションはConstraintsによってユーザーエージェントが制約可能プロパティに選択するSettingsを制御できます。

Capabilities辞書の例を下に示します。この場合、constrainableオブジェクトは非常に限定的なケイパビリティしか持たない動画ソースです。

{
  frameRate: {min: 1.0, max: 60.0},
  facingMode: ['user', 'left']
}

次の例は、範囲値のケイパビリティは個々の制約可能プロパティごとであって組み合わせでないことを示しています。特に映像のwidth・heightについてはそれぞれ個別に範囲が報告されます。例では、constrainableオブジェクトが640x480と800x600だけ対応できる場合、返されるケイパビリティは次の通りです:

{
  width: {min: 640, max: 800},
  height: {min: 480, max: 600},
  aspectRatio: {min: 4/3, max: 4/3}
}

上記例では、aspectRatioが任意のwidth・heightの組み合わせを不可にすることが分かりますが、2種類以上の解像度が利用可能に見える点にも注意してください。

Constrainableパターンを利用する仕様は下記辞書をサブクラス化せず、独自定義を持つべきです。例はMediaTrackCapabilities参照。

テンプレート:
WebIDLdictionary Capabilities {};

11.4 設定値

Settingsは1つ以上のキー・値ペアを持つ辞書です。各キーは getCapabilities()で返され、そのプロパティが返されるオブジェクト型に定義されている場合に必須で含まれねばなりません(例:音声MediaStreamTrackには"width"プロパティはありません)。各キーは1つだけ値を持ち、その値はgetCapabilities()で定義された集合のメンバーでなければなりませんSettings辞書はユーザーエージェントがオブジェクトの制約可能プロパティに選択した実際の値を持ちます。値の構文はプロパティ型によって異なります。

現行標準ユーザーエージェントは本仕様で定義された制約可能プロパティすべてを必須でサポートしなければなりません。

Settings辞書の例を下に示します。この例は現実的ではありませんが、実際にはユーザーエージェントはこれ以外にも多くの制約可能プロパティをサポートする必要があります。

{
  frameRate: 30.0,
  facingMode: 'user'
}

Constrainableパターンを利用する仕様は下記辞書をサブクラス化せず、独自定義を持つべきです。例はMediaTrackSettings参照。

テンプレート:
WebIDLdictionary Settings {};

11.5 制約・ConstraintSet

WebIDLの制約により、Constrainableパターンを実装するインターフェイスは、ここで定義されたConstraintsやConstraintSetを単純にサブクラス化できません。代わりにこのパターンに従い独自定義を持つ必要があります。例はMediaTrackConstraints参照。

テンプレート:
WebIDLdictionary ConstraintSet {};

ConstraintSetの各メンバーは制約可能プロパティに対応し、そのプロパティの有効ケイパビリティ値集合の部分集合を指定します。ConstraintSetを適用するとユーザーエージェントは対応する制約可能プロパティの設定値を指定値または値範囲に制限します。特定のプロパティは基本Constraintsセットと高度ConstraintSetsリストの両方、また高度リスト内の各ConstraintSetに最大1回まで現れてよいです。

テンプレート:
WebIDLdictionary Constraints : ConstraintSet {
  sequence<ConstraintSet> advanced;
};

11.5.1 辞書 Constraints メンバー

advancedsequence<ConstraintSet>

これはユーザーエージェントが順に満たすよう必須で試みるConstraintSetのリストです。順序は重要です。特にapplyConstraintsの引数で渡された場合、ユーザーエージェントは指定順で満たすよう必須で試みます。たとえばC1・C2が個別には満たせても同時は不可な場合、このリストの先頭の方が満たされ、他は満たされません。ユーザーエージェントはリスト内全ConstraintSetに対し、満たせなくても必須で処理を試みます。例でC3がC1,C2後に指定されていれば、C2が不可でもC3には挑戦します。各ConstraintSet内のプロパティ名は1回しか現れませんが、複数のConstraintSetには同一名が現れても問題ありません。

12. 利用例

このサンプルコードはボタンを表示します。クリックされるとボタンが無効化され、ユーザーにストリーム提供のプロンプトが表示されます。ユーザーがストリーム(例:ページにローカルカメラへのアクセス許可)を提供し、その後ストリームを無効化(例:そのアクセス許可を取り消す)することで、ボタンを再び有効化できます。

<button id="startBtn">開始</button>
<script>
const startBtn = document.getElementById('startBtn');

startBtn.onclick = async () => {
  try {
    startBtn.disabled = true;
    const constraints = {
      audio: true,
      video: true
    };

    const stream = await navigator.mediaDevices.getUserMedia(constraints);

    for (const track of stream.getTracks()) {
      track.onended = () => {
        startBtn.disabled = stream.getTracks().some((t) => t.readyState == 'live');
      };
    }
  } catch (err) {
    console.error(err);
  }
};
</script>

この例は、ローカルビデオカメラで自分の写真を撮れるようにします。なおImage Capture仕様 [image-capture] を使うと、より簡単に同じことが実現できます。

<script>
window.onload = async () => {
  const video = document.getElementById('monitor');
  const canvas = document.getElementById('photo');
  const shutter = document.getElementById('shutter');

  try {
    video.srcObject = await navigator.mediaDevices.getUserMedia({video: true});

    await new Promise(resolve => video.onloadedmetadata = resolve);
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    document.getElementById('splash').hidden = true;
    document.getElementById('app').hidden = false;

    shutter.onclick = () => canvas.getContext('2d').drawImage(video, 0, 0);
  } catch (err) {
    console.error(err);
  }
};
</script>

<h1>スナップショット・キオスク</h1>

<section id="splash">
  <p id="errorMessage">読み込み中...</p>
</section>

<section id="app" hidden>
  <video id="monitor" autoplay></video>
  <button id="shutter">&#x1F4F7;</button>
  <canvas id="photo"></canvas>
</section>

13. 権限統合

本仕様は2つの強力な機能を定義しています。これらは name "camera" および "microphone" で識別されます。

本仕様は以下の型とアルゴリズムも定義します:

権限ディスクリプタ型
WebIDLdictionary CameraDevicePermissionDescriptor : PermissionDescriptor {
  boolean panTiltZoom = false;
};

権限はその種別のいずれか1つ以上のデバイスへのアクセスをカバーします。

ディスクリプタの意味論は、その種別の任意のデバイスへのアクセスを問い合わせることです。 したがって "camera" 権限のクエリが "granted" を返した場合、クライアントは許可プロンプト無しでカメラ1台にアクセスできることを知り、 "denied" が返れば カメラへのgetUserMediaリクエストは全て失敗することを知ります。

ユーザーエージェントが一部デバイスのみ許可済みとみなす場合でも、クエリは "granted" を返します。

ユーザーエージェントが全デバイス拒否とみなす場合は "denied" を返します。

{name: "camera", panTiltZoom: true}より強い {name: "camera", panTiltZoom: false} です。

注記

"granted" 権限はgetUserMedia成功を保証しません。 これはユーザーに許可プロンプトが表示されないことだけを意味します。他の要因(制約やカメラ使用中など)でもgetUserMediaは失敗し得ます。

権限取消アルゴリズム
これは デバイス権限取消アルゴリズムname を引数として渡した結果です。

14. Permissions Policy統合

本仕様は2つのポリシー制御機能 を、"camera""microphone"という文字列で識別します。 両者の既定許可リスト"self" です。

注記

documentpermissions policy により、そのdocument内のコンテンツが getUserMediaでカメラやマイクの要求が 許可されるかが決まります。いずれかがdocumentで無効化されていれば、そのdocument内のコンテンツは 許可されている ことにはならず、 getUserMediaでカメラやマイク要求は不可となります。 これはrequest permission to use アルゴリズムによって強制されます。

さらに、enumerateDevicesは documentで許可されているデバイスだけを列挙します。

15. プライバシーインジケーター要件

注記

この仕様はプライバシーインジケータ要件を、単一のMediaDevicesオブジェクト視点のアルゴリズムで表現します。 実装者は、iframe等でページ内に複数のMediaDevicesオブジェクトが共存可能な場合でも、インジケータ表示の統一原則に拡張することが推奨されます。

getUserMedia() が公開する各kindデバイスについて、

anyAccessibleを全any<kind>Accessible値の論理和と定義する。

anyLiveを全any<kind>Live値の論理和と定義する。

以下はユーザーエージェントに対する要件:

以下はユーザーエージェントへの推奨事項:

16. プライバシーおよびセキュリティの考慮事項

このセクションは規範的ではありません。新しい動作は指定せず、仕様の他箇所に既に記載されている内容をまとめたものです。

この仕様はWebプラットフォームを拡張し、メディア用入力デバイス(特にマイク・カメラ)を管理できるようにします。他のメディアデバイス(スピーカーやヘッドホン等の音声出力デバイス)の情報公開も可能性がありますが、その詳細は他仕様に委ねられます。 ユーザーのマイク・カメラから音声・映像を取得することは、個人識別情報をアプリケーションへ公開することになり、この仕様はそれを共有する前に明示的なユーザー同意の取得を要求します。

カメラやマイクのキャプチャ前は、アプリケーション(「ドライブバイWeb」)にはユーザーがカメラやマイクを持っているか(数は不明)だけ判別可能です。 デバイス識別子はユーザーをオリジン間で追跡するフィンガープリント用途には使えないよう設計されていますが、カメラ・マイクの有無がフィンガープリント面に2bit分追加されます。 オリジンごとの永続識別子deviceIdは他の永続ストレージ(例:Cookie)同様に扱うことが推奨されます。

カメラやマイクキャプチャが開始されると、本仕様は該当デバイスからメディアデータへのアクセス・利用方法を記述します。このデータは機密性が高く、デバイス利用中のインジケータ表示推奨ですが、許可性や利用中インジケータ自体はプラットフォーム依存です。

キャプチャ開始許可は都度許可・永続許可いずれも可能です。都度許可の場合、ユーザーがUIをブロックすることなく「NO」を選択できること(「永続NO」を選べるか、モーダル権限ダイアログを使わない等)が重要です。

カメラ・マイクキャプチャ開始後、Webドキュメントは利用可能な全メディアキャプチャデバイスとそのラベルを列挙できるようになります。この権限はドキュメントが閉じるまで継続し、永続化できません。 多くの場合ラベルはオリジン間でも安定しており、デバイスをオリジン・時間を越えて追跡する手段となり得ます。

注記

この仕様は利用中以外のデバイス情報も公開します。これは後方互換・レガシー理由によるものです。将来の仕様はこのモデルを使わず、 デバイス列挙設計原則に従ったベストプラクティスを推奨します。

キャプチャ開始済みまたは過去に行われたWebドキュメント、またはビュー内のWebドキュメントでは、 devicechangeイベントが、メディアデバイス新規追加・削除のたび、navigables やオリジンに同時に発火され得ます。ユーザーエージェントは、オリジン間の閲覧行動相関リスクを緩和するため、イベント発火タイミングをファジングしたり、Webドキュメントがビュー内になるまで発火を遅延することができます。

Webドキュメントがキャプチャデバイスのメディアストリームにアクセスできるようになると、デバイスの詳細情報(例:カメラの利用可能解像度等の動作ケイパビリティ)にもアクセス可能となります。これらのケイパビリティは多くの場合、閲覧セッションやオリジンを越えて永続的であり、デバイスの追跡手段となり得ます。

キャプチャデバイスの映像ストリームにアクセスすると、たとえばデッドピクセル検出等でそのデバイスを一意にフィンガープリントできる可能性が高いです。同様に音声ストリームへのアクセスは、ユーザーの位置情報(部屋単位や複数ユーザー同時在室等)を、環境音解析やデバイススピーカーから出力される固有音解析等でフィンガープリント可能性があります。音声・映像両方のユーザーレベル対策は、カメラ/マイクを物理的に塞ぐか、ユーザーエージェントのChrome制御で許可を取り消すことです。

制約を使うことで、getUserMedia呼び出しの失敗が、ユーザーにプロンプトせずデバイス情報を返す場合があり、フィンガープリント面が拡大します。ユーザーエージェントはこの追加面積を制限するため、失敗したgetUserMedia呼び出し頻度制限を考慮すべきです。

キャプチャ開始の永続許可が保存される場合、許可リストを分かりやすく表示し、ユーザーが容易に許可取り消しできることが重要です。

許可後、ユーザーエージェントはユーザーに次の2点が明確に分かるようにすることが望ましいです:

注記

永続許可を持つサイト開発者は、これらの許可が悪用されないよう注意すべきです。許可は[permissions] APIで取り消し可能です。

特に、認可済みメディアデバイスからの音声・映像ストリームを、第三者が選択できるエンドポイントへ自動送信可能にすべきではありません。

実際、サイトが https://webrtc.example.org/?call=user のようなURLで自動通話・音声映像送信を設定可能とした場合、次のような悪用が考えられます:

ユーザーがhttps://webrtc.example.org/へ永続許可を与えていた場合、リンクやリダイレクトで https://webrtc.example.org/?user=EvilSpy に誘導されることで、攻撃者EvilSpy へ音声・映像ストリームが送信されてしまう可能性があります。

17. 拡張性

このセクションは規範的ではありません。

将来この仕様の新バージョンが作られる可能性はありますが、他仕様が本仕様を基礎として新しいケイパビリティを定義する必要も予想されます。本セクションはそうした拡張仕様作成者への指針を示します。

WebIDL定義のインターフェイス・メソッド・属性は拡張可能です。拡張ポイントとしては新しいメディア種別や新しい制約可能プロパティの定義が考えられます。

17.1 音声・映像以外の新しいkindメディア定義

新しいメディア種別を定義するには最低限、

加えて、次も更新すべきです:

さらに、以下も含めるとよいでしょう:

17.2 新しい制約可能プロパティの定義

これには、該当プロパティのConstraints・Capabilities・Settings(3. 用語参照)がどのように動作するかを検討し、定義する必要があります。参考テキストは MediaTrackSupportedConstraintsMediaTrackCapabilitiesMediaTrackConstraintsMediaTrackSettings4.3.8 制約可能プロパティMediaStreamConstraintsです。

拡張仕様の作成者は、仕様リポジトリで仕様管理者に通知することが強く推奨されます。
今後の現行標準およびWebRTC Working Groupで作成される他仕様は、既知の拡張を考慮して利用衝突を減らすよう努めます。

17.3 MediaStreamTrack および MediaStream の新しいシンク定義

他仕様は MediaStream および MediaStreamTrack の新しいシンクを定義できます。最低限、新しい MediaStreamTrack のコンシューマは次を定義する必要があります:

17.4 source としての新しい MediaStreamTrack の定義

他仕様は MediaStreamTrack の新しい source を定義できます。 最低限、新しい MediaStreamTrack の source は以下を定義する必要があります:

A. 謝辞

編集者は、ワーキンググループのチェアとチームコンタクトである Harald Alvestrand、Stefan Håkansson、Erik Lagerway、Dominique Hazaël-Massieux のサポートに感謝します。本仕様の多くのテキストは以下の方々から提供されました: Jim Barnett、Harald Alvestrand、Travis Leithead、Josh Soref、Martin Thomson、 Jan-Ivar Bruaroey、Peter Thatcher、 Dominique Hazaël-Massieux、Stefan Håkansson。Dan Burnett は、仕様開発中に Voxeo と Aspect から受けた多大な支援に謝意を表します。

B. 参考文献

B.1 規範参考文献

[COOKIES]
HTTP State Management Mechanism. A. Barth. IETF. 2011年4月. 提案標準. URL: https://httpwg.org/specs/rfc6265.html
[dom]
DOM 標準. Anne van Kesteren. WHATWG. 現行標準. URL: https://dom.spec.whatwg.org/
[ECMA-262]
ECMAScript 言語仕様. Ecma International. URL: https://tc39.es/ecma262/multipage/
[HTML]
HTML 標準. Anne van Kesteren; Domenic Denicola; Dominic Farolino; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. 現行標準. URL: https://html.spec.whatwg.org/multipage/
[infra]
Infra 標準. Anne van Kesteren; Domenic Denicola. WHATWG. 現行標準. URL: https://infra.spec.whatwg.org/
[permissions]
Permissions。Marcos Caceres、Mike Taylor。W3C。2025年10月6日。W3C作業草案。URL: https://www.w3.org/TR/permissions/
[permissions-policy]
Permissions Policy. Ian Clelland. W3C. 2025年10月6日. W3C 作業草案. URL: https://www.w3.org/TR/permissions-policy-1/
[RFC2119]
RFCで要求レベルを示すためのキーワード. S. Bradner. IETF. 1997年3月. 最良現行慣行. URL: https://www.rfc-editor.org/rfc/rfc2119
[rfc4122]
ユニバーサルユニーク識別子 (UUID) URN 名前空間. P. Leach; M. Mealling; R. Salz. IETF. 2005年7月. 提案標準. URL: https://www.rfc-editor.org/rfc/rfc4122
[RFC8174]
RFC 2119 キーワードにおける大文字・小文字の曖昧性. B. Leiba. IETF. 2017年5月. 最良現行慣行. URL: https://www.rfc-editor.org/rfc/rfc8174
[WEBAUDIO]
Web Audio API. Paul Adenot; Hongchan Choi. W3C. 2021年6月17日. W3C 勧告. URL: https://www.w3.org/TR/webaudio-1.0/
[WEBIDL]
Web IDL 標準. Edgar Chen; Timothy Gu. WHATWG. 現行標準. URL: https://webidl.spec.whatwg.org/
[WEBRTC]
WebRTC: ブラウザのリアルタイム通信. Cullen Jennings; Jan-Ivar Bruaroey; Henrik Boström; Florent Castelli. W3C. 2025年3月13日. W3C 勧告. URL: https://www.w3.org/TR/webrtc/

B.2 参考情報

[image-capture]
MediaStream Image Capture. Miguel Casas-sanchez; Rijubrata Bhaumik. W3C. 2025年4月23日. W3C 作業草案. URL: https://www.w3.org/TR/image-capture/
[mediacapture-fromelement]
DOM要素からのメディアキャプチャ. Martin Thomson; Miguel Casas-sanchez; Emircan Uysaler. W3C. 2025年2月12日. W3C 作業草案. URL: https://www.w3.org/TR/mediacapture-fromelement/
[mediastream-recording]
MediaStream Recording. Miguel Casas-sanchez. W3C. 2025年4月17日. W3C 作業草案. URL: https://www.w3.org/TR/mediastream-recording/