WebRTC:ブラウザでのリアルタイム通信

W3C勧告

この文書の詳細
このバージョン:
https://www.w3.org/TR/2025/REC-webrtc-20250313/
最新公開バージョン:
https://www.w3.org/TR/webrtc/
最新編集者ドラフト:
https://w3c.github.io/webrtc-pc/
履歴:
https://www.w3.org/standards/history/webrtc/
コミット履歴
テストスイート:
https://github.com/web-platform-tests/wpt/tree/master/webrtc/
実装レポート:
https://w3c.github.io/webrtc-interop-reports/webrtc-pc-report.html
編集者:
Cullen Jennings (Cisco)
Florent Castelli (Google)
Henrik Boström (Google)
Jan-Ivar Bruaroey (Mozilla)
以前の編集者:
Adam Bergkvist (Ericsson) -
Daniel C. Burnett (Invited Expert) -
Anant Narayanan (Mozilla) -
Bernard Aboba (Microsoft Corporation) -
Taylor Brandstetter (Google) -
フィードバック:
GitHub w3c/webrtc-pc (プルリクエスト, 新しい課題, オープン課題)
public-webrtc@w3.org 件名 [webrtc] … メッセージトピック … (アーカイブ)
参加方法
メーリングリスト

参考: 翻訳


概要

本文書は、ECMAScript APIのセットをWebIDLで定義し、メディアや汎用アプリケーションデータを、適切なリアルタイムプロトコルを実装する他のブラウザやデバイスへ送受信できるようにします。本仕様は、IETF RTCWEBグループによるプロトコル仕様およびローカルメディアデバイスへのアクセスAPI仕様と連携して開発されています。

この文書のステータス

このセクションは、公開時点での文書のステータスを説明しています。現在のW3C公開文書および本技術レポートの最新版は W3C技術レポート一覧 https://www.w3.org/TR/ にてご覧いただけます。

本書には候補修正が含まれています。

関連するテストスイートは、 勧告として初めて公開された時点でAPIの実装レポート作成に使用されました。そのテストスイートはその後、提案および候補修正を統合するよう更新され、これら修正の実装状況に焦点を当てた最新の実装レポートが作成されました。二重実装された機能は提案修正として選定され、本勧告バージョンに完全に統合されています。

本文書はWeb Real-Time Communicationsワーキンググループによって 勧告プロセスに基づき勧告として公開されました。 候補修正を含み、前回の勧告以降、重要な変更や新機能が追加されています。

W3Cは本仕様のWeb標準としての広範な展開を推奨します。

W3C勧告は、十分な合意形成の後に W3Cおよびそのメンバーによって承認され、 ワーキンググループのメンバーによる ロイヤルティフリーライセンス のコミットメントが伴います。 今後の勧告更新で 新機能 が組み込まれる可能性があります。

候補追加箇所は文書内で明示されています。

候補修正箇所は文書内で明示されています。

本文書は W3C 特許ポリシー のもとで活動するグループによって作成されました。 W3C関連する特許開示の公開リスト を管理しており、そのページには特許開示方法も記載されています。個人が本仕様に関して 必須クレーム を含む特許について認識している場合は、 W3C特許ポリシー第6節 に従って情報開示を行う必要があります。

本文書は 2023年11月3日 W3Cプロセス文書 に準拠しています。

1. はじめに

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

本仕様で扱うHTMLにおけるピアツーピア通信およびビデオ会議には、いくつかの側面があります:

これらの機能に使用されるAPIを本文書で定義します。本仕様は、IETF RTCWEBグループが策定するプロトコル仕様や、WebRTCワーキンググループが策定するローカルメディアデバイスへのアクセスのAPI仕様 [GETUSERMEDIA] と連携して開発されています。システムの概要は [RFC8825] および [RFC8826] に記載されています。

2. 適合性

規範的でないと記載されたセクションだけでなく、本仕様内のすべての著作ガイドライン、図、例、注記も規範的ではありません。それ以外の本仕様の内容は規範的です。

本文書における MAYMUSTMUST NOTSHOULD というキーワードは、BCP 14 [RFC2119] [RFC8174] に記載された通りに解釈されます。これらは、すべて大文字で表記されている場合のみ、ここで示すように解釈されます。

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

アルゴリズムや特定の手順として表現された適合要件は、最終結果が等価である限り、どのような方法で実装しても構いません。(特に、本仕様で定義されているアルゴリズムは理解しやすくするためであり、性能を考慮したものではありません。)

本仕様で定義するAPIをECMAScriptで実装する場合、MUST Web IDL仕様 [WEBIDL] で定義されるECMAScriptバインディングに従って実装しなければなりません。本仕様はWeb IDL仕様とその用語を使用しています。

3. 用語

コールバックとしてイベントハンドラ用に使われる EventHandler インターフェイスは [HTML] で定義されています。

queue a tasknetworking task source の概念は [HTML] で定義されています。

fire an event の概念は [DOM] で定義されています。

eventevent handlersevent handler event types という用語は [HTML] で定義されています。

Performance.timeOrigin および Performance.now() は [hr-time] で定義されています。

シリアライズ可能オブジェクトserialization stepsdeserialization steps という用語は [HTML] で定義されています。

MediaStreamMediaStreamTrackMediaStreamConstraints という用語は [GETUSERMEDIA] で定義されています。なお、MediaStream は本書の 9.2 MediaStream で拡張されており、MediaStreamTrack9.3 MediaStreamTrack で拡張されています。

Blob という用語は [FILEAPI] で定義されています。

メディア記述 という用語は [RFC4566] で定義されています。

メディアトランスポート という用語は [RFC7656] で定義されています。

世代 という用語は [RFC8838] の Section 2 で定義されています。

統計オブジェクト監視オブジェクト という用語は [WEBRTC-STATS] で定義されています。

例外について言及する場合、throw および created という用語は [WEBIDL] で定義されています。

コールバック VoidFunction は [WEBIDL] で定義されています。

"throw" という用語は [INFRA] で規定されている通りに使われます:現在の処理手順を終了します。

Promiseに関連する fulfilledrejectedresolved、および settled という用語は [ECMASCRIPT-6.0] で定義されています。

AlgorithmIdentifier は [WebCryptoAPI] で定義されています。

注記

一般的なJavascript APIの原則が適用されます。これは run-to-completion の原則や、[API-DESIGN-PRINCIPLES] で定義されるデータレースなしの原則を含みます。つまり、タスク実行中は外部イベントがJavascriptアプリケーションから見える状態に影響しません。例えば、データチャネルで "send" を呼んだ際にバッファされたデータ量はJavascript実行中に増加し、パケット送信による減少はタスクチェックポイント後に見えるようになります。
ユーザーエージェントは、アプリケーションへ提示する値が一貫性を持つよう責任を持ちます。例えば getContributingSources()(同期関数)が返す値は、すべて同時に測定されたソースであることが保証されます。

4. ピアツーピア接続

4.1 はじめに

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

RTCPeerConnection インスタンスは、アプリケーションが他の RTCPeerConnection インスタンス(別のブラウザや必要なプロトコルを実装している他のエンドポイント)と ピアツーピア通信を確立することを可能にします。通信は、シグナリングチャネル(制御メッセージの交換、シグナリングプロトコルと呼ばれる)を介して調整されます。 シグナリングチャネルは何らかの方法で提供されますが、通常はサーバーを介したページ内スクリプトによって提供されます。例えば、 WebSocketXMLHttpRequest などです。

4.2 設定

4.2.1 RTCConfiguration 辞書

RTCConfiguration は、 RTCPeerConnection を介して確立または再確立される ピアツーピア通信の構成方法を指定するためのパラメータセットを定義します。

WebIDLdictionary RTCConfiguration {
  sequence<RTCIceServer> iceServers = [];
  RTCIceTransportPolicy iceTransportPolicy = "all";
  RTCBundlePolicy bundlePolicy = "balanced";
  RTCRtcpMuxPolicy rtcpMuxPolicy = "require";
  sequence<RTCCertificate> certificates = [];
  [EnforceRange] octet iceCandidatePoolSize = 0;
};
RTCConfiguration のメンバー
iceServerssequence<RTCIceServer>, デフォルト値は []

ICEが利用可能なサーバー(STUNやTURNサーバーなど)を記述するオブジェクトの配列です。 ICEサーバーの数が実装定義の制限を超えた場合、制限を超えたICEサーバーは無視されます。この実装定義の制限は 必須で少なくとも32でなければなりません。

iceTransportPolicyRTCIceTransportPolicy, デフォルト値は "all"

ICEエージェント が 使用できる候補を示します。

bundlePolicyRTCBundlePolicy, デフォルト値は "balanced"

ICE候補を収集する際に使用する メディアバンドルポリシー を示します。

rtcpMuxPolicyRTCRtcpMuxPolicy, デフォルト値は "require"

ICE候補を収集する際に使用する rtcp-muxポリシー を示します。

certificatessequence<RTCCertificate>, デフォルト値は []

RTCPeerConnection が認証に使用する証明書セットです。

このパラメータの有効な値は、 generateCertificate() 関数の呼び出しによって作成されます。

いずれのDTLS接続も1つの証明書のみを使用しますが、この属性によって異なるアルゴリズムをサポートする複数の証明書を指定できます。 実際に使用される証明書はDTLSハンドシェイクによって選択され、許可された証明書が確立されます。 RTCPeerConnection の実装が どの証明書を使用するか選択しますが、証明書の選択方法はこの仕様の範囲外です。

注記

既存の実装では最初の証明書のみが利用され、他の証明書は無視されます。

この値が存在しない場合、各 RTCPeerConnection インスタンスごとにデフォルトの証明書セットが生成されます。

このオプションによりアプリケーションはキーの継続性を確立できます。 RTCCertificate は [INDEXEDDB] に保存して再利用できます。保存と再利用により、 キー生成コストも回避できます。

この構成オプションの値は初期選択後に変更できません。

iceCandidatePoolSizeoctet, デフォルト値は 0

[RFC9429] (セクション 3.5.4. および セクション 4.1.1.) で定義されるプリフェッチされたICEプールのサイズです。

4.2.2 RTCIceServer 辞書

RTCIceServer 辞書は、 ICEエージェント がピアとの接続を確立するために利用できる STUNおよびTURNサーバーを記述するために使用されます。

WebIDLdictionary RTCIceServer {
  required (DOMString または sequence<DOMString>) urls;
  DOMString username;
  DOMString credential;
};
RTCIceServer のメンバー
urls(DOMString または sequence<DOMString>), 必須

[RFC7064] や [RFC7065]、 その他のURIタイプで定義されるSTUNまたはTURNのURIです。

usernameDOMString

この RTCIceServer オブジェクトが TURNサーバーを表す場合、この属性はそのTURNサーバーで使用するユーザー名を指定します。

credentialDOMString

この RTCIceServer オブジェクトが TURNサーバーを表す場合、この属性はそのTURNサーバーで使用する認証情報を指定します。

credential は [RFC5389]、 セクション10.2で説明されている長期認証用のパスワードを表します。

RTCIceServer オブジェクトの配列例:

[
  {urls: 'stun:stun1.example.net'},
  {urls: ['turns:turn.example.org', 'turn:turn.example.net'],
    username: 'user',
    credential: 'myPassword',
];

4.2.3 RTCIceTransportPolicy 列挙型

[RFC9429] (セクション 4.1.1.)で説明されているように、 iceTransportPolicy メンバーが RTCConfiguration に指定された場合、 ブラウザがアプリケーションに許可された候補を表面化するために使用する ICE候補ポリシー [RFC9429] (セクション 3.5.3.) を定義します。これらの候補のみが接続性チェックに使われます。

WebIDLenum RTCIceTransportPolicy {
  "relay",
  "all"
};
RTCIceTransportPolicy 列挙型説明
列挙値 説明
relay

ICEエージェント は TURNサーバーを通過する候補など、メディアリレー候補のみを使用します。

注記
これにより、リモートエンドポイントがユーザーのIPアドレスを知るのを防ぐことができます。これは特定のユースケースで望ましい場合があります。 例えば「通話」ベースのアプリケーションでは、被呼者が何らかの方法で同意するまで 発信者が被呼者のIPアドレスを知るのを防ぎたい場合などです。
all

この値が指定されている場合、ICEエージェント は あらゆる種類の候補を使用できます。

注記
実装はまだ独自の候補フィルタリングポリシーを使用して アプリケーションに公開されるIPアドレスを制限できます。 詳細は RTCIceCandidateaddress の説明を参照してください。

4.2.4 RTCBundlePolicy 列挙型

[RFC9429] (セクション 4.1.1.)で説明されているように、 バンドルポリシーは、リモートエンドポイントがバンドル対応していない場合に どのメディアトラックがネゴシエートされるかや、どんなICE候補が収集されるかに影響します。 リモートエンドポイントがバンドル対応している場合、すべてのメディアトラックとデータチャネルは同じトランスポートにバンドルされます。

WebIDLenum RTCBundlePolicy {
  "balanced",
  "max-compat",
  "max-bundle"
};
RTCBundlePolicy 列挙型説明
列挙値 説明
balanced 使用中の各メディアタイプ(音声、映像、データ)ごとにICE候補を収集します。 リモートエンドポイントがバンドル対応していない場合は、音声・映像トラックのみ 別々のトランスポートでネゴシエートします。
max-compat 各トラックごとにICE候補を収集します。 リモートエンドポイントがバンドル対応していない場合は、 すべてのメディアトラックを別々のトランスポートでネゴシエートします。
max-bundle 1つのトラックのみのICE候補を収集します。 リモートエンドポイントがバンドル対応していない場合は、1つのメディアトラックのみネゴシエートします。

4.2.5 RTCRtcpMuxPolicy 列挙型

[RFC9429] (セクション 4.1.1.)で説明されているように、 RTCRtcpMuxPolicy は非多重化RTCPをサポートするために どのICE候補が収集されるかに影響します。この仕様で定義される値は "require" のみです。

WebIDLenum RTCRtcpMuxPolicy {
  "require"
};
RTCRtcpMuxPolicy 列挙型説明
列挙値 説明
require RTPおよび多重化RTCPのためのみICE候補を収集します。 リモートエンドポイントがrtcp-mux非対応の場合、セッションネゴシエーションは失敗します。

4.2.6 オファー/アンサー オプション

これらの辞書はオファー/アンサー生成処理を制御するために使用できるオプションを記述します。

WebIDLdictionary RTCOfferAnswerOptions {};
辞書 RTCOfferAnswerOptions のメンバー
WebIDLdictionary RTCOfferOptions : RTCOfferAnswerOptions {
  boolean iceRestart = false;
};
辞書 RTCOfferOptions のメンバー
iceRestartboolean, デフォルト値は false

この辞書メンバーの値が trueの場合、または該当するRTCPeerConnection オブジェクトの [[LocalIceCredentialsToReplace]] スロットが空でない場合、生成される記述には現在の認証情報と異なるICE認証情報が含まれます (currentLocalDescription 属性のSDPで確認できます)。生成された記述を適用すると、[RFC5245] セクション9.1.1.1で説明されているようにICEが再起動されます。

この辞書メンバーの値が falseで、該当するRTCPeerConnection オブジェクトの [[LocalIceCredentialsToReplace]] スロットが空であり、 currentLocalDescription 属性に有効なICE認証情報がある場合、生成される記述には currentLocalDescription 属性の現在値と同じICE認証情報が含まれます。

注記

iceConnectionState が "failed" に遷移した時にICEの再起動を行うことが推奨されます。 アプリケーションはさらに、 iceConnectionState が "disconnected" に遷移した際に getStats などで数秒後送受信バイト数が増加しているかを測定するなど 他の情報源を使ってICE再起動が適切か判断することもできます。

RTCAnswerOptions 辞書は "answer" 型のセッション記述に固有のオプションを記述します (この仕様の現行標準バージョンではオプションはありません)。

WebIDLdictionary RTCAnswerOptions : RTCOfferAnswerOptions {};

4.3 状態定義

4.3.1 RTCSignalingState 列挙型

WebIDLenum RTCSignalingState {
  "stable",
  "have-local-offer",
  "have-remote-offer",
  "have-local-pranswer",
  "have-remote-pranswer",
  "closed"
};
RTCSignalingState 列挙型説明
列挙値 説明
stable オファー/アンサー交換処理が進行中ではありません。これは初期状態でもあり、ローカル・リモート記述が空の場合です。
have-local-offer "offer" 型のローカル記述が正しく適用されました。
have-remote-offer "offer" 型のリモート記述が正しく適用されました。
have-local-pranswer "offer" 型のリモート記述が正しく適用され、 "pranswer" 型のローカル記述が正しく適用されました。
have-remote-pranswer "offer" 型のローカル記述が正しく適用され、 "pranswer" 型のリモート記述が正しく適用されました。
closed RTCPeerConnection がクローズされており、 [[IsClosed]] スロットが true です。
signaling state transition diagram
1 非規範的なシグナリング状態遷移図。メソッド呼び出しは略記。

遷移例セット:

発信側の遷移:
着信側の遷移:

4.3.2 RTCIceGatheringState 列挙型

WebIDLenum RTCIceGatheringState {
  "new",
  "gathering",
  "complete"
};
RTCIceGatheringState 列挙型説明
列挙値 説明
new いずれかの RTCIceTransport が "new" の収集状態にあり、 かついずれのトランスポートも "gathering" 状態でない、 またはトランスポートが存在しない場合。
gathering いずれかの RTCIceTransport が "gathering" 状態にある場合。
complete 少なくとも1つの RTCIceTransport が存在し、 すべての RTCIceTransport が "complete" の収集状態にある場合。

対象となるトランスポートの集合は、 現在 RTCPeerConnectionトランシーバ集合および、 RTCPeerConnection[[SctpTransport]] 内部スロットが null でない場合に考慮されます。

4.3.3 RTCPeerConnectionState 列挙型

WebIDLenum RTCPeerConnectionState {
  "closed",
  "failed",
  "disconnected",
  "new",
  "connecting",
  "connected"
};
RTCPeerConnectionState 列挙型説明
列挙値 説明
closed [[IceConnectionState]] が "closed" です。
failed 前の状態が適用されず、または [[IceConnectionState]] が "failed" であるか、 いずれかの RTCDtlsTransport が "failed" 状態である場合。
disconnected 前の状態が適用されず、 [[IceConnectionState]] が "disconnected" である場合。
new 前の状態が適用されず、または [[IceConnectionState]] が "new" であり、すべての RTCDtlsTransport が "new" または "closed" 状態であるか、トランスポートが存在しない場合。
connected 前の状態が適用されず、 [[IceConnectionState]] が "connected" であり、すべての RTCDtlsTransport が "connected" または "closed" 状態である場合。
connecting 前の状態が適用されません。
注記

"connecting" 状態では、1つ以上の RTCIceTransport が "new" または "checking" 状態、 または1つ以上の RTCDtlsTransport が "new" または "connecting" 状態です。

対象となるトランスポートの集合は、 現在 RTCPeerConnectionトランシーバ集合および RTCPeerConnection[[SctpTransport]] 内部スロットが null でない場合に考慮されます。

4.3.4 RTCIceConnectionState 列挙型

WebIDLenum RTCIceConnectionState {
  "closed",
  "failed",
  "disconnected",
  "new",
  "checking",
  "completed",
  "connected"
};
RTCIceConnectionState 列挙型説明
列挙値 説明
closed RTCPeerConnection オブジェクトの [[IsClosed]] スロットが true である状態。
failed 以前の状態が該当せず、すべての RTCIceTransport が "failed" 状態にある場合。
disconnected 以前の状態が該当せず、いずれかの RTCIceTransport が "disconnected" 状態にある場合。
new 以前の状態が該当せず、すべての RTCIceTransport が "new" または "closed" 状態、もしくはトランスポートが存在しない場合。
checking 以前の状態が該当せず、いずれかの RTCIceTransport が "new" または "checking" 状態にある場合。
completed 以前の状態が該当せず、すべての RTCIceTransport が "completed" または "closed" 状態にある場合。
connected 以前の状態が該当せず、すべての RTCIceTransport が "connected", "completed" または "closed" 状態にある場合。

対象となるトランスポートの集合は、現在参照されている RTCPeerConnectionトランシーバ集合および RTCPeerConnection[[SctpTransport]] 内部スロットが null でない場合に限ります。

RTCIceTransport が シグナリングの結果として廃棄された場合(例: RTCP muxやバンドル)、または シグナリングの結果として生成された場合(例: 新しい メディア記述 の追加)には、 状態が直接別の状態に遷移することがあります。

4.4 RTCPeerConnection インターフェイス

[RFC9429] 現行標準仕様全体で RTCPeerConnection の動作詳細が記述されています。 必要に応じて [RFC9429] の個別サブセクションへの参照があります。

4.4.1 動作

new RTCPeerConnection(configuration) を呼び出すことで RTCPeerConnection オブジェクトが生成されます。

configuration.iceServers には ICEで利用するサーバーの情報が含まれます。アプリケーションは各タイプのサーバーを複数指定でき、 TURNサーバーはサーバー反射候補の収集目的でSTUNサーバーとしても利用できる 可能性があります

RTCPeerConnection オブジェクトは [[SignalingState]]、 集約状態として [[ConnectionState]][[IceGatheringState]][[IceConnectionState]] を持ちます。これらはオブジェクト生成時に初期化されます。

RTCPeerConnection のICEプロトコル実装は ICEエージェント [RFC5245] で表されます。 RTCPeerConnection の特定のメソッドは ICEエージェント とやり取りします。具体的には addIceCandidatesetConfigurationsetLocalDescriptionsetRemoteDescriptionclose です。これらのやり取りの詳細は本仕様および [RFC9429] で説明されています。 ICEエージェントRTCIceTransport の内部状態が変化した際に ユーザーエージェントへ通知も行います(5.6 RTCIceTransport インターフェイス 参照)。

このセクション記載のタスクのタスクソースは ネットワークタスクソース です。

注記

SDPネゴシエーションの状態は内部変数 [[SignalingState]][[CurrentLocalDescription]][[CurrentRemoteDescription]][[PendingLocalDescription]][[PendingRemoteDescription]] で表現されます。これらは setLocalDescription および setRemoteDescription 操作でのみ設定されます。さらに addIceCandidate 操作と 候補の公開 手順によっても変更されます。 いずれの場合も、5つの変数へのすべての変更はイベント発火やコールバック呼び出しの前に完了し、 変更は同時に可視化されます。

アンロードドキュメントのクリーンアップ手順の一つとして、次の手順を実行する:

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

  2. RTCPeerConnection オブジェクト connection について、 その 関連付けられたグローバルオブジェクトwindow である場合、 接続を終了するconnection および値 true で実行する。

4.4.1.1 コンストラクター

RTCPeerConnection.constructor() が呼び出されたとき、 ユーザーエージェントは 必須で以下の手順を実行する:

  1. 以下に列挙されたいずれかの手順が、ここで特に指定されていない理由で失敗した場合、 throwUnknownError を、message 属性には適切な説明を設定して送出する。

  2. connection を新しく作られた RTCPeerConnection オブジェクトとする。

  3. connection[[DocumentOrigin]] 内部スロットを持たせ、 関連付けられた設定オブジェクトorigin で初期化する。

  4. configuration をこのメソッドの第1引数とする。
  5. configurationcertificates の値が空でない場合、 certificates の各 certificate について以下の手順を実行する:

    1. certificate.expires の値が現在時刻未満の場合、 throwInvalidAccessError を送出する。

    2. certificate.[[Origin]]同一オリジン でない場合、 connection.[[DocumentOrigin]] と比較して、 throwInvalidAccessError を送出する。

    3. certificate を保存する。

  6. それ以外の場合は、新しい RTCCertificate インスタンスを この RTCPeerConnection インスタンスと共に生成し、保存する。 これは 非同期で実行される可能性がありcertificates の値は後続ステップでは undefined のままとなる。 [RFC8826] Section 4.3.2.3 に記載の通り、WebRTCは PKI証明書ではなく自己署名証明書を利用するため、有効期限チェックは鍵の無制限利用防止のためであり、追加の証明書チェックは不要である。

  7. connectionICEエージェント を初期化する。

  8. connection[[Configuration]] 内部スロットを持たせ、null で初期化する。 指定された構成を設定するconfiguration で実行する。

  9. connection[[IsClosed]] 内部スロットを持たせ、false で初期化する。

  10. connection[[NegotiationNeeded]] 内部スロットを持たせ、false で初期化する。

  11. connection[[SctpTransport]] 内部スロットを持たせ、null で初期化する。

  12. connection[[DataChannels]] 内部スロットを持たせ、空の 順序付き集合 で初期化する。

  13. connection[[Operations]] 内部スロットを持たせ、操作チェーンを表し、空のリストで初期化する。

  14. connection[[UpdateNegotiationNeededFlagOnEmptyChain]] 内部スロットを持たせ、false で初期化する。

  15. connection[[LastCreatedOffer]] 内部スロットを持たせ、"" で初期化する。

  16. connection[[LastCreatedAnswer]] 内部スロットを持たせ、"" で初期化する。

  17. connection[[EarlyCandidates]] 内部スロットを持たせ、空のリストで初期化する。

  18. connection[[SignalingState]] 内部スロットを持たせ、"stable" で初期化する。

  19. connection[[IceConnectionState]] 内部スロットを持たせ、"new" で初期化する。

  20. connection[[IceGatheringState]] 内部スロットを持たせ、"new" で初期化する。

  21. connection[[ConnectionState]] 内部スロットを持たせ、"new" で初期化する。

  22. connection[[PendingLocalDescription]] 内部スロットを持たせ、null で初期化する。

  23. connection[[CurrentLocalDescription]] 内部スロットを持たせ、null で初期化する。

  24. connection[[PendingRemoteDescription]] 内部スロットを持たせ、null で初期化する。

  25. connection[[CurrentRemoteDescription]] 内部スロットを持たせ、null で初期化する。

  26. connection[[LocalIceCredentialsToReplace]] 内部スロットを持たせ、空集合で初期化する。

  27. connection を返す。

4.4.1.2 非同期操作のチェーン

RTCPeerConnection オブジェクトは 操作チェーン [[Operations]] を持ち、 チェーン内の非同期操作が同時に一つだけ実行されることを保証します。 以前の呼び出しの返されたPromiseがまだ確定していない状態で後続呼び出しが行われた場合、 それらはチェーンに追加され、すべての前の呼び出しが完了しPromiseが確定したときに実行されます。

操作のチェーンRTCPeerConnection オブジェクトの 操作チェーン に追加するには、以下の手順を実行します:

  1. connectionRTCPeerConnection オブジェクトとする。

  2. connection.[[IsClosed]]true の場合は、reject された 新規 作成済み InvalidStateError でPromiseを返す。

  3. operation をチェーンする操作とする。

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

  5. [[Operations]]operation を追加する。

  6. [[Operations]] の長さが 1 の場合、 operation を実行する。

  7. operation が返すPromiseの fulfillment または rejection 時に、以下を実行する:

    1. connection.[[IsClosed]]true ならこれらの手順を中止する。

    2. operation が返すPromiseが値で fulfilled された場合、 p をその値で fulfill する。

    3. operation が返すPromiseが値で reject された場合、 p をその値で reject する。

    4. pfulfillment または rejection 時に以下を実行する:

      1. connection.[[IsClosed]]true ならこれらの手順を中止する。

      2. [[Operations]] の最初の要素を削除する。

      3. [[Operations]] が空でない場合、 その先頭要素の操作を実行し、これらの手順を中止する。

      4. connection.[[UpdateNegotiationNeededFlagOnEmptyChain]]false ならこれらの手順を中止する。

      5. connection.[[UpdateNegotiationNeededFlagOnEmptyChain]]false に設定する。

      6. ネゴシエーション必要フラグを更新するconnection で実行する。

  8. p を返す。

4.4.1.3 接続状態の更新

RTCPeerConnection オブジェクトは 集約された [[ConnectionState]] を持ちます。 RTCDtlsTransport の状態が変化したとき、 ユーザーエージェントは必須で次の手順をキューイングします:

  1. connection を、状態が変化した RTCPeerConnection オブジェクトと関連付けられた RTCDtlsTransport オブジェクトとする。

  2. connection.[[IsClosed]]true なら、これらの手順を中止する。

  3. newState を、RTCPeerConnectionState 列挙型で記述された新しい状態値とする。

  4. connection.[[ConnectionState]]newState と等しい場合、これらの手順を中止する。

  5. connection.[[ConnectionState]]newState に設定する。

  6. connectionstatechange イベントを connection に発火する。

4.4.1.4 セッション記述の設定

ローカルセッション記述を設定する descriptionRTCPeerConnection オブジェクト connection 上で行うには、 セッション記述を設定するdescriptionconnection、追加値 false で実行する。

リモートセッション記述を設定する descriptionRTCPeerConnection オブジェクト connection 上で行うには、 セッション記述を設定するdescriptionconnection、追加値 true で実行する。

セッション記述を設定する descriptionRTCPeerConnection オブジェクト connection 上で、remote ブール値を指定して実行するには、以下の手順を行う:

  1. 新しい Promise である p を生成する。

  2. もし description.type が "rollback" であり、 connection.[[SignalingState]] が "stable"、 "have-local-pranswer"、 または "have-remote-pranswer" のいずれかであるなら、reject し、新たに 作成 した InvalidStateError を用いて p を拒否し、これらの手順を中止する。

  3. 並行して[RFC9429] (section 5.5. および section 5.6.) に記載されているとおりに description を適用する処理を開始し、以下の追加制約を適用する:

    1. どの "RtpTransceivers" が存在するかに関する唯一の信頼できる情報源として jsepSetOfTransceivers を使用し、その「mid プロパティ」として [[JsepMid]] 内部スロットを用いる。

    2. 候補修正 5:管理上禁止された候補に対する ICE 収集および接続性チェックを禁止する (PR #2708)

      remotefalse で、これにより [RFC9429] (section 5.9.) の ICE 候補収集処理がトリガーされる場合、ICE AgentMUST NOT 管理上 禁止された 候補を収集してはならない。

    3. 候補修正 5:管理上禁止された候補に対する ICE 収集および接続性チェックを禁止する (PR #2708)

      remotetrue で、これにより [RFC9429] (section 5.10.) の ICE 接続性チェックがトリガーされる場合、ICE AgentMUST NOT 管理上 禁止された 候補への接続を試みてはならない。

    4. remotetrue の場合、安定状態にあるかのように後続のオファーチェックを実行することで、間にアンサーが適用されたかのように連続するオファーを検証する。

    5. description の適用がトランシーバ transceiver の変更につながり、かつ transceiver.[[Sender]].[[SendEncodings]] が空ではなく、description を処理することで得られるエンコーディングと等しくない場合、description を適用する処理は失敗する。本仕様は遠隔から開始される RID 再ネゴシエーションを許可しない。

       
    6. description を適用する処理がいかなる理由で失敗した場合、ユーザーエージェントは以下の手順を実行するタスクをキューに入れなければならない MUST:

      1. connection.[[IsClosed]]true なら、これらの手順を中止する。

      2. description.type が、 [RFC9429] (section 5.5. および section 5.6.) に記載されている現在の connection.[[SignalingState]] に対して不正であるなら、reject し、新たに 作成 した InvalidStateError を用いて p を拒否し、これらの手順を中止する。

      3. description の内容が有効な SDP 構文でない場合、reject し、 pRTCErrorerrorDetail を "sdp-syntax-error" に設定し、sdpLineNumber 属性を構文エラーが検出された SDP の行番号に設定したもの)で拒否し、これらの手順を中止する。

      4. remotetrue で、 connectionRTCRtcpMuxPolicyrequire であり、かつその記述が RTCP mux を使用していないなら、reject し、新たに 作成 した InvalidAccessError を用いて p を拒否し、これらの手順を中止する。

      5. 上述のとおり RID の再ネゴシエーションを試みた記述である場合、reject し、新たに 作成 した InvalidAccessError を用いて p を拒否し、これらの手順を中止する。

      6. description の内容が不正である場合、reject し、新たに 作成 した InvalidAccessError を用いて p を拒否し、これらの手順を中止する。

      7. その他すべてのエラーについては、reject し、新たに 作成 した OperationError を用いて p を拒否する。

    7. description が正常に適用された場合、ユーザーエージェントは次の手順を実行するタスクをキューに入れなければならない MUST:

      1. connection.[[IsClosed]]true なら、これらの手順を中止する。

      2. remotetruedescription の型が "offer" の場合で、かつ description を適用する過程で connection 上の addTrack() メソッドが一つでも成功していたなら、これらの手順を中止し、それらが事前に成功していたかのように処理を最初からやり直し、追加のトランシーバをその処理に含める。

      3. connection に関連付けられた setParameters メソッドによるいずれかの Promise が settled でないなら、これらの手順を中止し、最初からやり直す。

      4. description の型が "offer" で、 connection.[[SignalingState]] が "stable" なら、 connectionset of transceivers 内の各 transceiver について以下を行う:

        1. transceiver.[[Sender]].[[LastStableStateSenderTransport]]transceiver.[[Sender]].[[SenderTransport]] に設定する。

        2. 候補修正 13:rollback で sRD(simulcastOffer) により上書きされた rid 無し encoding を復元する (PR #2797)

          もし transceiver.[[Sender]].[[SendEncodings]].length が 1 で、その唯一のエンコーディングが contains により rid メンバーを持たないなら、 transceiver.[[Sender]].[[LastStableRidlessSendEncodings]]transceiver.[[Sender]].[[SendEncodings]] に設定する。 そうでなければ transceiver.[[Sender]].[[LastStableRidlessSendEncodings]]null に設定する。

        3. transceiver.[[Receiver]].[[LastStableStateReceiverTransport]]transceiver.[[Receiver]].[[ReceiverTransport]] に設定する。

        4. transceiver.[[Receiver]].[[LastStableStateAssociatedRemoteMediaStreams]]transceiver.[[Receiver]].[[AssociatedRemoteMediaStreams]] に設定する。

        5. transceiver.[[Receiver]].[[LastStableStateReceiveCodecs]]transceiver.[[Receiver]].[[ReceiveCodecs]] に設定する。

      5. remotefalse の場合、以下のいずれかの手順を実行する:

        1. description の型が "offer" の場合、 connection.[[PendingLocalDescription]]description から構築した新しい RTCSessionDescription オブジェクトに設定し、 connection.[[SignalingState]] を "have-local-offer" に設定し、early candidates を解放する

        2. description の型が "answer" の場合、これは offer/answer ネゴシエーションを完了する。 connection.[[CurrentLocalDescription]]description から構築した新しい RTCSessionDescription オブジェクトに設定し、 connection.[[CurrentRemoteDescription]]connection.[[PendingRemoteDescription]] に設定する。さらに connection.[[PendingRemoteDescription]]connection.[[PendingLocalDescription]]null に設定する。 connection.[[LastCreatedOffer]] および connection.[[LastCreatedAnswer]]"" に設定し、 connection.[[SignalingState]] を "stable" に設定し、early candidates を解放する。最後に connection.[[LocalIceCredentialsToReplace]] 内の ICE クレデンシャルのいずれも description に存在しないなら、 connection.[[LocalIceCredentialsToReplace]] を空集合に設定する。

        3. description の型が "pranswer" の場合、 connection.[[PendingLocalDescription]]description から構築した新しい RTCSessionDescription オブジェクトに設定し、 connection.[[SignalingState]] を "have-local-pranswer" に設定し、 early candidates を解放する

      6. そうでなければ(remotetrue の場合)以下のいずれかの手順を実行する:

        1. description の型が "offer" の場合、 connection.[[PendingRemoteDescription]] 属性を description から構築した新しい RTCSessionDescription オブジェクトに設定し、 connection.[[SignalingState]] を "have-remote-offer" に設定する。

        2. description の型が "answer" の場合、これは offer/answer ネゴシエーションを完了する。 connection.[[CurrentRemoteDescription]]description から構築した新しい RTCSessionDescription オブジェクトに設定し、 connection.[[CurrentLocalDescription]]connection.[[PendingLocalDescription]] に設定する。さらに connection.[[PendingRemoteDescription]] および connection.[[PendingLocalDescription]]null に設定し、 connection.[[LastCreatedOffer]] および connection.[[LastCreatedAnswer]]"" に設定し、 connection.[[SignalingState]] を "stable" に設定する。最後に connection.[[LocalIceCredentialsToReplace]] 内の ICE クレデンシャルのいずれも新しく設定された connection.[[CurrentLocalDescription]] に存在しないなら、 connection.[[LocalIceCredentialsToReplace]] を空集合に設定する。

        3. description の型が "pranswer" の場合、 connection.[[PendingRemoteDescription]]description から構築した新しい RTCSessionDescription オブジェクトに設定し、 connection.[[SignalingState]] を "have-remote-pranswer" に設定する。

      7. description の型が "answer" で、 [RFC8841] の セクション 10.3 および 10.4 に定義される既存の SCTP アソシエーションのクローズを開始するなら、 connection.[[SctpTransport]] の値を null に設定する。

      8. trackEventInitsmuteTracksaddListremoveList および errorList を空リストとする。

      9. description の型が "answer" または "pranswer" の場合、以下の手順を実行する:

        1. description が新しい SCTP アソシエーションの確立を開始するなら([RFC8841] セクション 10.3 および 10.4)、 RTCSctpTransport を作成 し、 初期状態を "connecting" として、その結果を [[SctpTransport]] スロットに割り当てる。そうでなく既に SCTP アソシエーションが確立されていて max-message-size SDP 属性が更新された場合は、 データの最大メッセージサイズを更新するconnection.[[SctpTransport]] に対して行う。

        2. description が SCTP トランスポートの DTLS ロールをネゴシエートする場合、nullid を持つ各 RTCDataChannelchannel)について以下を行う:

          1. [RFC8832] に従って channel に新しい ID を割り当てる。利用可能な ID が生成できない場合、 channel.[[ReadyState]] を "closed" に設定し、 channnelerrorList に追加する。
      10. description の型が "rollback" でない場合、以下の手順を実行する:

        1. remotefalse の場合、 description 内の各 media description について以下を実行する:

          候補修正 26:createAnswer() の encodings と sLD(answer) における SendEncodings の剪定 (PR #2801)
          1. その media description がまだ associatedRTCRtpTransceiver オブジェクトを持っていない場合、以下を行う:

            1. transceiver をその RTCRtpTransceivermedia description を生成したもの)とする。

            2. transceiver.[[Mid]]transceiver.[[JsepMid]] に設定する。

            3. transceiver.[[Stopped]]true なら、これらのサブ手順を中止する。

            4. その media description が [RFC8843] に従って既存の media media transport を使用すると示されているなら、 transport をその RTP/RTCP コンポーネントを表す RTCDtlsTransport オブジェクトとする。

            5. そうでなければ、transport を新たに作成された RTCDtlsTransport オブジェクトとし、そこに新しい基盤の RTCIceTransport を持たせる。

            6. transceiver.[[Sender]].[[SenderTransport]]transport に設定する。

            7. transceiver.[[Receiver]].[[ReceiverTransport]]transport に設定する。

          2. transceiver をその RTCRtpTransceiver であり、 associated である media description に対応するものとする。

          3. transceiver.[[Stopped]]true なら、これらのサブ手順を中止する。

          4. directionRTCRtpTransceiverDirection 値で、media media description から示される方向を表すものとする。

          5. direction が "sendrecv" または "recvonly" の場合、 transceiver.[[Receptive]]true に、それ以外は false に設定する。

          6. transceiver.[[Receiver]].[[ReceiveCodecs]]description が受信のためにネゴシエートし、かつユーザーエージェントが現在受信可能なコーデックに設定する。

            Note

            direction が "sendonly" または "inactive" の場合、receiver は何も受信する準備がなく、リストは空になる。

          7. description の型が "answer" または "pranswer" の場合、以下の手順を実行する:

            1. もし transceiver. [[Sender]].[[SendEncodings]] .length が 1 より大きいなら、以下を実行する:

              1. description が以前にネゴシエートされた層を全て欠いている場合、 transceiver.[[Sender]].[[SendEncodings]] 内の最初以外の全辞書を削除し、次の手順をスキップする。

              2. description が以前にネゴシエートされた層の一部を欠いている場合、 欠落する層に対応する辞書を transceiver.[[Sender]].[[SendEncodings]] から削除する。

            2. transceiver.[[Sender]].[[SendCodecs]]description が送信のためにネゴシエートし、かつユーザーエージェントが現在送信可能なコーデックに設定し、 transceiver.[[Sender]].[[LastReturnedParameters]]null に設定する。

            3. direction が "sendonly" または "inactive" で、 transceiver.[[FiredDirection]] が "sendrecv" または "recvonly" の場合、以下を実行する:

              1. Set the associated remote streamstransceiver.[[Receiver]]、 空リスト、もう一つの空リスト、そして removeList を与えて実行する。

              2. process the removal of a remote remote trackmedia descriptiontransceiver および muteTracks を与えて実行する。

            4. transceiver.[[CurrentDirection]]transceiver.[[FiredDirection]]direction に設定する。

        2. そうでなければ(remotetrue の場合)description 内の各 media description について以下を実行する:

          候補修正 12:encoding.active と simulcast ~rid の相互作用の削除 (PR #2754)
          候補修正 14:RTCTransceiver.direction をオファーとアンサーでのローカルの希望を反映するように (PR #2759)
          候補修正 22:リモート offer における rid 剪定をクライアント answer で許可 (PR #2758)
          候補修正 37:rid 不一致で sRD(offer) を失敗させずユニキャストで応答 (PR #2794)
          候補修正 25:proposedSendEncodings 内の重複 rid を削除 (PR #2800)
          候補修正 27:コンマ区切り rid 代替を無視 (PR #2813)
          1. description の型が "offer" であり、その media descriptionシミュルキャスト受信要求を含む場合、simulcast 属性で指定された rid 値の順序を用いて各層に対する RTCRtpEncodingParameters 辞書を作成し、対応する rid value値(コンマ区切り代替がある場合は先頭のみ使用)に従って rid メンバーを設定し、 sendEncodingsproposedSendEncodingsそのリスト 作成した辞書を含むリスト とする。そうでなければ sendEncodings proposedSendEncodings リストとする。

          2. proposedSendEncodings 内の各エンコーディング encoding について逆順に、encodingridproposedSendEncodings 内の他のエンコーディングと一致する場合、 proposedSendEncodings から encoding を削除する。

          3. supportedEncodings を実装がサポートできる最大エンコーディング数とする。sendEncodingsproposedSendEncodings の長さが supportedEncodings を超える場合、 sendEncodingsproposedSendEncodings を切り詰めて長さを supportedEncodings にする。
          4. sendEncodingsproposedSendEncodings が空でないなら、各 encoding の 各エンコーディングの scaleResolutionDownBy2^(length of sendEncodingsproposedSendEncodings - encoding index - 1) に設定する。
          5. [RFC8829RFC9429] (section 5.10.) に記述されているように、既存の RTCRtpTransceiver オブジェクト transceiver を見つけ、 media description を表す。

          6. 適切な transceiver が見つかり(transceiver が設定済み)、 sendEncodingsproposedSendEncodings が空でない場合、 transceiver.[[Sender]].[[SendEncodings]]sendEncodings に設定し、 transceiver.[[Sender]].[[LastReturnedParameters]]null に設定する。 以下を実行する:

            1. もし transceiver.[[Sender]].[[SendEncodings]] の長さが 1 で、その唯一のエンコーディングが contains により rid メンバーを持たない場合、 transceiver.[[Sender]].[[SendEncodings]]proposedSendEncodings に設定し、 transceiver.[[Sender]].[[LastReturnedParameters]]null に設定する。

          7. 適切な transceiver が見つからない(transceiver が未設定)の場合、以下を行う:

            1. RTCRtpSender を作成sender とし、 media media description から sendEncodingsproposedSendEncodings を用いる。

            2. RTCRtpReceiver を作成receiver とし、 media media description を用いる。

            3. RTCRtpTransceiver を作成 し、 senderreceiver、および RTCRtpTransceiverDirection 値 "recvonly" を指定し、その結果を transceiver とする。

            4. transceiverconnectionset of of transceivers に追加する。

          8. description の型が "answer" または "pranswer" で、 transceiver. [[Sender]].[[SendEncodings]] .length が 1 より大きい場合、以下を行う:

            1. description がシミュルキャストをサポートまたは要求しないことを示す、または description が以前にネゴシエートされた層を全て欠いている 場合、 transceiver.[[Sender]].[[SendEncodings]] 内の最初以外の全辞書を削除し、これらのサブ手順を中止する。

            2. descriptionrejects 欠いている いずれかの offered 以前にネゴシエートされた 層を 示すなら 欠いているなら 対応する 欠落する 層に対応する辞書を transceiver.[[Sender]].[[SendEncodings]] から削除する。

            3. 各 simulcast layer の一時停止状態を [RFC8853] に示されるとおりに更新し、 該当する辞書の active メンバーを未停止なら true、停止なら false に設定する。

          9. transceiver.[[Mid]]transceiver.[[JsepMid]] に設定する。

          10. directionRTCRtpTransceiverDirection 値で、 media media description の方向をこのピア視点で送受信方向を反転させ表現するものとする。media description が拒否されているなら、 direction を "inactive" に設定する。

          11. direction が "sendrecv" または "recvonly" の場合、 msids を media description が transceiver.[[Receiver]].[[ReceiverTrack]] に関連付けるべきであると示す MSID のリストとする。そうでなければ msids を空リストとする。

            Note
            media description が拒否された場合、 msids は空リストとなる。
          12. Process remote trackstransceiverdirectionmsidsaddListremoveList、および trackEventInits を与えて実行する。

          13. transceiver.[[Receiver]].[[ReceiveCodecs]]description が受信のためにネゴシエートし、ユーザーエージェントが現在受信準備のできているコーデックに設定する。

          14. description の型が "answer" または "pranswer" の場合、以下を実行する:

            1. transceiver.[[Sender]].[[SendCodecs]]description が送信のためにネゴシエートし、ユーザーエージェントが現在送信可能なコーデックに設定する。

            2. transceiver.[[CurrentDirection]] および transceiver.[[Direction]] direction に設定する。

            3. transportRTCDtlsTransport オブジェクトとし、これは media media transport の RTP/RTCP コンポーネントを表し、 transceiverassociatedmedia description により [RFC8843] に従って用いられる。

            4. transceiver.[[Sender]].[[SenderTransport]]transport に設定する。

            5. transceiver.[[Receiver]].[[ReceiverTransport]]transport に設定する。

            6. transport[[IceRole]] を [RFC8445] の規則に従って設定する。

              Note
              ここで適用される [RFC8445] の規則:
              • [[IceRole]]unknown でない場合、変更しない。
              • description がローカル offer の場合、 controlling に設定する。
              • description がリモート offer で a=ice-lite を含むなら、 [[IceRole]]controlling に設定する。
              • description がリモート offer で a=ice-lite を含まないなら、 [[IceRole]]controlled に設定する。
              これにより [[IceRole]] は最初の offer 処理後に必ず値を持つ。
          15. media description が拒否され、 transceiver.[[Stopped]]false の場合、 stop the the RTCRtpTransceiver transceiver を実行する。

      11. そうでなければ(description の型が "rollback" の場合) 以下の手順を実行する:

        1. pendingDescriptionconnection.[[PendingLocalDescription]] または connection.[[PendingRemoteDescription]] のどちらか(null でない方)とする。

        2. connectionset of transceivers 内の各 transceiver について以下を行う:

          1. transceiverpendingDescription が設定される前に associatedmedia description を持っていなかった場合、それを解除し、 transceiver.[[JsepMid]]transceiver.[[Mid]]null に設定する。

          2. transceiver.[[Sender]].[[SenderTransport]]transceiver.[[Sender]].[[LastStableStateSenderTransport]] に設定する。

          3. 候補修正 13:rollback で sRD(simulcastOffer) により上書きされた rid 無し encoding を復元 (PR #2797)

            もし transceiver.[[Sender]].[[LastStableRidlessSendEncodings]]null でなく、 transceiver.[[Sender]].[[SendEncodings]] 内のどれかの encoding が rid メンバーを持つなら、 transceiver.[[Sender]].[[SendEncodings]]transceiver.[[Sender]].[[LastStableRidlessSendEncodings]] に設定する。

          4. transceiver.[[Receiver]].[[ReceiverTransport]]transceiver.[[Receiver]].[[LastStableStateReceiverTransport]] に設定する。

          5. transceiver.[[Receiver]].[[ReceiveCodecs]]transceiver.[[Receiver]].[[LastStableStateReceiveCodecs]] に設定する。

          6. connection.[[SignalingState]] が "have-remote-offer" である場合、以下のサブ手順を実行する:

            1. msidstransceiver.[[Receiver]].[[LastStableStateAssociatedRemoteMediaStreams]] 内のすべての id のリスト(存在しなければ空リスト)とする。

            2. Process remote trackstransceivertransceiver.[[CurrentDirection]]msidsaddListremoveList、および trackEventInits を与えて実行する。

          7. transceiverpendingDescription 設定時に作成され、 これまで addTrack() により track が一度も接続されていないなら、 stop the RTCRtpTransceiver transceiver を実行し、 connectionset of transceivers から削除する。

        3. connection.[[PendingLocalDescription]] および connection.[[PendingRemoteDescription]]null に設定し、 connection.[[SignalingState]] を "stable" に設定する。

      12. description の型が "answer" の場合、以下の手順を実行する:

        1. connectionset of transceivers 内の各 transceiver について以下を実行する:

          1. transceiverstopped であり、かつ m= セクションに associated され、 その m= セクションが connection.[[CurrentLocalDescription]] または connection.[[CurrentRemoteDescription]] で拒否されている場合、 transceiverconnectionset of transceivers から削除する。

      13. connection.[[SignalingState]] が 現在 "stable" であるなら、以下の手順を実行する:

        1. 以前の手順で set of transceivers から 削除された任意の transceiver について、 そのトランスポート (transceiver.[[Sender]].[[SenderTransport]] または transceiver.[[Receiver]].[[ReceiverTransport]]) がまだ閉じておらず、かつ非 stopped な transceiver から参照されていないなら、 その RTCDtlsTransport と 関連付けられた RTCIceTransport を閉じる。 これによりキューされたタスクでこれらのオブジェクト上のイベントが発火する。

        2. Candidate Addition 49:RTCRtpEncodingParameters に codec を追加 (PR #2985)

          connectionset of transceivers 内の各 transceiver について:

          1. codecstransceiver.[[Sender]].[[SendCodecs]] とする。

          2. codecs が空リストでない場合:

            1. transceiver.[[Sender]].[[SendEncodings]] 内の各 encoding について、 encoding.codeccodecs のどのエントリとも codec dictionary match アルゴリズム( ignoreLevelstrue に設定)で一致しない場合、 remove encoding.codec を行う。

        3. Clear the negotiation-needed flag を行い、 update the negotiation-needed flag を実行する。

      14. 上記で connection.[[SignalingState]] が変更された場合、fire an event で 名称 signalingstatechange のイベントを connection に対して発火する。

      15. errorList 内の各 channel について、 fire an event 名称 error を発火し、RTCErrorEvent インターフェイスを用いて errorDetail 属性を "data-channel-failure" に設定して channel 上で発火する。

      16. muteTracks 内の各 track について、 set the muted state を実行し、 その track の状態を true にする。

      17. removeList 内の各 streamtrack の組に対して、 remove the track trackstream から削除する。

      18. addList 内の各 streamtrack の組に対して、 add the track trackstream に追加する。

      19. trackEventInits 内の各エントリ entry について、 fire an event 名称 trackRTCTrackEvent インターフェイスで発火し、 その receiver 属性を entry.receiver に、 track 属性を entry.track に、 streams 属性を entry.streams に、 そして transceiver 属性を entry.transceiver に初期化して connection オブジェクト上で発火する。

      20. Resolve pundefined で解決する。

  4. p を返す。

4.4.1.5 構成を設定する

構成を設定するために configuration を用いる場合、次の手順を実行する:

  1. connection を対象の RTCPeerConnection オブジェクトとする。

  2. oldConfigconnection.[[Configuration]] とする。

  3. もし oldConfignull でないなら、以下の手順を実行し、そのいずれかが失敗した場合は 例外を投げ InvalidModificationError を送出する:

    1. configuration.certificates の長さが oldConfig.certificates の長さと異なるなら失敗とする。

    2. index を 0 とする。

    3. indexconfiguration.certificates の長さより小さい間、次を実行する:

      1. configuration.certificatesindex 位置の値で表される ECMAScript オブジェクトが、 oldConfig.certificatesindex 位置の値で表される ECMAScript オブジェクトと同一でなければ、失敗とする。

      2. index を 1 増加させる。

    4. configuration.bundlePolicy の値が oldConfig.bundlePolicy と異なるなら失敗とする。

    5. configuration.rtcpMuxPolicy の値が oldConfig.rtcpMuxPolicy と異なるなら失敗とする。

    6. configuration.iceCandidatePoolSize の値が oldConfig.iceCandidatePoolSize と異なり、かつ setLocalDescription が既に呼び出されている場合、失敗とする。

  4. iceServersconfiguration.iceServers とする。

  5. iceServers をサポートされる最大要素数まで切り詰める。

  6. iceServers の各 server について、 次を実行する:

    1. urlsserver.urls とする。

    2. もし urls が文字列なら、urls をその文字列のみからなるリストに設定する。

    3. もし urls が空なら、"SyntaxError" の DOMException送出する

    4. urls 内の各 url について、ICE サーバー URL を検証する アルゴリズムを url に対して実行する。

  7. ICE AgentICE トランスポート設定configuration.iceTransportPolicy の値に設定する。[RFC9429] (セクション 4.1.18.) に定義されるように、新しい ICE トランスポート設定 が既存の設定を変更しても、 次の収集フェーズまで何も行われない。スクリプトが即座の反映を望む場合、ICE リスタートを行うべきである。

  8. ICE Agent の事前取得された ICE 候補プールサイズ[RFC9429] (セクション 3.5.4. および セクション 4.1.1.) に従い、 configuration.iceCandidatePoolSize の値に設定する。新しい ICE 候補プールサイズ が既存の設定を変更する場合、 これは [RFC9429] (セクション 4.1.18.) に定義されるように、新しいプール候補の即時収集、もしくは既存のプール候補の破棄を引き起こし得る。

  9. ICE AgentICE サーバーリストiceServers に設定する。

    [RFC9429] (セクション 4.1.18.) に定義されるように、新しいサーバーのリストが ICE Agent の既存の ICE サーバーリスト を置き換えても、 次の収集フェーズまで何も行われない。スクリプトが即座の反映を望む場合、ICE リスタートを行うべきである。 しかし ICE 候補プール のサイズが 0 でない場合、 既存のプール候補は破棄され、新しいサーバーから新しい候補が収集される。

  10. configuration[[Configuration]] 内部スロットに格納する。

ICE サーバー URL を検証する url について、次の手順を実行する:

Candidate Correction 33:ICE サーバー URL を解析するために URL 仕様を使用する (PR #2853, PR #2996, PR #2998)
  1. url を [RFC3986] に定義された 一般的な URI 構文でパースし scheme name を得る。 [RFC3986] の構文に基づく パースに失敗したら throw SyntaxError を送出する。 もし scheme name がブラウザに実装されていなければ throw NotSupportedError を送出する。 もし scheme nameturn または turns で、 [RFC7065] に定義された構文による url のパースが失敗したら throw SyntaxError を送出する。 もし scheme namestun または stuns で、 [RFC7064] に定義された構文による url のパースが失敗したら throw SyntaxError を送出する。

  2. parsedURLパース した url の結果とする。

  3. 以下のいずれかの条件が当てはまる場合、 throw し、 "SyntaxError" の DOMException を送出する:

    • parsedURL が failure である
    • parsedURLscheme"stun", "stuns", "turn", "turns" のいずれでもない
    • parsedURLopaque path が存在しない
    • parsedURLopaque path が 1 つ以上の "/" または "@" を含む
    • parsedURLfragment が non-null である
    • parsedURLscheme"stun" または "stuns" であり、かつ parsedURLquery が non-null である
  4. もし parsedURLscheme がユーザーエージェントに実装されていなければ、 throwNotSupportedError を送出する。

  5. hostAndPortURL を、 "https://"parsedURLpath を連結したものを パース した結果とする。

  6. hostAndPortURL が failure なら、 throw し "SyntaxError" の DOMException を送出する。

    もし hostAndPortURLpath, username, または password が non-null であれば throw し "SyntaxError" の DOMException を送出する。

    Note

    "stun" および "stuns" スキームについては、 [RFC7064] セクション 3.1 を検証する。
    "turn" および "turns" スキームについては、これおよび以下の手順が [RFC7065] セクション 3.1 を検証する。

  7. もし parsedURLquery が non-null で、かつ parsedURLquery"transport=udp" または "transport=tcp" のいずれとも異なる場合、 throw し "SyntaxError" の DOMException を送出する。

  8. もし scheme nameparsedURLschemeturn"turn" または turnsまたは "turns" であり、 server.username または server.credential省略されている 存在しない なら、 throwInvalidAccessError を送出する

  9. もし scheme nameturn または turns で、 server.credentialType が "password" で、 かつ server.credentialDOMString でないなら throwInvalidAccessError を送出する。

4.4.2 インターフェイス定義

本節で提示される RTCPeerConnection インターフェイスは、この仕様全体を通じて複数の partial interface により拡張される。特に、RTP メディア API の節では、MediaStreamTrack オブジェクトを送受信するための API が追加される。

WebIDL[Exposed=Window]
interface RTCPeerConnection : EventTarget  {
  constructor(optional RTCConfiguration configuration = {});
  Promise<RTCSessionDescriptionInit> createOffer(optional RTCOfferOptions options = {});
  Promise<RTCSessionDescriptionInit> createAnswer(optional RTCAnswerOptions options = {});
  Promise<undefined> setLocalDescription(optional RTCLocalSessionDescriptionInit description = {});
  readonly attribute RTCSessionDescription? localDescription;
  readonly attribute RTCSessionDescription? currentLocalDescription;
  readonly attribute RTCSessionDescription? pendingLocalDescription;
  Promise<undefined> setRemoteDescription(RTCSessionDescriptionInit description);
  readonly attribute RTCSessionDescription? remoteDescription;
  readonly attribute RTCSessionDescription? currentRemoteDescription;
  readonly attribute RTCSessionDescription? pendingRemoteDescription;
  Promise<undefined> addIceCandidate(optional RTCIceCandidateInit candidate = {});
  readonly attribute RTCSignalingState signalingState;
  readonly attribute RTCIceGatheringState iceGatheringState;
  readonly attribute RTCIceConnectionState iceConnectionState;
  readonly attribute RTCPeerConnectionState connectionState;
  readonly attribute boolean? canTrickleIceCandidates;
  undefined restartIce();
  RTCConfiguration getConfiguration();
  undefined setConfiguration(optional RTCConfiguration configuration = {});
  undefined close();
  attribute EventHandler onnegotiationneeded;
  attribute EventHandler onicecandidate;
  attribute EventHandler onicecandidateerror;
  attribute EventHandler onsignalingstatechange;
  attribute EventHandler oniceconnectionstatechange;
  attribute EventHandler onicegatheringstatechange;
  attribute EventHandler onconnectionstatechange;

  // レガシーインターフェイス拡張
  // 本節のメソッドをサポートするかどうかは任意である。
  // これらのメソッドをサポートする場合
  // 定義されたとおりに実装しなければならない
  // 「Legacy Interface Extensions」節で
  Promise<undefined> createOffer(RTCSessionDescriptionCallback successCallback,
                            RTCPeerConnectionErrorCallback failureCallback,
                            optional RTCOfferOptions options = {});
  Promise<undefined> setLocalDescription(RTCLocalSessionDescriptionInit description,
                                    VoidFunction successCallback,
                                    RTCPeerConnectionErrorCallback failureCallback);
  Promise<undefined> createAnswer(RTCSessionDescriptionCallback successCallback,
                             RTCPeerConnectionErrorCallback failureCallback);
  Promise<undefined> setRemoteDescription(RTCSessionDescriptionInit description,
                                     VoidFunction successCallback,
                                     RTCPeerConnectionErrorCallback failureCallback);
  Promise<undefined> addIceCandidate(RTCIceCandidateInit candidate,
                                VoidFunction successCallback,
                                RTCPeerConnectionErrorCallback failureCallback);
};
属性
localDescription の型は RTCSessionDescription, readonly, nullable

localDescription 属性は [[PendingLocalDescription]]null でない場合それを返し、そうでない場合は [[CurrentLocalDescription]] を返さなければならない (MUST)。

注意: [[CurrentLocalDescription]].sdp[[PendingLocalDescription]].sdp は、対応する sdp 値を setLocalDescription 呼び出しに渡した文字列と逐語的に同一である必要はない (SDP がパースされ再整形されることや、ICE candidate が追加されることがある)。

currentLocalDescription の型は RTCSessionDescription, readonly, nullable

currentLocalDescription 属性は [[CurrentLocalDescription]] を返さなければならない (MUST)。

これは RTCPeerConnection が最後に stable 状態へ遷移した時に 正常にネゴシエートされたローカル記述と、その offer または answer が作成されて以後 ICE Agent によって生成されたすべてのローカル candidate を合わせたものを表す。

pendingLocalDescription の型は RTCSessionDescription, readonly, nullable

pendingLocalDescription 属性は [[PendingLocalDescription]] を返さなければならない (MUST)。

これはネゴシエーション中のローカル記述と、その offer または answer が作成されて以後 ICE Agent により生成された すべてのローカル candidate を含んだものを表す。RTCPeerConnection が stable 状態にある場合、この値は null である。

remoteDescription の型は RTCSessionDescription, readonly, nullable

remoteDescription 属性は [[PendingRemoteDescription]]null でない場合それを返し、そうでない場合は [[CurrentRemoteDescription]] を返さなければならない (MUST)。

注意: [[CurrentRemoteDescription]].sdp[[PendingRemoteDescription]].sdp は、対応する sdp 値を setRemoteDescription 呼び出しに渡した文字列と逐語的に同一である必要はない (SDP がパースされ再整形されることや、ICE candidate が追加されることがある)。

currentRemoteDescription の型は RTCSessionDescription, readonly, nullable

currentRemoteDescription 属性は [[CurrentRemoteDescription]] を返さなければならない (MUST)。

これは RTCPeerConnection が最後に stable 状態へ遷移した時に 正常にネゴシエートされた最新のリモート記述と、その offer または answer が作成されて以後 addIceCandidate() により供給されたすべてのリモート candidate を合わせたものを表す。

pendingRemoteDescription の型は RTCSessionDescription, readonly, nullable

pendingRemoteDescription 属性は [[PendingRemoteDescription]] を返さなければならない (MUST)。

これはネゴシエーション中のリモート記述と、その offer または answer が作成されて以後 addIceCandidate() によって供給されたすべてのリモート candidate を含むものを表す。RTCPeerConnection が stable 状態にある場合、この値は null である。

signalingState の型は RTCSignalingState, readonly

signalingState 属性は RTCPeerConnection オブジェクトの [[SignalingState]] を返さなければならない (MUST)。

iceGatheringState の型は RTCIceGatheringState, readonly

iceGatheringState 属性は RTCPeerConnection オブジェクトの [[IceGatheringState]] を返さなければならない (MUST)。

iceConnectionState の型は RTCIceConnectionState, readonly

iceConnectionState 属性は RTCPeerConnection オブジェクトの [[IceConnectionState]] を返さなければならない (MUST)。

connectionState の型は RTCPeerConnectionState, readonly

connectionState 属性は RTCPeerConnection オブジェクトの [[ConnectionState]] を返さなければならない (MUST)。

canTrickleIceCandidates の型は boolean, readonly, nullable

canTrickleIceCandidates 属性はリモートピアが trickle ICE candidate [RFC8838] を受け入れ可能かどうかを示す。この値はリモート記述が [RFC9429] (section 4.1.17.) に定義されるとおり trickle ICE サポートを示しているかどうかに基づき決定される。 setRemoteDescription の完了前は、この値は null である。

onnegotiationneeded の型は EventHandler
このイベントハンドラのイベント型は negotiationneeded である。
onicecandidate の型は EventHandler
このイベントハンドラのイベント型は icecandidate である。
onicecandidateerror の型は EventHandler
このイベントハンドラのイベント型は icecandidateerror である。
onsignalingstatechange の型は EventHandler
このイベントハンドラのイベント型は signalingstatechange である。
oniceconnectionstatechange の型は EventHandler
このイベントハンドラのイベント型は iceconnectionstatechange である
onicegatheringstatechange の型は EventHandler
このイベントハンドラのイベント型は icegatheringstatechange である。
onconnectionstatechange の型は EventHandler
このイベントハンドラのイベント型は connectionstatechange である。
メソッド
createOffer

createOffer メソッドは SDP のブロブを生成し、そこにはサポートされているセッション構成 (この RTCPeerConnection にアタッチされたローカル MediaStreamTrack の記述、実装がサポートする codec/RTP/RTCP 能力、 さらに ICE agent と DTLS 接続のパラメータを含む) を持つ RFC 3264 の offer が含まれる。 options 引数を与えて生成される offer を追加制御できる。

システムが限られたリソース (例: デコーダ数が有限) の場合、 createOffer はシステムの現在の状態を反映する offer を返す必要がある。これは setLocalDescription がそれらのリソース取得を試みる際に成功するためである。セッション記述は、返された Promise の fulfillment コールバックの終了時点までは setLocalDescription でエラーを引き起こすことなく使用可能でなければならない (MUST)。

SDP の生成は [RFC9429] に記述された offer 生成手順に従わなければならない (MUST)。 ただし、このケースではユーザーエージェントは stopping トランシーバを RFC9429 の目的において stopped とみなさなければならない (MUST)。

offer であるため、生成された SDP はセッションがサポートまたは優先する codec/RTP/RTCP 能力の完全な集合を含む (answer は使用する特定のネゴシエート済みサブセットのみを含むのとは対照)。セッション確立後に createOffer が呼び出された場合、 createOffer は現在のセッションと互換性のある offer を生成し、トラックの追加や削除など最後の完全な offer-answer 交換以降に行われた変更を取り込む。 変更がない場合、offer には現在のローカル記述の能力と、更新された offer でネゴシエート可能な追加の能力が含まれる。

生成された SDP には ICE agentusernameFragmentpassword および ICE オプション ([RFC5245] セクション 14 で定義) が含まれ、さらにエージェントによって収集済みのローカル candidate が含まれる場合がある。

certificates の値 ( configuration 内 ) はアプリケーションが RTCPeerConnection に対して設定した証明書を提供する。これらの証明書とデフォルト証明書は証明書フィンガープリント集合を生成するために用いられ、 そのフィンガープリントが SDP 構築に使用される。

SDP を生成する過程は基盤となるシステムのメディア能力のサブセットを公開し、デバイス上の一般に持続的でクロスオリジンな情報を提供する。 これはアプリケーションのフィンガープリンティング表面を増やす。プライバシー重視の文脈では、ブラウザは共通サブセットの能力にのみ一致する SDP を生成するなどの緩和策を検討できる。 (This is a fingerprinting vector.)

メソッドが呼ばれたとき、ユーザーエージェントは次の手順を実行しなければならない (MUST):

  1. connection を、そのメソッドが呼び出された RTCPeerConnection オブジェクトとする。

  2. もし connection.[[IsClosed]]true なら、Promise を新規に rejected 状態で返し、 新たに 作成された InvalidStateError を与える。

  3. chaining の結果を、 creating an offerconnection で行った結果と connectionoperations chain に対して実行したものとして返す。

connection を与えて create an offer するには次の手順を行う:

  1. もし connection.[[SignalingState]] が "stable" でも "have-local-offer" でもないなら、 新たに 作成された InvalidStateError で Promise を rejected にして返す。

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

  3. 並行して (In parallel)in-parallel steps to create an offerconnectionp を与えて開始する。

  4. p を返す。

connection と Promise p を与えた in-parallel steps to create an offer は次の通り:

  1. もし connection が証明書集合なしで構築され、かつ証明書がまだ生成されていないなら、 生成されるまで待機する。

  2. オファラーのシステム状態 を検査し、 offer 生成に必要な現在利用可能なリソースを確定する。 これは [RFC9429] (セクション 4.1.8.) に記述されている。

  3. この検査が何らかの理由で失敗した場合、 reject p し、新たに 作成された OperationError を与えてこれらの手順を中止する。

  4. タスクをキューし、connectionp を与えて final steps to create an offer を実行する。

connection と Promise p を与えた final steps to create an offer は次の通り:

  1. もし connection.[[IsClosed]]true なら、これらの手順を中止する。

  2. もし connection が変更され、その結果として オファラーのシステム状態 の追加検査が必要になったなら、 並行して 再び in-parallel steps to create an offerconnectionp を与えて開始し、これらの手順を中止する。

    Note
    例えば、createOffer が audio のみの RTCRtpTransceiver だけが connection に追加された状態で呼ばれたが、 in-parallel steps to create an offer の実行中に video RTCRtpTransceiver が追加され、追加のビデオリソース検査が必要になる場合が該当する。
  3. 以前の検査で得た情報、connection の現在の状態、およびその RTCRtpTransceiver 群の状態を用いて、 [RFC9429] (セクション 5.2.) に記述されるように SDP offer sdpString を生成する。

    1. [RFC8843] (セクション 7) に記載のとおり、バンドル ( RTCBundlePolicy 参照) が使用される場合、 BUNDLE グループをネゴシエートするために offerer tagged m= セクションを選択する必要がある。 ユーザーエージェントは MUSTset of transceivers における最初の非 stopped トランシーバに対応する m= セクションを offerer tagged m= セクションとして選ぶ。 これによりリモートエンドポイントは SDP をパースせずにどのトランシーバが offerer tagged m= セクションか予測できる。

    2. filteredCodecs を、 transceiver.[[PreferredCodecs]] に以下のフィルタを適用した結果とする。フィルタはコーデックの順序を変更してはならない (MUST NOT)。

      1. kindtransceiver[[Receiver]][[ReceiverTrack]]kind とする。

      2. もし transceiver.direction が "sendonly" または "sendrecv" の場合、 kindlist of implemented send codecs に含まれていないコーデックを除外する。 その際 codec dictionary match アルゴリズムを ignoreLevelstrue に設定して使用する。

      3. もし transceiver.direction が "recvonly" または "sendrecv" の場合、 kindlist of implemented receive codecs に含まれていないコーデックを除外する。 その際 codec dictionary match アルゴリズムを ignoreLevelstrue に設定して使用する。

      media descriptionassociated なトランシーバ transceivercodec preferences は、 filteredCodecs が空でない場合その値であり、 空の場合は未設定 (unset) とされる。

    3. もし [[SendEncodings]] スロットの長さが RTCRtpSender において 1 より大きいなら、 その [[SendEncodings]] に与えられた 各エンコーディングについて、対応するメディアセクションに a=rid send 行を追加し、さらに encodings フィールドで与えられた順に RID を列挙する a=simulcast:send 行を追加する。RID の制限は設定しない。

      Note

      [RFC8853] セクション 5.2 は a=simulcast 行の RID の順序が提案される優先順を示唆することを規定する。 ブラウザがすべてのエンコーディングを送信しないことを決定した場合、リスト最後のエンコーディングから送信を停止すると予想される。

  4. offer を新たに作成した RTCSessionDescriptionInit 辞書とし、その type メンバを文字列 "offer" に初期化し、 sdp メンバを sdpString に初期化する。

  5. [[LastCreatedOffer]] 内部スロットを sdpString に設定する。

  6. Resolve poffer で行う。

createAnswer

createAnswer メソッドは、リモート構成内のパラメータと互換性があり、セッションに対してサポートされる構成を持つ [SDP] の answer を生成する。 createOffer と同様に、 返される SDP のブロブには、この RTCPeerConnection にアタッチされたローカル MediaStreamTrack の記述、 このセッションについてネゴシエートされた codec/RTP/RTCP オプション、 そして ICE Agent によって収集済みのあらゆる candidate が含まれる。 options 引数を与えることで生成される answer への追加制御を行える。

createOffer と同様に、 返される記述はシステムの現在の状態を反映することが望ましい (SHOULD)。 セッション記述は、返された Promise の fulfillment コールバックの終了時点までは エラーを引き起こすことなく setLocalDescription で使用可能でなければならない (MUST)。

answer であるため、生成された SDP には、対応する offer と共にメディアプレーンをどのように確立するかを指定する 特定の codec/RTP/RTCP 構成が含まれる。SDP の生成は [RFC9429] に記述された answer 生成の適切な手順に従わなければならない (MUST)。

生成された SDP にはまた、ICE agentusernameFragmentpassword、および ICE オプション ([RFC5245] セクション 14) が含まれ、 さらにエージェントが収集したローカル candidate を含む場合がある。

certificates の値 ( configuration 内 ) は、 アプリケーションが RTCPeerConnection のために設定した証明書を提供する。 これらの証明書と任意のデフォルト証明書を用いて証明書フィンガープリント集合を生成し、 そのフィンガープリントは SDP の構築に利用される。

answer は [RFC9429] (section 4.1.10.1.) に記述されるように、 type を "pranswer" に設定することで 暫定 (provisional) としてマークできる。

メソッドが呼ばれたとき、ユーザーエージェントは以下の手順を実行しなければならない (MUST):

  1. connection を、そのメソッドが呼び出された RTCPeerConnection オブジェクトとする。

  2. もし connection.[[IsClosed]]true なら、新規に 作成された InvalidStateErrorrejected された Promise を返す。

  3. chaining の結果を返す。 これは creating an answerconnection で実行した結果を connectionoperations chain に連結したものである。

connection を与えた create an answer の手順:

  1. もし connection.[[SignalingState]] が "have-remote-offer" でも "have-local-pranswer" でもないなら、 新規に 作成された InvalidStateErrorrejected された Promise を返す。

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

  3. 並行して (In parallel)in-parallel steps to create an answerconnectionp を与えて開始する。

  4. p を返す。

connection と Promise p を与えた in-parallel steps to create an answer は次の通り:

  1. もし connection が証明書集合なしで構築され、証明書がまだ生成されていなければ、 生成されるまで待機する。

  2. アンサラーのシステム状態 を検査し、 answer 生成に必要な現在利用可能なリソースを特定する。 これは [RFC9429] (section 4.1.9.) に記述される。

  3. この検査が何らかの理由で失敗した場合、 reject p し、新たに 作成された OperationError を与えて手順を中止する。

  4. タスクをキューし、 final steps to create an answerp を与えて実行する。

Promise p を与えた final steps to create an answer は次の通り:

  1. もし connection.[[IsClosed]]true なら、これらの手順を中止する。

  2. もし connection が変更され、 アンサラーのシステム状態 の追加検査が必要になった場合、 並行して in-parallel steps to create an answerconnectionp を与えて再実行し、これらの手順を中止する。

    Note
    例えば createAnswer が、ある RTCRtpTransceiver の direction が "recvonly" のときに呼ばれたが、 in-parallel steps to create an answer の実行中にその direction が "sendrecv" に変更され、 追加のビデオエンコードリソース検査が必要になった場合などが該当する。
  3. 以前の検査で得られた情報、および connection とその RTCRtpTransceiver 群の現在の状態から、 [RFC9429] (section 5.3.) に記述されるように SDP answer sdpString を生成する。

    Candidate Correction 26:createAnswer() の encodings と SendEncodings を sLD(answer) で刈り込む。 (PR #2801)
    Candidate Correction 27:RID のカンマ区切り代替を無視する。 (PR #2813)
    1. m= セクションの関連付けられたトランシーバの codec preferences は、 RTCRtpTransceiver.[[PreferredCodecs]] に以下のフィルタを適用した値 (空であれば設定されていないとみなす) とされる:

      1. direction が "sendrecv" の場合、 RTCRtpSender.getCapabilities(kind).codecsRTCRtpReceiver.getCapabilities(kind).codecs の積集合に含まれないコーデックを除外する。

      2. direction が "sendonly" の場合、 RTCRtpSender.getCapabilities(kind).codecs に含まれないコーデックを除外する。

      3. direction が "recvonly" の場合、 RTCRtpReceiver.getCapabilities(kind).codecs に含まれないコーデックを除外する。

      フィルタリングはコーデック優先順位の順序を変更してはならない (MUST NOT)。

    2. もし [[SendEncodings]] スロットの長さが RTCRtpSender で 1 より大きいなら、[[SendEncodings]] の各エンコーディングについて 対応するメディアセクションに a=rid send 行を追加し、 さらに encodings フィールドに与えられた順序で RID を列挙する a=simulcast:send 行を追加する。RID 制限は設定しない。

    3. filteredCodecs を、 transceiver.[[PreferredCodecs]] に以下のフィルタを適用した結果とする。フィルタリングはコーデック優先順位の順序を変更してはならない (MUST NOT):

      1. kindtransceiver[[Receiver]][[ReceiverTrack]]kind とする。

      2. もし transceiver.direction が "sendonly" または "sendrecv" の場合、 kindlist of implemented send codecs に含まれないコーデックを除外する。 その際 codec dictionary match アルゴリズムを ignoreLevelstrue に設定して使用する。

      3. もし transceiver.direction が "recvonly" または "sendrecv" の場合、 kindlist of implemented receive codecs に含まれないコーデックを除外する。 その際 codec dictionary match アルゴリズムを ignoreLevelstrue に設定して使用する。

      media descriptionassociated なトランシーバ transceivercodec preferences は、 filteredCodecs が空でない場合その値、 空の場合は未設定 (unset) とされる。

    4. これが受信側 simulcast を提案する offer に対する answer である場合、 simulcast の受信を要求する各メディアセクションについて次を実行する:

      1. a=simulcast 属性が RID のカンマ区切り代替を含む場合、 最初のもの以外をすべて削除する。

      2. a=simulcast 属性に同名の RID が複数ある場合、 最初のもの以外をすべて削除する。RID 制限は設定しない。

      3. 対応するトランシーバの [[Sender]].[[SendEncodings]] に存在しない RID を、 answer のメディアセクションから除外する。

      Note

      setRemoteDescription(offer) が sender の proposed envelope を確立すると、 sender の [[SendEncodings]] は "have-remote-offer" で更新され、 rollback へ曝される。しかし一度 sender の simulcast envelope が確立されると、 その後の sender の [[SendEncodings]] の刈り込み (pruning) は、 この answer が setLocalDescription により設定されたときに行われる。

  4. answer を新たに作成した RTCSessionDescriptionInit 辞書とし、その type メンバを文字列 "answer" に初期化し、 sdp メンバを sdpString に初期化する。

  5. [[LastCreatedAnswer]] 内部スロットを sdpString に設定する。

  6. Resolve panswer で行う。

setLocalDescription

setLocalDescription メソッドは RTCPeerConnection に対し、与えられた RTCLocalSessionDescriptionInit をローカル記述として適用するよう指示する。

この API はローカルメディア状態を変更する。アプリケーションがあるメディアフォーマットから互換性のない別のフォーマットへ変更する提案を行いたいシナリオを正常に扱うために、 RTCPeerConnection は、最終的な answer を受信するまで現在と pending の両方のローカル記述(例: 両方の記述に存在するコーデックのサポート)を同時に利用可能な形で保持できなければならない (MUST)。最終的な answer を受信した時点で、 RTCPeerConnection は pending のローカル記述を完全に採用するか、リモート側が変更を拒否した場合は現在の記述へロールバックできる。

description を引数に渡すことは任意である。省略された場合、 setLocalDescription は必要に応じて暗黙的に create an offer または create an answer を行う。 [RFC9429] (section 5.4.) に記載されているように、SDP を含む記述が渡された場合、その SDP は createOffer または createAnswer から返された時点から変更されていてはならない。

メソッドが呼び出されたとき、ユーザーエージェントは以下の手順を実行しなければならない (MUST):

  1. description をメソッドの最初の引数とする。

  2. connection を、そのメソッドが呼び出された RTCPeerConnection オブジェクトとする。

  3. sdpdescription.sdp とする。

  4. 次の手順を connectionoperations chain に対して chaining した結果を返す:

    1. typedescription.type が存在すればその値、存在せず かつ connection.[[SignalingState]] が "stable"、 "have-local-offer"、 もしくは "have-remote-pranswer" のいずれかであれば "offer"、 それ以外の場合は "answer" とする。

    2. もし type が "offer" で、 sdp が空文字列でなく かつ connection.[[LastCreatedOffer]] と等しくないなら、新たに 作成された InvalidModificationErrorrejected された Promise を返し、これらの手順を中止する。

    3. もし type が "answer" または "pranswer" で、 sdp が空文字列でなく かつ connection.[[LastCreatedAnswer]] と等しくないなら、新たに 作成された InvalidModificationErrorrejected された Promise を返し、これらの手順を中止する。

    4. もし sdp が空文字列かつ type が "offer" なら、次のサブ手順を実行する:

      1. sdpconnection.[[LastCreatedOffer]] の値に設定する。

      2. もし sdp が空文字列であるか、またはもはや offerer's system state を正確に表していないなら、 pcreating an offerconnection で実行した結果とし、 p への reacting の結果を返す。その fulfillment 手順では最初の引数が示す sets the local session description を行う。

    5. もし sdp が空文字列で、 type が "answer" または "pranswer" の場合、次のサブ手順を実行する:

      1. sdpconnection.[[LastCreatedAnswer]] の値に設定する。

      2. もし sdp が空文字列であるか、またはもはや answerer's system state を正確に表していないなら、 pcreating an answerconnection で実行した結果とし、 p への reacting の結果を次の fulfillment 手順で返す:

        1. answer をこれらの fulfillment 手順への最初の引数とする。

        2. setting the local session description{type, answer.sdp} で示されるものについて実行した結果を返す。

    6. {type, sdp} で示される setting the local session description の結果を返す。

Note

[RFC9429] (section 5.9.) に記載されているように、このメソッドを呼び出すことは ICE Agent による ICE candidate 収集プロセスをトリガーする場合がある。

setRemoteDescription

setRemoteDescription メソッドは RTCPeerConnection に対し、与えられた RTCSessionDescriptionInit をリモートの offer または answer として適用するよう指示する。この API はローカルのメディア状態を変更する。

メソッドが呼ばれたとき、ユーザーエージェントは以下の手順を実行しなければならない (MUST):

  1. description をメソッドの最初の引数とする。

  2. connection を、そのメソッドが呼び出された RTCPeerConnection オブジェクトとする。

  3. 以下の手順を connectionoperations chainchaining した結果を返す:

    1. もし description.type が "offer" であり、 現在の connection.[[SignalingState]] に対して [RFC9429] (section 5.5. および section 5.6.) に記述される通り不正である場合、次のサブ手順を実行する:

      1. psetting the local session description{type: "rollback"} で示した結果とする。

      2. p への reacting の結果を返す。fulfillment 手順では descriptionsets the remote session description として設定し、これらの手順を中止する。

    2. setting the remote session description description の結果を返す。

addIceCandidate

addIceCandidate メソッドはリモート candidate を ICE Agent に提供する。このメソッドは candidate メンバに空文字列を渡して呼び出すことで、リモート candidate の終端を示すためにも使用できる。 このメソッドが利用する引数のメンバは candidatesdpMidsdpMLineIndex、 および usernameFragment のみであり、他は無視される。 メソッドが呼び出されたとき、ユーザーエージェントは以下の手順を実行しなければならない (MUST):

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

  2. connection を、そのメソッドが呼び出された RTCPeerConnection オブジェクトとする。

  3. もし candidate.candidate が空文字列でなく、かつ candidate.sdpMidcandidate.sdpMLineIndex の両方が null なら、新たに 作成された TypeError で Promise を rejected にして返す。

  4. 以下の手順を connectionoperations chainchaining した結果を返す:

    1. もし remoteDescriptionnull なら、新たに 作成された InvalidStateError で Promise を rejected にして返す。

    2. もし candidate.sdpMidnull でないなら、以下の手順を実行する:

      1. もし candidate.sdpMidremoteDescription 内のいずれのメディア記述の mid とも一致しないなら、新たに 作成された OperationError で Promise を rejected にして返す。

    3. そうでなく、candidate.sdpMLineIndexnull でないなら、以下の手順を実行する:

      1. もし candidate.sdpMLineIndexremoteDescription 内のメディア記述数以上であるなら、新たに 作成された OperationError で Promise を rejected にして返す。

    4. もし candidate.sdpMid または candidate.sdpMLineIndexremoteDescription 内の、対応するトランシーバが stopped であるメディア記述を指しているなら、 undefinedresolved された Promise を返す。

    5. もし candidate.usernameFragmentnull でなく、適用済みリモート記述の対応する media description 内に存在する任意の username fragment と一致しないなら、新たに 作成された OperationError で Promise を rejected にして返す。

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

    7. 並行して、candidate が administratively prohibited でない場合、[RFC9429] (section 4.1.19.) に記述される通り ICE candidate candidate を追加する。 candidate.usernameFragment を用いて ICE の generation を識別する。 もし usernameFragmentnull なら、最新の ICE generation に対して candidate を処理する。

      もし candidate.candidate が空文字列である場合、candidate を対応する media description および ICE candidate generation の end-of-candidates 指示として処理する。 もし candidate.sdpMidcandidate.sdpMLineIndex が両方とも null の場合、この end-of-candidates 指示はすべての media description に適用される。

      1. もし candidate を正常に追加できなかった場合、ユーザーエージェントは次の手順を実行するタスクをキューしなければならない (MUST):

        1. もし connection.[[IsClosed]]true なら、これらの手順を中止する。

        2. Reject p を新たに 作成された OperationError で行い、これらの手順を中止する。

      2. もし candidate が正常に適用されたか、または candidate が administratively prohibited であった場合、ユーザーエージェントは次の手順を実行するタスクをキューしなければならない (MUST):

        1. もし connection.[[IsClosed]]true なら、これらの手順を中止する。

        2. もし connection.[[PendingRemoteDescription]]null でなく、 candidate が処理された ICE generation を表すなら、 candidateconnection.[[PendingRemoteDescription]].sdp に追加する。

        3. もし connection.[[CurrentRemoteDescription]]null でなく、 candidate が処理された ICE generation を表すなら、 candidateconnection.[[CurrentRemoteDescription]].sdp に追加する。

        4. Resolve pundefined で行う。

    8. p を返す。

candidate は、UA がそのアドレスへの接続試行を許可しないと判断した場合、 administratively prohibited である。

プライバシー上の理由から、アドレス / ポートがブロックされているかどうかについて開発者には何の手掛かりも与えられず、 そのアドレスから応答がない場合と全く同じ挙動となる。

UA は [Fetch] の block bad port リスト上のアドレスへの接続を禁止しなければならない (MUST)。 また他のアドレスへの接続を禁止することもできる (MAY)。

もし iceTransportPolicy メンバが relay である RTCConfiguration の場合、 mDNS candidate や DNS candidate のような外部解決を要する candidate は禁止されなければならない (MUST)。

Note

WebIDL の処理上、 addIceCandidate(null) はデフォルト辞書が存在する呼び出しとして解釈され、上記アルゴリズムではすべてのメディア記述および ICE candidate generation に対する end-of-candidates を示す。 これはレガシー上の理由による設計である。

restartIce

restartIce メソッドは、RTCPeerConnection に ICE をリスタートすべきであることを指示する。続く createOffer の呼び出しは、[RFC5245] セクション 9.1.1.1 に記述されるように ICE をリスタートする記述を生成する。

このメソッドが呼び出されたとき、ユーザーエージェントは以下の手順を実行しなければならない (MUST):

  1. connection を、そのメソッドが呼び出された RTCPeerConnection とする。

  2. connection.[[LocalIceCredentialsToReplace]] を空にし、[RFC5245] セクション 15.4 で定義されるすべての ICE 資格情報 (ice-ufrag と ice-pwd) のうち、 connection.[[CurrentLocalDescription]] に存在するもの、ならびに connection.[[PendingLocalDescription]] に存在するものをすべて追加して埋める。

  3. connection について negotitation-needed フラグを更新する。

getConfiguration

現在のこの RTCPeerConnection オブジェクトの構成を表す RTCConfiguration オブジェクトを返す。

このメソッドが呼び出されたとき、ユーザーエージェントは RTCConfiguration オブジェクトで、 [[Configuration]] 内部スロットに格納されているものを返さなければならない (MUST)。

setConfiguration

setConfiguration メソッドはこの RTCPeerConnection オブジェクトの構成を更新する。これには ICE Agent の構成変更が含まれる。 [RFC9429] (section 3.5.1.) に記載されるように、ICE 構成が新たな収集フェーズを必要とする形で変化した場合、ICE リスタートが必要となる。

setConfiguration メソッドが呼び出されたとき、ユーザーエージェントは以下の手順を実行しなければならない (MUST):

  1. connection を、そのメソッドが呼び出された RTCPeerConnection とする。

  2. もし connection.[[IsClosed]]true なら、 throw InvalidStateError を投げる。

  3. 指定された構成を設定 (引数 configuration) する。

close

close メソッドが呼び出されたとき、ユーザーエージェントは以下の手順を実行しなければならない (MUST):

  1. connection を、そのメソッドが呼び出された RTCPeerConnection オブジェクトとする。

  2. close the connectionconnection と値 false で実行する。

close the connection アルゴリズム (引数: connection, 真偽値 disappear) は次の通り:

  1. もし connection.[[IsClosed]]true なら、これらの手順を中止する。

  2. connection.[[IsClosed]]true に設定する。

  3. connection.[[SignalingState]] を "closed" に設定する。イベントは発火しない。

  4. transceiversCollectTransceivers アルゴリズムの実行結果とする。各 RTCRtpTransceiver transceiver について以下の手順を実行する:

    1. もし transceiver.[[Stopped]]true なら、これらのサブ手順を中止する。

    2. Stop the RTCRtpTransceivertransceiverdisappear を与えて実行する。

  5. それぞれの connectionRTCDataChannel[[ReadyState]] スロットを "closed" に設定する。

    Note
    RTCDataChannel は即座に閉じられ、closing 手順は呼び出されない。
  6. もし connection.[[SctpTransport]]null でないなら、基盤となる SCTP アソシエーションを SCTP ABORT チャンク送信により破棄し、 [[SctpTransportState]] を "closed" に設定する。

  7. それぞれの connectionRTCDtlsTransport[[DtlsTransportState]] スロットを "closed" に設定する。

  8. connectionICE Agent を破棄し、進行中の ICE 処理を即座に終了し関連リソース (例: TURN permission) を解放する。

  9. それぞれの connectionRTCIceTransport[[IceTransportState]] スロットを "closed" に設定する。

  10. connection.[[IceConnectionState]] を "closed" に設定する。イベントは発火しない。

  11. connection.[[ConnectionState]] を "closed" に設定する。イベントは発火しない。

4.4.3 レガシーインターフェイス拡張

Note
これらのメソッドの IDL 定義は記述されており、 オーバーロードされた関数は partial interface 内で定義できないため RTCPeerConnection インターフェイスの主たる定義の中に含まれている。

本節のメソッドをサポートするかどうかは任意である。しかし、サポートする場合はここで規定されるとおりに実装することが必須である。

Note
かつて RTCPeerConnection 上に存在した addStream メソッドは次のように容易にポリフィルできる:
RTCPeerConnection.prototype.addStream = function(stream) {
  stream.getTracks().forEach((track) => this.addTrack(track, stream));
};
4.4.3.1 メソッド拡張
メソッド
createOffer

createOffer メソッドが呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない (MUST):

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

  2. failureCallback をメソッド第二引数で示されるコールバックとする。

  3. options をメソッド第三引数で示されるコールバックとする。

  4. RTCPeerConnectioncreateOffer() メソッドを options を唯一の引数として実行し、結果の Promise を p とする。

  5. pfulfillment し値 offer を得たとき、successCallbackoffer を引数として呼び出す。

  6. p が理由 rrejection したとき、 failureCallbackr を引数として呼び出す。

  7. undefinedresolved された Promise を返す。

setLocalDescription

setLocalDescription メソッドが呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない (MUST):

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

  2. successCallback をメソッド第二引数で示されるコールバックとする。

  3. failureCallback をメソッド第三引数で示されるコールバックとする。

  4. RTCPeerConnectionsetLocalDescription メソッドを description を唯一の引数として実行し、結果の Promise を p とする。

  5. pfulfillment したとき、 successCallbackundefined を引数として呼び出す。

  6. p が理由 rrejection したとき、 failureCallbackr を引数として呼び出す。

  7. undefinedresolved された Promise を返す。

createAnswer
Note
レガシーな createAnswer メソッドは RTCAnswerOptions 引数を取らない。 これは既知のレガシー実装においてこのオプションがサポートされた例が存在しなかったためである。

createAnswer メソッドが呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない (MUST):

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

  2. failureCallback をメソッド第二引数で示されるコールバックとする。

  3. RTCPeerConnectioncreateAnswer() メソッドを引数なしで実行し、結果の Promise を p とする。

  4. pfulfillment し値 answer を得たとき、successCallbackanswer を引数として呼び出す。

  5. p が理由 rrejection したとき、 failureCallbackr を引数として呼び出す。

  6. undefinedresolved された Promise を返す。

setRemoteDescription

setRemoteDescription メソッドが呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない (MUST):

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

  2. successCallback をメソッド第二引数で示されるコールバックとする。

  3. failureCallback をメソッド第三引数で示されるコールバックとする。

  4. RTCPeerConnectionsetRemoteDescription メソッドを description を唯一の引数として実行し、結果の Promise を p とする。

  5. pfulfillment したとき、 successCallbackundefined を引数として呼び出す。

  6. p が理由 rrejection したとき、 failureCallbackr を引数として呼び出す。

  7. undefinedresolved された Promise を返す。

addIceCandidate

addIceCandidate メソッドが呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない (MUST):

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

  2. successCallback をメソッド第二引数で示されるコールバックとする。

  3. failureCallback をメソッド第三引数で示されるコールバックとする。

  4. RTCPeerConnectionaddIceCandidate() メソッドを candidate を唯一の引数として実行し、結果の Promise を p とする。

  5. pfulfillment したとき、 successCallbackundefined を引数として呼び出す。

  6. p が理由 rrejection したとき、 failureCallbackr を引数として呼び出す。

  7. undefinedresolved された Promise を返す。

コールバック定義

これらのコールバックはレガシー API でのみ使用される。

RTCPeerConnectionErrorCallback
WebIDLcallback RTCPeerConnectionErrorCallback = undefined (DOMException error);
コールバック RTCPeerConnectionErrorCallback のパラメータ
error (型: DOMException)
何が問題であったかの情報をカプセル化するエラーオブジェクト。
RTCSessionDescriptionCallback
WebIDLcallback RTCSessionDescriptionCallback = undefined (RTCSessionDescriptionInit description);
コールバック RTCSessionDescriptionCallback のパラメータ
description (型: RTCSessionDescriptionInit)
SDP [SDP] を含むオブジェクト。
4.4.3.2 レガシー構成拡張

この節は、RTCPeerConnection に追加されたメディアに加え、offer の生成方法に影響を与えるために使用され得る一連のレガシー拡張を記述する。開発者は代わりに RTCRtpTransceiver API の使用が推奨される。

createOffer が本節で規定される任意のレガシーオプション付きで呼び出された場合、通常の createOffer 手順ではなく以下の手順を実行する:

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

  2. connection を現在の RTCPeerConnection オブジェクトとする。

  3. options 内の 各 offerToReceive<Kind> メンバ (種別 kind) について、次を実行する:

    1. 辞書メンバの値が false の場合、
      1. transceiver kind kind の停止していない "sendrecv" トランシーバそれぞれについて、 transceiver.[[Direction]] を "sendonly" に設定する。

      2. transceiver kind kind の停止していない "recvonly" トランシーバそれぞれについて、 transceiver.[[Direction]] を "inactive" に設定する。

      次のオプションへ進む (あれば)。

    2. connection が "sendrecv" または "recvonly" の停止していないトランシーバ (種別 transceiver kind kind) を持つなら、次のオプションへ進む (あれば)。

    3. transceiverconnection.addTransceiver(kind) と等価な呼び出しの結果とする。ただしこの操作は negotitation-needed フラグを更新してはならない (MUST NOT)。

    4. 直前の操作がエラーを投げた結果 transceiver が未設定である場合、これらの手順を中止する。

    5. transceiver.[[Direction]] を "recvonly" に設定する。

  4. createOffer により規定される手順を実行して offer を生成する。

WebIDLpartial dictionary RTCOfferOptions {
  boolean offerToReceiveAudio;
  boolean offerToReceiveVideo;
};
属性
offerToReceiveAudio (型: boolean)

この設定は音声の方向性に対し追加の制御を提供する。例えば音声を送信するかどうかに関わらず音声を受信可能であることを保証するために利用できる。

offerToReceiveVideo (型: boolean)

この設定は映像の方向性に対し追加の制御を提供する。例えば映像を送信するかどうかに関わらず映像を受信可能であることを保証するために利用できる。

4.4.4 ガーベジコレクション

任意のイベントがそのオブジェクト上のイベントハンドラを発火させ得る限り、 RTCPeerConnection オブジェクトはガーベジコレクションされてはならない (MUST not)。オブジェクトの [[IsClosed]] 内部スロットが true のとき、そのようなイベントハンドラは発火し得ず、そのため当該オブジェクトをガーベジコレクションしても安全である。

RTCPeerConnection に接続されているすべての RTCDataChannel および MediaStreamTrack オブジェクトは、 その RTCPeerConnection オブジェクトへの強参照を保持する。

4.5 エラー処理

4.5.1 一般原則

Promise を返すすべてのメソッドは、Promise の標準的なエラー処理規則に従う。Promise を返さないメソッドは、エラーを示すために例外を投げる場合がある。

4.6 セッション記述モデル

4.6.1 RTCSdpType

RTCSdpType 列挙は RTCSessionDescriptionInitRTCLocalSessionDescriptionInit、 あるいは RTCSessionDescription インスタンスの種類を表す。

WebIDLenum RTCSdpType {
  "offer",
  "pranswer",
  "answer",
  "rollback"
};
RTCSdpType 列挙の説明
列挙値 説明
offer

"offer" の RTCSdpType は、記述が [SDP] の offer として扱われなければならない (MUST) ことを示す。

pranswer

"pranswer" の RTCSdpType は、記述が [SDP] の answer だが最終的な answer ではないもの (暫定回答) として扱われなければならない (MUST) ことを示す。pranswer として使用された記述は SDP offer への応答、または以前送信した SDP pranswer の更新として適用され得る。

answer

"answer" の RTCSdpType は、記述が [SDP] の最終的な answer として扱われ、offer-answer 交換が完了したものと見なされなければならない (MUST) ことを示す。answer として使用された記述は SDP offer への応答、または以前送信された SDP pranswer の更新として適用され得る。

rollback

"rollback" の RTCSdpType は、記述が現在の SDP 交渉を取り消し、SDP [SDP] の offer を直前の stable 状態に戻すものとして扱われなければならない (MUST) ことを示す。直前の stable 状態におけるローカルまたはリモートの SDP 記述は、まだ成功した offer-answer 交渉がない場合 null であり得る。"answer" および "pranswer" はロールバックできない。

4.6.2 RTCSessionDescription クラス

RTCSessionDescription クラスは RTCPeerConnection によってローカルおよびリモートのセッション記述を公開するために用いられる。

WebIDL[Exposed=Window]
interface RTCSessionDescription {
  constructor(RTCSessionDescriptionInit descriptionInitDict);
  readonly attribute RTCSdpType type;
  readonly attribute DOMString sdp;
  [Default] RTCSessionDescriptionInit toJSON();
};
コンストラクタ
constructor()

RTCSessionDescription() コンストラクタは辞書引数 description を受け取り、その内容で新しい RTCSessionDescription オブジェクトを初期化する。このコンストラクタは非推奨であり、レガシー互換性のためだけに存在する。

属性
type (型: RTCSdpType), readonly
このセッション記述の種類。
sdp (型: DOMString), readonly, 既定値 ""
SDP [SDP] の文字列表現。
メソッド
toJSON()
呼び出されたとき、[WEBIDL] の default toJSON steps を実行する。
WebIDLdictionary RTCSessionDescriptionInit {
  required RTCSdpType type;
  DOMString sdp = "";
};
辞書 RTCSessionDescriptionInit のメンバー
type (型: RTCSdpType), required
このセッション記述の種類。
sdp (型: DOMString)
SDP [SDP] の文字列表現。 type が "rollback" の場合、このメンバーは使用されない。
WebIDLdictionary RTCLocalSessionDescriptionInit {
  RTCSdpType type;
  DOMString sdp = "";
};
辞書 RTCLocalSessionDescriptionInit のメンバー
type (型: RTCSdpType)
この記述の種類。指定されていない場合、 setLocalDescriptionRTCPeerConnection[[SignalingState]] に基づいて型を推論する。
sdp (型: DOMString)
SDP [SDP] の文字列表現。 type が "rollback" の場合、このメンバーは使用されない。

4.7 セッションネゴシエーションモデル

RTCPeerConnection の状態に対する多くの変更は、望む効果を得るためにシグナリングチャネルを介したリモート側との通信を必要とする。アプリはいつシグナリングが必要かについて、negotiationneeded イベントを監視することで把握できる。このイベントは、接続の negotiation-needed フラグ の状態に従って発火し、これは [[NegotiationNeeded]] 内部スロットで表される。

4.7.1 negotiation-needed の設定

この節は規範的ではない (non-normative)。

シグナリングを必要とする操作が RTCPeerConnection に対して行われた場合、接続はネゴシエーションが必要とマークされる。例として、RTCRtpTransceiver の追加または停止、あるいは最初の RTCDataChannel の追加などが含まれる。

実装内部での変更によっても接続がネゴシエーション必要状態とマークされることがある。

negotiation-needed フラグの更新 の正確な手順は後述で規定されている点に注意。

4.7.2 negotiation-needed のクリア

この節は規範的ではない (non-normative)。

negotiation-needed フラグ は型 "answer" のセッション記述が正常に 設定 され、かつ与えられた記述が現在存在する RTCRtpTransceiver 群および RTCDataChannel 群の状態と一致する場合にクリアされる。具体的には、停止していない (stopped でない) すべてのトランシーバーがローカル記述内で対応する (associated) セクションを持ちプロパティが一致し、さらにデータチャネルが作成されている場合にはローカル記述にデータセクションが存在することを意味する。

negotiation-needed フラグの更新 の正確な手順は後述で規定される点に注意。

4.7.3 negotiation-needed フラグの更新

以下の処理は本仕様書内の他の箇所から参照されたときに発生する。また、ネゴシエーションに影響する実装内部の変更の結果として発生することもある。そのような変更が起きた場合、ユーザーエージェントは MUST negotiation-needed フラグを更新 しなければならない。

negotiation-needed フラグを更新 するために connection について以下の手順を実行する:

  1. connection.[[Operations]] の長さが 0 でないなら、 connection.[[UpdateNegotiationNeededFlagOnEmptyChain]]true に設定し、これらの手順を中止する。

  2. 次の手順を実行するタスクをキューする:

    1. connection.[[IsClosed]]true なら、これらの手順を中止する。

    2. connection.[[Operations]] の長さが 0 でないなら、 connection.[[UpdateNegotiationNeededFlagOnEmptyChain]]true に設定し、これらの手順を中止する。

    3. connection.[[SignalingState]] が "stable" でないなら、これらの手順を中止する。

      Note

      negotiation-needed フラグ は状態が "stable" に遷移した際、 セッション記述を 設定する 手順の一部として更新される。

    4. ネゴシエーションが必要かの確認 の結果が false なら、 negotiation-needed フラグをクリア するため connection.[[NegotiationNeeded]]false に設定し、これらの手順を中止する。

    5. connection.[[NegotiationNeeded]] が既に true の場合、これらの手順を中止する。

    6. connection.[[NegotiationNeeded]]true に設定する。

    7. Fire an eventnegotiationneededconnection で発火させる。

    Note

    タスクのキューイングにより、複数の connection への変更が同時に行われている一般的な状況で negotiationneeded が早期に発火することを防ぐ。

    さらに、negotiationneededoperations chain が空のときのみ発火させることでネゴシエーションメソッドとの競合を避ける。

ネゴシエーションが必要かの確認connection について行うには、以下の確認を実施する:

  1. 節冒頭で述べたような実装依存のネゴシエーションが必要な場合、true を返す。

  2. connection.[[LocalIceCredentialsToReplace]] が空でないなら true を返す。

  3. descriptionconnection.[[CurrentLocalDescription]] とする。

  4. connection が任意の RTCDataChannel を作成しており、かつ description 内にデータ用の m= セクションがまだネゴシエートされていないなら true を返す。

  5. connectionset of transceivers 内の各 transceiver について以下を確認する:

    1. transceiver.[[Stopping]]true かつ transceiver.[[Stopped]]false なら true を返す。

    2. transceiverstopped ではなく、かつ description 内の m= セクションとまだ associated していないなら true を返す。

    3. transceiverstopped でなく、かつ description の m= セクションと associated している場合、次を確認する:

      1. transceiver.[[Direction]] が "sendrecv" または "sendonly" であり、かつ対応する m= セクションが単一の a=msid 行を含まない、またはこの m= セクション内の a=msid 行に由来する MSID の個数または MSID 値自体が transceiver.sender.[[AssociatedMediaStreamIds]] と異なるなら true を返す。

      2. description の型が "offer" であり、対応する m= セクションの方向が connection.[[CurrentLocalDescription]] にも connection.[[CurrentRemoteDescription]] にも transceiver.[[Direction]] と一致しないなら true を返す。この際 [[CurrentRemoteDescription]] にある方向と比較する場合、記述中の方向はピア視点を表すよう反転させる必要がある。

      3. description の型が "answer" であり、description 内の対応 m= セクションの方向が transceiver.[[Direction]] と、提示された方向との積 (交差) ( [RFC9429] (section 5.3.1.) 参照 ) と一致しないなら true を返す。

    4. transceiverstopped で、m= セクションと associated しているが、 その m= セクションがまだ connection.[[CurrentLocalDescription]] または connection.[[CurrentRemoteDescription]] で拒否されていないなら true を返す。

  6. 以上の確認を行っても true が返されなかった場合、ネゴシエーションすべきものは残っていないので false を返す。

4.8 インタラクティブコネクティビティ確立 (ICE) のためのインターフェイス

4.8.1 RTCIceCandidate インターフェイス

このインターフェイスは [RFC5245] セクション 2 で記述される ICE candidate を表す。 candidate, sdpMid, sdpMLineIndex および usernameFragment 以外の属性は、 candidateInitDict 内の candidate メンバを(正しく構成されていれば)パースすることで導出される。

Candidate Addition 16:RTCIceCandidate.relayProtocol の追加 (PR #2763)
Candidate Addition 23:RTCIceCandidate.url の追加 (PR #2773)
[Exposed=Window]
interface RTCIceCandidate {
  constructor(optional RTCIceCandidateInit candidateInitDict = {});
  readonly attribute DOMString candidate;
  readonly attribute DOMString? sdpMid;
  readonly attribute unsigned short? sdpMLineIndex;
  readonly attribute DOMString? foundation;
  readonly attribute RTCIceComponent? component;
  readonly attribute unsigned long? priority;
  readonly attribute DOMString? address;
  readonly attribute RTCIceProtocol? protocol;
  readonly attribute unsigned short? port;
  readonly attribute RTCIceCandidateType? type;
  readonly attribute RTCIceTcpCandidateType? tcpType;
  readonly attribute DOMString? relatedAddress;
  readonly attribute unsigned short? relatedPort;
  readonly attribute DOMString? usernameFragment;
  readonly attribute RTCIceServerTransportProtocol? relayProtocol;
  readonly attribute DOMString? url;
  RTCIceCandidateInit toJSON();
};
コンストラクタ
constructor()

RTCIceCandidate() コンストラクタは辞書引数 candidateInitDict を受け取り、その内容で新しい RTCIceCandidate オブジェクトを初期化する。

呼び出された際、以下の手順を実行する:

  1. candidateInitDictsdpMidsdpMLineIndex の両メンバが null の場合、throwTypeError を投げる。
  2. RTCIceCandidate の作成candidateInitDict で行った結果を返す。

candidateInitDict 辞書を用いて RTCIceCandidate を作成 するには、以下の手順を実行する:

  1. iceCandidate を新規に生成した RTCIceCandidate オブジェクトとする。
  2. iceCandidate の以下の属性用内部スロットを作成し null で初期化する: foundation, component, priority, address, protocol, port, type, tcpType, relatedAddress, relatedPort
  3. iceCandidate の以下の属性用内部スロットを candidateInitDict 内の同名値で初期化する: candidate, sdpMid, sdpMLineIndex, usernameFragment
  4. candidatecandidate 辞書メンバとし、candidate が空文字列でない場合以下を実行する:
    1. candidatecandidate-attribute 文法でパースする。
    2. candidate-attribute のパースに失敗した場合、これらの手順を中止する。
    3. パース結果内の任意のフィールドが iceCandidate の対応属性に対し不正な値を表す場合、これらの手順を中止する。
    4. iceCandidate の対応する内部スロットをパース結果の値に設定する。
  5. iceCandidate を返す。
Note

RTCIceCandidate のコンストラクタは candidateInitDict 内辞書メンバに対して基本的な構文解析と型確認のみを行う。 candidate, sdpMid, sdpMLineIndex, usernameFragment の整形式性に関する詳細な検証は、 RTCIceCandidate オブジェクトを addIceCandidate() に渡す際に行われる。

後方互換性維持のため、candidate 属性のパースエラーは無視される。 その場合 candidate 属性には candidateInitDict で与えられた生の文字列が保持され、 foundation, priority などの派生属性は null に設定される。

属性

以下のほとんどの属性は [RFC5245] セクション 15.1 で定義される。

candidateDOMString、readonly
これは [RFC5245] セクション 15.1 で定義される candidate-attribute を保持する。 この RTCIceCandidate が end-of-candidates 指示または peer reflexive リモート candidate を表す場合、 candidate は空文字列となる。
sdpMidDOMString、readonly、nullable
null でない場合、これは該当候補が関連付けられるメディアコンポーネントの [RFC5888] で定義された メディアストリーム "identification-tag" を含む。
sdpMLineIndexunsigned short、readonly、nullable
null でない場合、候補が対応する SDP 内の media description のインデックス(0 起算)を示す。
foundationDOMString、readonly、nullable
複数の RTCIceTransport 上に出現する候補を ICE が相関付けるための一意識別子。
componentRTCIceComponent、 readonly、nullable
候補に割り当てられたネットワークコンポーネント ("rtp" または "rtcp")。 これは candidate-attributecomponent-id フィールドに対応し、 RTCIceComponent で定義される文字列表現にデコードされる。
priorityunsigned long、readonly、nullable
候補に割り当てられた優先度。
addressDOMString、readonly、nullable

候補のアドレス。IPv4 / IPv6 アドレスおよび FQDN を許容。 これは candidate-attribute 内の connection-address フィールドに対応する。

リモート候補は [[SelectedCandidatePair]].remote などで公開され得る。 既定ではユーザーエージェントは公開されるリモート候補の address 属性を null のままに MUST する。 ウェブアプリが addIceCandidate を使ってアドレスを学習した後は、 ユーザーエージェントはそのアドレスを持つリモート候補を表す いずれの RTCIceCandidate においても address 属性値を公開できる。

Note

ICE により収集され RTCIceCandidate インスタンスとしてアプリケーションに渡されるアドレスは、 WebRTC 非対応ブラウザでユーザーが期待する以上の(例: 位置情報やローカルネットワークトポロジ)情報を デバイス・ユーザーについて漏らし得る。

これらのアドレスは常にアプリケーションおよび通信相手に公開され得るもので、 (データチャネルのみの接続や受信専用などにおいて)特別なユーザー同意無しに公開され得る。

これらのアドレスは一時的または永続的なクロスオリジン状態として利用され得、 デバイスのフィンガープリンティング面を増大させる。 (This is a fingerprinting vector.)

通信相手にアドレスを公開しない(あるいは一時的に抑制する)ために、 アプリケーションは ICE Agent に リレー候補のみを iceTransportPolicy メンバを通じて強制することで可能であり、 これは RTCConfiguration の設定である。

アプリケーション自身に露出されるアドレスを制限するため、 ブラウザはユーザーにローカルアドレス共有ポリシーを選択できるようにでき、 これは [RFC8828] に定義される。

protocolRTCIceProtocol、 readonly、nullable
候補のプロトコル ("udp"/"tcp")。これは candidate-attributetransport フィールドに対応する。
portunsigned short、readonly、nullable
候補のポート。
typeRTCIceCandidateType、 readonly、nullable
候補の種別。これは candidate-attributecandidate-types フィールドに対応する。
tcpTypeRTCIceTcpCandidateType、 readonly、nullable
protocol が "tcp" の場合、 tcpType は TCP 候補の種別を表す。 それ以外の場合 tcpTypenull。 これは candidate-attributetcp-type フィールドに対応。
relatedAddressDOMString、readonly、nullable
他の候補から導出された(例: relay や reflexive)候補において、 relatedAddress は元となる候補の IP アドレス。 host 候補では relatedAddressnull。これは candidate-attributerel-address フィールドに対応する。
relatedPortunsigned short、readonly、nullable
他候補から導出された候補(relay / reflexive など)の場合、 relatedPort は元となる候補のポート。 host 候補では relatedPortnull。これは candidate-attributerel-port フィールドに対応。
usernameFragmentDOMString、readonly、nullable
これは [RFC5245] セクション 15.4 で定義される ufrag を保持する。
Candidate Addition 16:RTCIceCandidate.relayProtocol の追加 (PR #2763)
relayProtocolRTCIceServerTransportProtocol、readonly、 nullable
ローカル候補が種別 "relay" の場合、 エンドポイントが TURN サーバと通信する際に使用したプロトコル。 それ以外の候補では null
Candidate Addition 23:RTCIceCandidate.url の追加 (PR #2773)
urlDOMString、readonly、nullable
ローカル候補が種別 "srflx" または "relay" の場合、候補を取得した ICE サーバの URL。 それ以外の候補では null
メソッド
toJSON()
toJSON() 操作を呼び出すため、以下の手順を実行する:
  1. json を新しい RTCIceCandidateInit 辞書とする。
  2. 属性識別子 attr を «candidate, sdpMid, sdpMLineIndex, usernameFragment» それぞれについて:
    1. attr で識別される属性の基礎値を、この RTCIceCandidate オブジェクトに対して取得し value とする。
    2. json[attr]value に設定する。
  3. json を返す。
WebIDLdictionary RTCIceCandidateInit {
  DOMString candidate = "";
  DOMString? sdpMid = null;
  unsigned short? sdpMLineIndex = null;
  DOMString? usernameFragment = null;
};
辞書 RTCIceCandidateInit のメンバー
candidateDOMString、既定値 ""
これは [RFC5245] セクション 15.1 で定義される candidate-attribute を保持する。 end-of-candidates 指示を表す場合、 candidate は空文字列となる。
sdpMidDOMString、nullable、既定値 null
null でない場合、 メディアストリーム "identification-tag" を保持する。
sdpMLineIndexunsigned short、nullable、既定値 null
null でない場合、候補が対応する SDP 内の media description のインデックス(0 起算)を示す。
usernameFragmentDOMString、nullable、既定値 null
null でない場合、[RFC5245] セクション 15.4 で定義される ufrag を保持する。
4.8.1.1 candidate-attribute 文法

candidate-attribute 文法は candidate メンバを RTCIceCandidate() コンストラクタ内でパースするために使用される。

candidate-attribute の主要文法は [RFC5245] セクション 15.1 で定義される。 さらにブラウザは [RFC6544] セクション 4.5 で定義される ICE TCP の文法拡張を MUST サポートする。

ブラウザは他の RFC で定義される candidate-attribute の文法拡張を MAY サポートしてもよい。

4.8.1.2 RTCIceProtocol 列挙

RTCIceProtocol は ICE candidate のプロトコルを表す。

WebIDLenum RTCIceProtocol {
  "udp",
  "tcp"
};
RTCIceProtocol 列挙説明
列挙値 説明
udp [RFC5245] に記述される UDP 候補。
tcp [RFC6544] に記述される TCP 候補。
4.8.1.3 RTCIceTcpCandidateType 列挙

RTCIceTcpCandidateType は ICE TCP 候補の種別を表し、 [RFC6544] で定義される。

WebIDLenum RTCIceTcpCandidateType {
  "active",
  "passive",
  "so"
};
RTCIceTcpCandidateType 列挙説明
列挙値 説明
active "active" TCP 候補は、アウトバウンド接続を開こうとするが受信接続要求は受けないもの。
passive "passive" TCP 候補は、受信接続試行を受け入れるが自ら接続を試みないもの。
so "so" 候補は ピアと同時に接続確立を試みるもの。
Note

ユーザーエージェントは通常 active な ICE TCP 候補のみ収集する。

4.8.1.4 RTCIceCandidateType 列挙

RTCIceCandidateType は ICE candidate の種別を [RFC5245] セクション 15.1 に従って表す。

WebIDLenum RTCIceCandidateType {
  "host",
  "srflx",
  "prflx",
  "relay"
};
RTCIceCandidateType 列挙説明
列挙値 説明
host [RFC5245] セクション 4.1.1.1 の host 候補。
srflx [RFC5245] セクション 4.1.1.2 の server reflexive 候補。
prflx [RFC5245] セクション 4.1.1.2 の peer reflexive 候補。
relay [RFC5245] セクション 7.1.3.2.1 の relay 候補。
Candidate Addition 16:RTCIceCandidate.relayProtocol の追加 (PR #2763)
4.8.1.5 RTCIceServerTransportProtocol 列挙

RTCIceServerTransportProtocol はクライアントとサーバ間で用いられる転送プロトコル種別を [RFC8656] セクション 3.1 に従って表す。

WebIDLenum RTCIceServerTransportProtocol {
  "udp",
  "tcp",
  "tls",
};
RTCIceServerTransportProtocol 列挙説明
列挙値 説明
udp TURN クライアントがサーバへのトランスポートとして UDP を使用している。
tcp TURN クライアントがサーバへのトランスポートとして TCP を使用している。
tls TURN クライアントがサーバへのトランスポートとして TLS を使用している。

4.8.2 RTCPeerConnectionIceEvent

icecandidate イベントは RTCPeerConnection 上で RTCPeerConnectionIceEvent インターフェイスを使用する。

RTCPeerConnectionIceEventRTCIceCandidate オブジェクトを含んで発火する際、 MUSTsdpMidsdpMLineIndex の両値を含める必要がある。 候補が種別 "srflx" または "relay" の場合、 イベントの url プロパティは候補を取得した ICE サーバの URL に MUST 設定される。

Note
icecandidate イベントは 3 種類の通知に使用される:
  • 候補が収集された。イベントの candidate メンバは通常どおり値を持つ。これをリモートピアへシグナリングし、 addIceCandidate に渡す。

  • ある RTCIceTransport が一つの generation の候補収集を完了し、 [RFC8838] セクション 8.2 に定義される end-of-candidates 指示を提供する。 これは candidate.candidate が空文字列に設定されることで示される。 この candidate オブジェクトは通常の ICE candidate 同様にリモートピアへシグナリングし addIceCandidate に渡し、end-of-candidates 指示をリモートピアに伝える。

  • すべての RTCIceTransport が候補収集を完了し、 RTCPeerConnectionRTCIceGatheringState が "complete" に遷移した。 これはイベントの candidate メンバが null に設定されることで示される。 (後方互換性のみのために存在し)リモートピアへシグナリングする必要はない。 これは "complete" 状態の icegatheringstatechange イベントと同等。

WebIDL[Exposed=Window]
interface RTCPeerConnectionIceEvent : Event {
  constructor(DOMString type, optional RTCPeerConnectionIceEventInit eventInitDict = {});
  readonly attribute RTCIceCandidate? candidate;
  readonly attribute DOMString? url;
};
コンストラクタ
RTCPeerConnectionIceEvent.constructor()
属性
candidateRTCIceCandidate、 readonly、nullable

candidate 属性はイベントを引き起こした新しい ICE 候補を持つ RTCIceCandidate オブジェクト。

候補収集終了を示すイベントでは、この属性は null に設定される。

Note

複数メディアコンポーネントがあっても、null 候補を含むイベントは一度だけ発火する。

urlDOMString、readonly、nullable

url 属性は、 その候補を収集した STUN または TURN サーバを識別する STUN/TURN URL。 STUN/TURN サーバから収集されていない候補では null

Candidate Correction 23:RTCPeerConnectionIceEvent.url を非推奨化 (PR #2773)

この属性は非推奨であり、レガシー互換性のためだけに存在する。候補の url を利用すること。

WebIDLdictionary RTCPeerConnectionIceEventInit : EventInit {
  RTCIceCandidate? candidate;
  DOMString? url;
};
辞書 RTCPeerConnectionIceEventInit のメンバー
candidateRTCIceCandidate、 nullable

candidate 属性を参照。

urlDOMString、nullable
候補を収集した STUN または TURN サーバを識別する STUN/TURN URL。

4.8.3 RTCPeerConnectionIceErrorEvent

icecandidateerror イベントは RTCPeerConnection 上で RTCPeerConnectionIceErrorEvent インターフェイスを使用する。

WebIDL[Exposed=Window]
interface RTCPeerConnectionIceErrorEvent : Event {
  constructor(DOMString type, RTCPeerConnectionIceErrorEventInit eventInitDict);
  readonly attribute DOMString? address;
  readonly attribute unsigned short? port;
  readonly attribute DOMString url;
  readonly attribute unsigned short errorCode;
  readonly attribute USVString errorText;
};
コンストラクタ
RTCPeerConnectionIceErrorEvent.constructor()
属性
addressDOMString、readonly、nullable

address 属性は STUN または TURN サーバとの通信に用いられたローカル IP アドレスである。

マルチホーム環境では複数のインターフェイスがサーバ接続に使用され得るため、この属性によりどのインターフェイスで失敗が起きたかをアプリケーションが把握できる。

ローカル IP アドレス値がまだローカル候補の一部として公開されていない場合、 address 属性は null に設定される。

portunsigned short、readonly、nullable

port 属性は STUN または TURN サーバとの通信に使用されたポートである。

address 属性が null の場合、 port 属性も null に設定される。

urlDOMString、readonly

url 属性は障害が発生した STUN または TURN サーバを識別する STUN/TURN URL である。

errorCodeunsigned short、readonly

errorCode 属性は STUN または TURN サーバから返された数値 STUN エラーコード [STUN-PARAMETERS] である。

いずれの host candidate もサーバに到達できない場合、 errorCode は STUN エラーコード範囲外の値 701 に設定される。このエラーは RTCIceGatheringState が "gathering" の間、サーバ URL ごとに一度だけ発火する。

errorTextUSVString、readonly

errorText 属性は STUN または TURN サーバから返された STUN reason text [STUN-PARAMETERS] である。

サーバに到達できなかった場合、 errorText はエラーの詳細を示す実装依存の値に設定される。

WebIDLdictionary RTCPeerConnectionIceErrorEventInit : EventInit {
  DOMString? address;
  unsigned short? port;
  DOMString url;
  required unsigned short errorCode;
  USVString errorText;
};
辞書 RTCPeerConnectionIceErrorEventInit のメンバー
addressDOMString、nullable

STUN または TURN サーバとの通信に使用されたローカルアドレス。あるいは null

portunsigned short、nullable

STUN または TURN サーバとの通信に使用されたローカルポート。あるいは null

urlDOMString

障害が発生した STUN または TURN サーバを識別する STUN/TURN URL。

errorCodeunsigned short、required

STUN または TURN サーバから返された数値 STUN エラーコード。

errorTextUSVString

STUN または TURN サーバから返された STUN reason text。

4.9 証明書管理

ピアとの認証に RTCPeerConnection インスタンスが使用する証明書は RTCCertificate インターフェイスを用いる。これらのオブジェクトはアプリケーションが generateCertificate メソッドで明示的に生成でき、 新しい RTCConfiguration を用いて RTCPeerConnection インスタンスを構築する際に提供できる。

ここで提供される明示的な証明書管理機能は任意である。アプリケーションが certificates 構成オプションを RTCPeerConnection 構築時に提供しない場合、 新しい証明書セットが MUSTユーザーエージェント により生成されなければならない。そのセットには P-256 曲線上の秘密鍵を持つ ECDSA 証明書と SHA-256 ハッシュによる署名を MUST で含める。

WebIDLpartial interface RTCPeerConnection {
  static Promise<RTCCertificate>
      generateCertificate(AlgorithmIdentifier keygenAlgorithm);
};

メソッド

generateCertificate, static

generateCertificate 関数は ユーザーエージェント に X.509 証明書 [X509V3] と対応する秘密鍵を作成させる。情報へのハンドルは RTCCertificate インターフェイスの形で提供される。返された RTCCertificateRTCPeerConnection が確立する DTLS セッションで提示される証明書を制御するために使用できる。

keygenAlgorithm 引数は証明書に関連付けられる秘密鍵がどのように生成されるかを制御する。keygenAlgorithm 引数は WebCrypto [WebCryptoAPI] AlgorithmIdentifier 型を利用する。

次の値は ユーザーエージェントMUST でサポートしなければならない: { name: "RSASSA-PKCS1-v1_5", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: "SHA-256" } および { name: "ECDSA", namedCurve: "P-256" }

Note

ユーザーエージェント は受け付ける値の集合を小規模または固定にすることが想定される。

このプロセスで生成される証明書には署名も含まれる。署名の妥当性は互換性の理由のみで意味を持つ。 RTCPeerConnection によって使用されるのは公開鍵と結果の証明書フィンガープリントのみであるが、証明書が整形式である方が受け入れられる可能性が高い。ブラウザは証明書の署名に使用するアルゴリズムを選択する。ブラウザはハッシュアルゴリズムが必要な場合 SHA-256 [FIPS-180-4] を選択することを SHOULD である。

生成された証明書はユーザーまたは ユーザーエージェント にリンク可能な情報を MUST NOT で含んではならない。識別名およびシリアル番号にはランダム化された値を用いることが SHOULD である。

メソッドが呼び出されたとき、ユーザーエージェントは MUST で次の手順を実行する:

  1. keygenAlgorithmgenerateCertificate の第1引数とする。

  2. expires を 2592000000 (30*24*60*60*1000) の値とする。

    Note

    これはデフォルトで証明書が generateCertificate 呼び出し時点から 30 日後に失効することを意味する。

  3. keygenAlgorithm がオブジェクトであれば以下を実行する:

    1. certificateExpiration変換 により、keygenAlgorithm を表す ECMAScript オブジェクトを RTCCertificateExpiration 辞書に変換した結果とする。

    2. 変換が error で失敗した場合、errorreject された promise を返す。

    3. もし certificateExpiration.expiresundefined でなければ、expirescertificateExpiration.expires に設定する。

    4. expires が 31536000000 を超える場合、 expires を 31536000000 に設定する。

      Note

      これは証明書が generateCertificate 呼び出し時点から 365 日より長く有効にならないことを意味する。

      ユーザーエージェントMAY でさらに expires の値を上限設定してよい。

  4. normalizedKeygenAlgorithmアルゴリズムの正規化 (operation name: generateKeysupportedAlgorithmsRTCPeerConnection の証明書生成専用の値)した結果とする。

  5. 上記正規化ステップが error で失敗したなら、 errorreject された promise を返す。

  6. normalizedKeygenAlgorithm が特定するアルゴリズムを ユーザーエージェントRTCPeerConnection の証明書生成に使用できない/使用しない場合、 reject された DOMException (NotSupportedError) を伴う promise を返す。特に normalizedKeygenAlgorithm は DTLS 接続認証に使用される署名を生成可能な非対称アルゴリズムであることを MUST とする。

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

  8. 次の手順を 並行して実行する:

    1. normalizedKeygenAlgorithm で指定された generate key 操作を keygenAlgorithm を用いて実行する。

    2. generatedKeyingMaterial および generatedKeyCertificate を上記で生成された秘密鍵材料と証明書とする。

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

    4. certificate.[[Expires]] を現在時刻 + expires に設定する。

    5. certificate.[[Origin]]関連設定オブジェクトorigin に設定する。

    6. generatedKeyingMaterial を安全なモジュールに保存し、handle をそれへの参照識別子とする。

    7. certificate.[[KeyingMaterialHandle]]handle に設定する。

    8. certificate.[[Certificate]]generatedCertificate に設定する。

    9. 現在の realm の グローバルオブジェクトglobal として ネットワークタスクソース 上で グローバルタスクをキューし、 pcertificateresolve する。

  9. p を返す。

4.9.1 RTCCertificateExpiration 辞書

RTCCertificateExpirationgenerateCertificate により生成される証明書に有効期限を設定するために使用される。

WebIDLdictionary RTCCertificateExpiration {
  [EnforceRange] unsigned long long expires;
};
expires, of type unsigned long long

アルゴリズム定義( generateCertificate に渡される)に MAY で追加できる任意の expires 属性。存在する場合、これは 証明書が作成された時点から計測して RTCCertificate が有効でいられる最大時間(ミリ秒)を示す。

4.9.2 RTCCertificate インターフェイス

RTCCertificate インターフェイスは WebRTC 通信を認証するために使用される証明書を表す。可視プロパティに加え、内部スロットは生成された秘密鍵材料へのハンドル ([[KeyingMaterialHandle]])、ピアとの認証に RTCPeerConnection が使用する証明書 ([[Certificate]])、およびオブジェクトを作成したオリジン ([[Origin]]) を含む。

WebIDL[Exposed=Window, Serializable]
interface RTCCertificate {
  readonly attribute EpochTimeStamp expires;
  sequence<RTCDtlsFingerprint> getFingerprints();
};
属性
expires of type EpochTimeStamp, readonly

expires 属性は、1970-01-01T00:00:00Z からのミリ秒で表される、ブラウザがその証明書を無効とみなす日時を示す。この時刻以降、この証明書を用いて RTCPeerConnection を構築しようとする試みは失敗する。

この値は証明書自体の notAfter パラメータに反映されないことがある点に注意。

メソッド
getFingerprints

証明書フィンガープリントの一覧を返す。そのうち1つは証明書署名で使用されたダイジェストアルゴリズムで計算される。

本 API の目的では、[[Certificate]] スロットには非構造化バイナリデータが含まれる。アプリケーションが [[KeyingMaterialHandle]] 内部スロットやそれが参照する鍵材料へアクセスする仕組みは提供されない。実装は MUST でアプリケーションが RTCCertificate オブジェクトを永続ストレージへ保存および取得することをサポートし、その際 [[KeyingMaterialHandle]] が参照する鍵材料も保持しなければならない。実装は機微な鍵材料を同一プロセスメモリアタックから安全なモジュールに保存することを SHOULD とする。これにより秘密鍵は保存および使用できるが、メモリアタックで容易に読み出されない。

RTCCertificate オブジェクトは serializable objects [HTML] である。これらの シリアライズ手順valueserialized が与えられたとき以下:

  1. serialized.[[Expires]] を value.expires 属性の値に設定する。
  2. serialized.[[Certificate]] を value.[[Certificate]] 内の非構造化バイナリデータのコピーに設定する。
  3. serialized.[[Origin]] を value.[[Origin]] 内の非構造化バイナリデータのコピーに設定する。
  4. serialized.[[KeyingMaterialHandle]] を value.[[KeyingMaterialHandle]] 内のハンドル(秘密鍵材料自体ではない)のシリアライズ結果に設定する。

これらの デシリアライズ手順serializedvalue が与えられたとき:

  1. value.expires 属性を serialized.[[Expires]] を含むよう初期化する。
  2. value.[[Certificate]]serialized.[[Certificate]] のコピーに設定する。
  3. value.[[Origin]]serialized.[[Origin]] のコピーに設定する。
  4. value.[[KeyingMaterialHandle]]serialized.[[KeyingMaterialHandle]] のデシリアライズ結果である秘密鍵材料ハンドルに設定する。
Note

この方法で構造化複製をサポートすることにより、 RTCCertificate インスタンスをストアに永続化できる。また postMessage(message, options) [html] のような API を使って他オリジンへ渡すことも可能になる。しかし、そのオブジェクトは元々作成したオリジン以外では使用できない。

5. RTPメディアAPI

RTPメディアAPIは、 ウェブアプリケーションがピアツーピア接続を通じて MediaStreamTrackを 送受信できるようにします。トラックが RTCPeerConnectionに追加されるとシグナリングが発生し、 このシグナリングがリモートピアに転送されることで、リモート側にも対応するトラックが作成されます。

ある RTCPeerConnection から送信されたトラックと相手側で受信されるトラックには、厳密な1:1対応関係はありません。 まず、送信側のトラックIDと受信側のトラックIDには対応関係がありません。 また、 replaceTrackは、 RTCRtpSenderが送信するトラックを変更しますが、 受信側で新しいトラックが作成されることはありません。対応する RTCRtpReceiverは常に一つのトラックだけを持ち、 そのトラックは複数のメディアソースが繋ぎ合わされている可能性があります。 addTransceiverreplaceTrackを使うことで 同じトラックを複数回送信することもでき、受信側ではそれぞれ独立したトラックとして複数のレシーバーから観測されます。 したがって、RTCRtpSender と、対応する受信側の RTCRtpReceiverのトラックとの間に 1:1関係があると考える方が正確です。必要に応じて RTCRtpTransceivermidで送信者と受信者を照合できます。

メディア送信時には、SDPでネゴシエートされた条件、エンコーダの整列制約、CPU過負荷検出や帯域幅推定など、様々な要件を満たすために メディアをリスケールやリサンプルする必要がある場合があります。

[RFC9429] (section 3.6.)に従い、 動画は縮小しても構いません。 メディアは、入力ソースに存在しない偽データを生成するために拡大してはならず、 ピクセル数の制約を満たすため以外には切り抜きしてはならず、 アスペクト比も変更してはなりません。

WebRTCワーキンググループは、この状況のより複雑な処理の必要性とタイムラインについて、実装者からのフィードバックを求めています。 いくつかの設計案がGitHub issue 1283で議論されています。

scaleResolutionDownBy により動画がリスケールされる場合、結果の幅や高さが整数にならないことがあります。 ユーザーエージェントは 整数部分 の幅・高さより大きな動画を送信してはなりません。 ただし、エンコーダの最小解像度を尊重する場合は例外です。 スケール後の幅または高さの整数部分がゼロの場合に送信すべき内容は 実装依存です。

MediaStreamTrackの 実際のエンコードと送信は RTCRtpSenderオブジェクトによって管理されます。 同様に、MediaStreamTrackの受信とデコードは RTCRtpReceiverオブジェクトによって管理されます。 各RTCRtpSenderは最大1つのトラックと関連し、 受信すべき各トラックは必ず1つの RTCRtpReceiverに関連付けられます。

MediaStreamTrackの エンコードと送信は、その特徴(動画の場合はwidthheightframeRate、 音声の場合はsampleSizesampleRatechannelCount)がリモート側で作成されるトラックによって ある程度保持されるようにすべきです。 しかし、必ずそうなるとは限らず、エンドポイントやネットワークのリソース制約や、 RTCRtpSenderの設定によって 実装が異なる動作を指示される場合があります。

RTCPeerConnectionオブジェクトは、 RTCRtpTransceiverの集合 を保持します。これは、ペアになった送信者と受信者の共有状態を表します。 この集合は RTCPeerConnectionオブジェクトが 作成された時点で空集合に初期化されます。 RTCRtpSenderおよび RTCRtpReceiverは 常にRTCRtpTransceiverの 作成時に同時に作られ、ライフタイム中ずっと紐付けられます。 RTCRtpTransceiverは、 アプリケーションが MediaStreamTrackRTCPeerConnectionaddTrack() メソッドで追加するか、 addTransceiverメソッドで 明示的に追加した時に暗黙的に作成されます。 また、リモート記述に新しいメディア記述が含まれている場合にも作成されます。 さらに、リモート記述がリモートエンドポイントが送信可能なメディアを持っていることを示している場合、 該当するMediaStreamTrack およびRTCRtpReceivertrackイベントを通じて アプリケーションに公開されます。

RTCRtpTransceiverが 他のエンドポイントとメディアを送受信するには、SDPで交渉される必要があり、 両方のエンドポイントが同じ RTCRtpTransceiverオブジェクトを 関連付けし、 同じメディア記述と結びつける必要があります。

オファー作成時には、全てのトランシーバーに対応するメディア記述が生成されます。 このオファーがローカル記述として設定されると、未関連のトランシーバーはオファー内のメディア記述と関連付けられます。

オファーがリモート記述として設定された場合、まだトランシーバーと関連していないメディア記述は 新規または既存のトランシーバーと関連付けられます。 この場合、addTrack() メソッドで作成された未関連のトランシーバーのみが関連付けられます。 addTransceiver() メソッドで作成された未関連のトランシーバーは、 たとえリモートオファーにメディア記述があっても関連付けられません。 代わりに、十分な addTrack() 作成のトランシーバーがなければ、新しくトランシーバーが作成・関連付けされます。 これにより、 addTrack() 作成と addTransceiver() 作成のトランシーバーは、属性を調べても判別できない重要な違いを持つことになります。

アンサー作成時には、オファーに含まれていたメディア記述のみがアンサーに記載されます。 そのため、リモートオファー設定時に関連付けされなかったトランシーバーは、 ローカルアンサー設定後も未関連のままとなります。 この状況は、アンサー側がフォローアップオファーを作成して再度オファー/アンサー交換を行うか、 addTrack() 作成のトランシーバーの場合は、最初の交換で十分なメディア記述がオファーされるようにすることで解消できます。

5.1 RTCPeerConnection インターフェイス拡張

RTPメディアAPIは、以下のように RTCPeerConnectionインターフェイスを拡張します。

WebIDL          partial interface RTCPeerConnection {
  sequence<RTCRtpSender> getSenders();
  sequence<RTCRtpReceiver> getReceivers();
  sequence<RTCRtpTransceiver> getTransceivers();
  RTCRtpSender addTrack(MediaStreamTrack track, MediaStream... streams);
  undefined removeTrack(RTCRtpSender sender);
  RTCRtpTransceiver addTransceiver((MediaStreamTrack or DOMString) trackOrKind,
                                   optional RTCRtpTransceiverInit init = {});
  attribute EventHandler ontrack;
};

属性

ontrackEventHandler

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

メソッド

getSenders

現在この RTCPeerConnection オブジェクトに接続されていて、停止していない RTCRtpTransceiver オブジェクトに属する RTP 送信者を表す RTCRtpSender オブジェクトのシーケンスを返します。

getSenders メソッドが呼び出されたとき、ユーザーエージェントは MUST(必須)で CollectSenders アルゴリズムを実行した結果を返さなければなりません。

CollectSenders アルゴリズムを次のように定義します:

  1. transceiversCollectTransceivers アルゴリズムを実行した結果とする。
  2. senders を新しい空のシーケンスとする。
  3. transceivers 内の各 transceiver について、
    1. もし transceiver.[[Stopped]]false なら、 transceiver.[[Sender]]senders に追加する。
  4. senders を返す。
getReceivers

現在この RTCPeerConnection オブジェクトに接続されていて、停止していない RTCRtpTransceiver オブジェクトに属する RTP 受信者を表す RTCRtpReceiver オブジェクトのシーケンスを返します。

getReceivers メソッドが呼び出されたとき、ユーザーエージェントは MUST 次の手順を実行します:

  1. transceiversCollectTransceivers アルゴリズムを実行した結果とする。
  2. receivers を新しい空のシーケンスとする。
  3. transceivers 内の各 transceiver について、
    1. もし transceiver.[[Stopped]]false なら、 transceiver.[[Receiver]]receivers に追加する。
  4. receivers を返す。
getTransceivers

現在この RTCPeerConnection オブジェクトに接続されている RTP トランシーバーを表す RTCRtpTransceiver オブジェクトのシーケンスを返します。

getTransceivers メソッドは MUST(必須)で CollectTransceivers アルゴリズムを実行した結果を返します。

CollectTransceivers アルゴリズムを次のように定義します:

  1. transceivers を、この RTCPeerConnection オブジェクトの set of transceivers に含まれるすべての RTCRtpTransceiver オブジェクトから構成される新しいシーケンスとし、その順序は挿入順とする。
  2. transceivers を返す。
addTrack

新しいトラックを RTCPeerConnection に追加し、指定された MediaStream に含まれていることを示します。

addTrack メソッドが呼び出されたとき、ユーザーエージェントは MUST 次の手順を実行します:

  1. connection を、このメソッドが呼び出された RTCPeerConnection オブジェクトとする。

  2. track を、メソッドの第一引数で示される MediaStreamTrack オブジェクトとする。

  3. kindtrack.kind とする。

  4. streams を、メソッドの残りの引数から構築された MediaStream オブジェクトのリストとし、メソッドが単一の引数で呼び出された場合は空リストとする。

  5. もし connection.[[IsClosed]]true なら、 例外を投げるInvalidStateError

  6. sendersCollectSenders アルゴリズムを実行した結果とする。 もし senders 内に track に対応する RTCRtpSender が既に存在するなら、 例外を投げるInvalidAccessError

  7. 既存の sender を再利用できるかどうかを判断する手順は以下のとおりです。再利用すると、今後の createOffercreateAnswer の呼び出しが、対応する media descriptionsendrecv または sendonly としてマークし、送信者のストリームの MSID を追加するようにします。これは [RFC9429] (セクション 5.2.2 および セクション 5.3.2) に定義されています。

    senders 内のいずれかの RTCRtpSender オブジェクトが以下の全ての条件に一致する場合、 sender をそのオブジェクトとし、そうでなければ null とする:

    • その sender の track が null である。

    • その sender に関連付けられた transceiver kindkind と一致する。

    • その sender に関連付けられた RTCRtpTransceiver[[Stopping]] スロットが false である。

    • その sender はこれまで送信に使用されたことがない。より厳密には、その sender に関連付けられた RTCRtpTransceiver[[CurrentDirection]] スロットがこれまでに "sendrecv" または "sendonly" の値を持ったことがない。

  8. もし sendernull でないなら、その sender を使用するために次の手順を実行する:

    1. sender.[[SenderTrack]]track に設定する。

    2. sender.[[AssociatedMediaStreamIds]] を空集合に設定する。

    3. streams 内の各 stream について、まだ存在しない場合は [[AssociatedMediaStreamIds]]stream.id を追加する。

    4. transceiver を、 sender に関連付けられた RTCRtpTransceiver とする。

    5. もし transceiver.[[Direction]] が "recvonly" なら、 transceiver.[[Direction]] を "sendrecv" に設定する。

    6. もし transceiver.[[Direction]] が "inactive" なら、 transceiver.[[Direction]] を "sendonly" に設定する。

  9. もし sendernull なら、次の手順を実行する:

    1. RTCRtpSender を作成し、 引数として trackkindstreams を渡し、結果を sender とする。

    2. RTCRtpReceiver を作成し、 引数として kind を渡し、結果を receiver とする。

    3. RTCRtpTransceiver を作成し、 senderreceiverRTCRtpTransceiverDirection の値 "sendrecv" を渡し、結果を transceiver とする。

    4. transceiverconnectionset of transceivers に追加する。

  10. トラックにはアプリケーションからアクセスできない内容が含まれている場合があります。これは、トラックを CORS によりクロスオリジン にする要因などによるものです。こうしたトラックは addTrack() メソッドに渡すことができ、RTCRtpSender が作成されますが、コンテンツは送信しては MUST NOT(禁止)です。トラックのコンテンツの代わりに、無音(音声)、黒フレーム(動画)、またはそれと同等のコンテンツなしが送信されます。

    この性質は時間とともに変化する可能性があることに注意してください。

  11. negotiation-needed フラグを更新し、 connection に対して適用する。

  12. sender を返す。

removeTrack

sender からのメディア送信を停止します。 RTCRtpSender は引き続き getSenders に表示されます。これにより、以後の createOffer の呼び出しは、対応するトランシーバーの media description を "recvonly" または "inactive" としてマークします。これは [RFC9429] (セクション 5.2.2) に定義されています。

他方のピアがこの方法でトラックの送信を停止した場合、当初 MediaStreamtrack イベントで公開された任意のリモートからトラックは削除され、 その MediaStreamTrack がまだミュートされていない場合は、 トラックで mute イベントが発火します。

対応するトランシーバーの RTCRtpTransceiverdirection 属性を設定し、送信者で RTCRtpSenderreplaceTrack(null) を呼び出すことで、 removeTrack() と同じ効果を得られます。小さな違いとして、 replaceTrack() は非同期であり、 removeTrack() は同期的です。

removeTrack メソッドが呼び出されたとき、ユーザーエージェントは MUST 次の手順を実行します:

  1. senderremoveTrack の引数とする。

  2. connection を、このメソッドが呼び出された RTCPeerConnection オブジェクトとする。

  3. もし connection.[[IsClosed]]true なら、 例外を投げるInvalidStateError

  4. もし senderconnection によって作成されたものでないなら、 例外を投げるInvalidAccessError

  5. transceiver を、 RTCRtpTransceiver のうち sender に対応するオブジェクトとする。

  6. もし transceiver.[[Stopping]]true なら、これ以降の手順を中止する。

  7. sendersCollectSenders アルゴリズムを実行した結果とする。

  8. もし sendersenders に含まれていないなら(これは、そのトランシーバーが停止したか、あるいは セッション記述の設定type が "rollback" のために削除されたことを示す)、 これ以降の手順を中止する。

  9. もし sender.[[SenderTrack]] が null なら、 これ以降の手順を中止する。

  10. sender.[[SenderTrack]] を null に設定する。

  11. もし transceiver.[[Direction]] が "sendrecv" なら、 transceiver.[[Direction]] を "recvonly" に設定する。

  12. もし transceiver.[[Direction]] が "sendonly" なら、 transceiver.[[Direction]] を "inactive" に設定する。

  13. negotiation-needed フラグを更新し、 connection に対して適用する。

addTransceiver

新しい RTCRtpTransceiver を作成し、 set of transceivers に追加します。

トランシーバーを追加すると、以後の createOffer の呼び出しで、対応するトランシーバーのための media description が追加されます。これは [RFC9429] (セクション 5.2.2) に定義されています。

mid の初期値は null です。 後で セッション記述の設定 により null 以外の値に変わる場合があります。

sendEncodings 引数は、提供されるシミュルキャストエンコーディングの数や、任意でそれらの RID とエンコーディングパラメータを指定するために使用できます。

このメソッドが呼び出されたとき、ユーザーエージェントは MUST 次の手順を実行します:

  1. init を第二引数とする。

  2. streamsinit.streams とする。

  3. sendEncodingsinit.sendEncodings とする。

  4. directioninit.direction とする。

  5. 第一引数が文字列の場合、kind を第一引数とし、次の手順を実行する:

    1. kind"audio" でも "video" でもない場合、 例外を投げるTypeError

    2. tracknull とする。

  6. 第一引数が MediaStreamTrack の場合、 track を第一引数とし、kindtrack.kind とする。

  7. もし connection.[[IsClosed]]true なら、 例外を投げるInvalidStateError

  8. sendEncodings を検証するため、次の addTransceiver sendEncodings 検証手順 を実行する。ここで、それぞれの RTCRtpEncodingParameters 辞書を「encoding」と呼ぶ:

    1. sendEncodings 内の各 rid の値が [RFC8851] のセクション 10 で規定された文法に適合することを検証する。 RID のいずれかがこれらの要件を満たさない場合は、 throw により TypeError を投げる。

      次のいずれかの条件を満たす場合、 例外を投げるTypeError
      • いずれかの encoding が rid メンバーを 含み、その値が [RFC8851] のセクション 10 で規定された文法要件に適合しない。
      • encoding のうち一部のみが rid メンバーを 含む
      • いずれかの encoding が rid メンバーを 含み、その値が sendEncodings 内の別の encoding に rid として 含まれる 値と同一である。
    2. いずれかの encoding が read-only parameter(ただし rid を除く)を 含む 場合、 例外を投げるInvalidAccessError

    3. 候補追加 49:codec を RTCRtpEncodingParameters に追加 (PR #2985)

      いずれかの encoding が codec メンバーを 含み、その値が 一致しない 場合( RTCRtpSendergetCapabilities(kind).codecs 内のいずれのコーデックとも)、 例外を投げるOperationError

    4. 候補追加 49:codec を RTCRtpEncodingParameters に追加 (PR #2985)

      ユーザーエージェントがネゴシエーションなしでのコーデック変更や、個々のエンコーディングごとのコーデック設定をサポートしない場合は、Promise を reject し、 新たに 作成された OperationError で拒否して返す。

    5. もし kind"audio" なら、 いずれかを 含む エンコーディングから scaleResolutionDownBy および maxFramerate メンバーを削除する。

    6. いずれかの encoding が scaleResolutionDownBy メンバーを 含み、その値が 1.0 より小さい場合、 例外を投げるRangeError

    7. sendEncodings 内で定義されている各 maxFramerate メンバーの値が 0.0 より大きいことを検証する。いずれかの maxFramerate の値がこの要件を満たさない場合、 例外を投げるRangeError

    8. maxN を、ユーザーエージェントがこの kind に対してサポートし得る同時エンコーディングの最大総数(最低でも 1)とする。 使用されるコーデックがまだ不明であるため、これは楽観的な数であるべきである。

    9. いずれかの encoding が scaleResolutionDownBy メンバーを 含む 場合、含まない各 encoding に対して scaleResolutionDownBy メンバーを値 1.0 で追加する。

    10. sendEncodings に格納されたエンコーディングの数が maxN を超える場合、 その長さが maxN になるまで末尾から sendEncodings を削減する。

    11. もし kind"video" で、どの encoding も scaleResolutionDownBy メンバーを 含まない 場合、各 encoding に scaleResolutionDownBy メンバーを追加し、その値を 2^(length of sendEncodings - encoding index - 1) とする。これにより、最後のエンコーディングにスケーリングが適用されない、小さい方から大きい方への解像度(例:長さが 3 の場合は 4:2:1)が得られる。

    12. 現在 sendEncodings に格納されているエンコーディングの数が 1 の場合、 唯一のエントリから rid メンバーを削除する。

      sendEncodings に単一のデフォルトの RTCRtpEncodingParameters を提供することで、シミュルキャストを使用しない場合でも、後から setParameters を使ってエンコーディングパラメータを設定できるようになります。
  9. RTCRtpSender を作成し、 trackkindstreamssendEncodings を渡し、結果を sender とする。

    もし sendEncodings が設定されている場合、以後の createOffer の呼び出しは、[RFC9429] (セクション 5.2.2 および セクション 5.2.1) に定義されるように、複数の RTP エンコーディングを送信するよう構成されます。 対応するリモート記述を伴う setRemoteDescription が呼び出され、[RFC9429] (セクション 3.7) に定義されるように、複数の RTP エンコーディングを受信できるなら、 RTCRtpSender は複数の RTP エンコーディングを送信でき、 トランシーバーの sender.getParameters() で取得されるパラメータは、ネゴシエートされたエンコーディングを反映します。

  10. RTCRtpReceiver を作成し、 kind を渡し、結果を receiver とする。

  11. RTCRtpTransceiver を作成し、 senderreceiverdirection を渡し、結果を transceiver とする。

  12. transceiverconnectionset of transceivers に追加する。

  13. negotiation-needed フラグを更新し、 connection に対して適用する。

  14. transceiver を返す。

WebIDLdictionary RTCRtpTransceiverInit {
  RTCRtpTransceiverDirection direction = "sendrecv";
  sequence<MediaStream> streams = [];
  sequence<RTCRtpEncodingParameters> sendEncodings = [];
};

辞書 RTCRtpTransceiverInit のメンバー

direction の型 RTCRtpTransceiverDirection、 既定値は「sendrecv
RTCRtpTransceiver の方向。
streams の型 sequence<MediaStream>

リモートの RTCPeerConnection の track イベントが、追加される RTCRtpReceiver に対応して発火したとき、 そのイベントに含められるストリーム。

sendEncodings の型 sequence<RTCRtpEncodingParameters>

メディアの RTP エンコーディング送信用パラメータを含むシーケンス。

WebIDLenum RTCRtpTransceiverDirection {
  "sendrecv",
  "sendonly",
  "recvonly",
  "inactive",
  "stopped"
};
RTCRtpTransceiverDirection 列挙の説明
列挙値 説明
sendrecv RTCRtpTransceiverRTCRtpSender sender は RTP の送信を提案し、リモートピアが受け入れ、かつ sender.getParameters().encodings[i].active が任意の i について true の場合に RTP を送信する。 また、RTCRtpTransceiverRTCRtpReceiver は RTP の受信を提案し、 リモートピアが受け入れた場合に RTP を受信する。
sendonly RTCRtpTransceiverRTCRtpSender sender は RTP の送信を提案し、リモートピアが受け入れ、かつ sender.getParameters().encodings[i].active が任意の i について true の場合に RTP を送信する。 RTCRtpTransceiverRTCRtpReceiver は RTP の受信を提案せず、 RTP を受信しない。
recvonly RTCRtpTransceiverRTCRtpSender は RTP の送信を提案せず、 RTP を送信しない。 RTCRtpTransceiverRTCRtpReceiver は RTP の受信を提案し、 リモートピアが受け入れた場合に RTP を受信する。
inactive RTCRtpTransceiverRTCRtpSender は RTP の送信を提案せず、 RTP を送信しない。 RTCRtpTransceiverRTCRtpReceiver も RTP の受信を提案せず、 RTP を受信しない。
stopped RTCRtpTransceiver は RTP を送信も受信もしない。 オファーではポート 0 を生成する。アンサーでは、 その RTCRtpSender は送信を提案せず、 RTCRtpReceiver は受信を提案しない。 これは終端状態である。

5.1.1 リモート MediaStreamTrack の処理

アプリケーションは、トランシーバーの direction を 「inactive」に設定して一時的に送受信の両方向を無効化するか、 「sendonly」に設定して受信側のみを拒否することで、 受信するメディア記述を拒否できる。再利用可能な形で m-line を恒久的に拒否するには、 RTCRtpTransceiverstop() を呼び出し、 その後自端からネゴシエーションを開始する必要がある。

process remote tracks を、 RTCRtpTransceiver transceiverdirectionmsidsaddListremoveList、および trackEventInits が与えられたときに実行するには、 次の手順を行う:

  1. 関連付けられたリモートストリームを設定 し、 transceiver.[[Receiver]]msidsaddListremoveList を用いる。

  2. もし direction が 「sendrecv」または 「recvonly」であり、 かつ transceiver.[[FiredDirection]] が 「sendrecv」でも 「recvonly」でもない場合、 あるいは直前の手順で addList の長さが増えた場合は、 リモートトラックの追加を処理 し、 transceivertrackEventInits を用いる。

  3. もし direction が 「sendonly」または 「inactive」なら、 transceiver.[[Receptive]]false に設定する。

  4. もし direction が 「sendonly」または 「inactive」であり、 かつ transceiver.[[FiredDirection]] が 「sendrecv」または 「recvonly」のいずれかであるなら、 リモートトラックの削除を処理 し、 対象の media description に対して transceivermuteTracks を用いる。

  5. transceiver.[[FiredDirection]]direction に設定する。

process the addition of a remote track を、RTCRtpTransceiver transceivertrackEventInits が与えられたときに実行するには、 次の手順を行う:

  1. receivertransceiver.[[Receiver]] とする。

  2. trackreceiver.[[ReceiverTrack]] とする。

  3. streamsreceiver.[[AssociatedRemoteMediaStreams]] とする。

  4. 新しい RTCTrackEventInit 辞書を作成し、 そのメンバーに receivertrackstreamstransceiver を設定して trackEventInits に追加する。

process the removal of a remote track を、RTCRtpTransceiver transceivermuteTracks を用いて実行するには、 次の手順を行う:

  1. receivertransceiver.[[Receiver]] とする。

  2. trackreceiver.[[ReceiverTrack]] とする。

  3. もし track.mutedfalse なら、 trackmuteTracks に追加する。

set the associated remote streams を、RTCRtpReceiver receivermsidsaddListremoveList が与えられたときに実行するには、 次の手順を行う:

  1. connection を、receiver に関連付けられた RTCPeerConnection オブジェクトとする。

  2. msids 内の各 MSID について、この connection に対してその id を持つ MediaStream オブジェクトがこれまでに作成されていない場合は、 その id を持つ MediaStream オブジェクトを作成する。

  3. streams を、この connection のために作成された MediaStream オブジェクトのリストとし、 その idmsids に対応するものとする。

  4. trackreceiver.[[ReceiverTrack]] とする。

  5. receiver.[[AssociatedRemoteMediaStreams]] 内の各 stream について、それが streams に存在しない場合は、 removeListstreamtrack のペアを追加する。

  6. streams 内の各 stream について、それが receiver.[[AssociatedRemoteMediaStreams]] に存在しない場合は、addListstreamtrack のペアを追加する。

  7. receiver.[[AssociatedRemoteMediaStreams]]streams に設定する。

5.2 RTCRtpSender インターフェイス

RTCRtpSender インターフェイスは、 アプリケーションが特定のMediaStreamTrackをどのようにエンコードし、 リモートピアに送信するかを制御できるようにします。 setParametersRTCRtpSender オブジェクトで 呼び出されると、エンコーディングが適切に変更されます。

MediaStreamTracktrack、文字列、kindMediaStream オブジェクトのリスト、 streams、およびオプションで RTCRtpEncodingParameters オブジェクトのリスト、 sendEncodings を指定して RTCRtpSenderを作成するには、以下の手順を実行します:

  1. senderを新しいRTCRtpSenderオブジェクトとします。

  2. sender[[SenderTrack]]内部スロットを持たせ、trackで初期化します。

  3. sender[[SenderTransport]] 内部スロットを持たせ、nullで初期化します。

  4. sender[[LastStableStateSenderTransport]]内部スロットを持たせ、 nullで初期化します。

  5. sender[[Dtmf]] 内部スロットを持たせ、nullで初期化します。

  6. kind"audio"の場合、 RTCDTMFSenderを作成し、 dtmfとして[[Dtmf]] 内部スロットをdtmfに設定します。

  7. sender[[AssociatedMediaStreamIds]]内部スロットを持たせ、 この送信者が関連付けられるMediaStreamオブジェクトのIDリストを表します。 [[AssociatedMediaStreamIds]] スロットは、senderが SDPで表される際に[RFC9429] (セクション 5.2.1.) に記載されるように使用されます。

  8. sender.[[AssociatedMediaStreamIds]]を 空の集合に設定します。

  9. streams内の各streamについて、 そのstream.id[[AssociatedMediaStreamIds]] に追加します(すでに存在しない場合)。

  10. sender[[SendEncodings]] 内部スロットを持たせ、RTCRtpEncodingParameters 辞書のリストを表します。

  11. sendEncodingsがこのアルゴリズムへの入力として与えられ、 空でない場合、[[SendEncodings]]スロットを sendEncodingsに設定します。そうでない場合は、新しい RTCRtpEncodingParameters 辞書を一つ含むリストに設定し、 kind"video"の場合は、 その辞書に1.0の値を持つ scaleResolutionDownBy メンバーを追加します。

    Note

    RTCRtpEncodingParameters 辞書には、デフォルトで値がtrueactive メンバーが含まれています。

  12. Candidate Correction 13:sRD(simulcastOffer)によって消されたridなしエンコーディングを復元します。 (PR #2797)

    sender[[LastStableRidlessSendEncodings]]内部スロットを持たせ、 nullで初期化します。

  13. sender[[SendCodecs]]内部スロットを持たせ、 RTCRtpCodecParameters 辞書のリストを表し、空のリストで初期化します。

  14. sender[[LastReturnedParameters]]内部スロットを持たせ、 getParameterssetParametersの トランザクションを一致させるために使用します。

  15. senderを返します。

WebIDL[Exposed=Window]
interface RTCRtpSender {
  readonly attribute MediaStreamTrack? track;
  readonly attribute RTCDtlsTransport? transport;
  static RTCRtpCapabilities? getCapabilities(DOMString kind);
  Promise<undefined> setParameters(RTCRtpSendParameters parameters,
      optional RTCSetParameterOptions setParameterOptions = {});
  RTCRtpSendParameters getParameters();
  Promise<undefined> replaceTrack(MediaStreamTrack? withTrack);
  undefined setStreams(MediaStream... streams);
  Promise<RTCStatsReport> getStats();
};

属性

track の型 MediaStreamTrack, 読み取り専用, nullable

track属性は、この RTCRtpSender オブジェクトに関連付けられているトラックです。 trackが終了した場合、 またはトラックの出力が無効化されている場合(すなわち、トラックが無効化および/またはミュートされている場合)、 RTCRtpSenderは、 MUST(必須)で黒いフレーム(ビデオ)を送信し、 MUST NOT(禁止)で音声を送信しません。 ビデオの場合、RTCRtpSenderは、 SHOULD(推奨)で1秒に1回黒いフレームを送信する必要があります。 tracknullの場合、 RTCRtpSenderは送信しません。 取得時、この属性は MUST[[SenderTrack]]スロットの値を返す必要があります。

transport の型 RTCDtlsTransport, 読み取り専用, nullable

transport属性は、 trackからRTPパケットの形式で送信される メディアのトランスポートです。 RTCDtlsTransportオブジェクトの 構築前、このtransport属性はnullになります。 バンドリングが使用される場合、複数のRTCRtpSender オブジェクトは 1つのtransportを共有し、 全て同じトランスポート上でRTPとRTCPを送信します。

取得時、この属性はMUST[[SenderTransport]]スロットの 値を返す必要があります。

メソッド

getCapabilities(静的)

静的な RTCRtpSender.getCapabilities() メソッドは、与えられた種類のメディアを送信するためにユーザーエージェントがサポートする能力の種類を、リソースやポート、その他の状態を確保することなく調べる手段を提供します。

getCapabilities メソッドが呼び出されたとき、ユーザーエージェントは次の手順を実行する MUST(必須):

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

  2. kind"video" でも "audio" でもない場合、null を返す。

  3. 新しい RTCRtpCapabilities 辞書を返し、その codecs メンバーを kind実装済み送信コーデック一覧 に初期化し、 headerExtensions メンバーを kind に対する 実装済み送信用ヘッダー拡張一覧 に初期化する。

実装済み送信コーデック一覧 は、与えられた kind について、ユーザーエージェントがそのメディア(video または audio)送信にサポートするコーデックに関する最も楽観的な見通しを表す RTCRtpCodec 辞書の 実装依存の一覧である。

実装済み送信用ヘッダー拡張一覧 は、与えられた kind について、ユーザーエージェントがそのメディア送信にサポートするヘッダー拡張に関する最も楽観的な見通しを表す RTCRtpHeaderExtensionCapability 辞書の 実装依存の一覧である。

これらのケイパビリティはデバイスに関する原則として永続的なクロスオリジン情報を提供し、アプリケーションのフィンガープリンティング面を増大させる。 プライバシーに敏感な状況では、ユーザーエージェントは共通のサブセットのみを報告するなどの緩和策を検討しても MAY よい。 (これはフィンガープリンティング要因です。)

返されるコーデックケイパビリティは setCodecPreferences() アルゴリズムや、それがどの入力で InvalidModificationError を投げるかに影響し、 また、送信用にネゴシエートされたコーデックに関して createOffer() および createAnswer() によって明らかにされる情報とも整合しているべきである。これはプライバシー緩和策の有効性を確保するためである。

setParameters

setParameters メソッドは、 track のエンコード方法とリモートピアへの送信方法を更新します。

setParameters が呼び出されたとき、ユーザーエージェントは次を実行する MUST:

  1. parameters をメソッドの第1引数とする。
  2. sender を、 RTCRtpSender オブジェクト(この setParameters が呼び出された対象)とする。
  3. transceiver を、 sender に関連付けられた RTCRtpTransceiver オブジェクト(すなわち sendertransceiver.[[Sender]])とする。
  4. もし transceiver.[[Stopping]]true なら、 新たに作成された InvalidStateErrorreject された Promise を返す。
  5. もし sender.[[LastReturnedParameters]]null なら、 新たに作成された InvalidStateErrorreject された Promise を返す。
  6. 次の setParameters 検証手順を実行して parameters を検証する:
    1. encodingsparameters.encodings とする。
    2. codecsparameters.codecs とする。
    3. 候補追加 49:codec を RTCRtpEncodingParameters に追加 (PR #2985)

      choosableCodecscodecs とする。

    4. 候補追加 49:codec を RTCRtpEncodingParameters に追加 (PR #2985)

      もし choosableCodecs が空のリストなら、 choosableCodecs を transceiver.[[PreferredCodecs]] に設定し、 実装済み送信コーデック一覧 に含まれないコーデックを除外する。

    5. 候補追加 49:codec を RTCRtpEncodingParameters に追加 (PR #2985)

      それでも choosableCodecs が空のリストなら、 choosableCodecs をトランシーバーの種類に対する 実装済み送信コーデック一覧 に設定する。

    6. N を、 RTCRtpEncodingParameters の、sender.[[SendEncodings]] に格納されている個数とする。
    7. 次のいずれかの条件に当てはまる場合、 新たに作成された InvalidModificationErrorreject された Promise を返す:
      • encodings.lengthN と異なる。
      • encodings の順序が変更されている。
      • parameters 内の任意のパラメータが Read-only parameter(RID など)としてマークされ、 その値が sender.[[LastReturnedParameters]] 内の対応する値と異なる。 これは transactionId にも適用される点に注意。
      • 候補追加 49:codec を RTCRtpEncodingParameters に追加 (PR #2985)
        encodings 内の任意の encoding が、 choosableCodecs に見つからない codec を codec dictionary match アルゴリズム(ignoreLevelstrue に設定)で照合した結果として 含む
    8. トランシーバーの種類"audio" の場合、 scaleResolutionDownBymaxFramerate を、それらを含むすべての encodings から削除する。

    9. トランシーバーの種類"video" の場合、 encodings 内で 含まない エンコーディングそれぞれに scaleResolutionDownBy メンバーを値 1.0 で追加する。

    10. トランシーバーの種類"video" で、 かつ encodings 内の任意のエンコーディングが scaleResolutionDownBy の値として 1.0 未満を含む場合、 新たに作成された RangeErrorreject された Promise を返す。

    11. encodings 内の各エンコーディングが maxFramerate メンバーを持ち、その値が 0.0 以上であることを検証する。要件を満たさない値がある場合、 新たに作成された RangeErrorreject された Promise を返す。

    12. 候補追加 49:codec を RTCRtpEncodingParameters に追加 (PR #2985)

      ユーザーエージェントが任意のエンコーディングに対するコーデック設定や、エンコーディングごとに異なるコーデック値の混在をサポートしない場合、 新たに作成された OperationErrorreject された Promise を返す。

  7. p を新しい Promise とする。
  8. 並行して、メディアスタックを構成して、 sender.[[SenderTrack]] を送信するために parameters を用いる。
    1. メディアスタックが parameters で正常に構成された場合、次の手順を実行するタスクをキューする:
      1. sender.[[LastReturnedParameters]]null に設定する。
      2. sender.[[SendEncodings]]parameters.encodings に設定する。
      3. Resolvepundefined で解決する。
    2. メディアスタックの構成中にエラーが発生した場合、次の手順を実行するタスクをキューする:
      1. ハードウェアリソースが利用できないことに起因するエラーの場合、 reject により p を 新たに作成した RTCError で拒否し、 その errorDetail を "hardware-encoder-not-available" に設定し、これ以降の手順を中止する。
      2. ハードウェアエンコーダーがparametersをサポートしないためにエラーが発生した場合、reject p を新しく作成されたRTCErrorで、 そのerrorDetail が "hardware-encoder-error" に設定されたもので拒否し、これらのステップを中止します。
      3. その他すべてのエラーについては、 reject により p を新たに作成された OperationError で拒否する。
  9. p を返す。

setParameters は SDP の再ネゴシエーションを引き起こさず、 Offer/Answer によってネゴシエートされた枠組みの範囲内でメディアスタックが送受信する内容のみを変更するために使用できます。 RTCRtpSendParameters 辞書の属性はこれを可能にしないように設計されており、変更できない cname のような属性は読み取り専用です。 他の項目(例えばビットレート)は、 maxBitrate のような上限で制御されます。 ユーザーエージェントは、SDP など他の箇所で指定されたビットレートに関する制約を満たしつつ、 指定された maxBitrate の最大値を超えないことを保証する必要があります。

getParameters

getParameters() メソッドは、RTCRtpSender オブジェクトにおける、 track のエンコードと リモートの RTCRtpReceiver への送信に関する現在のパラメータを返します。

getParameters が呼び出されたとき、ユーザーエージェントは次を実行する MUST:

  1. sender を、このゲッターが呼び出された RTCRtpSender オブジェクトとする。

  2. もし sender.[[LastReturnedParameters]]null でないなら、 sender.[[LastReturnedParameters]] を返し、これ以降の手順を中止する。

  3. result を次のように構築された新しい RTCRtpSendParameters 辞書とする:

  4. sender.[[LastReturnedParameters]]result に設定する。

  5. タスクをキューして、 sender.[[LastReturnedParameters]]null に設定する。

  6. result を返す。

getParameterssetParameters と組み合わせて、次のようにパラメータを変更するために使用できます:

async function updateParameters() {
  try {
    const params = sender.getParameters();
    // ... make changes to parameters
    params.encodings[0].active = false;
    await sender.setParameters(params);
  } catch (err) {
    console.error(err);
  }
}

setParameters の呼び出しが完了した後は、 以降の getParameters の呼び出しは変更後のパラメータ集合を返します。

replaceTrack

リネゴシエーションなしで、提供された別のトラック(または null のトラック)で、 RTCRtpSender の現在の track を置き換えようとします。

replaceTrack メソッドが呼び出されたとき、ユーザーエージェントは次を実行する MUST:

  1. sender を、この replaceTrack が呼び出された RTCRtpSender オブジェクトとする。

  2. transceiver を、sender に関連付けられた RTCRtpTransceiver オブジェクトとする。

  3. connection を、sender に関連付けられた RTCPeerConnection オブジェクトとする。

  4. withTrack をこのメソッドの引数とする。

  5. もし withTrack が非 null で、 withTrack.kindtransceiverトランシーバーの種類 と異なる場合、 新たに作成された TypeErrorreject された Promise を返す。

  6. connectionoperations chain に対し、次の手順を 連鎖して返す:

    1. もし transceiver.[[Stopping]]true なら、 新たに作成された InvalidStateErrorreject された Promise を返す。

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

    3. sending を、transceiver.[[CurrentDirection]] が "sendrecv" または "sendonly" の場合に true、それ以外は false とする。

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

      1. もし sendingtrue で、 withTracknull なら、 送信者に送信を停止させる。

      2. もし sendingtrue で、 withTracknull でないなら、 送信者がすでにネゴシエートされた枠組みに違反せずに直ちに withTrack を送信できるか判定し、できない場合は:

        1. 現在の realm の グローバルオブジェクトglobal として ネットワーキングタスクソース 上に グローバルタスクをキューし、 新たに作成された InvalidModificationErrorreject により p を拒否する。
        2. これ以降の手順を中止する。
      3. もし sendingtrue で、 withTracknull でないなら、 送信者に、既存のトラックの代わりにシームレスに withTrack の送信へ切り替えさせる。

      4. 次の手順を実行するタスクをキューする:

        1. もし connection.[[IsClosed]]true なら、これ以降の手順を中止する。

        2. sender.[[SenderTrack]]withTrack に設定する。

        3. 現在の realm の グローバルオブジェクトglobal として、 ネットワーキングタスクソース 上に グローバルタスクをキューし、 resolve により pundefined で解決する。

    5. p を返す。

解像度やフレームレートの変更はネゴシエーションを必要としない場合があります。ネゴシエーションが必要となる場合の例:

  1. [RFC6236] に記載のとおり、ネゴシエートされた imageattr の範囲外への解像度変更。
  2. フレームレートを、コーデックのブロックレートを超過させる値に変更すること。
  3. 生データと事前エンコード済みの形式が異なるビデオトラック。
  4. チャンネル数が異なるオーディオトラック。
  5. エンコードも行うソース(一般にハードウェアエンコーダ)は、ネゴシエートされたコーデックを生成できない場合がある。同様に、ソフトウェアソースはエンコーディングソースに対してネゴシエートされたコーデックを実装していない可能性がある。
setStreams

この送信者のトラックに関連付ける MediaStream を設定します。

setStreams メソッドが呼び出されたとき、ユーザーエージェントは次を実行する MUST:

  1. sender を、このメソッドが呼び出された RTCRtpSender オブジェクトとする。

  2. connection を、このメソッドが呼び出された RTCPeerConnection オブジェクトとする。

  3. もし connection.[[IsClosed]]true なら、例外を投げるInvalidStateError

  4. streams を、メソッドの引数から構築した MediaStream オブジェクトのリストとし、引数なしで呼び出された場合は空のリストとする。

  5. sender.[[AssociatedMediaStreamIds]] を空の集合に設定する。

  6. streams 内の各 stream について、 その stream.id[[AssociatedMediaStreamIds]] に、未登録であれば追加する。

  7. negotiation-needed フラグを更新し、 connection に適用する。

getStats

この送信者に関する統計のみを収集し、その結果を非同期に報告します。

getStats() メソッドが呼び出されたとき、ユーザーエージェントは次を実行する MUST:

  1. selector を、このメソッドが呼び出された RTCRtpSender オブジェクトとする。

  2. p を新しい Promise とし、次の手順を 並行して実行する:

    1. selector が示す統計を、 統計選択アルゴリズム に従って収集する。

    2. 現在の realm の グローバルオブジェクトglobal として、 ネットワーキングタスクソース 上に グローバルタスクをキューし、 収集した統計を含む RTCStatsReport オブジェクトで resolve により p を解決する。

  3. p を返す。

5.2.1 RTCRtpParameters 辞書

WebIDLdictionary RTCRtpParameters {
  required sequence<RTCRtpHeaderExtensionParameters> headerExtensions;
  required RTCRtcpParameters rtcp;
  required sequence<RTCRtpCodecParameters> codecs;
};
辞書 RTCRtpParameters のメンバー
headerExtensionssequence<RTCRtpHeaderExtensionParameters>, 必須

RTP ヘッダー拡張のパラメータを含むシーケンス。 読み取り専用パラメータ

rtcpRTCRtcpParameters, 必須

RTCP に使用されるパラメータ。読み取り専用パラメータ

codecssequence<RTCRtpCodecParameters>, 必須

RTCRtpSender が選択するメディアコーデックや、 RTX、RED、FEC メカニズムのエントリを含むシーケンス。 RTX を介した再送が有効になっている各メディアコーデックに対応するエントリが、 codecs に含まれ、 mimeType 属性で audio/rtx または video/rtx を介した再送を示し、 sdpFmtpLine 属性("apt" および "rtx-time" パラメータを提供)を持つ。 読み取り専用パラメータ

5.2.2 RTCRtpSendParameters 辞書

WebIDLdictionary RTCRtpSendParameters : RTCRtpParameters {
  required DOMString transactionId;
  required sequence<RTCRtpEncodingParameters> encodings;
};
辞書 RTCRtpSendParameters のメンバー
transactionIdDOMString, 必須

適用された最後のパラメータセットに対する一意の識別子。 setParameters が、以前の getParameters に基づいてのみ呼び出され、介入する変更がないことを保証する。 読み取り専用パラメータ

encodingssequence<RTCRtpEncodingParameters>, 必須

メディアの RTP エンコーディングに関するパラメータを含むシーケンス。

5.2.3 RTCRtpReceiveParameters 辞書

WebIDLdictionary RTCRtpReceiveParameters : RTCRtpParameters {
};

5.2.4 RTCRtpCodingParameters 辞書

WebIDLdictionary RTCRtpCodingParameters {
  DOMString rid;
};
辞書 RTCRtpCodingParameters のメンバー
ridDOMString

設定された場合、この RTP エンコーディングは [RFC9429] (セクション 5.2.1.) で定義されている RID ヘッダー拡張を使用して送信される。 RID は setParameters によって変更することはできない。 送信側では addTransceiver の中でのみ設定または変更可能である。 読み取り専用パラメータ

5.2.5 RTCRtpEncodingParameters 辞書

WebIDLdictionary RTCRtpEncodingParameters : RTCRtpCodingParameters {
  boolean active = true;
  RTCRtpCodec codec;
  unsigned long maxBitrate;
  double maxFramerate;
  double scaleResolutionDownBy;
};
辞書 RTCRtpEncodingParameters のメンバー
activeboolean, デフォルト値 true

このエンコーディングがアクティブに送信されていることを示します。 false に設定すると、このエンコーディングの送信が停止されます。 true に設定すると、このエンコーディングが送信されます。 値を false に設定しても SSRC が削除されることはないため、 RTCP BYE メッセージは送信されません。

候補追加 49:codec を RTCRtpEncodingParameters に追加 (PR #2985)
codecRTCRtpCodec

このエンコーディングの RTP ストリームに使用されるコーデックを選択するためのオプション値。 存在しない場合、ユーザーエージェントは送信用にネゴシエートされた任意のコーデックを使用することができます。

codec が設定され、 [[SendCodecs]] がネゴシエートされている場合、 ユーザーエージェントは、送信用に codec に一致する [[SendCodecs]] の最初のものを使用する SHOULD。 このマッチングは、 codec dictionary match アルゴリズムを使用し、 ignoreLevelstrue に設定して行われます。

maxBitrateunsigned long

存在する場合、このエンコーディングを送信するために使用できる最大ビットレートを示します。 ユーザーエージェントは、 maxBitrate の値を超えない範囲で、エンコーディング間で帯域幅を自由に割り当てることができます。 エンコーディングは、ここで指定された最大値よりもさらに制約を受ける場合もあります(たとえば、トランスポートやセッションごとの帯域幅制限など)。 maxBitrate は、[RFC3890] セクション 6.2.2 で定義されているトランスポートに依存しないアプリケーション固有の最大値(TIAS)と同じ方法で計算されます。 これは、IP や TCP、UDP などの他のトランスポートレイヤを含まない最大帯域幅を指します。 maxBitrate の単位はビット毎秒です。

ビットレートの実現方法は、メディアとエンコーディングに依存します。 ビデオの場合、フレームは常に可能な限り速く送信されますが、ビットレートが十分に低くなるまでフレームがドロップされる可能性があります。 したがって、ビットレートがゼロであっても 1 フレームの送信は可能です。 オーディオの場合、選択したエンコーディングに十分な帯域幅を送信できない場合、再生を停止する必要があるかもしれません。

maxFrameratedouble

このメンバーは、送信者の kind"video" の場合にのみ存在します。 存在する場合、このエンコーディングを送信するために使用できる最大フレームレートを示します(単位は fps)。 ユーザーエージェント は、 maxFramerate の値を超えない範囲でエンコーディング間の帯域幅を自由に割り当てることができます。

もし setParameters() で変更された場合、新しいフレームレートは現在のピクチャが完了した後に反映されます。 最大フレームレートをゼロに設定すると、次のフレームでビデオがフリーズする効果があります。

scaleResolutionDownBydouble

このメンバーは、送信者の kind"video" の場合にのみ存在します。 動画の解像度は、送信前に指定された値で各次元をスケールダウンします。 たとえば、値が 2.0 の場合、ビデオは各次元で 2 倍スケールダウンされ、結果として 1/4 サイズのビデオが送信されます。 値が 1.0 の場合、ビデオには影響しません。 値は 1.0 以上である必要があります。 デフォルトでは、スケーリングは逆順で 2 倍の因数を使用して適用され、解像度が小さい順から大きい順に並びます(例: 4:2:1)。 レイヤーが 1 つだけの場合、送信者はデフォルトでスケーリングを適用しません(すなわち scaleResolutionDownBy は 1.0 となります)。

5.2.6 RTCRtcpParameters 辞書

WebIDLdictionary RTCRtcpParameters {
  DOMString cname;
  boolean reducedSize;
};
辞書 RTCRtcpParameters のメンバー
cnameDOMString

RTCP によって使用されるカノニカル名 (CNAME)(例: SDES メッセージ内)。 読み取り専用パラメータ

reducedSizeboolean

縮小サイズの RTCP [RFC5506] が構成されている場合(true)、または [RFC3550] で指定された複合 RTCP(false)。 読み取り専用パラメータ

5.2.7 RTCRtpHeaderExtensionParameters 辞書

WebIDLdictionary RTCRtpHeaderExtensionParameters {
  required DOMString uri;
  required unsigned short id;
  boolean encrypted = false;
};
辞書 RTCRtpHeaderExtensionParameters のメンバー
uriDOMString, 必須

RTP ヘッダー拡張の URI。[RFC5285] に定義されている。 読み取り専用パラメータ

idunsigned short, 必須

ヘッダー拡張を識別するために RTP パケットに挿入される値。 読み取り専用パラメータ

encryptedboolean

ヘッダー拡張が暗号化されているかどうか。 読み取り専用パラメータ

RTCRtpHeaderExtensionParameters 辞書は、アプリケーションがヘッダー拡張が RTCRtpSender または RTCRtpReceiver 内で構成されているかどうかを確認できるようにします。 RTCRtpTransceivertransceiver に対して、 アプリケーションは SDP を解析することなく、以下のようにヘッダー拡張の "direction" パラメータ([RFC5285] セクション 5 で定義)を判断できます。

  1. sendonly: ヘッダー拡張は transceiver.sender.getParameters().headerExtensions にのみ含まれます。
  2. recvonly: ヘッダー拡張は transceiver.receiver.getParameters().headerExtensions にのみ含まれます。
  3. sendrecv: ヘッダー拡張は transceiver.sender.getParameters().headerExtensionstransceiver.receiver.getParameters().headerExtensions の両方に含まれます。
  4. inactive: ヘッダー拡張は transceiver.sender.getParameters().headerExtensions にも transceiver.receiver.getParameters().headerExtensions にも含まれません。

5.2.8 RTCRtpCodec 辞書

WebIDLdictionary RTCRtpCodec {
  required DOMString mimeType;
  required unsigned long clockRate;
  unsigned short channels;
  DOMString sdpFmtpLine;
};
辞書 RTCRtpCodec のメンバー

RTCRtpCodec 辞書はコーデックオブジェクトに関する情報を提供します。

mimeTypeDOMString, 必須

コーデックの MIME メディアタイプ/サブタイプ。 有効なメディアタイプおよびサブタイプは [IANA-RTP-2] に記載されています。

clockRateunsigned long, 必須

コーデックのクロックレート(ヘルツ単位)。

channelsunsigned short

存在する場合、チャネルの最大数(モノラル=1、ステレオ=2)を示します。

sdpFmtpLineDOMString

コーデックに対応する SDP 内の a=fmtp 行の "format specific parameters" フィールド。 存在する場合、以下の定義に従います。 [RFC9429] (セクション 5.8)

5.2.9 RTCRtpCodecParameters 辞書

WebIDLdictionary RTCRtpCodecParameters : RTCRtpCodec {
  required octet payloadType;
};
辞書 RTCRtpCodecParameters メンバー

RTCRtpCodecParameters 辞書はネゴシエートされたコーデックに関する情報を提供します。 RTCRtpCodec から継承されたフィールドはすべて 読み取り専用パラメータ でなければなりません

RTCRtpSenderの場合、sdpFmtpLineパラメータは [[CurrentRemoteDescription]] から取得され、 RTCRtpReceiverの場合、それらはローカル記述( [[PendingLocalDescription]]nullでない場合はそこから取得され、 [[CurrentLocalDescription]] それ以外の場合はそこから取得されます)。

payloadTypeoctet, 必須

このコーデックを識別するために使用されるRTPペイロードタイプ。 読み取り専用パラメータ

5.2.10 RTCRtpCapabilities 辞書

WebIDLdictionary RTCRtpCapabilities {
  required sequence<RTCRtpCodec> codecs;
  required sequence<RTCRtpHeaderExtensionCapability> headerExtensions;
};
辞書 RTCRtpCapabilities メンバー
codecssequence<RTCRtpCodec>, 必須

サポートされているメディアコーデック、RTX、REDおよびFECメカニズムのエントリ。 生成されたSDPオファーで異なるペイロードタイプを利用する組み合わせのみが提供されるべきです。 例:

  1. 2つのH.264/AVCコーデック、それぞれ異なるパケット化モード値をサポート。
  2. 異なるクロックレートを持つ2つのCNコーデック。

再送信をRTXで行う場合、codecsには単一のエントリしか存在してはならず、 sdpFmtpLineは存在してはなりません。

headerExtensionssequence<RTCRtpHeaderExtensionCapability>, 必須

サポートされているRTPヘッダー拡張。

5.2.11 RTCRtpHeaderExtensionCapability 辞書

WebIDLdictionary RTCRtpHeaderExtensionCapability {
  required DOMString uri;
};
辞書 RTCRtpHeaderExtensionCapability のメンバー
uriDOMString, 必須

RTP ヘッダー拡張の URI。[RFC5285] に定義されている。

5.2.12 RTCSetParameterOptions 辞書

WebIDLdictionary RTCSetParameterOptions {
};
辞書 RTCSetParameterOptions のメンバー

RTCSetParameterOptions は拡張性を考慮して、空の辞書として定義されています。

5.3 RTCRtpReceiver インターフェイス

RTCRtpReceiver インターフェイスは、 アプリケーションが MediaStreamTrack の受信を検査できるようにする。

文字列 kind を用いて RTCRtpReceiver を作成するには、次の手順を実行する:

  1. receiver を新しい RTCRtpReceiver オブジェクトとする。

  2. track を新しい MediaStreamTrack オブジェクト [GETUSERMEDIA] とする。track のソースは receiver によって提供される リモートソース である。 なお、track.idユーザーエージェント によって生成され、リモート側のいかなるトラック ID にも対応しない。

  3. track.kindkind に初期化する。

  4. 文字列 "remote "kind を連結した結果で track.label を初期化する。

  5. track.readyStatelive に初期化する。

  6. track.mutedtrue に初期化する。MediaStreamTrack セクションでは、属性 mutedMediaStreamTrack がメディアデータを受信しているかどうかを どのように反映するかについて説明している。

  7. receiver に内部スロット [[ReceiverTrack]] を持たせ、track で初期化する。

  8. receiver に内部スロット [[ReceiverTransport]] を持たせ、null で初期化する。

  9. receiver に内部スロット [[LastStableStateReceiverTransport]] を持たせ、 null で初期化する。

  10. receiver に内部スロット [[AssociatedRemoteMediaStreams]] を持たせる。 これはこのレシーバの MediaStreamTrack オブジェクトが関連付けられている MediaStream オブジェクトのリストを表し、空のリストで初期化する。

  11. receiver に内部スロット [[LastStableStateAssociatedRemoteMediaStreams]] を持たせ、空のリストで初期化する。

  12. receiver に内部スロット [[ReceiveCodecs]] を持たせる。これは RTCRtpCodecParameters 辞書のリストを表し、空のリストで初期化する。

  13. receiver に内部スロット [[LastStableStateReceiveCodecs]] を持たせ、 空のリストで初期化する。

  14. receiver に内部スロット [[JitterBufferTarget]] を持たせ、null で初期化する。

  15. receiver を返す。

WebIDL[Exposed=Window]
interface RTCRtpReceiver {
  readonly attribute MediaStreamTrack track;
  readonly attribute RTCDtlsTransport? transport;
  static RTCRtpCapabilities? getCapabilities(DOMString kind);
  RTCRtpReceiveParameters getParameters();
  sequence<RTCRtpContributingSource> getContributingSources();
  sequence<RTCRtpSynchronizationSource> getSynchronizationSources();
  Promise<RTCStatsReport> getStats();
  attribute DOMHighResTimeStamp? jitterBufferTarget;
};

属性

track の型 MediaStreamTrack, 読み取り専用

track 属性は、 この RTCRtpReceiver オブジェクト receiver に関連付けられているトラックである。

track.stop() は最終的な動作であり、 クローンには影響しない点に注意。receiver.track.stop()receiver を暗黙的に停止させないため、レシーバレポートは送信され続ける。 取得時、この属性は MUST [[ReceiverTrack]] スロットの値を返さなければならない。

transport の型 RTCDtlsTransport, 読み取り専用, nullable

transport 属性は、 レシーバの track のメディアが RTP パケットの形で受信される トランスポートである。RTCDtlsTransport オブジェクトの構築前は、 transport 属性は null となる。バンドリングが使用される場合、複数の RTCRtpReceiver オブジェクトは 1 つの transport を共有し、 同じトランスポート上で RTP および RTCP をすべて受信する。

取得時、この属性は MUST [[ReceiverTransport]] スロットの値を返さなければならない。

jitterBufferTarget の型 DOMHighResTimeStamp, nullable

この属性により、RTCRtpReceiver のジッタバッファが保持する メディアの目標時間(ミリ秒)をアプリケーションが指定できる。 これは ユーザーエージェント によるバッファリング量に影響し、 ひいては再送やパケットロス復旧にも影響する。目標値を変更することで、 再生遅延とネットワークジッタにより音声・映像フレームが枯渇するリスクとのトレードオフを制御できる。

ユーザーエージェント は、 許容最小ターゲット許容最大ターゲット を持つ MUST。 これらはネットワーク状況やメモリ制約に基づき、 ユーザーエージェント が提供可能または提供意図のある範囲を反映し、 いつでも変化しうる。

これは目標値である。遅延の変化は時間とともに徐々に観測されうる。 レシーバの平均ジッタバッファ遅延は、 jitterBufferDelay の差分を jitterBufferEmittedCount の差分で割ることで測定できる。

DTX を使用している場合でも平均遅延は想定される。例えば DTX 使用時に無音後にパケットが流れ始めると、 目標値を大きくすることで ユーザーエージェント が それらのパケットを再生するのではなくバッファリングするよう影響しうる。

取得時、この属性は MUST [[JitterBufferTarget]] 内部スロットの値を返さなければならない。

設定時、ユーザーエージェント は次の手順を実行する MUST:

  1. receiver を、セッターが呼び出された RTCRtpReceiver オブジェクトとする。

  2. target をセッターへの引数とする。

  3. もし target が負または 4000 ミリ秒を超えるなら、 例外を投げRangeError とする。

  4. receiver[[JitterBufferTarget]]target に設定する。

  5. track を、receiver[[ReceiverTrack]] とする。

  6. 並行して、次の手順の実行を開始する:

    1. 基盤システムに新しい target を通知する。 ただし targetnull の場合はアプリケーションの希望がないことを通知する。

      もし track が別の RTCRtpReceiver のトラックと 音声/映像の同期 のために同期されている場合、 ユーザーエージェント は両レシーバに対して 2 つの [[JitterBufferTarget]] のうち大きい方を用いる SHOULD

      基盤システムがジッタバッファターゲットを適用している間は、 実際のジッタバッファターゲットが常に 許容最小ターゲット許容最大ターゲット の範囲内にクランプされるようにする。

      ユーザーエージェント が 要求とは異なるターゲット(例: ネットワーク状況や物理メモリ制約による)を最終的に用いたとしても、 これは [[JitterBufferTarget]] 内部スロットには反映されない。

    2. 基盤システムのジッタバッファターゲットの変更は、 ユーザー体験を損なわないよう内部の音声または映像のバッファリングに段階的に影響する SHOULD。 音声サンプルや映像フレームは再生前に加速または減速される SHOULD。 これは 音声/映像の同期 や輻輳制御への対応と同様である。

      加速や減速の速度は、ネットワーク状況や受信している音声の種類(例: 音声、背景雑音)に応じて変化しうる。 パケットが受信されていることを前提に、1 秒のバッファリングを達成するまでに数秒かかる MAY が、30 秒を超えるべきではない SHOULD。速度は音声と映像で異なってもよい MAY

      音声については、加速・減速は insertedSamplesForDeceleration および removedSamplesForAcceleration によって測定できる。映像では、同一フレームを複数回レンダリングしたり、フレームがドロップされることがある。

メソッド

getCapabilities(静的)

静的な RTCRtpReceiver.getCapabilities() メソッドは、与えられた種類のメディアを受信するためにユーザーエージェントがサポートする能力の種類を、 リソースやポート、その他の状態を確保することなく調べる手段を提供する。

getCapabilities が呼び出されたとき、ユーザーエージェントは次の手順を実行する MUST:

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

  2. kind"video" でも "audio" でもない場合、null を返す。

  3. 新しい RTCRtpCapabilities 辞書を返し、その codecs メンバーを kind に対する 実装済み受信コーデック一覧 で初期化し、 headerExtensions メンバーを kind に対する 実装済み受信用ヘッダー拡張一覧 で初期化する。

実装済み受信コーデック一覧 は、 与えられた kind について、 RTCRtpCodec 辞書の 実装依存 のリストであり、 ユーザーエージェントがそのメディア(video または audio)の受信にサポートするコーデックに関する 最も楽観的な見通しを表す。

実装済み受信用ヘッダー拡張一覧 は、 与えられた kind についての 実装依存 のリストであり、 RTCRtpHeaderExtensionCapability 辞書で構成され、ユーザーエージェントがそのメディア(video または audio)の受信にサポートする ヘッダー拡張に関する楽観的な見通しを表す。

これらのケイパビリティはデバイスに関する原則として永続的なクロスオリジン情報を提供し、 アプリケーションのフィンガープリンティング面を増大させる。 プライバシーに敏感な状況では、ユーザーエージェントは共通のサブセットのみを報告するなどの緩和策を検討しても MAY よい。 (これはフィンガープリンティング要因です。)

返されるコーデックケイパビリティは setCodecPreferences() アルゴリズムや、それがどの入力で InvalidModificationError を投げるかに影響し、 また、受信用にネゴシエートされたコーデックに関して createOffer() および createAnswer() によって明らかにされる情報とも整合しているべきである。 これはプライバシー緩和策の有効性を確保するためである。

getParameters

getParameters() メソッドは、RTCRtpReceiver オブジェクトにおける、 track がどのようにデコードされるかの現在のパラメータを返す。

getParameters が呼び出されたとき、 RTCRtpReceiveParameters 辞書は次のように構築される:

  • headerExtensions シーケンスは、レシーバが現在受信する準備ができているヘッダー拡張に基づいて設定される。
  • codecs は、 内部スロット [[ReceiveCodecs]] の値に設定される。

    ローカル記述とリモート記述の両方がこのコーデックリストに影響しうる。 例えば 3 つのコーデックがオファーされた場合、レシーバはそれぞれを受信する準備をし、 getParameters からすべてを返す。 しかしリモートエンドポイントが 2 つだけで回答した場合、欠けているコーデックは レシーバがもはや受信準備をする必要がないため getParameters では返されなくなる。
  • rtcp.reducedSize は、レシーバが現在 reduced-size RTCP パケットを受信する準備ができていれば true、 そうでなければ false に設定される。 rtcp.cname は含めない。
getContributingSources

この RTCRtpReceiver が直近 10 秒間に受信した 各一意の CSRC 識別子について、 降順の timestamp 順で RTCRtpContributingSource を返す。

getSynchronizationSources

この RTCRtpReceiver が直近 10 秒間に受信した 各一意の SSRC 識別子について、 降順の timestamp 順で RTCRtpSynchronizationSource を返す。

getStats

このレシーバに関する統計のみを収集し、その結果を非同期に報告する。

getStats() メソッドが呼び出されたとき、ユーザーエージェントは次の手順を実行する MUST:

  1. selector を、このメソッドが呼び出された RTCRtpReceiver オブジェクトとする。

  2. p を新しい Promise とし、次の手順を 並行して実行する:

    1. selector によって示される統計を、 統計選択アルゴリズム に従って収集する。

    2. 現在の realm の グローバルオブジェクトglobal として、 ネットワーキングタスクソース 上に グローバルタスクをキューし、 収集した統計を含む RTCStatsReport オブジェクトで resolve により p を解決する。

  3. p を返す。

RTCRtpContributingSource および RTCRtpSynchronizationSource 辞書は、 それぞれ特定の寄与ソース(CSRC)または同期ソース(SSRC)に関する情報を含む。 1 つ以上の RTP パケットからの音声または映像フレームが RTCRtpReceiverMediaStreamTrack に配信されると、 ユーザーエージェントは、そのパケットの内容に基づいて 関連する RTCRtpContributingSourceRTCRtpSynchronizationSource の情報を更新するタスクを キューに入れる MUST。 SSRC 識別子に対応する RTCRtpSynchronizationSource 辞書に 関連する情報は毎回更新され、RTP パケットが CSRC 識別子を含む場合には、 それら CSRC 識別子に対応する RTCRtpContributingSource 辞書に関連する情報も更新される。 ユーザーエージェントは RTP パケットを RTP タイムスタンプの昇順で処理する MUST。ユーザーエージェントは直近 10 秒間に RTCRtpReceiverMediaStreamTrack に配信された RTP パケットからの情報を保持する MUST

MediaStreamTrack が再生のためにいかなるシンクにも接続されていなくても、 トラックが終了していない限り、 getSynchronizationSources および getContributingSources は最新の情報を返す。シンクは RTP パケットのデコードの前提条件ではない。
適合性セクション で述べられているように、 アルゴリズムとして表現された要件は、最終的な結果が等価である限り任意の方法で実装してよい。 したがって、特定のイベントループのタスク実行内で、特定の RTCRtpSynchronizationSource および RTCRtpContributingSource 辞書が 特定の時点の RTP ストリームからの情報を含むという結果が得られるのであれば、 毎フレームごとに実際にタスクをキューに入れる必要はない。
WebIDLdictionary RTCRtpContributingSource {
  required DOMHighResTimeStamp timestamp;
  required unsigned long source;
  double audioLevel;
  required unsigned long rtpTimestamp;
};

辞書 RTCRtpContributingSource のメンバー

timestamp の型 DOMHighResTimeStamp, 必須

このソースに由来する RTP パケットからのフレームが最後に RTCRtpReceiverMediaStreamTrack に配信された時刻を示す timestamptimestamp は、 その時点の Performance.timeOrigin + Performance.now() と定義される。

source の型 unsigned long, 必須

寄与ソースまたは同期ソースの CSRC または SSRC 識別子。

audioLevel の型 double

音声レシーバにのみ存在する。これは 0..1(線形)の値で、1.0 は 0 dBov、0 は無音、 0.5 は 0 dBov から約 6 dBSPL の音圧レベルの変化を表す。

CSRC に対しては、RFC 6465 ヘッダー拡張が存在する場合、 [RFC6465] で定義された レベル値から変換される MUST。存在しない場合、このメンバーは 省略される MUST

SSRC に対しては、[RFC6464] で定義された レベル値から変換される MUST。 受信パケットに RFC 6464 ヘッダー拡張が存在しない場合(相手がユーザーエージェントでない、またはレガシーエンドポイントなど)、 この値は省略される SHOULD

両 RFC はレベルを 0 から 127 の整数値として定義し、 システムがエンコード可能な最大の信号に対する負のデシベルでの音量を表す。 したがって、0 はシステムがエンコード可能な最大の信号、127 は無音を表す。

これらの値を 0..1 の線形範囲に変換するには、127 を 0 に変換し、 他のすべての値は次の式を用いて変換する: 10^(-rfc_level/20)

rtpTimestamp の型 unsigned long, 必須

timestamp において再生されたメディアの RTP タイムスタンプ。 [RFC3550] セクション 5.1 に定義される。

WebIDLdictionary RTCRtpSynchronizationSource : RTCRtpContributingSource {};

RTCRtpSynchronizationSource 辞書は、仕様が SSRC にのみ存在するデータを公開するための拡張ポイントとして機能することが期待されている。

5.4 RTCRtpTransceiver インターフェイス

RTCRtpTransceiver インターフェイスは、共通の メディアストリーム「identification-tag」 を共有する RTCRtpSenderRTCRtpReceiver の組み合わせを表す。 [RFC9429] (セクション 3.4.1) で定義されるように、 RTCRtpTransceiver は、その「mid」プロパティが null でなく、 メディア記述内の メディアストリーム「identification-tag」 と一致する場合、 その メディア記述関連付けられている と言い、 そうでなければ、その メディア記述 と切り離されていると言う。

RTCRtpTransceiver は、現行の記述とは 切り離されたまま、RFC9429 の新しい保留中の記述に関連付けられる場合がある。 これは ネゴシエーションが必要かの確認 において起こりうる。

RTCRtpTransceiverトランシーバの kind は、 関連付けられた RTCRtpReceiverMediaStreamTrack オブジェクトの kind によって定義される。

RTCRtpTransceiver を作成する ために、 RTCRtpReceiver オブジェクト receiverRTCRtpSender オブジェクト sender、および RTCRtpTransceiverDirectiondirection を用いて、次の手順を実行する:

  1. transceiver を新しい RTCRtpTransceiver オブジェクトとする。

  2. transceiver に内部スロット [[Sender]] を持たせ、 sender で初期化する。

  3. transceiver に内部スロット [[Receiver]] を持たせ、receiver で初期化する。

  4. transceiver に内部スロット [[Stopping]] を持たせ、false で初期化する。

  5. transceiver に内部スロット [[Stopped]] を持たせ、false で初期化する。

  6. transceiver に内部スロット [[Direction]] を持たせ、direction で初期化する。

  7. transceiver に内部スロット [[Receptive]] を持たせ、false で初期化する。

  8. transceiver に内部スロット [[CurrentDirection]] を持たせ、null で初期化する。

  9. transceiver に内部スロット [[FiredDirection]] を持たせ、null で初期化する。

  10. transceiver に内部スロット [[PreferredCodecs]] を持たせ、空のリストで初期化する。

  11. transceiver に内部スロット [[JsepMid]] を持たせ、null で初期化する。これは [RFC9429] (セクション 5.2.1 および セクション 5.3.1) で定義される 「RtpTransceiver mid property」であり、そこでのみ変更される。

  12. transceiver に内部スロット [[Mid]] を持たせ、null で初期化する。

  13. transceiver を返す。

トランシーバを作成しても、基盤となる RTCDtlsTransport および RTCIceTransport オブジェクトは作成されない。 これは セッション記述の設定 の処理の一部としてのみ行われる。
WebIDL[Exposed=Window]
interface RTCRtpTransceiver {
  readonly attribute DOMString? mid;
  [SameObject] readonly attribute RTCRtpSender sender;
  [SameObject] readonly attribute RTCRtpReceiver receiver;
  attribute RTCRtpTransceiverDirection direction;
  readonly attribute RTCRtpTransceiverDirection? currentDirection;
  undefined stop();
  undefined setCodecPreferences(sequence<RTCRtpCodec> codecs);
};

属性

midDOMString、読み取り専用、nullable

mid 属性は、ローカルおよびリモートの記述で ネゴシエートされ存在する メディアストリーム 「identification-tag」 である。取得時、この属性は [[Mid]] スロットの値を返さなければならない (MUST)。

senderRTCRtpSender、読み取り専用

sender 属性は、 mid = [[Mid]] で送信されうる RTP メディアに対応する RTCRtpSender を公開する。 取得時、この属性は [[Sender]] スロットの値を返さなければならない (MUST)。

receiverRTCRtpReceiver、読み取り専用

receiver 属性は、 mid = [[Mid]] で受信されうる RTP メディアに対応する RTCRtpReceiver である。 取得時、この属性は [[Receiver]] スロットの値を返さなければならない (MUST)。

directionRTCRtpTransceiverDirection

[RFC9429] (セクション 4.2.4) に定義されるように、 direction 属性はこのトランシーバの希望する方向を示す。これは createOffer および createAnswer の呼び出しで使用される。 方向性の更新は即座には効力を持たない。代わりに、以降の createOffer および createAnswer の呼び出しは、 対応する メディア記述sendrecvsendonlyrecvonly または inactive の印を付ける。 これは [RFC9429] (セクション 5.2.2 および セクション 5.3.2) に従う。

取得時、ユーザーエージェントは次の手順を実行しなければならない (MUST)。

  1. transceiver を、ゲッターが呼び出された RTCRtpTransceiver オブジェクトとする。

  2. もし transceiver[[Stopping]]true なら、"stopped" を返す。

  3. それ以外の場合は、[[Direction]] スロットの値を返す。

設定時、ユーザーエージェントは次の手順を実行しなければならない (MUST)。

  1. transceiver を、セッターが呼び出された RTCRtpTransceiver オブジェクトとする。

  2. connection を、transceiver に関連付けられた RTCPeerConnection オブジェクトとする。

  3. もし transceiver[[Stopping]]true なら、例外を投げInvalidStateError とする。

  4. newDirection をセッターの引数とする。

  5. もし newDirectiontransceiver[[Direction]] と等しければ、 これらの手順を中止する。

  6. もし newDirection が "stopped" と等しければ、 例外を投げTypeError とする。

  7. transceiver[[Direction]]newDirection に設定する。

  8. ネゴシエーション必要フラグを更新 する(connection に対して)。

currentDirectionRTCRtpTransceiverDirection、 読み取り専用、nullable

[RFC9429] (セクション 4.2.5) に定義されるように、 currentDirection 属性はこのトランシーバに対してネゴシエートされた現在の方向を示す。 currentDirection の値は RTCRtpEncodingParameters.active の値とは独立であり、 互いに一方から他方を推測することはできない。オファー/アンサー交換に一度も表れていない場合は null。トランシーバが stopped の場合、 値は "stopped" となる。

取得時、ユーザーエージェントは次の手順を実行しなければならない (MUST)。

  1. transceiver を、ゲッターが呼び出された RTCRtpTransceiver オブジェクトとする。

  2. もし transceiver[[Stopped]]true なら、"stopped" を返す。

  3. それ以外の場合は、 [[CurrentDirection]] スロットの値を返す。

メソッド

stop

すでに stopped でない限り、トランシーバを stopping として不可逆にマークする。 これにより直ちに、トランシーバの sender は送信を停止し、receiver は受信を停止する。 stop() の呼び出しは、 この ネゴシエーション必要フラグの更新 を、 この RTCRtpTransceiver に関連付けられた RTCPeerConnection に対して行う。

stopping のトランシーバは、以降の createOffer の呼び出しで、 対応する メディア記述 にゼロポートを生成させる。 これは [RFC9429] (セクション 4.2.1) に従う (この場合に限って、ユーザーエージェントは RFC9429 の目的のために stopping のトランシーバを stopped として扱わなければならない (MUST))。 ただし、[RFC8843] との問題を避けるため、 stopping ではあるが stopped ではないトランシーバは、 createAnswer に影響しない。

stopped のトランシーバは、 以降の createOffer または createAnswer の呼び出しで、 対応する メディア記述 にゼロポートを生成させる。 これは [RFC9429] (セクション 4.2.1) に従う。

トランシーバは stopping の状態のままである。ただし、 リモートのオファーまたはアンサーにおける m-line の拒否を setRemoteDescription が処理することにより stopped になる場合を除く。

stopping ではあるが stopped ではないトランシーバは、 常にネゴシエーションが必要となる。実際には、トランシーバに対して stop() を呼び出すと、 両端でネゴシエーションが完了することが許される限り、そのトランシーバは最終的に stopped になる。

stop メソッドが呼び出されたとき、 ユーザーエージェントは次の手順を実行しなければならない (MUST)。

  1. transceiver を、このメソッドが呼び出された RTCRtpTransceiver オブジェクトとする。

  2. connection を、transceiver に関連付けられた RTCPeerConnection オブジェクトとする。

  3. もし connection[[IsClosed]]true なら、例外を投げInvalidStateError とする。

  4. もし transceiver[[Stopping]]true なら、これらの手順を中止する。

  5. 送受信の停止transceiver に対して行う。

  6. ネゴシエーション必要フラグを更新 する(connection に対して)。

送受信の停止 アルゴリズムは、 transceiver と、省略可能な disappear(既定は false)を与えられた場合、 次のとおりである。

  1. sender を、 transceiver[[Sender]] とする。

  2. receiver を、 transceiver[[Receiver]] とする。

  3. 並行してsender によるメディアの送信を停止し、 sender が送信していた各 RTP ストリームに対して RTCP BYE を送信する。 これは [RFC3550] に従う。

  4. 並行してreceiver によるメディアの受信を停止する。

  5. もし disappearfalse であれば、 receiver[[ReceiverTrack]]ended にする手順を実行する。 これはイベントを発火させる。

  6. transceiver[[Direction]] を "inactive" に設定する。

  7. transceiver[[Stopping]]true に設定する。

RTCRtpTransceiver の停止 アルゴリズムは、 transceiver と、省略可能な disappear(既定は false)を与えられた場合、 次のとおりである。

  1. もし transceiver[[Stopping]]false なら、 送受信の停止transceiverdisappear に対して行う。

  2. transceiver[[Stopped]]true に設定する。

  3. transceiver[[Receptive]]false に設定する。

  4. transceiver[[CurrentDirection]]null に設定する。

setCodecPreferences
候補追加 51:setCodecPreferences は送受信コーデックの両方をサポート(direction でフィルタ) (PR #3018)

setCodecPreferences メソッドは、ユーザーエージェント がネゴシエーションに入力として用いる既定の コーデック優先順位を上書きする。When セッション記述を生成する際( createOffer または createAnswer のいずれかを使用する場合)、 ユーザーエージェントは使用しなければならない ユーザーエージェントは、 direction に基づいて 優先コーデックをフィルタし、 その結果が空でないリストであれば、 指定された コーデックを codecs 引数の順序で使用し、 該当するメディアセクションに適用しなければならない (MUST)。

このメソッドにより、アプリケーションは特定のコーデック(RTX/RED/FEC を含む)のネゴシエーションを無効化できる また、アプリケーションは、リストの先頭に現れるコーデックをリモートピアに優先させることもできる。無効化したいコーデックを除くすべてを列挙することで

m= セクションが受信に使用される場合、SDP(オファーおよびアンサー)のコーデック順序は、 ローカルエンドポイントが受信を希望するコーデックの優先度をリモートに伝える。 m= セクションが受信に使用されない場合でも、独自のコーデック優先がないアンサー側は、 既定で同じ順序をアンサーに用いる。

RTCRtpSender はデフォルトで、 リモートエンドポイントが受信を希望すると示したものを送信するが、 アプリケーションはネゴシエート済みの codecs の中から どのコーデックを送るかを、 setParameters を呼び、 送信する codec を指定することで変更できる。 RTCRtpReceiver は、 ネゴシエートされた任意のコーデックを受信する準備がある。

コーデック優先順位は、この RTCRtpTransceiver を含む createOffer および createAnswer の すべての呼び出しに対して有効であり、このメソッドを再度呼ぶまで持続する。 codecs を空のシーケンスに設定すると優先順位は既定値にリセットされるシーケンスに設定する、または direction でのフィルタ後に空になった場合は、 既定のコーデック優先順位となる。

コーデックには SDP の各 m= セクションの下にペイロードタイプが列挙され、ペイロードタイプとコーデックの対応が定義される。 これらのペイロードタイプは m=video または m=audio 行で優先順位の順に参照され、 ネゴシエーションされなかったコーデックはこのリストに現れない( [RFC9429] のセクション 5.2.1 に定義)。 以前にネゴシエートされたコーデックが後に削除された場合、 そのコーデックは m=video または m=audio 行から消え、将来のオファーやアンサーでそのペイロードタイプを再利用すべきではないが、 SDP 内のペイロードタイプの対応からも削除されることがある。

渡された codecs シーケンスは setCodecPreferences にのみ含めることができます。は、codecs を設定しようとする試みを拒否します。一致しない コーデックは、以下によって返されるコーデックに限られます。 次のいずれかに見つかったものである必要があります。 RTCRtpSender.getCapabilities(kind) または RTCRtpReceiver.getCapabilities(kind)、 ここで kind は、メソッドが呼び出される RTCRtpTransceiver の種類です。

Note

[SDP] の勧告により、 createAnswer の呼び出しは、オファーに現れるコーデックとコーデック優先順位の共通部分のみを使用するべきである (SHOULD)。例えば、コーデック優先が "C, B, A" で、 オファーに "A, B" しか含まれない場合、アンサーは "B, A" のみを含めるべきである。 しかし、[RFC8829] (セクション 5.3.1) は オファーにないコーデックの追加を許容しているため、実装は異なる振る舞いをすることがある。

setCodecPreferences()呼び出されたとき、ユーザーエージェント は 次の手順を実行しなければならない (MUST)。

  1. transceiver を、このメソッドが呼び出された RTCRtpTransceiver オブジェクトとする。

  2. codecs を第 1 引数とする。

  3. もし codecs が空リストなら、 transceiver[[PreferredCodecs]]codecs に設定し、これらの手順を中止する。

  4. codecs 内の 重複 を削除し、各値の最初の出現位置は保持する。

  5. kind を、transceiverトランシーバの kind とする。

  6. codecCapabilities を、 RTCRtpSender.getCapabilities(kind).codecsRTCRtpReceiver.getCapabilities(kind).codecs の和集合とする。

  7. codecs の各 codec について、

    1. もし codeccodecCapabilities のいずれのコーデックにも 一致 しなければ、 InvalidModificationError を投げる。

  8. もし codecs に RTX, RED, FEC または Comfort Noise のエントリのみが含まれる、あるいは空集合であれば、 InvalidModificationError を投げる。 これは、transceiverdirection に関わらず 常に申し出る何かを持つことを保証する。

  9. transceiver[[PreferredCodecs]]codecs に設定する。

codec dictionary match アルゴリズムは、2 つの RTCRtpCodec 辞書 firstsecond、および省略可能な ignoreLevels(指定されない場合は false)を受け取り、 次のとおりに行う。

  1. もし first.mimeType が、 second.mimeTypeASCII 大文字小文字を無視した一致にならないなら、false を返す。

  2. もし first.clockRatesecond.clockRate と異なるなら、 false を返す。

  3. first.channelssecond.channels の 片方のみが欠落している、または両方が存在していて値が異なる場合は、false を返す。

  4. first.sdpFmtpLinesecond.sdpFmtpLine の 片方のみが欠落している場合、false を返す。

  5. first.sdpFmtpLinesecond.sdpFmtpLine が両方とも 存在する場合、次の手順を実行する:

    1. もし first.sdpFmtpLine または second.sdpFmtpLine のどちらかが key-value 形式でない場合、両者の等価比較の結果を返す。

    2. firstMediaFormat を、 first.sdpFmtpLine から構成された メディアフォーマットの key-value マップとし、 secondMediaFormatsecond.sdpFmtpLine から構成された メディアフォーマットの key-value マップとする。

      どの FMTP パラメータがメディアフォーマットを構成するかはコーデック固有である。 場合によっては、あるパラメータが省略されても推定可能であり、その場合はそのコーデックのメディアフォーマットの一部とみなされる。

    3. もし firstMediaFormatsecondMediaFormat と等しくなければ、 false を返す。

    4. 候補修正 52:level-id が一致しなくても 2 つのコーデックは同一と見なす (PR #3023)

      もし ignoreLevelsfalse で、 first.sdpFmtpLinesecond.sdpFmtpLine から推定される 準拠ビットストリームの最高レベルが異なるなら、false を返す。

      ignoreLevelstrue の場合でも、 一部のコーデック(例: H.264)はメディアフォーマットにレベルを含むため、 レベルを無視するにはコーデック固有の解析が必要になる。

  6. true を返す。

設定された場合、オファラーの受信コーデック優先順位はオファー内のコーデック順を決定する。 アンサー側にコーデック優先がない場合、アンサーでも同じ順序が使用される。 しかし、アンサー側にも優先がある場合、アンサーではその優先が順序を上書きする。 この場合、オファラーの優先は、どのコーデックがオファーに載るかに影響するが、 最終的な順序には影響しない。

5.4.1 Simulcast 機能

Simulcast 送信機能は、 addTransceiver メソッドの sendEncodings 引数、または setRemoteDescription メソッドによって有効化される。これらはいずれも RTCPeerConnection オブジェクト上のメソッドである。 さらに、 各 setParameters メソッドを用いて、 機能を確認・変更できる。

RTCRtpSendersimulcast エンベロープ は、 単一送信ではなく Simulcast を送信することを伴う最初の成功したネゴシエーションで確立され、 送信可能な Simulcast ストリームの最大数と、 その encodings の順序を含む。 この simulcast エンベロープ は、 後続の再ネゴシエーションで(レイヤ数を減らす形で)狭めることはできるが、再拡張はできない。 個々の Simulcast ストリームの特性は、 setParameters メソッドを使って変更できるが、 simulcast エンベロープ 自体はそのメソッドでは変更できない。

Simulcast を構成する 1 つの方法は、 sendEncodings オプションを addTransceiver() に渡す方法である。 addTrack() メソッドには Simulcast を構成するために必要な sendEncodings 引数が存在しないが、ユーザーエージェントがアンサー側である場合、sender を Simulcast に昇格させることができる。 Simulcast の受信を申し出るリモートオファーとともに setRemoteDescription メソッドを呼び出すと、指定されたセッション記述に記載されたレイヤを含むように RTCRtpSender 上に proposed envelope が設定される。 この記述がロールバックされない限り、ネゴシエーションが完了すると proposed envelopeRTCRtpSendersimulcast エンベロープ になる。 前述のとおり、この simulcast エンベロープ は 後続の再ネゴシエーションで狭めることはできるが、再拡張はできない。

Candidate Correction 12:RTP の一時停止/再開を非対応としてマークする (PR #2755)

setParameters では simulcast simulcast エンベロープを変更できないが、を変更できないとしても、 送信されるストリームの本数やその特性を制御することは可能である。 setParameters を用いれば、 Simulcast ストリームは active メンバーを false に設定することで非アクティブ化でき、逆に active メンバーを true に設定して再度有効化できる。 [RFC7728](RTP の一時停止/再開)はサポートされない。SDP の Offer/Answer による一時停止/再開のシグナリングもサポートされない。 setParameters を用いれば、 ストリームの特性は maxBitrate のような属性を変更することで 調整できる。

Simulcast は SFU に複数のエンコーディングを送る用途で頻繁に使われ、SFU はそのうちの 1 本の Simulcast ストリームをエンドユーザーへ転送する。 したがってユーザーエージェントは、すべての Simulcast ストリームが単独でも使用可能となるよう、エンコーディング間に帯域を割り当てることが期待される。 例えば 2 本の Simulcast ストリームが同じ maxBitrate を持つなら、 両ストリームで類似のビットレートが観測されることが期待される。帯域幅の制約により、すべての Simulcast ストリームを有用な形で送信できない場合は、 ユーザーエージェントが一部の Simulcast ストリームの送信を停止することが期待される。

[RFC9429] (セクション 3.7) に定義されるように、 ユーザーエージェントからのオファーは a=simulcast 行において "send" 記述のみを含み、 "recv" 記述は含まない。代替案や制限( [RFC8853] に記載)には対応しない。

本仕様は、createOffercreateAnswer、または addTransceiver を使って 複数の RTP エンコーディングの受信を構成する方法を定義しない。しかし、 setRemoteDescription が、 [RFC9429] に定義される複数 RTP エンコーディングの送信が可能な 対応するリモート記述とともに呼び出され、かつブラウザが複数の RTP エンコーディングの受信をサポートする場合、 RTCRtpReceiver は複数の RTP エンコーディングを受信でき、 トランシーバの receiver.getParameters() を通じて取得されるパラメータは、 ネゴシエートされたエンコーディングを反映する。

RTCRtpReceiver は、選択型転送装置(SFU)が ユーザーエージェントから受信した Simulcast ストリーム間を切り替えるシナリオで、複数の RTP ストリームを受信できる。 SFU が転送前に切り替えられたストリームを単一の RTP ストリームにまとめるよう RTP ヘッダを書き換えない場合、 RTCRtpReceiver は、それぞれ固有の SSRC とシーケンス番号空間を持つ 別個の RTP ストリームからパケットを受信する。SFU はある時点で 1 本の RTP ストリームしか転送しない場合でも、 並べ替えの結果、複数の RTP ストリームからのパケットが受信側で混在することがある。複数の RTP ストリームを受信できる RTCRtpReceiver は、受信パケットを正しく並べ替え、 起こりうる損失イベントを認識して対処できる必要がある。このシナリオでの正しい動作は容易ではないため、 本仕様の実装においては任意である。

5.4.1.1 エンコーディングパラメータの例

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

エンコーディングパラメータを用いた Simulcast シナリオの例:

// 解像度が最も低いレイヤーを除き、すべて無効化された3層の空間Simulcastの例
var encodings = [
  {rid: 'q', active: true, scaleResolutionDownBy: 4.0}
  {rid: 'h', active: false, scaleResolutionDownBy: 2.0},
  {rid: 'f', active: false},
];

5.4.2 「保留」機能

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

direction 属性と replaceTrack メソッドを組み合わせることで、 開発者は「保留」シナリオを実装することができます。

ピアに音楽を送信し、受信した音声の再生を停止する(音楽保留)には:

async function playMusicOnHold() {
  try {
    // audioトランシーバとmusicTrackという名前の音楽トラックがあると仮定します
    await audio.sender.replaceTrack(musicTrack);
    // 受信音声をミュートする
    audio.receiver.track.enabled = false;
    // directionをsend-onlyに設定する(ネゴシエーションが必要)
    audio.direction = 'sendonly';
  } catch (err) {
    console.error(err);
  }
}

リモートピアの「sendonly」オファーに応答するには:

async function handleSendonlyOffer() {
  try {
    // まずsendonlyオファーを適用して、
    // レシーバーがICE候補に対応できるようにする
    await pc.setRemoteDescription(sendonlyOffer);
    // 音声の送信を停止する
    await audio.sender.replaceTrack(null);
    // さらなるネゴシエーションを避けるためにdirectionを調整する
    audio.direction = 'recvonly';
    // createAnswerを呼び出してrecvonlyのアンサーを送信する
    await doAnswer();
  } catch (err) {
    // シグナリングエラーを処理する
  }
}

音楽の送信を停止し、マイクロフォンからキャプチャした音声を送信する。同時に受信音声を再生するには:

async function stopOnHoldMusic() {
  // audioトランシーバとmicTrackという名前のマイクトラックがあると仮定します
  await audio.sender.replaceTrack(micTrack);
  // 受信音声のミュートを解除する
  audio.receiver.track.enabled = true;
  // directionをsendrecvに設定する(ネゴシエーションが必要)
  audio.direction = 'sendrecv';
}

リモートピアから保留解除された場合に応答するには:

async function onOffHold() {
  try {
    // まずsendrecvオファーを適用して、レシーバーがICE候補に対応できるようにする
    await pc.setRemoteDescription(sendrecvOffer);
    // 音声の送信を開始する
    await audio.sender.replaceTrack(micTrack);
    // directionをsendrecvに設定する(アンサーの直前)
    audio.direction = 'sendrecv';
    // createAnswerを呼び出してsendrecvのアンサーを送信する
    await doAnswer();
  } catch (err) {
    // シグナリングエラーを処理する
  }
}

5.5 RTCDtlsTransport インターフェイス

RTCDtlsTransport インターフェイスは、アプリケーションが Datagram Transport Layer Security (DTLS) トランスポートに関する情報にアクセスすることを可能にします。 このトランスポートは、RTP および RTCP パケットが RTCRtpSender および RTCRtpReceiver オブジェクトによって送受信されるトランスポートであり、 またデータチャネルによって送受信される SCTP パケットなどの他のデータについても含まれます。 特に、DTLS は基礎となるトランスポートにセキュリティを追加し、 RTCDtlsTransport インターフェイスは 基礎となるトランスポートおよび追加されたセキュリティに関する情報へのアクセスを可能にします。 RTCDtlsTransport オブジェクトは、 setLocalDescription() または setRemoteDescription() の呼び出しの結果として構築されます。 各 RTCDtlsTransport オブジェクトは、 RTP または RTCP の特定の component のための DTLS トランスポート層を表します。また、 [RFC8843] を介してそのような グループがネゴシエーションされた場合には、RTCRtpTransceiver のグループを表します。

既存の RTCRtpTransceiver のための新しい DTLS アソシエーションは、 既存のRTCDtlsTransport オブジェクトによって表され、 そのstate が適切に更新されることになります。 これは、新しいオブジェクトによって表されるのではありません。

RTCDtlsTransport には、[[DtlsTransportState]] という内部スロットがあり、初期値として "new" が設定されています。また、 [[RemoteCertificates]] スロットは 空のリストとして初期化されます。

基礎となる DTLS トランスポートで、証明書検証の失敗や致命的なアラート([RFC5246] セクション 7.2 を参照)などのエラーが発生した場合、ユーザーエージェントは以下のステップを実行するタスクをキューに追加しなければなりません

  1. transport を、状態の更新とエラー通知を受け取る RTCDtlsTransport オブジェクトとします。

  2. transport の状態がすでに "failed" である場合、 これらのステップを中止します。

  3. transport.[[DtlsTransportState]] を "failed" に設定します。

  4. イベントを発火し、error という名前を付けます。 このイベントは RTCErrorEvent インターフェイスを使用し、errorDetail 属性を "dtls-failure" または "fingerprint-failure" のいずれかに設定します。他のフィールドは RTCErrorDetailType 列挙型の記述に従って設定し、transport で発火します。

  5. イベントを発火し、statechange という名前を付け、 transport で発火します。

基礎となる DTLS トランスポートが、対応する RTCDtlsTransport オブジェクトの状態を他の理由で更新する必要がある場合、 ユーザーエージェントは以下のステップを実行するタスクをキューに追加しなければなりません

  1. transport を、状態の更新を受け取る RTCDtlsTransport オブジェクトとします。

  2. newState を新しい状態とします。

  3. transport.[[DtlsTransportState]]newState に設定します。

  4. newStateconnected の場合、 newRemoteCertificates を、リモート側で使用されている証明書チェーンとし、 各証明書をバイナリの Distinguished Encoding Rules (DER) [X690] で エンコードされたものとします。そして、 transport.[[RemoteCertificates]]newRemoteCertificates に設定します。

  5. イベントを発火し、statechange という名前を付け、 transport で発火します。

WebIDL[Exposed=Window]
interface RTCDtlsTransport : EventTarget {
  [SameObject] readonly attribute RTCIceTransport iceTransport;
  readonly attribute RTCDtlsTransportState state;
  sequence<ArrayBuffer> getRemoteCertificates();
  attribute EventHandler onstatechange;
  attribute EventHandler onerror;
};

属性

iceTransport の型は RTCIceTransport で、 読み取り専用

iceTransport 属性はパケットの送受信に使用される基礎トランスポートです。この基礎トランスポートは、複数のアクティブな RTCDtlsTransport オブジェクト間で共有されない場合があります。

state の型は RTCDtlsTransportState で、 読み取り専用

state 属性は、 取得時に [[DtlsTransportState]] スロットの値を返さなければ なりません

onstatechange の型は EventHandler
このイベントハンドラーのイベントタイプは statechange です。
onerror の型は EventHandler
このイベントハンドラーのイベントタイプは error です。

メソッド

getRemoteCertificates

[[RemoteCertificates]] の値を返します。

5.5.1 RTCDtlsTransportState 列挙型

WebIDLenum RTCDtlsTransportState {
  "new",
  "connecting",
  "connected",
  "closed",
  "failed"
};
RTCDtlsTransportState 列挙型の説明
列挙値 説明
new DTLS はまだネゴシエーションを開始していません。
connecting DTLS は安全な接続をネゴシエートし、リモートフィンガープリントを検証中です。
connected DTLS は安全な接続のネゴシエーションを完了し、リモートフィンガープリントを検証しました。
closed トランスポートは、close_notify アラートの受信、または close() の呼び出しの結果として意図的に終了されました。
failed トランスポートは、エラー(エラーアラートの受信やリモートフィンガープリントの検証失敗など)の結果として失敗しました。

5.5.2 RTCDtlsFingerprint 辞書

RTCDtlsFingerprint 辞書には、 [RFC4572] に記載されているように、ハッシュ関数アルゴリズムと証明書フィンガープリントが含まれます。

WebIDLdictionary RTCDtlsFingerprint {
  DOMString algorithm;
  DOMString value;
};
辞書 RTCDtlsFingerprint メンバー
algorithm の型は DOMString

'Hash function Textual Names' レジストリ [IANA-HASH-FUNCTION] に定義されている ハッシュ関数アルゴリズムのいずれか。

value の型は DOMString

[RFC4572] セクション5に記載された 'fingerprint' の構文を使用して表現された 小文字の16進文字列形式の証明書フィンガープリントの値。

5.6 RTCIceTransport インターフェイス

RTCIceTransport インターフェイスは、 パケットが送受信される ICE トランスポートに関する情報にアプリケーションがアクセスすることを可能にします。 特に、ICE はピアツーピア接続を管理し、アプリケーションがアクセスしたい状態を含む場合があります。 RTCIceTransport オブジェクトは、 setLocalDescription() または setRemoteDescription() の呼び出しの結果として構築されます。 基礎となる ICE の状態は ICE エージェント によって管理されます。 そのため、RTCIceTransport の状態は、 以下で説明するように、ICE エージェント がユーザーエージェントに指示を与えるときに変化します。 各 RTCIceTransport オブジェクトは、 特定の RTP または RTCP の component、 または [RFC8843] を介してネゴシエートされた場合には、RTCRtpTransceiver のグループのための ICE トランスポート層を表します。

既存の RTCRtpTransceiver のための ICE 再起動は、 既存のRTCIceTransport オブジェクトによって表され、 そのstate が適切に更新されることになります。 これは、新しいオブジェクトによって表されるのではありません。
Candidate Correction 24:ICE ギャザリングの完了時に 2 つのタスクをキューに追加し、gatheringstatechange と icegatheringstatechange を同じタスク内で発火させる (PR #2894)

ICEエージェント世代の候補をRTCIceTransport transportRTCPeerConnection connectionに関連付けて収集し始めたとき、ユーザーエージェントは次のステップを実行するタスクをキューに追加しなければならない:

  1. このICEエージェントに関連付けられたRTCPeerConnection オブジェクトをconnectionとする。

  2. もしconnection.[[IsClosed]]trueである場合、これらのステップを中止する。

  3. 候補収集が始まったRTCIceTransporttransportとする。

  4. transport.[[IceGathererState]]gatheringに設定する。

    .

  5. connection.[[IceGatheringState]]RTCIceGatheringState列挙型によって記述された新しい状態値を導出することで得られる値に設定する。

  6. もし前のステップでconnection.[[IceGatheringState]] が変更された場合、connectionIceGatheringStateChangedtrueとし、それ以外の場合はfalseとする。

  7. これ以降、状態を読み取ったり変更したりしてはならない。

  8. イベントgatheringstatechangetransportで発火する。

  9. ICE収集状態を更新connectionに対して行う。

  10. もしconnectionIceGatheringStateChangedtrueである場合、イベントicegatheringstatechangeconnectionで発火する。

ICEエージェント世代の候補をRTCIceTransport transportRTCPeerConnection connectionに関連付けて収集を完了し、それらの候補がアプリケーションに提供されたとき、ユーザーエージェントは次のステップを実行するタスクを実行するをキューに追加する:

  1. このICEエージェントに関連付けられたRTCPeerConnection オブジェクトをconnectionとする。

  2. もしconnection.[[IsClosed]]trueである場合、これらのステップを中止する。

  3. 候補収集が完了したRTCIceTransporttransportとする。

  4. もしconnection.[[PendingLocalDescription]]nullでなく、ICE 世代 を表しており、収集が終了した場合、 a=end-of-candidatesconnection.[[PendingLocalDescription]].sdp に追加する。

  5. もしconnection.[[CurrentLocalDescription]]nullでなく、ICE 世代 を表しており、収集が終了した場合、 a=end-of-candidatesconnection.[[CurrentLocalDescription]].sdp に追加する。

  6. newCandidateendOfGatheringCandidateRTCIceCandidateを作成する結果とし、新しい辞書の sdpMidsdpMLineIndex をこのRTCIceTransport に関連付けられた値に設定し、 usernameFragment を候補が収集された世代のユーザー名フラグメントに設定し、 candidate空文字列""に設定する。

  7. イベントicecandidateRTCPeerConnectionIceEvent インターフェイスを使用して候補属性をnewCandidateendOfGatheringCandidateに設定し、connection で発火する。

  1. もし、別の世代の候補がまだ収集されている場合、これらのステップを中止する。

    これは、ICEエージェントが前の世代の候補を収集している間にICE再起動が開始された場合に発生することがあります。
  2. transport.[[IceGathererState]]completeに設定する。

  3. イベントを発火する名前付きgatheringstatechangetransportで。

  4. ICE収集状態を更新する connectionの。

ICEエージェントが上記のタスクをキューに追加し、他の世代の候補が収集されていない場合、ユーザーエージェントは次のステップを実行するために2番目のタスクをキューに追加しなければならない:

他の世代の候補がまだ収集されている可能性があります。 これは、ICEエージェントが前の世代の候補を収集している間にICE再起動が開始された場合に発生することがあります。
  1. もしconnection.[[IsClosed]]trueである場合、これらのステップを中止する。

  2. transport.[[IceGathererState]]completeに設定する。

  3. connection.[[IceGatheringState]]RTCIceGatheringState列挙型で記述される新しい状態値を導出する値に設定する。

  4. 前のステップでconnection.[[IceGatheringState]]が変更された場合、connectionIceGatheringStateChangedtrueとし、それ以外の場合はfalseとする。

  5. これ以降、状態を読み取ったり変更したりしてはならない。

  6. イベントgatheringstatechangetransportで発火する。

  7. もしconnectionIceGatheringStateChangedtrueである場合、イベントicegatheringstatechangeconnectionで発火する。

  8. イベント名前付きicecandidateRTCPeerConnectionIceEvent インターフェイスを使用して候補属性をnullに設定しconnectionで発火する。

    null候補イベントはレガシー互換性を確保するために発火されます。 新しいコードはRTCIceTransportおよび/またはRTCPeerConnectionの収集状態を監視する必要があります。

ICEエージェントが、新しいICE候補が RTCIceTransport のために利用可能であることを示した場合、ICE候補プールから取得するか、または新たに収集するかに関わらず、 ユーザーエージェントは以下のステップを実行するタスクをキューに追加しなければならない:

  1. candidateを利用可能なICE候補とする。

  2. connectionを、このICEエージェントに関連付けられた RTCPeerConnection オブジェクトとする。

  3. もしconnection.[[IsClosed]]trueである場合、これらのステップを中止する。

  4. もし connection.[[PendingLocalDescription]] または connection.[[CurrentLocalDescription]]のいずれかが nullでなく、candidateが収集されたICE 世代 を表している場合、候補を表面化するcandidateconnectionを使用)し、これらのステップを中止する。

  5. それ以外の場合、candidateconnection.[[EarlyCandidates]] に追加する。

ICEエージェント が、[RFC8445] セクション7.3.1.1に基づく役割衝突を含むICEバインディングリクエストによりICE役割が変更されたことを通知した場合、UAはタスクをキューに追加し、 [[IceRole]] の値を新しい値に設定します。

connection早期候補を解放するには、以下のステップを実行します:

  1. connection.[[EarlyCandidates]] 内の各候補candidateに対して、candidateconnectionを使用して 候補を表面化する タスクをキューに追加します。

  2. connection.[[EarlyCandidates]]を空のリストに設定します。

candidateconnectionを使用して候補を表面化するには、以下のステップを実行します:

  1. もしconnection.[[IsClosed]]trueである場合、これらのステップを中止します。

  2. candidateが利用可能にされるRTCIceTransporttransportとします。

  3. もしconnection.[[PendingLocalDescription]]nullでなく、candidateが収集されたICE 世代 を表している場合、candidateconnection.[[PendingLocalDescription]].sdp に追加します。

  4. もしconnection.[[CurrentLocalDescription]]nullでなく、candidateが収集されたICE 世代 を表している場合、candidateconnection.[[CurrentLocalDescription]].sdp に追加します。

  5. 新しい辞書を使用してRTCIceCandidateを作成する結果を newCandidateとし、 sdpMidsdpMLineIndexを このRTCIceTransport に関連付けられた値に設定し、 usernameFragmentを 候補のユーザー名フラグメントに設定し、 candidatecandidate-attribute 文法を使用してcandidateを表現する文字列に設定します。

  6. newCandidatetransportのローカル候補セットに追加します。

  7. イベントicecandidateを使用して、 RTCPeerConnectionIceEvent インターフェイスを使用し、候補属性をnewCandidateに設定してconnection で発火します。

RTCIceTransportStateRTCIceTransportの候補ペアが利用可能な接続を持ち、選択された場合や、選択された候補ペアが変わらないまま変更される可能性があります。 選択されたペアとRTCIceTransportStateは関連があり、同じタスク内で処理されます。

ICEエージェントRTCIceTransportの選択された候補ペア、 RTCIceTransportState、またはその両方が変更されたことを示した場合、ユーザーエージェントは 選択された候補ペアと状態を変更する手順を実行するタスクをキューに追加しなければならない:

  1. connectionを、このRTCPeerConnectionオブジェクトとする。

  2. もしconnection.[[IsClosed]]trueである場合、これらのステップを中止する。

  3. transportを、状態が変化している RTCIceTransportとする。

  4. selectedCandidatePairChangedfalseとする。

  5. transportIceConnectionStateChangedfalseとする。

  6. connectionIceConnectionStateChangedfalseとする。

  7. connectionStateChangedfalseとする。

  8. もしtransportの選択された候補ペアが変更された場合、以下のステップを実行する:

    1. RTCIceCandidatePairを作成する 結果をnewCandidatePairとし、ローカルおよびリモート候補を表す localおよびremoteを持つペアを示し、選択されていない場合はnullとする。

    2. transport.[[SelectedCandidatePair]]newCandidatePairに設定する。

    3. selectedCandidatePairChangedtrueに設定する。

  9. もしtransportRTCIceTransportStateが変更された場合、以下のステップを実行する:

    1. transport.[[IceTransportState]]を、新しい RTCIceTransportStateに設定する。

    2. transportIceConnectionStateChangedtrueに設定する。

    3. connection.[[IceConnectionState]]を、 RTCIceConnectionState列挙型で記述される新しい状態値に設定する。

    4. もしconnection.[[IceConnectionState]]が前のステップで変更された場合、 connectionIceConnectionStateChangedtrueに設定する。

    5. connection.[[ConnectionState]]を、 RTCPeerConnectionState列挙型で記述される新しい状態値に設定する。

    6. もしconnection.[[ConnectionState]]が前のステップで変更された場合、 connectionStateChangedtrueに設定する。

  10. もしselectedCandidatePairChangedtrueである場合、 イベント selectedcandidatepairchangetransportで発火する。

  11. もしtransportIceConnectionStateChangedtrueである場合、 イベント statechangetransportで発火する。

  12. もしconnectionIceConnectionStateChangedtrueである場合、 イベント iceconnectionstatechangeconnectionで発火する。

  13. もしconnectionStateChangedtrueである場合、 イベント connectionstatechangeconnectionで発火する。

RTCIceTransport オブジェクトには以下の内部スロットがあります:

WebIDL[Exposed=Window]
interface RTCIceTransport : EventTarget {
  readonly attribute RTCIceRole role;
  readonly attribute RTCIceComponent component;
  readonly attribute RTCIceTransportState state;
  readonly attribute RTCIceGathererState gatheringState;
  sequence<RTCIceCandidate> getLocalCandidates();
  sequence<RTCIceCandidate> getRemoteCandidates();
  RTCIceCandidatePair? getSelectedCandidatePair();
  RTCIceParameters? getLocalParameters();
  RTCIceParameters? getRemoteParameters();
  attribute EventHandler onstatechange;
  attribute EventHandler ongatheringstatechange;
  attribute EventHandler onselectedcandidatepairchange;
};

属性

roleRTCIceRole, 読み取り専用

role属性は、 取得時に[[IceRole]]内部スロットの値を返さなければならない

componentRTCIceComponent, 読み取り専用

component属性は、 トランスポートのICEコンポーネントを返さなければならない。 RTCP mux が使用される場合、単一のRTCIceTransportがRTP とRTCPの両方をトランスポートし、 componentは "rtp"に設定される。

stateRTCIceTransportState, 読み取り専用

state属性は、 取得時に[[IceTransportState]] スロットの値を返さなければならない

gatheringStateRTCIceGathererState, 読み取り専用

gatheringState 属性は、取得時に[[IceGathererState]] スロットの値を返さなければならない

onstatechangeEventHandler
このイベントハンドラーは、イベントハンドラーイベントタイプ statechange に属し、RTCIceTransportstate が変更されたときに発火しなければならない
ongatheringstatechangeEventHandler
このイベントハンドラーは、イベントハンドラーイベントタイプ gatheringstatechange に属し、 RTCIceTransport[[IceGathererState]] が変更されたときに発火しなければならない
onselectedcandidatepairchangeEventHandler
このイベントハンドラーは、イベントハンドラーイベントタイプ selectedcandidatepairchange に属し、 RTCIceTransportの選択された候補ペアが変更されたときに発火しなければならない

メソッド

getLocalCandidates

このRTCIceTransportのために収集され、 onicecandidate で送信されたローカルICE候補を記述するシーケンスを返します。

getRemoteCandidates

このRTCIceTransportaddIceCandidate() 経由で受信したリモートICE候補を記述するシーケンスを返します。

getRemoteCandidates はピアリフレクティブ候補を公開しません。これは、 addIceCandidate() を介して受信されないためです。
getSelectedCandidatePair

パケットが送信される選択された候補ペアを返します。このメソッドは、 [[SelectedCandidatePair]] スロットの値を返さなければならないRTCIceTransport.stateが "new" または "closed" の場合、 getSelectedCandidatePairnullを返します。

getLocalParameters

このRTCIceTransportsetLocalDescription 経由で受信したローカルICEパラメータを返します。パラメータがまだ受信されていない場合はnullを返します。

getRemoteParameters

このRTCIceTransportsetRemoteDescription 経由で受信したリモートICEパラメータを返します。パラメータがまだ受信されていない場合はnullを返します。

5.6.1 RTCIceParameters 辞書

WebIDLdictionary RTCIceParameters {
  DOMString usernameFragment;
  DOMString password;
};
辞書 RTCIceParameters メンバー
usernameFragmentDOMString

[RFC5245]セクション 7.1.2.3で定義されているICEユーザー名フラグメント。

passwordDOMString

[RFC5245]セクション 7.1.2.3で定義されているICEパスワード。

候補追加 45:RTCIceCandidatePair辞書をインターフェイスに変換 (PR #2961)

5.6.2 RTCIceCandidatePair 辞書

5.6.2 RTCIceCandidatePair インターフェイス

このインターフェイスはICE候補ペアを表し、[RFC8445]セクション4で説明されています。 RTCIceCandidatePairは ローカルおよびリモートのRTCIceCandidateのペアリングです。

RTCIceCandidatePairを作成するには、 RTCIceCandidateオブジェクトlocalremoteを使用して、以下のステップを実行します:

  1. candidatePairを新たに作成したRTCIceCandidatePairオブジェクトとします。
  2. candidatePair[[Local]]内部スロットを持たせ、localで初期化します。
  3. candidatePair[[Remote]]内部スロットを持たせ、remoteで初期化します。
  4. candidatePairを返します。
dictionary [Exposed=Window]
interface RTCIceCandidatePair {
  [SameObject] readonly attribute RTCIceCandidate local;
  [SameObject] readonly attribute RTCIceCandidate remote;
};
辞書 RTCIceCandidatePair メンバー
属性
localRTCIceCandidate , 読み取り専用

ローカルICE候補。

local 属性は、取得時に[[Local]]内部スロットの値を返さなければならない

remoteRTCIceCandidate , 読み取り専用

リモートICE候補。

remote 属性は、取得時に[[Remote]]内部スロットの値を返さなければならない

5.6.3 RTCIceGathererState 列挙型

WebIDLenum RTCIceGathererState {
  "new",
  "gathering",
  "complete"
};
RTCIceGathererState 列挙型の説明
列挙値 説明
new RTCIceTransportが 作成されたばかりで、候補の収集をまだ開始していない状態。
gathering RTCIceTransportが 候補を収集している最中の状態。
complete RTCIceTransportが 候補の収集を完了し、このトランスポートの候補終了指示が送信された状態。 ICE再起動が発生し、再開するまで候補は再収集されない。

5.6.4 RTCIceTransportState 列挙型

WebIDLenum RTCIceTransportState {
  "closed",
  "failed",
  "disconnected",
  "new",
  "checking",
  "completed",
  "connected"
};
RTCIceTransportState の説明
列挙値 説明
closed RTCIceTransport はシャットダウンしており、もはや STUN 要求に応答しません。
failed
RTCIceTransport は収集を完了し、これ以上リモート候補がないことの通知を受け取り、すべての候補ペアの検査を終え、全ペアが接続性チェックに失敗したか同意を失っており、さらにローカル候補が 0 件であったか、PAC タイマーが期限切れになっています [RFC8863]。これは ICE が再起動されるまでの終端状態です。ICE の再起動によって接続性が回復する可能性があるため、 "failed" 状態に入っても、DTLS トランスポート、SCTP アソシエーション、またはその上で動作するデータチャネルが閉じられたり、トラックがミュートされたりすることはありません。
disconnected ICE エージェント は、この RTCIceTransport の接続性が現在失われていると判断しました。これは一時的な状態で、品質の不安定なネットワークでは断続的に発生し(対応しなくても自然に解消することがあります)。この状態の判定方法は実装依存です。例としては:
  • 使用中の接続に対するネットワークインターフェイスを失う。
  • STUN 要求への応答受信に繰り返し失敗する。
あるいは、RTCIceTransport が既存の候補ペアの検査をすべて終えても接続が見つからず(かつ、いったん成功していた同意の鮮度確認 [RFC7675] が失敗した)、それでもなお収集中である、または追加のリモート候補を待機している場合です。
new RTCIceTransport は候補の収集中またはリモート候補の提供を待機中で、まだ検査を開始していません。
checking RTCIceTransport は少なくとも 1 つのリモート候補を受信しており(addIceCandidate() によるか、STUN Binding 要求の受信時にピア反射候補として発見)、候補ペアの検査を行っていて、まだ接続が見つかっていないか、以前に成功していた候補ペアのすべてで同意の鮮度確認 [RFC7675] が失敗しています。検査に加えて、引き続き候補の収集中である場合もあります。
completed RTCIceTransport は収集を完了し、これ以上リモート候補がないことの通知を受け取り、すべての候補ペアの検査を終えて接続を見つけました。のちに同意の鮮度確認 [RFC7675] が成功していたすべての候補ペアで失敗した場合、状態は "failed" に遷移します。
connected RTCIceTransport は使用可能な接続を見つけましたが、より良い接続があるか確認するため、他の候補ペアの検査を継続しています。候補の収集中や、追加のリモート候補の待機中である場合もあります。同意の鮮度確認 [RFC7675] が使用中の接続で失敗し、他に成功している候補ペアがない場合、状態は "checking" (検査すべき候補ペアが残っている場合)または "disconnected" (検査すべき候補ペアはないが、ピアがまだ収集中または追加のリモート候補を待機中の場合)に遷移します。
注記

通常、成功する通話における最も一般的な遷移は new -> checking -> connected -> completed ですが、特定の状況(最後に検査した候補だけが成功し、収集完了と「これ以上候補なし」の通知が成功前にどちらも起こる)では、状態が "checking" から 直接 "completed" に遷移することがあります。

ICE の再起動は候補の収集と接続性チェックを最初からやり直させ、開始時の状態が "connected" (開始時に "completed" 状態だった場合)への遷移を引き起こします。開始時の状態が一時的な "disconnected" の場合は、 "checking" への遷移を引き起こし、以前に接続性が失われていたことを事実上忘れます。

"failed" と "completed" の各状態には、追加のリモート候補が存在しないことの示唆が必要です。これは、addIceCandidate を、candidate プロパティが空文字列に設定された候補値で呼び出すか、canTrickleIceCandidatesfalse に設定されることで示すことができます。

状態遷移の例:

ICE transport state transition diagram
2 非規範的 ICE トランスポート状態遷移図

5.6.5 RTCIceRole 列挙型

WebIDLenum RTCIceRole {
  "unknown",
  "controlling",
  "controlled"
};
RTCIceRole 列挙型の説明
列挙値 説明
unknown [RFC5245]、 セクション 3 に定義されている役割がまだ決定されていないエージェント。
controlling [RFC5245]、 セクション 3 に定義されているコントローリングエージェント。
controlled [RFC5245]、 セクション 3 に定義されているコントロールドエージェント。

5.6.6 RTCIceComponent 列挙型

WebIDLenum RTCIceComponent {
  "rtp",
  "rtcp"
};
RTCIceComponent 列挙型の説明
列挙値 説明
rtp ICE トランスポートは RTP(または RTCP 多重化)に使用されます。これは [RFC5245]、 セクション 4.1.1.1 に定義されています。RTP と多重化されるプロトコル(例: データチャネル)は、そのコンポーネント ID を共有します。これは candidate-attribute でエンコードされた際の component-id1 を表します。
rtcp ICE トランスポートは RTCP に使用されます。これは [RFC5245]、 セクション 4.1.1.1 に定義されています。これは candidate-attribute でエンコードされた際の component-id2 を表します。

5.7 RTCTrackEvent

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

WebIDL[Exposed=Window]
interface RTCTrackEvent : Event {
  constructor(DOMString type, RTCTrackEventInit eventInitDict);
  readonly attribute RTCRtpReceiver receiver;
  readonly attribute MediaStreamTrack track;
  [SameObject] readonly attribute FrozenArray<MediaStream> streams;
  readonly attribute RTCRtpTransceiver transceiver;
};

コンストラクター

RTCTrackEvent.constructor()

属性

receiver 型は RTCRtpReceiver, 読み取り専用

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

track 型は MediaStreamTrack, 読み取り専用

track 属性は、このイベントに関連付けられた MediaStreamTrack オブジェクトを表します。このオブジェクトは、receiver によって識別される RTCRtpReceiver に関連付けられています。

streams 型は FrozenArray<MediaStream>, 読み取り専用

streams 属性は、このイベントの track が一部となる MediaStream オブジェクトの配列を返します。

transceiver 型は RTCRtpTransceiver, 読み取り専用

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

WebIDLdictionary RTCTrackEventInit : EventInit {
  required RTCRtpReceiver receiver;
  required MediaStreamTrack track;
  sequence<MediaStream> streams = [];
  required RTCRtpTransceiver transceiver;
};

辞書 RTCTrackEventInit メンバー

receiver 型は RTCRtpReceiver, 必須

receiver メンバーは、このイベントに関連付けられた RTCRtpReceiver オブジェクトを表します。

track 型は MediaStreamTrack, 必須

track メンバーは、このイベントに関連付けられた MediaStreamTrack オブジェクトを表します。このオブジェクトは、receiver によって識別される RTCRtpReceiver に関連付けられています。

streams 型は sequence<MediaStream>, デフォルト値は []

streams メンバーは、このイベントの track が一部となる MediaStream オブジェクトの配列を表します。

transceiver 型は RTCRtpTransceiver, 必須

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

6. ピアツーピアデータAPI

ピアツーピアデータAPIは、ウェブアプリケーションがピアツーピアで汎用的なアプリケーションデータを送受信できるようにします。データ送受信のAPIは、Web Sockets の動作をモデル化しています。

6.1 RTCPeerConnection インターフェイス拡張

ピアツーピアデータAPIは、以下に記載されているようにRTCPeerConnectionインターフェイスを拡張します。

WebIDL          partial interface RTCPeerConnection {
  readonly attribute RTCSctpTransport? sctp;
  RTCDataChannel createDataChannel(USVString label,
                                   optional RTCDataChannelInit dataChannelDict = {});
  attribute EventHandler ondatachannel;
};

属性

sctp の型は RTCSctpTransport, 読み取り専用、nullable

SCTPデータが送受信されるSCTPトランスポート。 SCTPがネゴシエートされていない場合、この値はnullです。この属性はMUSTRTCSctpTransportオブジェクト([[SctpTransport]]内部スロットに格納)を返さなければなりません。

ondatachannel の型は EventHandler
このイベントハンドラーのイベントタイプはdatachannelです。

メソッド

createDataChannel

指定されたラベルを持つ新しいRTCDataChannelオブジェクトを作成します。 RTCDataChannelInit辞書を使用して、 データの信頼性など、基盤となるチャネルのプロパティを構成できます。

createDataChannel メソッドが呼び出されたとき、ユーザーエージェントは以下の手順を実行するMUSTとします。

  1. connectionを、メソッドが呼び出されたRTCPeerConnectionオブジェクトとします。

  2. もしconnection.[[IsClosed]]trueなら、throw an InvalidStateErrorをスローします。

  3. RTCDataChannel を作成し、channelとします。

  4. channel.[[DataChannelLabel]]を 最初の引数の値に初期化します。

  5. [[DataChannelLabel]]の UTF-8表現が65535バイトを超える場合、throw a TypeErrorをスローします。

  6. optionsを第2引数とします。

  7. channel.[[MaxPacketLifeTime]]option.maxPacketLifeTime に初期化します(存在する場合)。存在しない場合はnull

  8. channel.[[MaxRetransmits]]option.maxRetransmits に初期化します(存在する場合)。存在しない場合はnull

  9. channel.[[Ordered]]option.orderedに初期化します。

  10. channel.[[DataChannelProtocol]]option.protocolに初期化します。

  11. [[DataChannelProtocol]]の UTF-8表現が65535バイトを超える場合、throw a TypeErrorをスローします。

  12. channel.[[Negotiated]]option.negotiatedに初期化します。

  13. channel.[[DataChannelId]]を、 option.idの値に初期化します(それが存在し、かつ [[Negotiated]]が true の場合)。それ以外は null

    注記
    これは、データチャネルがインバンドでネゴシエートされる場合、idメンバーが無視されることを意味します。これは意図的なものです。インバンドでネゴシエートされるデータチャネルのIDは、 [RFC8832]で規定されているとおり、DTLSの役割に基づいて選択されるべきです。
  14. もし[[Negotiated]]trueで、 [[DataChannelId]]nullなら、throw a TypeErrorをスローします。

  15. [[MaxPacketLifeTime]][[MaxRetransmits]]の両属性が設定されている(nullでない)場合、 throw a TypeErrorをスローします。

  16. 設定([[MaxPacketLifeTime]]または [[MaxRetransmits]]のいずれか)が 非信頼モードを示すように設定され、その値がユーザーエージェントでサポートされる最大値を超える場合、その値はユーザーエージェントの最大値に設定されるMUSTとします。

  17. もし[[DataChannelId]]が65535に等しい場合(許可される最大IDである65534を超えるが、それでも unsigned shortとしては有効)、throw a TypeErrorをスローします。

  18. [[DataChannelId]]スロットが nullcreateDataChannelにIDが渡されていない、または [[Negotiated]]が false であるため)で、 かつSCTPトランスポートのDTLSロールがすでにネゴシエートされている場合、[RFC8832]に従ってユーザーエージェントが生成した値で [[DataChannelId]]を初期化し、次の手順へ進みます。使用可能なIDが生成できなかった場合、または [[DataChannelId]]スロットの値が既存の RTCDataChannelによって使用されている場合は、 throw an OperationError 例外をスローします。

    注記
    この手順の後でも[[DataChannelId]]スロットが nullである場合、RTCSctpTransport connected手続の間に設定されます。
  19. transportを、 connection.[[SctpTransport]]とします。

    [[DataChannelId]]スロットが nullでなく、transportが "connected" 状態であり、かつ [[DataChannelId]]transport.[[MaxChannels]]以上である場合、 throw an OperationErrorをスローします。

  20. もしchannelconnection上で作成された最初のRTCDataChannelであるなら、 update the negotiation-needed flagconnectionに対して行います。

  21. Append channelconnection.[[DataChannels]]に追加します。

  22. channelを返し、以下の手順をin parallelで続けます。

  23. channelに関連付けられた基盤となるデータトランスポートを作成し、 channelの関連プロパティに従って構成します。

6.1.1 RTCSctpTransport インターフェイス

RTCSctpTransport インターフェイスは、特定の SCTP アソシエーションに紐付けられた SCTP データチャネルに関する情報へアプリケーションからアクセスできるようにします。

6.1.1.1 インスタンスの作成

初期状態 initialState を用いて create an RTCSctpTransport を行うには、次の手順を実行します:

  1. transport を新しい RTCSctpTransport オブジェクトとします。

  2. transport は内部スロット [[SctpTransportState]] を持ち、initialState で初期化されているものとします。

  3. transport は内部スロット [[MaxMessageSize]] を持ち、これを初期化するために update the data max message size とラベル付けされた手順を実行します。

  4. transport は内部スロット [[MaxChannels]] を持ち、null で初期化されているものとします。

  5. transport を返します。

6.1.1.2 最大メッセージサイズの更新

RTCSctpTransportupdate the data max message size を行うには、次の手順を実行します:

  1. 更新対象の RTCSctpTransport オブジェクトを transport とします。

  2. remoteMaxMessageSize を、[RFC8841](セクション 6)に記載のとおり、リモート記述から読み取った max-message-size SDP 属性の値、またはその属性が欠落している場合は 65536 とします。

  3. canSendSize を、このクライアントが送信できるバイト数(すなわちローカル送信バッファのサイズ)とし、実装が任意サイズのメッセージを処理できる場合は 0 とします。

  4. remoteMaxMessageSizecanSendSize の両方が 0 の場合、 [[MaxMessageSize]] を正の Infinity 値に設定します。

  5. そうでなく、remoteMaxMessageSize または canSendSize のいずれかが 0 の場合、 [[MaxMessageSize]] を二つのうち大きい方に設定します。

  6. それ以外の場合、 [[MaxMessageSize]]remoteMaxMessageSizecanSendSize の小さい方に設定します。

6.1.1.3 接続時の手順

SCTP transport is connected、つまり RTCSctpTransport の SCTP アソシエーションが確立されたら、ユーザーエージェントは以下の手順を実行する タスクをキューに追加MUST します:

  1. transportRTCSctpTransport オブジェクトとします。

  2. connectiontransport に関連付けられた RTCPeerConnection オブジェクトとします。

  3. [[MaxChannels]] を、交渉済みの受信・送信 SCTP ストリーム数の最小値に設定します。

  4. connection の各 RTCDataChannel について:

    1. channelRTCDataChannel オブジェクトとします。

    2. もし channel.[[DataChannelId]]null の場合、[[DataChannelId]] を、 [RFC8832] に従い、 基盤となる SCTP データチャネルによって生成された値に初期化する。

    3. もし channel.[[DataChannelId]]transport.[[MaxChannels]] 以上である、または前の手順で id の割り当てに失敗した場合は、close により失敗として channel を閉じます。そうでなければ、announce the channel as open を行います。

  5. Fire an eventstatechange のイベントを transport に対して発火します。

    注記

    このイベントは、open イベント(announcing the channel as open により発火)よりも前に発火します。 open イベントは別のキューに入れられたタスクから発火されます。

WebIDL[Exposed=Window]
interface RTCSctpTransport : EventTarget {
  readonly attribute RTCDtlsTransport transport;
  readonly attribute RTCSctpTransportState state;
  readonly attribute unrestricted double maxMessageSize;
  readonly attribute unsigned short? maxChannels;
  attribute EventHandler onstatechange;
};
属性
transport の型は RTCDtlsTransport、読み取り専用

データチャネル用のすべての SCTP パケットが送受信されるトランスポートです。

state の型は RTCSctpTransportState、読み取り専用

SCTP トランスポートの現在の状態。取得時、この属性は [[SctpTransportState]] スロットの値を返さなければなりません MUST

maxMessageSize の型は unrestricted double、読み取り専用

RTCDataChannelsend() メソッドに渡すことができるデータの最大サイズ。取得時、この属性は [[MaxMessageSize]] スロットの値を返さなければなりません MUST

maxChannels の型は unsigned short、読み取り専用、nullable

同時に使用できる RTCDataChannel の最大数。取得時、この属性は [[MaxChannels]] スロットの値を返さなければなりません MUST

注記
この属性の値は、SCTP トランスポートが "connected" 状態になるまで null です。
onstatechange の型は EventHandler

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

6.1.2 RTCSctpTransportState 列挙型

RTCSctpTransportState は、SCTP トランスポートの状態を示します。

WebIDLenum RTCSctpTransportState {
  "connecting",
  "connected",
  "closed"
};
RTCSctpTransportState 列挙型の説明
列挙値 説明
connecting

RTCSctpTransport はアソシエーションのネゴシエーション中です。これは、RTCSctpTransport が作成されたときの [[SctpTransportState]] スロットの初期状態です。

connected

アソシエーションのネゴシエーションが完了すると、[[SctpTransportState]] スロットを "connected" に更新するタスクがキューに追加されます。

closed

次の場合、[[SctpTransportState]] スロットを "closed" に更新するタスクがキューに追加されます:

  • SHUTDOWN または ABORT チャンクを受信したとき。
  • ピア接続を閉じる、データを拒否するリモート記述を適用する、SCTP ポートを変更するなどにより、SCTP アソシエーションが意図的に閉じられたとき。
  • 基盤となる DTLS アソシエーションが "closed" 状態に遷移したとき。

最後の遷移が論理的であるのは、SCTP アソシエーションには確立済みの DTLS 接続が必要であり([RFC8261] セクション 6.1 では DTLS 上の SCTP はシングルホームであると規定)、この API では代替トランスポートへの切り替え方法が定義されていないためです。

6.2 RTCDataChannel

RTCDataChannel インターフェイスは、2 つのピア間の双方向データチャネルを表します。RTCDataChannel は、RTCPeerConnection オブジェクト上のファクトリメソッドによって作成されます。ブラウザー間でやり取りされるメッセージは [RFC8831] および [RFC8832] に記述されています。

RTCDataChannel で接続を確立する方法は 2 つあります。 1 つ目は、ピアの一方で RTCDataChannel を作成する際に、negotiated RTCDataChannelInit 辞書メンバーを未設定のまま、または既定値の false に設定する方法です。これにより、新しいチャネルがインバンドで通知され、相手側ピアでは対応する RTCDataChannelEvent が発火し、対応する RTCDataChannel オブジェクトが渡されます。2 つ目は、アプリケーションが RTCDataChannel をネゴシエートする方法です。そのためには、 RTCDataChannel オブジェクトを作成する際に negotiated RTCDataChannelInit 辞書メンバーを true に設定し、アウトオブバンド(例: Web サーバー経由)で相手側に、 同じ id を用い、 negotiated を true に設定した対応する RTCDataChannel を作成するべきである(SHOULD)ことを通知します。これにより、別々に作成された RTCDataChannel オブジェクト 2 つが接続されます。2 つ目の方法では、非対称なプロパティを持つチャネルを作成したり、一致する id を指定して宣言的にチャネルを作成したりできます。

RTCDataChannel には、他方のピアへ実データを輸送するために使用される、関連付けられた underlying data transport があります。RTCSctpTransport(SCTP アソシエーションの状態を表す)を利用する SCTP データチャネルの場合、基盤となるデータトランスポートは SCTP のストリーム・ペアです。underlying data transport のトランスポート特性(順序どおり配信の設定や信頼性モードなど)は、チャネル作成時にピアによって構成されます。チャネルのプロパティは、作成後に変更できません。ピア間での実際のワイヤプロトコルは、WebRTC DataChannel Protocol 仕様 [RFC8831] によって規定されています。

RTCDataChannel は、異なる信頼性モードで動作するよう構成できます。信頼性のあるチャネルは、再送によってデータが相手のピアへ確実に届くことを保証します。非信頼チャネルは、再送回数を制限する( maxRetransmits )か、送信(再送を含む)が許可される時間を設定する( maxPacketLifeTime )ように構成されます。これらのプロパティは同時には使用できず、そのようにしようとするとエラーになります。いずれのプロパティも設定しない場合は、信頼性のあるチャネルになります。

RTCDataChannel は、createDataChannel によって作成されるか、 RTCDataChannelEvent を介してディスパッチされるもので、初期状態では MUSTconnecting」でなければなりません。RTCDataChannel オブジェクトの underlying data transport の準備が整ったら、ユーザーエージェントは MUST announce the RTCDataChannel as open しなければなりません。

6.2.1 データチャネルの作成

RTCDataChannel を作成するには、 次の手順を実行します:

  1. channel を新しく作成された RTCDataChannel オブジェクトとします。

  2. channel は、内部スロット [[ReadyState]] を持ち、 初期値は "connecting" とします。

  3. channel は、内部スロット [[BufferedAmount]] を持ち、 初期値は 0 とします。

  4. channel は、次の名称の内部スロットを持つものとします: [[DataChannelLabel]][[Ordered]][[MaxPacketLifeTime]][[MaxRetransmits]][[DataChannelProtocol]][[Negotiated]]、および [[DataChannelId]]

  5. channel は、内部スロット [[IsTransferable]] を持ち、 初期値は true とします。
  6. Queue a task して次の手順を実行します:
    1. channel.[[IsTransferable]]false に設定します。

    このタスクは、channel に対して receiving messages on a data channel アルゴリズムによってキューに入れられるいかなるタスクよりも先に実行される必要があります。 これは、RTCDataChannel の転送中にメッセージが失われないことを保証するためです。

  7. channel を返します。

6.2.2 データチャネルをオープンとして通知

ユーザーエージェントが RTCDataChannel をオープンとして通知する場合、ユーザーエージェントは MUST 次の手順を実行するタスクをキューに追加します:

  1. 関連する RTCPeerConnection オブジェクトの [[IsClosed]] スロットが true の場合、これらの手順を中止します。

  2. channel を、通知対象の RTCDataChannel オブジェクトとします。

  3. もし channel.[[ReadyState]] が "closing" または "closed" の場合、これらの手順を中止します。

  4. channel.[[ReadyState]] を "open" に設定します。

  5. Fire an eventopen のイベントを channel に対して発火します。

6.2.3 データチャネルインスタンスの通知

underlying data transport を通知する必要がある場合( 相手のピアが negotiated を未設定または false に設定してチャネルを作成した場合)、作成処理を開始しなかった側のピアのユーザーエージェントは MUST 次の手順を実行するタスクをキューに追加します:

  1. connection を、underlying data transport に関連付けられた RTCPeerConnection オブジェクトとします。

  2. もし connection.[[IsClosed]]true であれば、これらの手順を中止します。

  3. RTCDataChannel を作成し、 channel とします。

  4. configuration を、WebRTC DataChannel Protocol 仕様 [RFC8832] に記載された underlying data transport を確立する過程の一部として、 相手のピアから受け取った情報バンドルとします。

  5. channel の内部スロット [[DataChannelLabel]][[Ordered]][[MaxPacketLifeTime]][[MaxRetransmits]][[DataChannelProtocol]]、 および [[DataChannelId]] を、configuration の対応する値で初期化します。

  6. channel.[[Negotiated]]false に初期化します。

  7. Append により channelconnection.[[DataChannels]] に追加します。

  8. channel.[[ReadyState]] を "open" に設定します(ただし、まだ open イベントは発火しません)。

    注記
    これにより、datachannel イベントハンドラー内で、 open イベントが発火する前に メッセージ送信を開始できます。
  9. Fire an eventdatachannel のイベントを、 RTCDataChannelEvent インターフェイスを用い、 channel 属性を channel に設定して connection に対して発火します。

  10. Announce the data channel as open

候補の修正 38:クローズされていない RTCDataChannel の GC を防止 (PR #2902)

6.2.4 クローズ手順

6.2.4 クローズ手順

RTCDataChannel オブジェクトの 基盤となるデータトランスポートは、クローズ手順 を実行することで、非突発的な方法で解体される場合があります。 その場合、ユーザーエージェントは MUST 次の手順を実行するタスクをキューに追加します:

  1. channel を、その RTCDataChannel オブジェクト(基盤となるデータトランスポート がクローズされたもの)とします。

  2. connection を、channel に関連付けられた RTCPeerConnection オブジェクトとします。

  3. Remove により、connection.[[DataChannels]] から channel を削除します。

  4. channel.close によってこの手順が開始されたのでない限り、 channel.[[ReadyState]] を "closing" に設定し、イベントを発火して closing という名前のイベントを channel に対して発火します。

  5. 次の手順を in parallelin parallel で実行します:

    1. channel の現在保留中のすべてのメッセージ送信を完了します。

    2. channel基盤となるデータトランスポート に定義されたクローズ手順に従います:

      1. SCTP ベースの transport の場合は、 [RFC8831] セクション 6.7 に従います。

    3. 関連する手順に従って、channeldata transportClose します closed

6.2.5 データチャネルをクローズとして通知

RTCDataChannel オブジェクトの 基盤となるデータトランスポートクローズ されたとき、ユーザーエージェントは MUST 次の手順を実行するタスクをキューに追加します:

  1. channel を、その RTCDataChannel オブジェクト(基盤となるデータトランスポート がクローズされたもの)とします。

  2. もし channel.[[ReadyState]] が "closed" の場合、 これらの手順を中止します。
  3. channel.[[ReadyState]] を "closed" に設定します。

  4. まだ存在している場合は、Remove により connection.[[DataChannels]] から channel を削除します。

  5. transportエラーを伴ってクローズされた場合、イベントを発火して、error という名前のイベントを RTCErrorEvent インターフェイスを用いて channel に対して発火します。このとき、その errorDetail 属性は "sctp-failure" に設定します。

  6. イベントを発火して、close という名前のイベントを channel に対して発火します。

6.2.6 データチャネルの転送

RTCDataChanneltransfer steps は、valuedataHolder が与えられたとき、次のとおりです。

  1. もし value.[[IsTransferable]]false なら、DataCloneError DOMException をスローします。

  2. dataHolder.[[ReadyState]]value.[[ReadyState]] に設定します。

  3. dataHolder.[[DataChannelLabel]]value.[[DataChannelLabel]] に設定します。

  4. dataHolder.[[Ordered]]value.[[Ordered]] に設定します。

  5. dataHolder.[[MaxPacketLifeTime]]value..[[MaxPacketLifeTime]] に設定します。

  6. dataHolder.[[MaxRetransmits]]value.[[MaxRetransmits]] に設定します。

  7. dataHolder.[[DataChannelProtocol]]value.[[DataChannelProtocol]] に設定します。

  8. dataHolder.[[Negotiated]]value.[[Negotiated]] に設定します。

  9. dataHolder.[[DataChannelId]]value.[[DataChannelId]] に設定します。

  10. dataHolderunderlying data transportvalueunderlying data transport に設定します。

  11. value.[[IsTransferable]]false に設定します。

  12. value.[[ReadyState]] を "closed" に設定します。

RTCDataChanneltransfer-receiving steps は、dataHolderchannel が与えられたとき、次のとおりです。

  1. channel.[[ReadyState]]dataHolder.[[ReadyState]] に初期化します。

  2. channel.[[DataChannelLabel]]dataHolder.[[DataChannelLabel]] に初期化します。

  3. channel.[[Ordered]]dataHolder.[[Ordered]] に初期化します。

  4. channel.[[MaxPacketLifeTime]]dataHolder.[[MaxPacketLifeTime]] に初期化します。

  5. channel.[[MaxRetransmits]]dataHolder.[[MaxRetransmits]] に初期化します。

  6. channel.[[DataChannelProtocol]]dataHolder.[[DataChannelProtocol]] に初期化します。

  7. channel.[[Negotiated]]dataHolder.[[Negotiated]] に初期化します。

  8. channel.[[DataChannelId]]dataHolder.[[DataChannelId]] に初期化します。

  9. channelunderlying data transportdataHolderunderlying data transport に初期化します。

上記の手順では、[[BufferedAmount]] を転送する必要はありません。値は常に 0 に等しいためです。 理由は、RTCDataChannel は、その send() algorithm が転送前に呼び出されていない場合にのみ転送できるためです。

もし underlying data transporttransfer-receiving steps の時点でクローズされている場合、 RTCDataChannel オブジェクトは、 announcing a data channel as closed アルゴリズムを transfer-receiving steps の直後に実行することでクローズされます。

6.2.7 データチャネル作成時のエラー

場合によっては、ユーザーエージェントが unable to create an RTCDataChannelunderlying data transport を作成できないことがあります。例えば、データチャネルの id が、SCTP ハンドシェイクにおいて [RFC8831] の実装によってネゴシエートされた範囲外である場合があります。ユーザーエージェントが RTCDataChannelunderlying data transport を作成できないと判断した場合、ユーザーエージェントは MUST 以下の手順を実行するタスクをキューに追加します。

  1. channel を、ユーザーエージェントが underlying data transport を作成できなかった対象の RTCDataChannel オブジェクトとします。

  2. channel.[[ReadyState]] を "closed" に設定します。

  3. イベントを発火して、error という名前のイベントを、 RTCErrorEvent インターフェイスを用い、errorDetail 属性を "data-channel-failure" に設定して、channel に対して発火します。

  4. イベントを発火して、close という名前のイベントを channel に対して発火します。

6.2.8 データチャネルでのメッセージ受信

RTCDataChannel のメッセージが、underlying data transport を介して 型 type、データ rawData とともに受信されたとき、ユーザーエージェントは MUST 以下の手順を実行するタスクをキューに追加します。

  1. channel を、ユーザーエージェントがメッセージを受信した対象の RTCDataChannel オブジェクトとします。

  2. connection を、channel に関連付けられた RTCPeerConnection オブジェクトとします。

  3. もし channel.[[ReadyState]] が "open" でない場合、 これらの手順を中止し、rawData を破棄します。

  4. typechannel.binaryType に応じて、以下のサブ手順を実行します:

    • typerawDatastring と示す場合:

      data を、rawData を UTF-8 としてデコードした結果を表す DOMString とします。

    • typerawData をバイナリと示し、かつ binaryType"blob" の場合:

      data を、新しい Blob オブジェクト(その生データソースとして rawData を含む)とします。

    • typerawData をバイナリと示し、かつ binaryType"arraybuffer" の場合:

      data を、新しい ArrayBuffer オブジェクト(その生データソースとして rawData を含む)とします。

  5. イベントを発火して、message という名前のイベントを、 MessageEvent インターフェイスを用いて発火します。このとき、その origin 属性は serialization of an origin of connection.[[DocumentOrigin]] に初期化し、data 属性は data に初期化して、channel に対して発火します。

WebIDL[Exposed=(Window,DedicatedWorker), Transferable]
interface RTCDataChannel : EventTarget {
  readonly attribute USVString label;
  readonly attribute boolean ordered;
  readonly attribute unsigned short? maxPacketLifeTime;
  readonly attribute unsigned short? maxRetransmits;
  readonly attribute USVString protocol;
  readonly attribute boolean negotiated;
  readonly attribute unsigned short? id;
  readonly attribute RTCDataChannelState readyState;
  readonly attribute unsigned long bufferedAmount;
  [EnforceRange] attribute unsigned long bufferedAmountLowThreshold;
  attribute EventHandler onopen;
  attribute EventHandler onbufferedamountlow;
  attribute EventHandler onerror;
  attribute EventHandler onclosing;
  attribute EventHandler onclose;
  undefined close();
  attribute EventHandler onmessage;
  attribute BinaryType binaryType;
  undefined send(USVString data);
  undefined send(Blob data);
  undefined send(ArrayBuffer data);
  undefined send(ArrayBufferView data);
};

属性

label の型は USVString、読み取り専用

label 属性は、この RTCDataChannel オブジェクトを他の RTCDataChannel オブジェクトと区別するために使用できるラベルを表します。スクリプトは、同じラベルを持つ複数の RTCDataChannel オブジェクトを作成できます。取得時、この属性は MUST[[DataChannelLabel]] スロットの値を返さなければなりません。

ordered の型は boolean、読み取り専用

ordered 属性は、 RTCDataChannel が順序保証されている場合は true を、順不同の配信が許可されている場合は false を返します。取得時、この属性は MUST[[Ordered]] スロットの値を返さなければなりません。

maxPacketLifeTime の 型は unsigned short、読み取り専用、 nullable

maxPacketLifeTime 属性は、非信頼モードにおいて送信および再送信が行われ得る時間窓(ミリ秒)を返します。取得時、この属性は MUST[[MaxPacketLifeTime]] スロットの値を返さなければなりません。

maxRetransmits の型は unsigned short、 読み取り専用、nullable

maxRetransmits 属性は、非信頼モードで試行される再送の最大回数を返します。取得時、この属性は MUST[[MaxRetransmits]] スロットの値を返さなければなりません。

protocol の型は USVString、読み取り専用

protocol 属性は、この RTCDataChannel で使用されるサブプロトコル名を返します。取得時、この属性は MUST[[DataChannelProtocol]] スロットの値を返さなければなりません。

negotiated の型は boolean、読み取り専用

negotiated 属性は、 その RTCDataChannel がアプリケーションによってネゴシエートされた場合は true を、そうでない場合は false を返します。取得時、この属性は MUST[[Negotiated]] スロットの値を返さなければなりません。

id の型は unsigned short、読み取り専用、nullable

id 属性は、この RTCDataChannel の ID を返します。値は初期状態では null であり、これはチャネル作成時に ID が指定されておらず、かつ SCTP トランスポートの DTLS の役割がまだネゴシエートされていない場合に返される値です。そうでなければ、スクリプトによって選択された ID、または [RFC8832] に従ってユーザーエージェントによって生成された ID を返します。ID が null 以外の値に設定された後は、変更されません。取得時、この属性は MUST[[DataChannelId]] スロットの値を返さなければなりません。

readyState の型は RTCDataChannelState、 読み取り専用

readyState 属性は、 RTCDataChannel オブジェクトの状態を表します。取得時、この属性は MUST[[ReadyState]] スロットの値を返さなければなりません。

bufferedAmount の型は unsigned long、 読み取り専用

bufferedAmount 属性は、取得時に MUST[[BufferedAmount]] スロットの値を返さなければなりません。この属性は、send() を使用してキューに入れられたアプリケーションデータ(UTF-8 テキストおよびバイナリデータ)のバイト数を公開します。データ送信はin parallelで行われ得ますが、競合状態を防ぐため、現在のタスクがイベントループに制御を戻す前に返される値を減少させてはMUST NOTなりません。値には、プロトコルによって発生するフレーミングのオーバーヘッドや、OS やネットワークハードウェアによるバッファリングは含まれません。 [[BufferedAmount]] スロットの値は、 send() メソッドの呼び出しごとに、 [[ReadyState]] スロットが "open" である限り増加するだけですが、チャネルが閉じてもスロットは 0 にリセットされません。underlying data transport がキューからデータを送信したとき、ユーザーエージェントは送信されたバイト数だけ [[BufferedAmount]] を減少させるタスクをキューに入れなければなりません MUST

bufferedAmountLowThreshold の型は unsigned long

bufferedAmountLowThreshold 属性は、bufferedAmount が低いと見なされるしきい値を設定します。bufferedAmount がこのしきい値を上回っている状態から、等しいまたは下回る状態に減少したとき、bufferedamountlow イベントが発火します。bufferedAmountLowThreshold は、新しい各 RTCDataChannel で初期値が 0 ですが、アプリケーションはいつでもその値を変更できます。

onopen の型は EventHandler
このイベントハンドラーのイベントタイプは open です。
onbufferedamountlow の型は EventHandler
このイベントハンドラーのイベントタイプは bufferedamountlow です。
onerror の型は EventHandler

このイベントハンドラーのイベントタイプは RTCErrorEvent です。 errorDetail には "sctp-failure" が含まれ、 sctpCauseCode には SCTP の Cause Code の値が、 また message には SCTP の Cause-Specific-Information が、必要に応じて追加のテキストとともに含まれます。

onclosing の型は EventHandler

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

onclose の型は EventHandler

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

onmessage の型は EventHandler

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

binaryType の型は BinaryType

binaryType 属性は、最後に設定された値を返します。 RTCDataChannel オブジェクトが作成されるとき、 binaryType 属性は文字列 "arraybuffer" に初期化されなければなりません MUST

この属性は、バイナリデータがスクリプトにどのように公開されるかを制御します。Web Socket の binaryType を参照してください。

メソッド

close()

RTCDataChannel を閉じます。これは、このピアによって作成されたか、リモートピアによって作成されたかに関係なく呼び出すことができます。

close メソッドが呼び出されたとき、ユーザーエージェントは MUST 次の手順を実行します:

  1. 閉じようとしている RTCDataChannel オブジェクトを channel とします。

  2. もし channel.[[ReadyState]] が "closing" または "closed" の場合、これらの手順を中止します。

  3. channel.[[ReadyState]] を "closing" に設定します。

  4. もし クローズ手順 がまだ開始されていない場合は、開始します。

send

引数の型が string オブジェクトの場合、send() アルゴリズム に記載の手順を実行します。

send

引数の型が Blob オブジェクトの場合、send() アルゴリズム に記載の手順を実行します。

send

引数の型が ArrayBuffer オブジェクトの場合、send() アルゴリズム に記載の手順を実行します。

send

引数の型が ArrayBufferView オブジェクトの場合、send() アルゴリズム に記載の手順を実行します。

send() メソッドは、異なるデータ引数型を扱うようにオーバーロードされています。いずれのバージョンのメソッドが呼び出された場合でも、ユーザーエージェントは MUST 次の手順を実行します:

  1. データを送信しようとしている RTCDataChannel オブジェクトを channel とします。

  2. channel.[[IsTransferable]]false に設定します。

  3. もし channel.[[ReadyState]] が "open" でない場合、throw し、 InvalidStateError を送出します。

  4. メソッドの引数の型に対応するサブ手順を実行します:

    • string オブジェクト:

      メソッドの引数を UTF-8 としてエンコードした結果を表すバイトバッファを data とします。

    • Blob オブジェクト:

      Blob オブジェクトが表す生データを data とします。

      注記
      実際に Blob オブジェクトから data を取得する処理は非同期に行われることがありますが、ユーザーエージェントは channel基盤となるデータトランスポート へデータをキューに入れる順序が send メソッドの呼び出し順と同じになるようにします。data のバイトサイズは同期的に把握されている必要があります。
    • ArrayBuffer オブジェクト:

      ArrayBuffer オブジェクトで記述されるバッファに格納されたデータを data とします。

    • ArrayBufferView オブジェクト:

      ArrayBuffer オブジェクトで記述され、ArrayBufferView オブジェクトが参照しているバッファの区間に格納されたデータを data とします。

    注記
    このメソッドでオーバーロードされていない任意のデータ引数型は、TypeError となります。これには null および undefined が含まれます。
  5. data のバイトサイズが、 channel に関連付けられた RTCSctpTransport 上の maxMessageSize の値を超える場合、throw し、 TypeError を送出します。

  6. channel基盤となるデータトランスポート 上で送信のために data をキューに入れます。 バッファ空き容量が不十分で data をキューに入れられない場合、throw し、 OperationError を送出します。

    注記
    データの実際の送信はin parallelで行われます。データ送信が SCTP レベルのエラーにつながった場合、アプリケーションには非同期に onerror を通じて通知されます。
  7. [[BufferedAmount]] スロットの値を data のバイトサイズだけ増加させます。

WebIDLdictionary RTCDataChannelInit {
  boolean ordered = true;
  [EnforceRange] unsigned short maxPacketLifeTime;
  [EnforceRange] unsigned short maxRetransmits;
  USVString protocol = "";
  boolean negotiated = false;
  [EnforceRange] unsigned short id;
};

辞書 RTCDataChannelInit のメンバー

ordered の型は boolean、既定値は true

false に設定された場合、データは順不同で配信されることが許可されます。既定値の true は、データが順序どおりに配信されることを保証します。

maxPacketLifeTime の型は unsigned short

確認応答がない場合に、チャネルがデータを送信または再送信する時間(ミリ秒)を制限します。この値がユーザーエージェントでサポートされる最大値を超える場合、値は切り詰め(クランプ)られることがあります。

maxRetransmits の型は unsigned short

配信に失敗した場合に、チャネルがデータを再送信する最大回数を制限します。この値がユーザーエージェントでサポートされる最大値を超える場合、値は切り詰め(クランプ)られることがあります。

protocol の型は USVString、既定値は ""

このチャネルで使用されるサブプロトコル名。

negotiated の型は boolean、既定値は false

既定値の false は、ユーザーエージェントがチャネルをインバンドで通知し、相手のピアに対応する RTCDataChannel オブジェクトをディスパッチするよう指示することを意味します。true に設定した場合は、アプリケーション側でチャネルをネゴシエートし、相手のピアで同じ id を持つ RTCDataChannel オブジェクトを作成する必要があります。

注記
true に設定した場合、相手のピアが受信のためのデータチャネルを作成するまで、アプリケーションはメッセージを送信しないよう注意する必要があります。関連付けられたデータチャネルのない SCTP ストリームでメッセージを受信する動作は未定義であり、黙って破棄される可能性があります。両端点が最初のオファー/アンサー交換の完了前に自分のデータチャネルを作成している限り、これは起こりません。
id の 型は unsigned short

negotiated が true のとき、チャネル ID を設定します。 negotiated が false の場合は無視されます。

WebIDLenum RTCDataChannelState {
  "connecting",
  "open",
  "closing",
  "closed"
};
RTCDataChannelState 列挙型の説明
列挙値 説明
connecting

ユーザーエージェントは、基盤となるデータトランスポートの確立を試みています。これは、RTCDataChannel オブジェクトの初期状態であり、createDataChannel で作成された場合でも、 RTCDataChannelEvent の一部としてディスパッチされた場合でも同様です。

open

基盤となるデータトランスポートが確立され、通信が可能です。

closing

手順に従って 基盤となるデータトランスポートのクローズが開始されています。

closed

基盤となるデータトランスポートclosed になったか、確立できませんでした。

6.3 RTCDataChannelEvent

datachannel イベントは、RTCDataChannelEvent インターフェイスを使用します。

WebIDL[Exposed=Window]
interface RTCDataChannelEvent : Event {
  constructor(DOMString type, RTCDataChannelEventInit eventInitDict);
  readonly attribute RTCDataChannel channel;
};

コンストラクター

RTCDataChannelEvent.constructor()

属性

channel の型は RTCDataChannel、読み取り専用

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

WebIDLdictionary RTCDataChannelEventInit : EventInit {
  required RTCDataChannel channel;
};

辞書 RTCDataChannelEventInit のメンバー

channel の型は RTCDataChannel、必須

イベントによって通知される RTCDataChannel オブジェクト。

6.4 ガベージコレクション

RTCDataChannel オブジェクトは、次のいずれかの場合、MUST ガベージコレクションされてはならない。

7. ピアツーピア DTMF

本セクションでは、RTCRtpSender 上のインターフェイスについて説明します。これは、RTCPeerConnection を介して DTMF(電話のキーパッド)値を送信するためのものです。DTMF が相手ピアにどのように送信されるかの詳細は [RFC7874] に記載されています。

7.1 RTCRtpSender インターフェイス拡張

ピアツーピア DTMF API は、以下のとおり RTCRtpSender インターフェイスを拡張します。

WebIDL          partial interface RTCRtpSender {
  readonly attribute RTCDTMFSender? dtmf;
};

属性

dtmf の型は RTCDTMFSender、読み取り専用、 nullable

取得時、dtmf 属性は、[[Dtmf]] 内部スロットの値を返します。これは DTMF の送信に使用できる RTCDTMFSender を表し、未設定の場合は null を返します。[[Dtmf]] 内部スロットは、RTCRtpSender[[SenderTrack]] の kind が "audio" のときに設定されます。

7.2 RTCDTMFSender

RTCDTMFSender を作成するために、ユーザーエージェントは MUST 次の手順を実行します:

  1. dtmf を、新しく作成された RTCDTMFSender オブジェクトとします。

  2. dtmf が内部スロット [[Duration]] を持つようにします。

  3. dtmf が内部スロット [[InterToneGap]] を持つようにします。

  4. dtmf が内部スロット [[ToneBuffer]] を持つようにします。

WebIDL[Exposed=Window]
interface RTCDTMFSender : EventTarget {
  undefined insertDTMF(DOMString tones, optional unsigned long duration = 100, optional unsigned long interToneGap = 70);
  attribute EventHandler ontonechange;
  readonly attribute boolean canInsertDTMF;
  readonly attribute DOMString toneBuffer;
};

属性

ontonechange の型は EventHandler

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

canInsertDTMF の型は boolean、読み取り専用

RTCDTMFSender dtmfSender が DTMF を送信可能かどうか。取得時、ユーザーエージェントは MUST DTMF を送信できるかどうかを判定 の結果を dtmfSender に対して返します。

toneBuffer の型は DOMString、読み取り専用

toneBuffer 属性は、再生待ちのトーンの一覧を MUST 返します。この一覧の構文、内容、解釈については insertDTMF を参照してください。

メソッド

insertDTMF

RTCDTMFSender オブジェクトの insertDTMF メソッドは、 DTMF トーンを送信するために使用されます。

tones 引数は文字の並びとして扱われます。文字 0〜9、A〜D、#、* は対応する DTMF トーンを生成します。文字 a〜d は入力時に大文字へ正規化され MUST、A〜D と同等です。[RTCWEB-AUDIO] セクション 3 に記載のとおり、0〜9、A〜D、#、* のサポートは必須です。文字 ',' は MUST サポートされ、tones 引数内の次の文字を処理する前に 2 秒の遅延を示します。その他すべての文字(かつそれらのみ)は MUST 未認識 と見なされます。

duration 引数は、tones 引数で渡された各文字に用いる継続時間(ms)を示します。継続時間は 6000 ms を超えることも 40 ms 未満であることもできません。既定値は各トーン 100 ms です。

interToneGap 引数は、トーン間の間隔(ms)を示します。ユーザーエージェントはその値を少なくとも 30 ms、最大で 6000 ms にクランプします。既定値は 70 ms です。

ブラウザーは MAYdurationinterToneGap の時間を増やし、DTMF の開始・停止時間が RTP パケット境界に整合するようにできますが、どちらも単一の RTP オーディオパケットの継続時間を超えて増加させてはなりません MUST

insertDTMF() メソッドが呼び出されたとき、ユーザーエージェントは MUST 次の手順を実行します:

  1. sender を、DTMF 送信用の RTCRtpSender とします。
  2. transceiver を、sender に関連付けられた RTCRtpTransceiver オブジェクトとします。

  3. dtmf を、sender に関連付けられた RTCDTMFSender とします。
  4. DTMF を送信できるかどうかを判定dtmf に対して false を返す場合、throw し、InvalidStateError を送出します。
  5. tones を、このメソッドの第 1 引数とします。
  6. duration を、このメソッドの第 2 引数とします。
  7. interToneGap を、このメソッドの第 3 引数とします。
  8. tones未認識 の文字が含まれている場合、throw し、InvalidCharacterError を送出します。
  9. オブジェクトの [[ToneBuffer]] スロットを tones に設定します。
  10. dtmf[[Duration]]duration の値に設定します。
  11. dtmf[[InterToneGap]]interToneGap の値に設定します。
  12. duration の値が 40 ms 未満の場合、dtmf[[Duration]] を 40 ms に設定します。
  13. duration の値が 6000 ms を超える場合、dtmf[[Duration]] を 6000 ms に設定します。
  14. interToneGap の値が 30 ms 未満の場合、dtmf[[InterToneGap]] を 30 ms に設定します。
  15. interToneGap の値が 6000 ms を超える場合、dtmf[[InterToneGap]] を 6000 ms に設定します。
  16. [[ToneBuffer]] スロットが空文字列である場合、これらの手順を中止します。
  17. もし DTMF 再生タスクの手順 を実行するタスクがスケジュール済みであれば、これらの手順を中止します。そうでなければ、次の DTMF 再生タスクの手順 を実行するタスクをキューに入れます:
    1. If transceiver.[[CurrentDirection]]もし DTMF を送信できるかどうかを判定 is neither "sendrecv" nor "sendonly"dtmf に対して false を返す場合、これらの手順を中止します。
    2. もし [[ToneBuffer]] スロットが空文字列を含む場合、イベントを発火して tonechange という名前のイベントを、 RTCDTMFToneChangeEvent インターフェイスを用い、 tone 属性を空文字列に設定して RTCDTMFSender オブジェクトに対して発火し、これらの手順を中止します。
    3. [[ToneBuffer]] スロットから最初の文字を取り除き、その文字を tone とします。
    4. もし tone"," の場合、関連する RTP メディアストリームで 2000 ms のあいだトーン送信を遅延し、今から 2000 ms 後に実行するタスクをキューに入れ、DTMF 再生タスクの手順 を実行します。
    5. もし tone"," でない場合、適切なコーデックを用いて関連する RTP メディアストリーム上で tone の再生を [[Duration]] ms 行い、その後 [[Duration]] + [[InterToneGap]] ms 後に DTMF 再生タスクの手順 を実行するタスクをキューに入れます。
    6. イベントを発火して tonechange という名前のイベントを、 RTCDTMFToneChangeEvent インターフェイスを用い、 tone 属性を tone に設定して RTCDTMFSender オブジェクトに対して発火します。

insertDTMF はトーンバッファを置き換えるため、再生中の DTMF トーンに追加するには、insertDTMF を、([[ToneBuffer]] スロットに格納された)残りのトーンと新しいトーンを連結した文字列で呼び出す必要があります。空の tones 引数で insertDTMF を呼び出すと、現在再生中のトーンの後に再生予定のすべてのトーンをキャンセルできます。

7.3 canInsertDTMF アルゴリズム

DTMF を送信できるかどうかを判定するために、RTCDTMFSender インスタンス dtmfSender に対して、ユーザーエージェントは MUST 次の手順を実行します:

  1. sender を、 RTCRtpSenderdtmfSender に関連付け)とします。
  2. transceiver を、 RTCRtpTransceiversender に関連付け)とします。
  3. connection を、 RTCPeerConnectiontransceiver に関連付け)とします。
  4. もし connectionRTCPeerConnectionState が "connected" でない場合、false を返します。
  5. もし transceiver[[Stopping]]true の場合、false を返します。
  6. もし sender[[SenderTrack]]null の場合、 false を返します。
  7. もし transceiver[[CurrentDirection]] が "sendrecv" でも "sendonly" でもない場合、 false を返します。
  8. もし sender[[SendEncodings]][0]activefalse の場合、false を返します。
  9. mimetype が "audio/telephone-event" のコーデックが、この sender で送信用にネゴシエートされていない場合、false を返します。
  10. それ以外の場合、true を返します。

7.4 RTCDTMFToneChangeEvent

tonechange イベントは、RTCDTMFToneChangeEvent インターフェイスを使用します。

WebIDL[Exposed=Window]
interface RTCDTMFToneChangeEvent : Event {
  constructor(DOMString type, optional RTCDTMFToneChangeEventInit eventInitDict = {});
  readonly attribute DOMString tone;
};

コンストラクター

RTCDTMFToneChangeEvent.constructor()

属性

tone の型は DOMString、読み取り専用

tone 属性には、再生がちょうど開始されたトーン("," を含む)の文字が含まれます(insertDTMF を参照)。値が空文字列の場合、[[ToneBuffer]] スロットが空文字列であり、以前のトーンの再生が完了したことを示します。

WebIDL          dictionary RTCDTMFToneChangeEventInit : EventInit {
  DOMString tone = "";
};

辞書 RTCDTMFToneChangeEventInit のメンバー

tone の型は DOMString、既定値は ""

tone 属性には、再生がちょうど開始されたトーン("," を含む)の文字が含まれます(insertDTMF を参照)。値が空文字列の場合、[[ToneBuffer]] スロットが空文字列であり、以前のトーンの再生が完了したことを示します。

8. 統計モデル

8.1 イントロダクション

基本的な統計モデルは、ブラウザーが監視対象オブジェクトに対する統計の集合を、 統計オブジェクトの形で維持する、というものである。

関連するオブジェクト群は、セレクターで参照される場合がある。セレクターは例えば MediaStreamTrack であってよい。トラックが有効なセレクターであるためには、 MUST MediaStreamTrack であり、統計要求が発行された RTCPeerConnection オブジェクトによって送受信されていることが必要である。 呼び出し元の Web アプリケーションはセレクターを getStats() メソッドに渡し、ブラウザーは 統計選択アルゴリズムに従って、そのセレクターに関連する統計の集合を(JavaScript で)出力する。 なお、このアルゴリズムはセレクターの送信側または受信側を対象とする。

統計オブジェクトで返される統計は、 繰り返しの問い合わせをRTCStatsid辞書メンバーで関連付けられるよう設計されている。 したがって、Web アプリケーションは、ある期間の始めと終わりに測定を要求することで、その期間にわたる測定値を得ることができる。

いくつかの例外を除き、監視対象オブジェクトは一度作成されると、 対応するRTCPeerConnectionの存続期間中は存在し続ける。 これにより、対応するピア接続がcloseされた後でも getStats() の結果にそれらの統計が含まれることが保証される。

ごく一部の監視対象オブジェクトのみがより短い存続期間を持つ。 これらのオブジェクトの統計は、その後の getStats() の結果には含まれない。 [WEBRTC-STATS] のオブジェクト記述に、これらの監視対象オブジェクトがいつ削除されるかが記載されている。

8.2 RTCPeerConnection インターフェイス拡張

統計 API は、以下のとおりRTCPeerConnection インターフェイスを拡張する。

WebIDL          partial interface RTCPeerConnection {
  Promise<RTCStatsReport> getStats(optional MediaStreamTrack? selector = null);
};

メソッド

getStats

指定されたセレクターの統計を収集し、結果を非同期に報告する。

getStats() メソッドが呼び出されたとき、ユーザーエージェントは MUST 次の手順を実行する:

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

  2. connection を、このメソッドが呼び出された RTCPeerConnection オブジェクトとする。

  3. もし selectorArgnull なら、 selectornull とする。

  4. もし selectorArgMediaStreamTrack なら、 selectorconnection 上の、 RTCRtpSender または RTCRtpReceiver のうち、 そのtrack属性が selectorArg に一致するものとする。 そのような sender 又は receiver が存在しない場合、または条件に合致する sender 又は receiver が複数存在する場合は、 新たに生成した InvalidAccessError で promise をrejectして返す。

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

  6. 次の手順を並行して実行する:

    1. 統計選択アルゴリズムに従って、 selector により示される統計を収集する。

    2. 現在の realm のグローバルオブジェクトglobal として、ネットワーキング タスク ソース上で グローバルタスクをキューに入れ、 収集した統計を含む RTCStatsReport オブジェクトで resolve する。

  7. p を返す。

8.3 RTCStatsReport オブジェクト

getStats() メソッドは、成功結果を RTCStatsReport オブジェクトの形式で返す。 RTCStatsReport オブジェクトは、 調査対象のオブジェクト(id 属性。RTCStats インスタンス内)を識別する文字列と、 それに対応する RTCStats 派生辞書とのマップである。

RTCStatsReport は、 複数の RTCStats 派生辞書で構成されうる。 それぞれが、実装が当該セレクターに関連すると考える 1 つの基盤オブジェクトの統計を報告する。 セレクターの合計値は、特定の型の統計を全て合算することで得られる。 例えば、RTCRtpSender がネットワーク上でそのトラックを運ぶために複数の SSRC を用いる場合、 RTCStatsReport には SSRC ごとに 1 つの RTCStats 派生辞書が含まれうる (これは統計属性 ssrc の値で区別できる)。

WebIDL[Exposed=Window]
interface RTCStatsReport {
  readonly maplike<DOMString, object>;
};

これらを用いて、この統計レポートを構成する RTCStats 由来の各種辞書を取得できる。 サポートされるプロパティ名の集合 [WEBIDL] は、 この統計レポートのために生成された全ての RTCStats 派生辞書の id で定義される。

8.4 RTCStats 辞書

RTCStats 辞書は、 特定の監視対象オブジェクトを検査して構築された 統計オブジェクト を表す。 RTCStats 辞書は基本型であり、 timestamptype のような既定属性の集合を規定する。 個別の統計は、この RTCStats 辞書を拡張することで追加される。

統計名は標準化されているが、実装によっては実験的な値、またはWeb アプリケーションがまだ知らない値を使用している場合がある。 したがって、アプリケーションは未知の統計に対処できるようにしておく MUST がある。

統計は計算において妥当な値を得るため、互いに同期している必要がある。 例えば、bytesSentpacketsSent が共に報告される場合、 「平均パケットサイズ」を「bytes / packets」として計算できるよう、同一の間隔で報告されなければならない。 間隔が異なると誤差を生じる。 したがって実装は、単一の RTCStats 派生辞書内の全ての統計について同期した値を返す MUST がある。

WebIDLdictionary RTCStats {
  required DOMHighResTimeStamp timestamp;
  required RTCStatsType type;
  required DOMString id;
};

辞書 RTCStats のメンバー

timestamp の型は DOMHighResTimeStamp
候補の修正 50:統計のタイムスタンプに Performance.timeOrigin + Performance.now() を用いる (PR #3005)

The timestamp, of type タイムスタンプは DOMHighResTimeStamp, associated with this object. The time is relative to the UNIX epoch (Jan 1[HIGHRES-TIME] に準拠し、1970,PerformancetimeOrigin UTC)+ Performance.now() (情報収集時点)として定義される。 受信した RTCP パケットなど、リモートソースに由来する統計については、 timestamp は情報がローカルのエンドポイントに到着した時刻を表す。リモート側のタイムスタンプは、該当する場合、 RTCStats 派生辞書の追加フィールドに含まれる。

type の型は RTCStatsType

このオブジェクトの種類。

type 属性は、 この RTCStats 辞書が表す最も具体的な型の名称に初期化される MUST

id の型は DOMString

この RTCStats オブジェクトを生成するために調査されたオブジェクトに関連付けられた一意の id。 2 つの RTCStats オブジェクトが、 2 つの異なる RTCStatsReport から抽出された場合でも、 同じ基盤オブジェクトを調査して生成されたものであれば、同一の id を持つ MUST

統計の id は、アプリケーションによって予測可能であってはならない MUST NOT。 これは、特定のユーザーエージェントの id 生成方法に依存することを防ぎ、 特定の統計オブジェクトの id を既に読み取っていない限り、アプリケーションが id で統計オブジェクトを取得できないようにするためである。

ユーザーエージェントは、上記要件を満たす限り、任意の形式の id を選択できる。

注記

ユーザーエージェントは、ピア接続ごとに一意なソルトを用いる限り、予測可能に生成された文字列をハッシュ関数で予測不能な文字列に変換できる。 これにより、実装は内部的に予測可能な id を持つことができ、 getStats() 呼び出し間で統計オブジェクトが安定した id を持つことを保証しやすくなる。

RTCStatsType の有効な値の集合と、それらが示す RTCStats 由来の辞書は、 [WEBRTC-STATS] に記載されている。

8.5 統計選択アルゴリズム

統計選択アルゴリズムは次のとおりである:

  1. result を空の RTCStatsReport とする。
  2. もし selectornull なら、 connection 全体の統計を収集して result に追加し、 result を返してこれ以降の手順を中止する。
  3. もし selectorRTCRtpSender なら、次のオブジェクトの統計を収集して result に追加する:
    • selector によって送信されている RTP ストリームを表すすべての RTCOutboundRtpStreamStats オブジェクト。
    • 追加した RTCOutboundRtpStreamStats オブジェクトから、 直接または間接に参照される全ての統計オブジェクト。
  4. もし selectorRTCRtpReceiver なら、次のオブジェクトの統計を収集して result に追加する:
    • selector によって受信されている RTP ストリームを表すすべての RTCInboundRtpStreamStats オブジェクト。
    • 追加した RTCInboundRtpStreamStats から、 直接または間接に参照される全ての統計オブジェクト。
  5. result を返す。

8.6 実装必須の統計

[WEBRTC-STATS] に挙げられている統計は、 幅広いユースケースをカバーすることを意図している。 そのすべてをすべての WebRTC 実装が実装する必要はない。

実装は、対応するオブジェクトが RTCPeerConnection 上に存在する場合に、 次のtypeの統計を生成することをサポートする MUST。 その際、汎用フィールドに加えて、当該オブジェクトに対して有効な場合に列挙されたフィールドを含めること。

RTCStatsType 辞書 フィールド
"codec" RTCCodecStats payloadType, mimeType, clockRate, channels, sdpFmtpLine
"inbound-rtp" RTCRtpStreamStats ssrc, kind, transportId, codecId
RTCReceivedRtpStreamStats packetsReceived, packetsLost, jitter,
RTCInboundRtpStreamStats trackIdentifier, remoteId, framesDecoded, framesDropped nackCount, framesReceived, bytesReceived, totalAudioEnergy, totalSamplesDuration packetsDiscarded,
"outbound-rtp" RTCRtpStreamStats ssrc, kind, transportId, codecId
RTCSentRtpStreamStats packetsSent, bytesSent
RTCOutboundRtpStreamStats remoteId, framesEncoded, nackCount, framesSent
"remote-inbound-rtp" RTCRtpStreamStats ssrc, kind, transportId, codecId
RTCReceivedRtpStreamStats packetsReceived, packetsLost, jitter
RTCRemoteInboundRtpStreamStats localId, roundTripTime
"remote-outbound-rtp" RTCRtpStreamStats ssrc, kind, transportId, codecId
RTCSentRtpStreamStats packetsSent, bytesSent
RTCRemoteOutboundRtpStreamStats localId, remoteTimestamp
"media-source" RTCMediaSourceStats trackIdentifier, kind
RTCAudioSourceStats totalAudioEnergy, totalSamplesDuration(sender に接続された音声トラックの場合)
RTCVideoSourceStats width, height, framesPerSecond(sender に接続された映像トラックの場合)
"peer-connection" RTCPeerConnectionStats dataChannelsOpened, dataChannelsClosed
"data-channel" RTCDataChannelStats label , protocol, dataChannelIdentifier, state, messagesSent, bytesSent, messagesReceived, bytesReceived
"transport" RTCTransportStats bytesSent, bytesReceived, selectedCandidatePairId, localCertificateId, remoteCertificateId
"candidate-pair" RTCIceCandidatePairStats transportId, localCandidateId, remoteCandidateId, state, nominated, bytesSent, bytesReceived, totalRoundTripTime, responsesReceived, currentRoundTripTime
"local-candidate" RTCIceCandidateStats address, port, protocol, candidateType, url
"remote-candidate"
"certificate" RTCCertificateStats fingerprint, fingerprintAlgorithm, base64Certificate, issuerCertificateId

実装は、[WEBRTC-STATS] に定義された他の任意の統計を生成することが MAY であり、 文書化されていない統計を生成することも MAY である。

8.7 GetStats の例

ユーザーが音声品質の低下を体験しており、その原因がパケットロスかどうかをアプリケーションが判定したいケースを考える。 次のサンプルコードが利用できる:

async function gatherStats(pc) {
  try {
    const [sender] = pc.getSenders();
    const baselineReport = await sender.getStats();
    await new Promise(resolve => setTimeout(resolve, aBit)); // 少し待機する
    const currentReport = await sender.getStats();

    // 現在のレポートの要素をベースラインと比較する
    for (const now of currentReport.values()) {
      if (now.type != 'outbound-rtp') continue;

      // ベースラインレポートから対応する統計を取得する
      const base = baselineReport.get(now.id);
      if (!base) continue;

      const remoteNow = currentReport.get(now.remoteId);
      const remoteBase = baselineReport.get(base.remoteId);

      const packetsSent = now.packetsSent - base.packetsSent;
      const packetsReceived = remoteNow.packetsReceived -
                              remoteBase.packetsReceived;

      const fractionLost = (packetsSent - packetsReceived) / packetsSent;
      if (fractionLost > 0.3) {
        // fractionLost が 0.3 より大きければ、原因である可能性が高い
      }
    }
  } catch (err) {
    console.error(err);
  }
}

9. ネットワーク利用のための Media Stream API 拡張

9.1 イントロダクション

[GETUSERMEDIA] 仕様で定義される MediaStreamTrack インターフェイスは、通常、音声または映像のデータストリームを表す。1 つ以上の MediaStreamTrackMediaStream にまとめることができる(厳密には、[GETUSERMEDIA] で定義される MediaStream は 0 個以上の MediaStreamTrack オブジェクトを含みうる)。

MediaStreamTrack は、(例えばローカルカメラに限らず)リモートピアから来る、またはリモートピアへ送られるメディアフローを表すように拡張されうる。この能力を MediaStreamTrack オブジェクトで有効にするために必要な拡張について本節で述べる。メディアがピアへどのように送信されるかは、 [RFC8834]、[RFC7874]、および [RFC8835] に記載されている。

他のピアへ送信された MediaStreamTrack は、受信側からはただ 1 つの MediaStreamTrack として見える。ピアとは、この仕様をサポートするユーザーエージェントと定義される。さらに、送信側アプリケーションは、当該 MediaStream オブジェクト(群)を示すことができる。受信側では対応する MediaStream オブジェクト(群)が(未作成であれば)生成され、適宜内容が設定される。

本書の前の節でも述べたとおり、RTCRtpSender および RTCRtpReceiver オブジェクトは、アプリケーションが MediaStreamTrack の送受信をより細かく制御するために利用できる。

Media Capture and Streams 仕様で扱われる最小単位は「チャンネル」である。チャンネルは、例えば RTP のペイロードタイプとして、送信用にまとめてエンコードされることを意図している。コーデックが共同でエンコードする必要のあるすべてのチャンネルは同じ MediaStreamTrack に含まれていなければならず MUST、コーデックはそのトラック内のすべてのチャンネルをエンコード、または破棄できるべきである SHOULD

ある MediaStreamTrack に対する入力および出力の概念は、ネットワーク経由で送受信される MediaStreamTrack オブジェクトにも適用される。RTCPeerConnection オブジェクト(本書前節で説明)により作成される MediaStreamTrack は、リモートピアから受信したデータを入力として受け取る。同様に、ローカルのソース、例えば [GETUSERMEDIA] を介したカメラからの MediaStreamTrack は、当該オブジェクトを RTCPeerConnection オブジェクトと共に用いる場合、リモートピアに送信される内容を表す出力を持つ。

[GETUSERMEDIA] で述べられている MediaStream および MediaStreamTrack オブジェクトの複製の概念も、ここで適用される。この機能は例えばビデオ会議のシナリオにおいて、ユーザーのカメラとマイクからのローカル映像をローカルモニターに表示しつつ、音声のみをリモートピアに送信する(例えばユーザーが「ビデオミュート」機能を使用した場合の応答として)用途に利用できる。異なる MediaStreamTrack オブジェクトを新たな MediaStream オブジェクトに組み合わせることは、特定の状況で有用である。

注記

本書では、RTCPeerConnection と併用される際に関係する以下のオブジェクトの側面のみを規定する。MediaStream および MediaStreamTrack の一般的な利用方法については、[GETUSERMEDIA] 文書の元の定義を参照のこと。

9.2 MediaStream

9.2.1 id

id 属性(MediaStream にて規定)は、このストリームに固有の id を返す。これにより、RTCPeerConnection API のリモート側でストリームを識別できる。

リモートピアから得られたストリームを表すために MediaStream が作成される場合、id 属性は、リモートソースから提供された情報で初期化される。

注記

id はストリームのソースに対して一意であるが、重複が発生しないことを意味するわけではない。例えば、ローカルで生成されたストリームのトラックが、あるユーザーエージェントからリモートピアへ RTCPeerConnection を用いて送られ、その後同じ方法で元のユーザーエージェントへ送り返される場合、元のユーザーエージェントは同じ id を持つ複数のストリーム(ローカル生成のものとリモートピアから受信したもの)を持つことになる。

9.3 MediaStreamTrack

非ローカルなメディアソース(各 MediaStreamTrackRTCRtpReceiver に関連付けられている場合の RTP ソース)における、オブジェクトの MediaStream への参照は、常に強参照である。

RTCRtpReceiver が、対応する MediaStreamTrack がミュート状態で終了していない(muted だが ended ではない)RTP ソースでデータを受信し、かつ当該 [[Receptive]] スロットを持つ RTCRtpTransceiver オブジェクトで RTCRtpReceiver がメンバーであるものの値が true の場合、対応する ミュート状態を設定する タスクをキューに入れ、その MediaStreamTrack のミュート状態を false にしなければならない MUST

RTCRtpReceiver が受信する RTP ソースのメディアストリームに対する SSRC の一つが、BYE の受信またはタイムアウトによって削除された場合、対応する ミュート状態を設定する タスクをキューに入れ、対応する MediaStreamTrack のミュート状態を true にしなければならない MUST。なお、setRemoteDescription によっても、当該 ミュート状態の設定track の値を true にする)が生じうる。

手続き トラックの追加トラックの削除、および トラックのミュート状態の設定 は、 [GETUSERMEDIA] に規定されている。

RTCRtpReceiver receiver によって生成された MediaStreamTrack のトラックが [GETUSERMEDIA] における ended 状態(例えば receiver.track.stop の呼び出しにより)になった場合、ユーザーエージェントは、例えば receiver のデコーダーを停止するなどして、受信ストリームに割り当てられたリソースを解放してもよい MAY

9.3.1 MediaTrackSupportedConstraints、MediaTrackCapabilities、 MediaTrackConstraints、MediaTrackSettings

制約および制約可能プロパティの概念(MediaTrackConstraintsMediaStreamTrack.getConstraints()MediaStreamTrack.applyConstraints())、および MediaTrackSettingsMediaStreamTrack.getSettings())を含む)は、[GETUSERMEDIA] に概説されている。ただし、ピア接続に由来するトラックの制約可能プロパティは、getUserMedia() によって供給されるものとは異なる。MediaStreamTrackリモートソース に由来する場合に適用される制約および設定はここで定義する。リモートトラックの設定は、最新に受信したフレームを表す。

MediaStreamTrack.getCapabilities() は常に空集合を返さなければならず MUSTMediaStreamTrack.applyConstraints() は、ここで定義する制約について、リモートトラック上では常に OverconstrainedError で reject しなければならない MUST

次の制約可能プロパティは、MediaStreamTrack(動画)が リモートソース に由来する場合に適用されるものとして定義する:

プロパティ名 注記
width ConstrainULong 設定としては、最新に受信したフレームの幅(ピクセル)を表す。
height ConstrainULong 設定としては、最新に受信したフレームの高さ(ピクセル)を表す。
frameRate ConstrainDouble 設定としては、直近に受信したフレームに基づくフレームレートの推定値である。
aspectRatio ConstrainDouble 設定としては、最新フレームのアスペクト比(幅ピクセル数を高さピクセル数で割った値)であり、10 桁目に丸めた倍精度小数で表す。

本書は、MediaStreamTrack(音声)が リモートソース に由来する場合に適用される制約可能プロパティを定義しない。

10. 例とコールフロー

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

10.1 シンプルなピアツーピアの例

2 つのピアが相互に接続を確立することを決めたとき、両者とも次の手順を踏みます。STUN/TURN サーバーの設定は、パブリック IP アドレスの取得や NAT 越えの設定に使用できるサーバーを記述します。最初に通信することを確認したのと同じ帯域外のメカニズムを用いて、シグナリングチャネル向けのデータも互いに送信する必要があります。

const signaling = new SignalingChannel(); // JSON.stringify/parse を処理する
const constraints = {audio: true, video: true};
const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
const pc = new RTCPeerConnection(configuration);

// ICE candidate を相手ピアへ送る
pc.onicecandidate = ({candidate}) => signaling.send({candidate});

// 「negotiationneeded」イベントでオファー生成を開始する
pc.onnegotiationneeded = async () => {
  try {
    await pc.setLocalDescription();
    // オファーを相手ピアへ送る
    signaling.send({description: pc.localDescription});
  } catch (err) {
    console.error(err);
  }
};

pc.ontrack = ({track, streams}) => {
  // リモートトラックのメディアが到着したら、リモート側の video 要素に表示する
  track.onunmute = () => {
    // 既に設定済みなら srcObject を再設定しない。
    if (remoteView.srcObject) return;
    remoteView.srcObject = streams[0];
  };
};

// start() を呼んで開始する
function start() {
  addCameraMic();
}

// カメラとマイクを接続に追加する
async function addCameraMic() {
  try {
    // ローカルストリームを取得し、自分のビューに表示して送信に追加する
    const stream = await navigator.mediaDevices.getUserMedia(constraints);
    for (const track of stream.getTracks()) {
      pc.addTrack(track, stream);
    }
    selfView.srcObject = stream;
  } catch (err) {
    console.error(err);
  }
}

signaling.onmessage = async ({data: {description, candidate}}) => {
  try {
    if (description) {
      await pc.setRemoteDescription(description);
      // オファーを受け取ったら、アンサーで応答する必要がある
      if (description.type == 'offer') {
        if (!selfView.srcObject) {
          // 権限取得でネゴシエーションをブロックする(本番コードでは非推奨)
          await addCameraMic();
        }
        await pc.setLocalDescription();
        signaling.send({description: pc.localDescription});
      }
    } else if (candidate) {
      await pc.addIceCandidate(candidate);
    }
  } catch (err) {
    console.error(err);
  }
};

10.2 ウォームアップ付きの高度なピアツーピアの例

2 つのピアが相互に接続を確立し、ICE、DTLS、メディアの接続を「ウォームアップ」して、即座にメディアの送受信を可能にしたい場合、両者とも次の手順を踏みます。

const signaling = new SignalingChannel(); // JSON.stringify/parse を処理する
const constraints = {audio: true, video: true};
const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
let pc;
let audio;
let video;
let started = false;

// メディア準備前に warmup() を呼び出し、ICE・DTLS・メディアをウォームアップする
async function warmup(isAnswerer) {
  pc = new RTCPeerConnection(configuration);
  if (!isAnswerer) {
    audio = pc.addTransceiver('audio');
    video = pc.addTransceiver('video');
  }

  // ICE candidate を相手ピアへ送る
  pc.onicecandidate = ({candidate}) => signaling.send({candidate});

  // 「negotiationneeded」イベントでオファー生成を開始する
  pc.onnegotiationneeded = async () => {
    try {
      await pc.setLocalDescription();
      // オファーを相手ピアへ送る
      signaling.send({description: pc.localDescription});
    } catch (err) {
      console.error(err);
    }
  };

  pc.ontrack = async ({track, transceiver}) => {
    try {
      // リモートトラックのメディアが到着したら、video 要素に表示する
      event.track.onunmute = () => {
        // 既に設定済みなら srcObject を再設定しない。
        if (!remoteView.srcObject) {
          remoteView.srcObject = new MediaStream();
        }
        remoteView.srcObject.addTrack(track);
      }

      if (isAnswerer) {
        if (track.kind == 'audio') {
          audio = transceiver;
        } else if (track.kind == 'video') {
          video = transceiver;
        }
        if (started) await addCameraMicWarmedUp();
      }
    } catch (err) {
      console.error(err);
    }
  };

  try {
    // ローカルストリームを取得し、自分のビューに表示して送信に追加する
    selfView.srcObject = await navigator.mediaDevices.getUserMedia(constraints);
    if (started) await addCameraMicWarmedUp();
  } catch (err) {
    console.error(err);
  }
}

// warmup() の後に start() を呼び、両端からのメディア送信を開始する
function start() {
  signaling.send({start: true});
  signaling.onmessage({data: {start: true}});
}

// ウォームアップ済みの接続にカメラとマイクを追加する
async function addCameraMicWarmedUp() {
  const stream = selfView.srcObject;
  if (audio && video && stream) {
    await Promise.all([
      audio.sender.replaceTrack(stream.getAudioTracks()[0]),
      video.sender.replaceTrack(stream.getVideoTracks()[0]),
    ]);
  }
}

signaling.onmessage = async ({data: {start, description, candidate}}) => {
  if (!pc) warmup(true);

  try {
    if (start) {
      started = true;
      await addCameraMicWarmedUp();
    } else if (description) {
      await pc.setRemoteDescription(description);
      // オファーを受け取ったら、アンサーで応答する
      if (description.type == 'offer') {
        await pc.setLocalDescription();
        signaling.send({description: pc.localDescription});
      }
    } else {
      await pc.addIceCandidate(candidate);
    }
  } catch (err) {
    console.error(err);
  }
};

10.3 同時送信(Simulcast)の例

クライアントがサーバーへ複数の RTP エンコーディング(シミュルキャスト)を送信したい。

const signaling = new SignalingChannel(); // JSON.stringify/parse を処理する
const constraints = {audio: true, video: true};
const configuration = {'iceServers': [{'urls': 'stun:stun.example.org'}]};
let pc;

// start() を呼んで開始する
async function start() {
  pc = new RTCPeerConnection(configuration);

  // 「negotiationneeded」イベントでオファー生成を開始する
  pc.onnegotiationneeded = async () => {
    try {
      await pc.setLocalDescription();
      // オファーを相手ピアへ送る
      signaling.send({description: pc.localDescription});
    } catch (err) {
      console.error(err);
    }
  };

  try {
    // ローカルストリームを取得し、自分のビューに表示して送信に追加する
    const stream = await navigator.mediaDevices.getUserMedia(constraints);
    selfView.srcObject = stream;
    pc.addTransceiver(stream.getAudioTracks()[0], {direction: 'sendonly'});
    pc.addTransceiver(stream.getVideoTracks()[0], {
      direction: 'sendonly',
      sendEncodings: [
        {rid: 'q', scaleResolutionDownBy: 4.0}
        {rid: 'h', scaleResolutionDownBy: 2.0},
        {rid: 'f'},
      ]
    });
  } catch (err) {
    console.error(err);
  }
}

signaling.onmessage = async ({data: {description, candidate}}) => {
  try {
    if (description) {
      await pc.setRemoteDescription(description);
      // オファーを受け取ったら、アンサーで応答する必要がある
      if (description.type == 'offer') {
        await pc.setLocalDescription();
        signaling.send({description: pc.localDescription});
      }
    } else if (candidate) {
      await pc.addIceCandidate(candidate);
    }
  } catch (err) {
    console.error(err);
  }
};

10.4 ピアツーピアのデータの例

この例は、RTCDataChannel オブジェクトを作成し、チャネルを相手ピアへ接続するために必要なオファー/アンサー交換を実行する方法を示します。RTCDataChannel は、input フィールドを使ったシンプルなチャットアプリケーションの文脈で使用されます。

const signaling = new SignalingChannel(); // JSON.stringify/parse を処理する
const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
let pc, channel;

// start() を呼んで開始する
function start() {
  pc = new RTCPeerConnection(configuration);

  // ICE candidate を相手ピアへ送る
  pc.onicecandidate = ({candidate}) => signaling.send({candidate});

  // 「negotiationneeded」イベントでオファー生成を開始する
  pc.onnegotiationneeded = async () => {
    try {
      await pc.setLocalDescription();
      // オファーを相手ピアへ送る
      signaling.send({description: pc.localDescription});
    } catch (err) {
      console.error(err);
    }
  };

  // データチャネルを作成し、「negotiated」パターンでチャットをセットアップする
  channel = pc.createDataChannel('chat', {negotiated: true, id: 0});
  channel.onopen = () => input.disabled = false;
  channel.onmessage = ({data}) => showChatMessage(data);

  input.onkeydown = ({key}) => {
    if (key != 'Enter') return;
    channel.send(input.value);
  }
}

signaling.onmessage = async ({data: {description, candidate}}) => {
  if (!pc) start();

  try {
    if (description) {
      await pc.setRemoteDescription(description);
      // オファーを受け取ったら、アンサーで応答する必要がある
      if (description.type == 'offer') {
        await pc.setLocalDescription();
        signaling.send({description: pc.localDescription});
      }
    } else if (candidate) {
      await pc.addIceCandidate(candidate);
    }
  } catch (err) {
    console.error(err);
  }
};

10.5 ブラウザー間のコールフロー

これは 2 つのブラウザー間で想定されるコールフローの一例を示します。ローカルメディアへのアクセス手順や、発火するすべてのコールバックを示すものではなく、主要なイベントとメッセージのみに絞って示します。

2つのブラウザー間のコールフローを詳細化したメッセージシーケンス図

10.6 DTMF の例

以下の例では、senderRTCRtpSender であると仮定します。

各トーン 500 ms の継続時間で DTMF 信号「1234」を送信する:

if (sender.dtmf.canInsertDTMF) {
  const duration = 500;
  sender.dtmf.insertDTMF('1234', duration);
} else {
  console.log('DTMF function not available');
}

DTMF 信号「123」を送信し、「2」送信後に中止する。

async function sendDTMF() {
  if (sender.dtmf.canInsertDTMF) {
    sender.dtmf.insertDTMF('123');
    await new Promise(r => sender.dtmf.ontonechange = e => e.tone == '2' && r());
    // 「2」以降のトーンを再生しないようにバッファを空にする
    sender.dtmf.insertDTMF('');
  } else {
    console.log('DTMF function not available');
  }
}

DTMF 信号「1234」を送信し、トーンの再生中に lightKey(key) で押下中のキーを点灯する(lightKey("") が全キーの消灯だと仮定):

const wait = ms => new Promise(resolve => setTimeout(resolve, ms));

if (sender.dtmf.canInsertDTMF) {
  const duration = 500; // ms
  sender.dtmf.insertDTMF(sender.dtmf.toneBuffer + '1234', duration);
  sender.dtmf.ontonechange = async ({tone}) => {
    if (!tone) return;
    lightKey(tone); // 再生開始時にキーを点灯
    await wait(duration);
    lightKey(''); // トーン継続時間後に消灯
  };
} else {
  console.log('DTMF function not available');
}

トーンバッファへの追加は常に安全です。この例では、再生開始前と再生中の両方で追加しています。

if (sender.dtmf.canInsertDTMF) {
  sender.dtmf.insertDTMF('123');
  // 再生開始前に、さらにトーンをトーンバッファに追加する
  sender.dtmf.insertDTMF(sender.dtmf.toneBuffer + '456');

  sender.dtmf.ontonechange = ({tone}) => {
    // 再生開始後に、さらにトーンを追加する
    if (tone != '1') return;
    sender.dtmf.insertDTMF(sender.dtmf.toneBuffer + '789');
  };
} else {
  console.log('DTMF function not available');
}

1 秒の「1」のトーンに続けて 2 秒の「2」のトーンを送信する:

if (sender.dtmf.canInsertDTMF) {
  sender.dtmf.ontonechange = ({tone}) => {
    if (tone == '1') {
      sender.dtmf.insertDTMF(sender.dtmf.toneBuffer + '2', 2000);
    }
  };
  sender.dtmf.insertDTMF(sender.dtmf.toneBuffer + '1', 1000);
} else {
  console.log('DTMF function not available');
}

10.7 パーフェクトネゴシエーションの例

パーフェクトネゴシエーションは、ネゴシエーションを自動的に管理し、この非対称なタスクをアプリケーション本体から切り離すために推奨されるパターンです。このパターンは、常に片側がオファーを出す方式よりも利点があり、両方のピア接続オブジェクトを同時に操作しても、(「stable」状態の外からオファーが来る)グレアの危険を避けられます。アプリケーションの残りの部分は、シグナリング状態の競合を気にせず、あらゆる変更メソッドや属性を使用できます。

これは 2 つのピアに異なる役割を割り当て、シグナリングの衝突を解決する振る舞いを定義します:

  1. 丁寧なピア(polite peer)は、着信したオファーとの衝突を避けるためにロールバックを使用する。

  2. 不作法なピア(impolite peer)は、自身のオファーと衝突する場合、着信したオファーを無視する。

これらを組み合わせることで、アプリケーションの残りの部分に対してデッドロックしない方法でシグナリングを管理します。以下の例では、指定された役割を示す真偽値 polite を仮定します:

const signaling = new SignalingChannel(); // JSON.stringify/parse を処理する
const constraints = {audio: true, video: true};
const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
const pc = new RTCPeerConnection(configuration);

// 任意のタイミングで start() を呼び、接続にカメラとマイクを追加する
async function start() {
  try {
    const stream = await navigator.mediaDevices.getUserMedia(constraints);
    for (const track of stream.getTracks()) {
      pc.addTrack(track, stream);
    }
    selfView.srcObject = stream;
  } catch (err) {
    console.error(err);
  }
}

pc.ontrack = ({track, streams}) => {
  // リモートトラックのメディアが到着したら、リモート側の video 要素に表示する
  track.onunmute = () => {
    // 既に設定済みなら srcObject を再設定しない。
    if (remoteView.srcObject) return;
    remoteView.srcObject = streams[0];
  };
};

// - アプリケーション本体と分離されたパーフェクトネゴシエーションのロジック ---

// レースやエラーを防ぐため、いくつかのネゴシエーション状態を追跡する
let makingOffer = false;
let ignoreOffer = false;
let isSettingRemoteAnswerPending = false;

// ICE candidate を相手ピアへ送る
pc.onicecandidate = ({candidate}) => signaling.send({candidate});

// 「negotiationneeded」イベントでオファー生成を開始する
pc.onnegotiationneeded = async () => {
  try {
    makingOffer = true;
    await pc.setLocalDescription();
    signaling.send({description: pc.localDescription});
  } catch (err) {
     console.error(err);
  } finally {
    makingOffer = false;
  }
};

signaling.onmessage = async ({data: {description, candidate}}) => {
  try {
    if (description) {
      // 我々が SRD(answer) を処理中にオファーが到着する場合がある。
      // この場合、オファーが処理される頃には状態は "stable" になっているため、
      // いま Operations Chain に連結しても安全。
      const readyForOffer =
          !makingOffer &&
          (pc.signalingState == "stable" || isSettingRemoteAnswerPending);
      const offerCollision = description.type == "offer" && !readyForOffer;

      ignoreOffer = !polite && offerCollision;
      if (ignoreOffer) {
        return;
      }
      isSettingRemoteAnswerPending = description.type == "answer";
      await pc.setRemoteDescription(description); // 必要に応じて SRD がロールバックを行う
      isSettingRemoteAnswerPending = false;
      if (description.type == "offer") {
        await pc.setLocalDescription();
        signaling.send({description: pc.localDescription});
      }
    } else if (candidate) {
      try {
        await pc.addIceCandidate(candidate);
      } catch (err) {
        if (!ignoreOffer) throw err; // 無視したオファーに属する candidate のエラーは抑制
      }
    }
  } catch (err) {
    console.error(err);
  }
}

これはタイミングに敏感であり、意図的に引数なしの setLocalDescription と、(暗黙のロールバック付きの)setRemoteDescription のバージョンを使用して、他のシグナリングメッセージ処理との競合を避けています。

ignoreOffer 変数が必要なのは、不作法側(impolite)の RTCPeerConnection オブジェクトは無視されたオファーについて知らされないためです。そのため、そのようなオファーに属する着信 candidate からのエラーを抑制する必要があります。

11. エラー処理

いくつかの操作は RTCError をスローまたはイベントとして発火する。これは DOMException を拡張したもので、WebRTC 固有の追加情報を保持する。

11.1 RTCError インターフェイス

WebIDL[Exposed=Window]
interface RTCError : DOMException {
  constructor(RTCErrorInit init, optional DOMString message = "");
  readonly attribute RTCErrorDetailType errorDetail;
  readonly attribute long? sdpLineNumber;
  readonly attribute long? sctpCauseCode;
  readonly attribute unsigned long? receivedAlert;
  readonly attribute unsigned long? sentAlert;
};

11.1.1 コンストラクター

constructor()

次の手順を実行する:

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

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

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

  4. eDOMException コンストラクターを、message 引数を message に、name 引数を "OperationError" に設定して呼び出す。

    注記

    この name は旧来の code へのマッピングを持たないため、 e.code は 0 を返す。

  5. e のすべての RTCError 属性を、init に対応する属性が存在する場合はその値に、存在しない場合は null に設定する。

  6. e を返す。

11.1.2 属性

errorDetail の型は RTCErrorDetailType、読み取り専用

発生したエラーの種類に対する WebRTC 固有のエラーコード。

sdpLineNumber の型は long、読み取り専用、nullable

errorDetail が "sdp-syntax-error" の場合、エラーが検出された行番号(最初の行は 1)を表す。

sctpCauseCode の型は long、読み取り専用、nullable

errorDetail が "sctp-failure" の場合、失敗した SCTP ネゴシエーションの SCTP 原因コードを表す。

receivedAlert の型は unsigned long、読み取り専用、nullable

errorDetail が "dtls-failure" で、致命的な DTLS アラートを受信した場合、受信した DTLS アラートの値を表す。

sentAlert の型は unsigned long、読み取り専用、nullable

errorDetail が "dtls-failure" で、致命的な DTLS アラートを送信した場合、送信した DTLS アラートの値を表す。

(実装リスクのある機能) 課題 1

RTCError で定義されるすべての属性は、実装不足のためリスク付きとされている(errorDetailsdpLineNumbersctpCauseCodereceivedAlert および sentAlert)。これは、 DOMException から継承される属性は含まない。

11.1.3 RTCErrorInit 辞書

WebIDLdictionary RTCErrorInit {
  required RTCErrorDetailType errorDetail;
  long sdpLineNumber;
  long sctpCauseCode;
  unsigned long receivedAlert;
  unsigned long sentAlert;
};

errorDetailsdpLineNumbersctpCauseCodereceivedAlert および sentAlert は、RTCErrorInit のメンバーであり、RTCError の同名の属性と同じ定義を持つ。

11.2 RTCErrorDetailType 列挙型

WebIDLenum RTCErrorDetailType {
  "data-channel-failure",
  "dtls-failure",
  "fingerprint-failure",
  "sctp-failure",
  "sdp-syntax-error",
  "hardware-encoder-not-available",
  "hardware-encoder-error"
};
RTCErrorDetailType 列挙の説明
列挙値 説明
data-channel-failure データチャネルが失敗した。
dtls-failure DTLS ネゴシエーションが失敗したか、致命的なエラーで接続が終了した。message にはエラーの性質に関する情報が含まれる。致命的な DTLS アラートを受信した場合、receivedAlert 属性に受信した DTLS アラートの値が設定される。致命的な DTLS アラートを送信した場合、sentAlert 属性に送信した DTLS アラートの値が設定される。
fingerprint-failure RTCDtlsTransport のリモート証明書が、SDP で提供されたいずれのフィンガープリントとも一致しなかった。リモートピアが、提供されたフィンガープリントに対してローカル証明書を一致させられない場合、このエラーは生成されない。その代わりにリモートピアから "bad_certificate"(42)DTLS アラートが受信されることがあり、その結果として "dtls-failure" となりうる。
sctp-failure SCTP ネゴシエーションが失敗したか、致命的なエラーで接続が終了した。sctpCauseCode 属性には SCTP 原因コードが設定される。
sdp-syntax-error SDP の構文が不正である。sdpLineNumber 属性には、構文エラーが検出された SDP の行番号が設定される。
hardware-encoder-not-available 要求された操作に必要なハードウェアエンコーダーのリソースが利用できない。
hardware-encoder-error ハードウェアエンコーダーが指定されたパラメーターをサポートしていない。

11.3 RTCErrorEvent インターフェイス

RTCErrorEvent インターフェイスは、 RTCError がイベントとして発生した場合のために定義されている:

WebIDL[Exposed=Window]
interface RTCErrorEvent : Event {
  constructor(DOMString type, RTCErrorEventInit eventInitDict);
  [SameObject] readonly attribute RTCError error;
};

11.3.1 コンストラクター

constructor()

新しい RTCErrorEvent を構築する。

11.3.2 属性

error の型は RTCError、 読み取り専用

イベントを引き起こしたエラーを記述する RTCError

11.4 RTCErrorEventInit 辞書

WebIDL          dictionary RTCErrorEventInit : EventInit {
  required RTCError error;
};

11.4.1 辞書 RTCErrorEventInit のメンバー

error の型は RTCError

イベントに関連付けられたエラー(存在する場合)を記述する RTCError

12. イベント概要

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

以下のイベントは RTCDataChannel オブジェクトで発火する:

イベント名 インターフェイス 発火条件
open Event RTCDataChannel オブジェクトの 基盤となるデータ輸送 が確立(または再確立)された。
message MessageEvent [html] メッセージが正常に受信された。
bufferedamountlow Event RTCDataChannel オブジェクトの bufferedAmount が、その bufferedAmountLowThreshold を上回る値から、 当該 bufferedAmountLowThreshold 以下に 減少した。
error RTCErrorEvent データチャネルでエラーが発生した。
closing Event RTCDataChannel オブジェクトが 「closing」 状態へ遷移した。
close Event RTCDataChannel オブジェクトの 基盤となるデータ輸送 がクローズされた。

以下のイベントは RTCPeerConnection オブジェクトで発火する:

イベント名 インターフェイス 発火条件
track RTCTrackEvent 特定の RTCRtpReceiver に対して新しい受信メディアが ネゴシエートされ、そのレシーバーの track が関連するリモートの MediaStream に追加された。
negotiationneeded Event ブラウザーが、セッションのネゴシエーションが必要であること(すなわち createOffer の呼び出しと それに続く setLocalDescription)をアプリケーションに通知しようとするとき。
signalingstatechange Event 接続の [[SignalingState]] が変更された。 この状態変化は、 setLocalDescription または setRemoteDescription の呼び出しの結果である。
iceconnectionstatechange Event RTCPeerConnection[[IceConnectionState]] が 変更された。
icegatheringstatechange Event RTCPeerConnection[[IceGatheringState]] が 変更された。
icecandidate RTCPeerConnectionIceEvent 新しい RTCIceCandidate が スクリプトで利用可能になった。
connectionstatechange Event RTCPeerConnectionconnectionState が変更された。
icecandidateerror RTCPeerConnectionIceErrorEvent ICE 候補の収集中に失敗が発生した。
datachannel RTCDataChannelEvent 相手ピアがチャネルを作成したことに応じて、新しい RTCDataChannel が スクリプトにディスパッチされる。

以下のイベントは RTCDTMFSender オブジェクトで発火する:

イベント名 インターフェイス 発火条件
tonechange RTCDTMFToneChangeEvent RTCDTMFSender オブジェクトが、 トーンの再生を開始した直後(tone 属性として返される) か、toneBuffer 内のトーンの再生を 終了した直後(tone 属性が空値として返される)。

以下のイベントは RTCIceTransport オブジェクトで発火する:

イベント名 インターフェイス 発火条件
statechange Event RTCIceTransport の状態が変更された。
gatheringstatechange Event RTCIceTransport の gathering 状態が 変更された。
selectedcandidatepairchange Event RTCIceTransport の選択された候補ペアが 変更された。

以下のイベントは RTCDtlsTransport オブジェクトで発火する:

イベント名 インターフェイス 発火条件
statechange Event RTCDtlsTransport の状態が変更された。
error RTCErrorEvent RTCDtlsTransport でエラーが発生した (「dtls-failure」または 「fingerprint-failure」)。

以下のイベントは RTCSctpTransport オブジェクトで発火する:

イベント名 インターフェイス 発火条件
statechange Event RTCSctpTransport の状態が変更された。

13. プライバシーとセキュリティに関する考慮事項

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

このセクションは規範的ではなく、新たな動作を規定するものではありません。むしろ、仕様の他の部分に既に含まれている情報を要約します。WebRTC で用いられる API とプロトコルの一般的な集合に関する全体的なセキュリティ考慮事項は [RFC8827] に記述されています。

13.1 同一オリジンポリシーへの影響

本書は、他のブラウザーを含むブラウザーや他のデバイス間で、リアルタイムかつ直接の通信を設定する能力で Web プラットフォームを拡張します。

これは、異なるブラウザーで動作するアプリケーション間、あるいは同じブラウザーで動作するアプリケーションとブラウザーではない何かとの間で、データやメディアが共有できることを意味します。これは Web モデルで通常、異なるオリジン間のデータ送信に対して存在する障壁を拡張するものです。

WebRTC 仕様は通信のためのユーザープロンプトやブラウザー UI インジケーターを提供しません。ウェブページがメディアへのアクセスを許可された時点で、そのメディアを任意の相手と自由に共有できるものと仮定しています。そのため、WebRTC のデータチャネル経由でのピアツーピアのデータ交換は、ユーザーの明示的な同意や関与なしに行われ得ます。これは、サーバー仲介の交換(例えば WebSockets 経由)がユーザーの関与なしに起こり得るのと同様です。

13.2 IP アドレスの露出

WebRTC を用いなくても、Web アプリケーションを提供する Web サーバーは、そのアプリケーションが配信される先のパブリック IP アドレスを知ることができます。通信の確立は、ブラウザーのネットワーク環境に関する追加情報を Web アプリケーションへ露出し得ます。この中には、ブラウザーが WebRTC で使用可能な(プライベートである可能性のある)IP アドレスの集合が含まれる場合があります。こうした情報の一部は、通信セッションの確立を可能にするために、相手側に渡す必要があります。

IP アドレスの露出は、位置情報や接続手段を漏えいさせ得ます。これは機微情報となり得ます。ネットワーク環境によっては、フィンガープリンティングの表面積を増やし、ユーザーが容易に消去できない永続的なクロスオリジン状態を作り出すことにもつながります。

接続は常に、通信に提案された IP アドレスを相手側に露出します。アプリケーションは、RTCIceTransportPolicy 辞書で公開される設定を用いて、特定のアドレスを使用しないことを選択したり、参加者間の直接接続ではなくリレー(例えば TURN サーバー)を使用したりすることで、この露出を制限できます。一般的に、TURN サーバーの IP アドレスは機微情報ではないと想定されます。これらの選択は、たとえばユーザーが相手とのメディア接続を開始することに同意を示したかどうかに基づいて、アプリケーションが行うことができます。

アプリケーション自体への IP アドレスの露出を軽減するには、使用可能な IP アドレスを制限する必要があり、これはエンドポイント間の最も直接的な経路での通信能力に影響します。ブラウザーは、ユーザーが望むセキュリティ姿勢に基づいて、どの IP アドレスをアプリケーションに利用可能とするかを決定するための適切な制御を提供することが推奨されます。どのアドレスを露出するかの選択はローカルポリシーによって管理されます(詳細は [RFC8828] を参照)。

13.3 ローカルネットワークへの影響

ブラウザーは信頼されたネットワーク環境(ファイアウォール内)で実行されるアクティブなプラットフォームであるため、ブラウザーがローカルネットワーク上の他の要素に与え得る被害を制限すること、そして信頼できない参加者による傍受・改ざん・変更からデータを保護することが重要です。

緩和策には次が含まれます:

これらの対策は、関連する IETF 文書に規定されています。

13.4 通信の機密性

ネットワークを観測できる攻撃者に対して、通信が行われているという事実を隠すことはできません。したがって、これは公開情報として扱う必要があります。

将来の必要性を見越して、postMessage(message, options) を用いて、通信証明書を不透明に共有することができます。ユーザーエージェントは、RTCCertificate オブジェクトへアクセスできるプロセスから、これらのオブジェクトがハンドルする秘密鍵マテリアルを分離(アイソレーション)し、メモリ攻撃の表面積を減らすことが強く推奨されます。

13.5 WebRTC によって露出される永続的な情報

上述のとおり、WebRTC API によって露出される IP アドレスの一覧は、永続的なクロスオリジン状態として利用され得ます。

IP アドレスに加えて、WebRTC API は基盤となるメディアシステムに関する情報を RTCRtpSendergetCapabilities および RTCRtpReceivergetCapabilities メソッドを通じて公開します。ここには、システムが生成・消費可能なコーデックに関する詳細で順序付けられた情報が含まれます。その情報のサブセットは、多くの場合、 セッションネゴシエーション 中に生成・公開・送信される SDP セッション記述に含まれます。これらの情報は、ほとんどの場合、時間やオリジンをまたいで永続的であり、特定デバイスのフィンガープリンティングの表面積を増加させます。

DTLS 接続を確立する際、WebRTC API は、アプリケーションが(例えば IndexedDB に)永続化できる証明書を生成できます。これらの証明書はオリジン間で共有されず、当該オリジンの永続ストレージが消去されると同時に消去されます。

13.6 リモートエンドポイントからの SDP 設定

setRemoteDescription は、例外を投げることで不正な形式や無効な SDP に対しては防御しますが、アプリケーションにとって予期しない SDP に対しては防御しません。リモート記述を設定すると、(画像バッファやネットワークポートを含む)多大なリソースが割り当てられたり、メディアが流れ始めたり(プライバシーや帯域幅への影響を含む)といった事態が発生し得ます。悪意のある SDP に対して防御しないアプリケーションは、リソース枯渇のリスクや、相手が送信をネゴシエートしない場合に ontrack のような特定のイベントが発火しないリスク、意図せず受信メディアを許容してしまうリスクにさらされ得ます。アプリケーションは、悪意のある SDP に対して警戒する必要があります。

14. アクセシビリティに関する考慮事項

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

WebRTC 1.0 仕様は、リアルタイムの音声・映像・データ交換を確立するために必要なプロトコル(IETF で定義)を制御する API を公開します。

TDD/TTY(Telecommunications Device for the Deaf)は、聴覚・発話に障害のある(他の人々を含む)個人が電話回線上で通信できるようにするものです。リアルタイムテキスト(Real-Time Text)は [RFC4103] で定義され、T.140 を RTP にカプセル化して、TDD/TTY デバイスから IP ベースの通信( Public Safety Access Points (PSAP) を含む緊急通信)への移行を可能にします。

リアルタイムテキストは、ほぼリアルタイムでデータを送受信する能力を必要とするため、WebRTC 1.0 のデータチャネル API によって最もよくサポートできます。IETF によって定義されているように、データチャネルプロトコルは SCTP/DTLS/UDP プロトコルスタックを使用し、信頼的・非信頼的の両方のデータチャネルをサポートします。IETF は、SRTP 鍵管理に依存し、非信頼的通信に重点を置いた RTP データチャネルの提案よりも、SCTP/DTLS/UDP を標準化することを選択しました。

IETF が、WebRTC のプロトコル群の一部として RTP データチャネルとは異なるアプローチを選択したため、本書の公開時点では、IETF で定義され米国(FCC)規制で実装されているリアルタイムテキストを WebRTC API が直接サポートする標準化された方法は存在しません。WebRTC ワーキンググループは、この分野における進行中の IETF プロトコルをブラウザー API で直接公開することが妥当かを評価しており、この潜在的なギャップについて関連ユーザーコミュニティからの意見を求めています。

IETF MMUSIC Working Group においては、 WebRTC データチャネル上でリアルタイムテキストを送信できるようにする 作業が進行中です。これにより、SCTP データチャネルプロトコルと RFC 4103 のリアルタイムテキストの間を相互変換するゲートウェイを展開できるようになります。この作業が完了すれば、ゲートウェイ経由かそれ以外かにかかわらず、WebRTC ユーザーエージェント(ブラウザーを含む)にリアルタイムテキストを統一的かつ相互運用的に統合するアプローチが可能になると期待されています。

本書の公開時点では、WebRTC クライアントで効果的な RTT をサポートするゲートウェイは、例えばカスタムの WebRTC データチャネルを通じて開発できます。これは、将来的に IETF のプロトコル(SCTP データチャネルプロトコルや RFC 4103 のリアルタイムテキストなど)によって標準化されたゲートウェイが有効化されるまでの間、十分であると見なされます。これは、関連する W3C グループでの作業と連携して IETF で定義され、国際的に RTT のサポートを効果的かつ一貫して標準化する必要があります。

A. 候補修正案

2021年1月にW3C 勧告として公開されて以来、以下の候補修正案が本ドキュメントに統合されています。

B. 謝辞

編集者は、ワーキンググループ議長ならびにチームコンタクトであるHarald Alvestrand、Stefan Håkansson、Erik Lagerway、Dominique Hazaël-Massieuxのご支援に感謝します。本仕様書の多くの文章は、Martin Thomson、Harald Alvestrand、Justin Uberti、Eric Rescorla、Peter Thatcher、Jan-Ivar Bruaroey、Peter Saint-Andreなど多くの方々によって提供されました。Dan Burnettは、本仕様書の開発にあたりVoxeoおよびAspectから受けた多大な支援に謝意を表します。

RTCRtpSender および RTCRtpReceiver オブジェクトは、 当初 W3C ORTC CG で記述され、本仕様書への利用向けに調整されました。

C. 参考文献

候補修正 46:RFC8829参照をRFC9429に置換 (PR #2966)

B.1 規範的参考文献

C.1 規範的参考文献

[DOM]
DOM標準. Anne van Kesteren. WHATWG. 現行標準. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT-6.0]
ECMA-262 第6版 ECMAScript 2015 言語仕様. Allen Wirfs-Brock. Ecma International. 2015年6月. 標準. URL: http://www.ecma-international.org/ecma-262/6.0/index.html
[Fetch]
Fetch標準. Anne van Kesteren. WHATWG. 現行標準. URL: https://fetch.spec.whatwg.org/
[FILEAPI]
File API. Marijn Kruisselbrink; Arun Ranganathan. W3C. 2019年9月11日2024年12月4日. W3C作業草案. URL: https://www.w3.org/TR/FileAPI/
[FIPS-180-4]
FIPS PUB 180-4 180-4: Secure Hash StandardStandard (SHS). 米国商務省/米国標準技術研究所. 2015年8月. 国家標準. URL: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
[GETUSERMEDIA]
Media Capture and Streams. Cullen Jennings; Bernard Aboba; Jan-Ivar Bruaroey; Henrik Boström; youenn fablet; Daniel Burnett; Adam Bergkvist; Anant Narayanan. W3C. 2021年1月21日2024年12月19日. W3C 候補勧告CRD. URL: https://www.w3.org/TR/mediacapture-streams/
[hr-time]
高精度Time Level 2タイム. Ilya GrigorikYoav Weiss. W3C. 2019年21日2024年11月7日. W3C 勧告作業草案. URL: https://www.w3.org/TR/hr-time-2/org/TR/hr-time-3/
[HTML]
HTML標準. Anne van Kesteren; Domenic Denicola; Dominic Farolino; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. 現行標準. URL: https://html.spec.whatwg.org/multipage/
[IANA-HASH-FUNCTION]
Hash Function Textual Names. IANA. URL: https://www.iana.org/assignments/hash-function-text-names/hash-function-text-names.xml
[IANA-RTP-2]
RTP Payload Format media types. IANA. URL: https://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml#rtp-parameters-2
[INFRA]
Infra標準. Anne van Kesteren; Domenic Denicola. WHATWG. 現行標準. URL: https://infra.spec.whatwg.org/
[RFC2119]
RFCで要求レベルを示すためのキーワード. S. Bradner. IETF. 1997年3月. 現行最善慣行. URL: https://tools.ietf.org/html/rfc2119https://www.rfc-editor.org/rfc/rfc2119
[RFC3550]
RTP: リアルタイムアプリケーション用トランスポートプロトコル. H. Schulzrinne; S. Casner; R. Frederick; V. Jacobson. IETF. 2003年7月. インターネット標準. URL: https://tools.ietf.org/html/rfc3550https://www.rfc-editor.org/rfc/rfc3550
[RFC3890]
セッション記述プロトコル(SDP)のトランスポート非依存帯域幅修飾子. M. Westerlund. IETF. 2004年9月. 提案標準. URL: https://tools.ietf.org/html/rfc3890https://www.rfc-editor.org/rfc/rfc3890
[RFC3986]
Uniform Resource Identifier (URI): Generic Syntax. T. Berners-Lee; R. Fielding; L. Masinter. IETF. January 2005. Internet Standard. URL: https://tools.ietf.org/html/rfc3986
[RFC4566]
SDP: セッション記述プロトコル. M. Handley; V. Jacobson; C. Perkins. IETF. 2006年7月. 提案標準. URL: https://tools.ietf.org/html/rfc4566https://www.rfc-editor.org/rfc/rfc4566
[RFC4572]
セッション記述プロトコル(SDP)におけるTLSプロトコルによる接続指向メディアトランスポート. J. Lennox. IETF. 2006年7月. 提案標準. URL: https://tools.ietf.org/html/rfc4572https://www.rfc-editor.org/rfc/rfc4572
[RFC5245]
インタラクティブコネクティビティ確立(ICE): Offer/Answerプロトコル用NATトラバーサルプロトコル. J. Rosenberg. IETF. 2010年4月. 提案標準. URL: https://tools.ietf.org/html/rfc5245https://www.rfc-editor.org/rfc/rfc5245
[RFC5246]
トランスポート層セキュリティ(TLS)プロトコル バージョン1.2. T. Dierks; E. Rescorla. IETF. 2008年8月. 提案標準. URL: https://tools.ietf.org/html/rfc5246https://www.rfc-editor.org/rfc/rfc5246
[RFC5285]
RTPヘッダ拡張のための一般メカニズム. D. Singer; H. Desineni. IETF. 2008年7月. 提案標準. URL: https://tools.ietf.org/html/rfc5285https://www.rfc-editor.org/rfc/rfc5285
[RFC5389]
NAT用セッショントラバーサルユーティリティ(STUN). J. Rosenberg; R. Mahy; P. Matthews; D. Wing. IETF. 2008年10月. 提案標準. URL: https://tools.ietf.org/html/rfc5389https://www.rfc-editor.org/rfc/rfc5389
[RFC5506]
縮小サイズRTCPサポート: 機会と結果. I. Johansson; M. Westerlund. IETF. 2009年4月. 提案標準. URL: https://tools.ietf.org/html/rfc5506https://www.rfc-editor.org/rfc/rfc5506
[RFC5888]
セッション記述プロトコル(SDP)グループ化フレームワーク. G. Camarillo; H. Schulzrinne. IETF. 2010年6月. 提案標準. URL: https://tools.ietf.org/html/rfc5888https://www.rfc-editor.org/rfc/rfc5888
[RFC6464]
クライアントからミキサーへのオーディオレベル通知用RTPヘッダ拡張. J. Lennox, Ed.; E. Ivov; E. Marocco. IETF. 2011年12月. 提案標準. URL: https://tools.ietf.org/html/rfc6464https://www.rfc-editor.org/rfc/rfc6464
[RFC6465]
ミキサーからクライアントへのオーディオレベル通知用RTPヘッダ拡張. E. Ivov, Ed.; E. Marocco, Ed.; J. Lennox. IETF. 2011年12月. 提案標準. URL: https://tools.ietf.org/html/rfc6465https://www.rfc-editor.org/rfc/rfc6465
[RFC6544]
インタラクティブコネクティビティ確立(ICE)におけるTCP候補. J. Rosenberg; A. Keranen; B. B. Lowekamp; A. B. Roach. IETF. 2012年3月. 提案標準. URL: https://tools.ietf.org/html/rfc6544https://www.rfc-editor.org/rfc/rfc6544
[RFC7064]
セッショントラバーサルユーティリティ(STUN)プロトコル用URIスキーム. S. Nandakumar; G. Salgueiro; P. Jones; M. Petit-Huguenin. IETF. 2013年11月. 提案標準. URL: https://tools.ietf.org/html/rfc7064https://www.rfc-editor.org/rfc/rfc7064
[RFC7065]
リレーを利用したNAT越え(TURN)用URI. M. Petit-Huguenin; S. Nandakumar; G. Salgueiro; P. Jones. IETF. 2013年11月. 提案標準. URL: https://tools.ietf.org/html/rfc7065https://www.rfc-editor.org/rfc/rfc7065
[RFC7656]
RTPソースのセマンティクスおよびメカニズムの分類. J. Lennox; K. Gross; S. Nandakumar; G. Salgueiro; B. Burman, Ed.. IETF. 2015年11月. 情報提供. URL: https://tools.ietf.org/html/rfc7656https://www.rfc-editor.org/rfc/rfc7656
[RFC7675]
同意の新鮮さ維持目的のSTUN利用. M. Perumal; D. Wing; R. Ravindranath; T. Reddy; M. Thomson. IETF. 2015年10月. 提案標準. URL: https://tools.ietf.org/html/rfc7675https://www.rfc-editor.org/rfc/rfc7675
[RFC7874]
WebRTCオーディオコーデックおよび処理要件. JM. Valin; C. Bran. IETF. 2016年5月. 提案標準. URL: https://tools.ietf.org/html/rfc7874https://www.rfc-editor.org/rfc/rfc7874
[RFC8174]
RFC2119キーワードの大文字・小文字の曖昧性. B. Leiba. IETF. 2017年5月. 現行最善慣行. URL: https://tools.ietf.org/html/rfc8174https://www.rfc-editor.org/rfc/rfc8174
[RFC8261]
DTLSによるSCTPパケットカプセル化. M. Tuexen; R. Stewart; R. Jesup; S. Loreto. IETF. 2017年11月. 提案標準. URL: https://tools.ietf.org/html/rfc8261https://www.rfc-editor.org/rfc/rfc8261
[RFC8445]
インタラクティブコネクティビティ確立(ICE): NATトラバーサルプロトコル. A. Keranen; C. Holmberg; J. Rosenberg. IETF. 2018年7月. 提案標準. URL: https://tools.ietf.org/html/rfc8445https://www.rfc-editor.org/rfc/rfc8445
[RFC8656]
TURN: セッショントラバーサルユーティリティ(STUN)のリレー拡張. T. Reddy, Ed.; A. Johnston, Ed.; P. Matthews; J. Rosenberg. IETF. 2020年2月. 提案標準. URL: https://www.rfc-editor.org/rfc/rfc8656
[RFC8826]
WebRTCのセキュリティ考察. E. Rescorla. IETF. 2021年1月. 提案標準. URL: https://tools.ietf.org/html/rfc8826https://www.rfc-editor.org/rfc/rfc8826
[RFC8829]
JavaScript Session Establishment Protocol (JSEP). J. Uberti; C. Jennings; E. Rescorla, Ed.. IETF. January 2021. Proposed Standard. URL: https://tools.ietf.org/html/rfc8829
[RFC8831]
WebRTCデータチャネル. R. Jesup; S. Loreto; M. Tüxen. IETF. 2021年1月. 提案標準. URL: https://tools.ietf.org/html/rfc8831https://www.rfc-editor.org/rfc/rfc8831
[RFC8832]
WebRTCデータチャネル確立プロトコル. R. Jesup; S. Loreto; M. Tüxen. IETF. 2021年1月. 提案標準. URL: https://tools.ietf.org/html/rfc8832https://www.rfc-editor.org/rfc/rfc8832
[RFC8834]
WebRTCにおけるメディアトランスポートとRTPの利用. C. Perkins; M. Westerlund; J. Ott. IETF. 2021年1月. 提案標準. URL: https://tools.ietf.org/html/rfc8834https://www.rfc-editor.org/rfc/rfc8834
[RFC8835]
WebRTCのためのトランスポート. H. Alvestrand. IETF. 2021年1月. 提案標準. URL: https://tools.ietf.org/html/rfc8835https://www.rfc-editor.org/rfc/rfc8835
[RFC8838]
Trickle ICE: インタラクティブコネクティビティ確立(ICE)プロトコル用逐次候補提示. E. Ivov; J. Uberti; P. Saint-Andre. IETF. 2021年1月. 提案標準. URL: https://tools.ietf.org/html/rfc8838https://www.rfc-editor.org/rfc/rfc8838
[RFC8841]
SCTP/DTLSトランスポート上のSDPオファー/アンサー手順. C. Holmberg; R. Shpount; S. Loreto; G. Camarillo. IETF. 2021年1月. 提案標準. URL: https://tools.ietf.org/html/rfc8841https://www.rfc-editor.org/rfc/rfc8841
[RFC8843]
SDPによるメディア多重化の交渉. C. Holmberg; H. Alvestrand; C. Jennings. IETF. 2021年1月. 提案標準. URL: https://tools.ietf.org/html/rfc8843https://www.rfc-editor.org/rfc/rfc8843
[RFC8851]
RTPペイロードフォーマット制限. A.B. Roach, Ed.. IETF. 2021年1月. 提案標準. URL: https://tools.ietf.org/html/rfc8851https://www.rfc-editor.org/rfc/rfc8851
[RFC8853]
SDPおよびRTPセッションでの同時送信(Simulcast)の利用. B. Burman; M. Westerlund; S. Nandakumar; M. Zanaty. IETF. 2021年1月. 提案標準. URL: https://tools.ietf.org/html/rfc8853https://www.rfc-editor.org/rfc/rfc8853
[RFC8863]
インタラクティブコネクティビティ確立(ICE PAC). C. Holmberg; J. Uberti. IETF. 2021年1月. 提案標準. URL: https://www.rfc-editor.org/rfc/rfc8863
[RFC9429]
JavaScriptセッション確立プロトコル(JSEP). J. Uberti; C. Jennings; E. Rescorla, Ed. IETF. 2024年4月. 提案標準. URL: https://www.rfc-editor.org/rfc/rfc9429
[SDP]
SDPによるオファー/アンサーモデル. J. Rosenberg; H. Schulzrinne. IETF. 2002年6月. 提案標準. URL: https://tools.ietf.org/html/rfc3264https://www.rfc-editor.org/rfc/rfc3264
[STUN-PARAMETERS]
STUNエラーコード. IETF. IANA. 2011年4月. IANAパラメータ割当. URL: https://www.iana.org/assignments/stun-parameters/stun-parameters.xhtml#stun-parameters-6
[WebCryptoAPI]
Web暗号API. Mark Watson. W3C. 2017年1月26日. W3C勧告. URL: https://www.w3.org/TR/WebCryptoAPI/
[WEBIDL]
Web IDL. Boris Zbarsky. W3C. 2016年12月15日. W3C Editor's Draft. URL: https://heycam.github.io/webidl/
Web IDL標準. Edgar Chen; Timothy Gu. WHATWG. 現行標準. URL: https://webidl.spec.whatwg.org/
[WEBRTC-STATS]
WebRTCの統計API用識別子. Harald Alvestrand; Varun Singh; Henrik Boström. W3C. 2021年1月20日2025年3月6日. W3C 候補勧告CRD. URL: https://www.w3.org/TR/webrtc-stats/
[X509V3]
ITU-T勧告X.509バージョン3(1997)「情報技術 - オープンシステム相互接続 - ディレクトリア認証フレームワーク」ISO/IEC 9594-8:1997.. ITU.
[X690]
勧告X.690 — 情報技術 — ASN.1符号化規則 — 基本符号化規則(BER)、正規符号化規則(CER)、区別符号化規則(DER)の仕様. ITU. URL: https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf

C.2 参考情報

[API-DESIGN-PRINCIPLES]
Webプラットフォーム設計原則. Martin Thomson; Jeffrey Yasskin. W3C. 2025年3月6日. W3C作業グループノート. URL: https://www.w3.org/TR/design-principles/
[INDEXEDDB]
Indexed Database API. Nikunj Mehta; Jonas Sicking; Eliot Graff; Andrei Popescu; Jeremy Orlow; Joshua Bell. W3C. 2015年1月8日. W3C 勧告. URL: https://www.w3.org/TR/IndexedDB/
[RFC4103]
RTPペイロードによるテキスト会話. G. Hellstrom; P. Jones. IETF. 2005年6月. 提案標準. URL: https://www.rfc-editor.org/rfc/rfc4103
[RFC6236]
SDPにおける汎用画像属性の交渉. I. Johansson; K. Jung. IETF. 2011年5月. 提案標準. URL: https://www.rfc-editor.org/rfc/rfc6236
[RFC7728]
RTPストリームの一時停止および再開. B. Burman; A. Akram; R. Even; M. Westerlund. IETF. 2016年2月. 提案標準. URL: https://www.rfc-editor.org/rfc/rfc7728
[RFC8825]
概要: ブラウザベースアプリケーションのためのリアルタイムプロトコル. H. Alvestrand. IETF. 2021年1月. 提案標準. URL: https://www.rfc-editor.org/rfc/rfc8825
[RFC8827]
WebRTCセキュリティアーキテクチャ. E. Rescorla. IETF. 2021年1月. 提案標準. URL: https://www.rfc-editor.org/rfc/rfc8827
[RFC8828]
WebRTC IPアドレス取扱要件. J. Uberti; G. Shieh. IETF. 2021年1月. 提案標準. URL: https://www.rfc-editor.org/rfc/rfc8828