This document defines a set of ECMAScript APIs in WebIDL to allow media to be sent and received from another browser or device implementing the appropriate set of real-time protocols. However, unlike the WebRTC 1.0 API, Object Real-Time Communications (ORTC) does not utilize Session Description Protocol (SDP) in the API, nor does it mandate support for the Offer/Answer state machine (though an application is free to choose SDP and Offer/Answer as an on-the-wire signaling mechanism). Instead, ORTC uses "sender", "receiver" and "transport" objects, which have "capabilities" describing what they are capable of doing, as well as "parameters" which define what they are configured to do. "Tracks" are encoded by senders and sent over transports, then decoded by receivers while "data channels" are sent over transports directly.

Overview

Object Real-Time Communications (ORTC) provides a powerful API for the development of WebRTC based applications. ORTC does not utilize Session Description Protocol (SDP) in the API, nor does it mandate support for the Offer/Answer state machine (though an application is free to choose SDP and Offer/Answer as an on-the-wire signaling mechanism). Instead, ORTC uses "sender", "receiver" and "transport" objects, which have "capabilities" describing what they are capable of doing, as well as "parameters" which define what they are configured to do. "Tracks" are encoded by senders and sent over transports, then decoded by receivers while "data channels" are sent over transports directly.

In a Javascript application utilizing the ORTC API, the relationship between the application and the objects, as well as between the objects themselves is shown below. Horizontal or slanted arrows denote the flow of media or data, whereas vertical arrows denote interactions via methods and events.

The non-normative ORTC Big Picture Diagram
Non-normative ORTC Big Picture Diagram

In the figure above, the RTCRtpSender (Section 5) encodes the track provided as input, which is transported over a RTCDtlsTransport (Section 4). An RTCDataChannel (Section 11) utilizes an RTCSctpTransport (Section 12) which can also be multiplexed over the RTCDtlsTransport. Sending of Dual Tone Multi Frequency (DTMF) tones is supported via the RTCDtmfSender (Section 10).

The RTCDtlsTransport utilizes an RTCIceTransport (Section 3) to select a communication path to reach the receiving peer's RTCIceTransport, which is in turn associated with an RTCDtlsTransport which de-multiplexes media to the RTCRtpReceiver (Section 6) and data to the RTCSctpTransport and RTCDataChannel. The RTCRtpReceiver then decodes media, producing a track which is rendered by an audio or video tag.

Several other objects also play a role. The RTCIceGatherer (Section 2) gathers local ICE candidates for use by one or more RTCIceTransport objects, enabling forking scenarios. The RTCIceTransportController (Section 7) manages freezing/unfreezing (defined in [[!RFC5245]]) and bandwidth estimation. The RTCRtpListener (Section 8) detects whether an RTP stream is received that cannot be delivered to any existing RTCRtpReceiver, providing an onunhandledrtp event handler that the application can use to correct the situation. The RTCQuicTransport (Section 13) utilizes an RTCIceTransport to select a communication path to reach the receiving peer's RTCIceTransport, which is in turn associated with an RTCQuicTransport. An RTCQuicTransport is associated with zero or more RTCQuicStream (Section 14) objects which read data from and write data to RTCQuicStream objects on the remote peer.

Remaining sections of the specification fill in details relating to RTP capabilities and parameters, operational statistics, media authentication via Certificates and Identity Providers (IdP) and compatibility with the WebRTC 1.0 API. RTP dictionaries are described in Section 9, the Statistics API is described in Section 15, the Identity API is described in Section 16, the Certificate API is described in Section 17, privacy and security considerations are described in Section 18, an event summary is provided in Section 19, WebRTC 1.0 compatibility issues are discussed in Section 20, and complete examples are provided in Section 21.

This specification defines conformance criteria that apply to a single product: the user agent that implements the interfaces that it contains.

Conformance requirements phrased as algorithms or specific steps may be implemented in any manner, so long as the end result is equivalent. In particular, the algorithms defined in this specification are intended to be easy to follow, and not intended to be performant.

Implementations that use ECMAScript to implement the APIs defined in this specification MUST implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [[!WEBIDL-1]], as this specification uses that specification and terminology.

Implementation of the following interfaces is mandatory: RTCIceGatherer (Section 2), RTCIceTransport (Section 3), RTCDtlsTransport (Section 4), RTCRtpSender (Section 5), RTCRtpReceiver (Section 6), RTCDtmfSender (Section 10), RTCDataChannel (Section 11), RTCSctpTransport (Section 12) and RTCCertificate (Section 17). Since the send and receive methods are mandatory-to-implement, the RTP dictionaries (Section 9) that these methods depend on are also mandatory-to-implement. Mandatory-to-implement statistics are described in Section 15.3.

Implementation of the following interfaces is optional: RTCIceTransportController (Section 7), RTCRtpListener (Section 8), RTCQuicTransport (Section 13), RTCQuicStream (Section 14) and RTCIdentity (Section 16).

Terminology

The EventHandler interface, representing a callback used for event handlers, and the ErrorEvent interface are defined in [[!HTML5]].

The concepts queue a task, fires a simple event and networking task source are defined in [[!HTML5]].

The terms event, event handlers and event handler event types are defined in [[!HTML5]].

The terms MediaStream, MediaStreamTrack, and MediaStreamConstraints are defined in [[!GETUSERMEDIA]].

The term RTCStatsType is defined in [[!WEBRTC-STATS]].

When referring to exceptions, the terms throw and create are defined in [[!WEBIDL-1]].

The terms fulfilled, rejected, resolved, pending and settled used in the context of Promises are defined in [[!ECMASCRIPT-6.0]].

The terms isolated stream, peeridentity, request an identity assertion and validate the identity are defined in [[!WEBRTC-IDENTITY]].

In this specification the term user agent refers to any implementation; the term browser specifically refers to browser implementations.

The RTCIceCredentialType enum is defined in [[!WEBRTC10]] Section 4.2.2 and the RTCOauthCredential dictionary is defined in [[!WEBRTC10]] Section 4.2.3.

The RTCIdentityProvider dictionary and the generateAssertion and validateAssertion callbacks are defined in [[WEBRTC-IDENTITY]] Section 5.1. The RTCIdentityAssertionResult, RTCIdentityProviderDetails and RTCIdentityValidationResult dictionaries are defined in [[WEBRTC-IDENTITY]] Section 5.2. The RTCIdentityProviderOptions dictionary and the RTCIdentityAssertion interface are defined in [[WEBRTC-IDENTITY]] Section 9.

Scope

For Scalable Video Coding (SVC), the terms single-session transmission (SST) and multi-session transmission (MST) are defined in [[RFC6190]]. This specification only supports SST but not MST. The term Single Real-time transport protocol stream Single Transport (SRST), defined in [[RFC7656]] Section 3.7, refers to a Scalable Video Coding (SVC) implementation that transmits all layers within a single transport, using a single Real-time Transport Protocol (RTP) stream and synchronization source (SSRC). The term Multiple RTP stream Single Transport (MRST), also defined in [[RFC7656]] Section 3.7, refers to an implementation that transmits all layers within a single transport, using multiple RTP streams with a distinct SSRC for each layer. This specification supports SVC codecs that can only utilize SRST transport (such as VP8, VP9 and AV1) as well as implementations of codecs (such as H.264/SVC or HEVC) that support SRST transport. Also, sending of simulcast is supported. Implementations supporting MRST transport (such as H.264/SVC) can also be supported, along with reception of simulcast. However, these features should be considered experimental, since implementation experience is limited.

At the time of publication, there were two ORTC implementations supporting simulcast reception. Since neither implementation supported [[!RFC6051]], mechanisms needed to be provided to handle intermingling of received simulcast streams due to reordering. The ORTC Lib implementation deals with this by utilizing timing heuristics as well as "hidden" receivers for each received simulcast stream, with each "hidden" receiver producing a "hidden" track. The "hidden" tracks are then mixed internally to produce a single MediaStreamTrack RTCRtpReceiver.track.

RTCIceGatherer Interface

The RTCIceGatherer gathers local host, server reflexive and relay candidates, as well as enabling the retrieval of local Interactive Connectivity Establishment (ICE) parameters which can be exchanged in signaling. By enabling an endpoint to use a set of local candidates to construct multiple RTCIceTransport objects, the RTCIceGatherer enables support for scenarios such as parallel forking.

Overview

An RTCIceGatherer instance can be associated to multiple RTCIceTransport objects. The RTCIceGatherer does not prune local candidates until at least one RTCIceTransport object has become associated and all associated RTCIceTransport objects are in the completed or failed state.

As noted in [[!RFC5245]] Section 7.1.2.2, an incoming connectivity check contains an ICE-CONTROLLING or ICE-CONTROLLED attribute, depending on the role of the ICE agent initiating the check. Since an RTCIceGatherer object does not have a role, it cannot determine whether to respond to an incoming connectivity check with a 487 (Role Conflict) error; however, it can validate that an incoming connectivity check utilizes the correct local username fragment and password, and if not, can respond with an 401 (Unauthorized) error, as described in [[!RFC5389]] Section 10.1.2.

For incoming connectivity checks that pass validation, the RTCIceGatherer MUST buffer the incoming connectivity checks so as to be able to provide them to associated RTCIceTransport objects so that they can respond.

Operation

An RTCIceGatherer instance is constructed from an RTCIceGatherOptions object.

An RTCIceGatherer object in the closed state can be garbage-collected when it is no longer referenced.

Interface Definition

[ Constructor (RTCIceGatherOptions options), Exposed=Window]
interface RTCIceGatherer : RTCStatsProvider {
    readonly        attribute RTCIceComponent     component;
    readonly        attribute RTCIceGathererState state;
    static sequence<RTCIceServer> getDefaultIceServers ();
    undefined                 close ();
    undefined                 gather (optional RTCIceGatherOptions options);
    RTCIceParameters          getLocalParameters ();
    sequence<RTCIceCandidate> getLocalCandidates ();
    RTCIceGatherer            createAssociatedGatherer ();
                    attribute EventHandler        onstatechange;
                    attribute EventHandler        onerror;
                    attribute EventHandler        onlocalcandidate;
};

Constructors

To validate the options argument in the RTCIceGatherer constructor, implementations MUST run the following steps:

  1. Let options be the argument passed in the constructor.

  2. Let servers be the value of options.iceServers.

  3. Let validatedServers be an empty list.

  4. Run the following steps for each element in servers:

    1. Let server be the current list element.

    2. If server.urls is a string, let server.urls be a list consisting of just that string.

    3. For each url in server.urls run the following steps:

      1. Parse the url using the generic URI syntax defined in [[!RFC3986]] and obtain the scheme name. If the parsing based on the syntax defined in [[!RFC3986]] fails, throw a SyntaxError. If the scheme name is not implemented by the browser throw a NotSupportedError. If scheme name is turn or turns, and parsing the url using the syntax defined in [[!RFC7064]] fails, throw a SyntaxError. If scheme name is stun or stuns, and parsing the url using the syntax defined in [[!RFC7065]] fails, throw a SyntaxError.

      2. If scheme name is turn or turns, and either of server.username or server.credential are omitted, then throw an InvalidAccessError.

      3. If scheme name is turn or turns, and server.credentialType is "password", and server.credential is not a DOMString, then throw an InvalidAccessError and abort these steps.

      4. If scheme name is turn or turns, and server.credentialType is "oauth", and server.credential is not an RTCOAuthCredential, then throw an InvalidAccessError and abort these steps.

    4. Append server to validatedServers.

    Let validatedServers be the ICE servers list.

    RTCIceGatherer
    Parameter Type Nullable Optional Description
    options RTCIceGatherOptions

Attributes

component of type RTCIceComponent, readonly

The component-id of the RTCIceGatherer object. In RTCIceGatherer objects returned by createAssociatedGatherer() the value of the component attribute is rtcp. In all other RTCIceGatherer objects, the value of the component attribute is rtp.

state of type RTCIceGathererState, readonly

The current state of the ICE gatherer.

onstatechange of type EventHandler

This event handler, of event handler event type statechange, MUST be fired any time the RTCIceGathererState changes.

onerror of type EventHandler

This event handler, of event handler event type icecandidateerror, MUST be fired if an error occurs in the gathering of ICE candidates (such as if TURN credentials are invalid).

onlocalcandidate of type EventHandler

This event handler, of event handler event type icecandidate, uses the RTCIceGathererEvent interface. It receives events when a new local ICE candidate is available. Since ICE candidate gathering begins once an RTCIceGatherer object is created, candidate events are queued until an onlocalcandidate event handler is assigned. When the final candidate is gathered, a candidate event occurs with an RTCIceCandidateComplete emitted.

Methods

getDefaultIceServers

Returns a list of ICE servers that are configured into the browser. A browser might be configured to use local or private STUN or TURN servers. This method allows an application to learn about these servers and optionally use them.

This list is likely to be persistent and is the same across origins. It thus increases the fingerprinting surface of the browser. In privacy-sensitive contexts, browsers can consider mitigations such as only providing this data to whitelisted origins (or not providing it at all.)

Since the use of this information is left to the discretion of application developers, configuring a user agent with these defaults does not per se increase a user's ability to limit the exposure of their IP addresses.

close

Prunes all local candidates, and closes the port. Associated RTCIceTransport objects transition to the disconnected state (unless they were in the failed state). Calling close() when state is closed has no effect.

No parameters.
Return type: undefined
gather

Gather ICE candidates. If options is omitted, utilize the value of options passed in the constructor. If state is closed, throw an InvalidStateError.

Parameter Type Nullable Optional Description
options RTCIceGatherOptions
Return type: undefined
getLocalParameters()

Obtains the ICE parameters of the RTCIceGatherer. If state is closed, throw an InvalidStateError.

No parameters.
Return type: RTCIceParameters
getLocalCandidates

Retrieve the sequence of valid local candidates associated with the RTCIceGatherer. This retrieves all unpruned local candidates currently known (except for peer reflexive candidates), even if an onlocalcandidate event hasn't been processed yet. Prior to calling gather() an empty list will be returned. If state is closed, throw an InvalidStateError.

No parameters.
Return type: sequence<RTCIceCandidate>
createAssociatedGatherer

Create an associated RTCIceGatherer for RTCP, with the same RTCIceParameters and RTCIceGatherOptions. If state is closed, throw an InvalidStateError. If an RTCIceGatherer calls the method more than once, or if component is rtcp, throw an InvalidStateError.

No parameters.
Return type: RTCIceGatherer

RTCIceParameters Dictionary

The RTCIceParameters dictionary includes the ICE username fragment and password and other ICE-related parameters.

dictionary RTCIceParameters {
             required DOMString usernameFragment;
             required DOMString password;
             boolean   iceLite;
};

Dictionary RTCIceParameters Members

usernameFragment of type DOMString, required

ICE username fragment.

password of type DOMString, required

ICE password.

iceLite of type boolean

If only ICE-lite is supported (true) or not (false or unset). Since [[!RTCWEB-TRANSPORT]] Section 3.4 requires browser support for full ICE, iceLite will only be true for a remote peer such as a gateway. getLocalParameters().iceLite MUST NOT be set.

RTCIceCandidate Dictionary

The RTCIceCandidate dictionary includes information relating to an ICE candidate.

{
  foundation: "abcd1234",
  priority: 1694498815,
  ip: "192.0.2.33",
  protocol: "udp",
  port: 10000,
  type: "host"
};
                

The RTCIceGatherCandidate provides either an RTCIceCandidate or an RTCIceCandidateComplete indication that candidate gathering is complete.

typedef (RTCIceCandidate or RTCIceCandidateComplete) RTCIceGatherCandidate;
dictionary RTCIceCandidate {
             required DOMString              foundation;
             required unsigned long          priority;
             required DOMString              ip;
             required RTCIceProtocol         protocol;
             required unsigned short         port;
             required RTCIceCandidateType    type;
             RTCIceTcpCandidateType tcpType;
             DOMString              relatedAddress;
             unsigned short         relatedPort;
};

Dictionary RTCIceCandidate Members

foundation of type DOMString, required

A unique identifier that allows ICE to correlate candidates that appear on multiple RTCIceTransports.

priority of type unsigned long, required

The assigned priority of the candidate. This is automatically populated by the browser.

ip of type DOMString, required

The IP address of the candidate.

protocol of type RTCIceProtocol, required

The protocol of the candidate (udp/tcp).

port of type unsigned short, required

The port for the candidate.

type of type RTCIceCandidateType, required

The type of candidate.

tcpType of type RTCIceTcpCandidateType

The type of TCP candidate. For UDP candidates, this attribute is unset.

relatedAddress of type DOMString

For candidates that are derived from others, such as relay or reflexive candidates, the relatedAddress refers to the candidate that these are derived from. For host candidates, the relatedAddress is unset.

relatedPort of type unsigned short

For candidates that are derived from others, such as relay or reflexive candidates, the relatedPort refers to the host candidate that these are derived from. For host candidates, the relatedPort is unset.

RTCIceProtocol Enum

The RTCIceProtocol includes the protocol of the ICE candidate.

enum RTCIceProtocol {
    "udp",
    "tcp"
};
Enumeration description
udp

A UDP candidate, as described in [[!RFC5245]].

tcp

A TCP candidate, as described in [[!RFC6544]].

RTCIceTcpCandidateType Enum

The RTCIceTcpCandidateType includes the type of the ICE TCP candidate, as described in [[!RFC6544]]. Browsers MUST gather active TCP candidates and only active TCP candidates. Servers and other endpoints MAY gather active, passive or so candidates.

enum RTCIceTcpCandidateType {
    "active",
    "passive",
    "so"
};
Enumeration description
active

An active TCP candidate is one for which the transport will attempt to open an outbound connection but will not receive incoming connection requests.

passive

A passive TCP candidate is one for which the transport will receive incoming connection attempts but not attempt a connection.

so

An so candidate is one for which the transport will attempt to open a connection simultaneously with its peer.

RTCIceCandidateType Enum

The RTCIceCandidateType includes the type of the ICE candidate as defined in [[!RFC5245]] section 15.1.

enum RTCIceCandidateType {
    "host",
    "srflx",
    "prflx",
    "relay"
};
Enumeration description
host

A host candidate, as defined in Section 4.1.1.1 of [[!RFC5245]].

srflx

A server reflexive candidate, as defined in Section 4.1.1.2 of [[!RFC5245]].

prflx

A peer reflexive candidate, as defined in Section 4.1.1.2 of [[!RFC5245]].

relay

A relay candidate, as defined in Section 7.1.3.2.1 of [[!RFC5245]].

RTCIceCandidateComplete Dictionary

RTCIceCandidateComplete is a dictionary signifying that all RTCIceCandidates are gathered.

dictionary RTCIceCandidateComplete {
             boolean complete = true;
};

Dictionary RTCIceCandidateComplete Members

complete of type boolean, defaulting to true

This attribute is always present and set to true, indicating that ICE candidate gathering is complete.

RTCIceGathererState Enum

RTCIceGathererState represents the current state of the ICE gatherer.

enum RTCIceGathererState {
    "new",
    "gathering",
    "complete",
    "closed"
};
Enumeration description
new

The object has been created but gather() has not been called.

gathering

gather() has been called, and the RTCIceGatherer is in the process of gathering candidates (which includes adding new candidates and removing invalidated candidates).

complete

The RTCIceGatherer has completed gathering. Events such as adding, updating or removing an interface, or adding, changing or removing a TURN server will cause the state to go back to gathering before re-entering complete once all candidate changes are finalized.

closed

The closed state can only be entered when the RTCIceGatherer has been closed intentionally by calling close(). This is a terminal state.

RTCIceGathererIceErrorEvent

The icecandidateerror event of the RTCIceGatherer object uses the RTCIceGathererIceErrorEvent interface.

[ Constructor (DOMString type, RTCIceGathererIceErrorEventInit eventInitDict), Exposed=Window]
interface RTCIceGathererIceErrorEvent : Event {
    readonly        attribute RTCIceCandidate? hostCandidate;
    readonly        attribute DOMString        url;
    readonly        attribute unsigned short   errorCode;
    readonly        attribute USVString        statusText;
};

Constructors

RTCIceGathererIceErrorEvent
Parameter Type Nullable Optional Description
type DOMString
eventInitDict RTCIceGathererIceErrorEventInit

Attributes

hostCandidate of type RTCIceCandidate, readonly , nullable

The RTCIceCandidate used to communicate with the STUN or TURN server. On a multihomed system, multiple interfaces may be used to contact the server, and this attribute allows the application to figure out on which one the failure occurred. If the browser is in a privacy mode disallowing host candidates, this attribute will be null.

If use of multiple interfaces has been prohibited for privacy reasons, hostCandidate will be null.

url of type DOMString, readonly , nullable

The url attribute is the STUN or TURN URL identifying the server on which the failure ocurred.

errorCode of type unsigned short, readonly

The errorCode attribute is the numeric STUN error code returned by the STUN or TURN server [[STUN-PARAMETERS]].

If no host candidate can reach the server, errorCode will be set to a value of 701, as this does not conflict with the STUN error code range, and hostCandidate will be null. This error is only fired once per server URL while in the RTCIceGathererState of gathering.

statusText of type USVString, readonly

The STUN reason text returned by the STUN or TURN server [[STUN-PARAMETERS]].

If the server could not be reached, statusText will be set to an implementation-specific value providing details about the error.

The RTCIceGathererIceErrorEventInit dictionary provides information on ICE gathering errors.

dictionary RTCIceGathererIceErrorEventInit : EventInit {
             RTCIceCandidate hostCandidate;
             DOMString       url;
             required unsigned short  errorCode;
             USVString       errorText;
};

Dictionary RTCIceGathererIceErrorEventInit Members

hostCandidate of type RTCIceCandidate

The RTCIceCandidate used to communicate with the STUN or TURN server.

url of type DOMString

The url attribute is the STUN or TURN URL identifying the server on which the failure ocurred.

errorCode of type unsigned short, required

The errorCode attribute is the numeric STUN error code returned by the STUN or TURN server [[STUN-PARAMETERS]].

errorText of type USVString

The errorText attribute is the STUN reason text returned by the STUN or TURN server [[STUN-PARAMETERS]].

RTCIceGathererEvent

The icecandidate event of the RTCIceGatherer object uses the RTCIceGathererEvent interface.

Firing an RTCIceGathererEvent event named e with an RTCIceGatherCandidate candidate and URL url means that an event with the name e, which does not bubble (except where otherwise stated) and is not cancelable (except where otherwise stated), and which uses the RTCIceGathererEvent interface with the candidate attribute set to the new ICE candidate, MUST be created and dispatched at the given target.

[ Constructor (DOMString type, RTCIceGathererEventInit eventInitDict), Exposed=Window]
interface RTCIceGathererEvent : Event {
    readonly        attribute RTCIceGatherCandidate candidate;
    readonly        attribute DOMString?            url;
};

Constructors

RTCIceGathererEvent
Parameter Type Nullable Optional Description
type DOMString
eventInitDict RTCIceGathererEventInit

Attributes

candidate of type RTCIceGatherCandidate, readonly

The candidate attribute is the RTCIceGatherCandidate object with the new ICE candidate that caused the event. If candidate is of type RTCIceCandidateComplete, there are no additional candidates.

url of type DOMString, readonly , nullable
The URL of the server from which the candidate was obtained.

The RTCIceGathererEventInit dictionary provides information on the RTCIceGatherCandidate.

dictionary RTCIceGathererEventInit : EventInit {
             required RTCIceGatherCandidate candidate;
             DOMString             url;
};

Dictionary RTCIceGathererEventInit Members

candidate of type RTCIceGatherCandidate, required

The ICE candidate that caused the event.

url of type DOMString
The URL of the server from which the candidate was obtained.

RTCIceGatherOptions Dictionary

RTCIceGatherOptions provides options relating to the gathering of ICE candidates.

dictionary RTCIceGatherOptions {
             RTCIceGatherPolicy     gatherPolicy = "all";
             sequence<RTCIceServer> iceServers;
};

Dictionary RTCIceGatherOptions Members

gatherPolicy of type RTCIceGatherPolicy

The ICE gather policy.

iceServers of type sequence<RTCIceServer>

Additional ICE servers to be configured. Since implementations MAY provide default ICE servers, and applications can desire to restrict communications to the local LAN, iceServers need not be set.

RTCIceGatherPolicy Enum

RTCIceGatherPolicy denotes the policy relating to the gathering of ICE candidates.

enum RTCIceGatherPolicy {
    "all",
    "relay"
};
Enumeration description
all

The RTCIceGatherer MAY gather any type of candidate when this value is specified.

The implementation may still use its own candidate filtering policy in order to limit the IP addresses exposed to the application.
relay

The RTCIceGatherer MUST only gather media relay candidates such as candidates passing through a TURN server.

This can be used to prevent the remote endpoint from learning the user's IP addresses, which may be desired in certain use cases. For example, in a "call"-based application, the application may want to prevent an unknown caller from learning the callee's IP addresses until the callee has consented in some way.

RTCIceServer Dictionary

The RTCIceServer dictionary is used to configure the STUN and/or TURN servers. In network topologies with multiple layers of NATs, it is desirable to have a STUN server between every layer of NATs in addition to the TURN servers to minimize the peer to peer network latency.

dictionary RTCIceServer {
    required (DOMString or sequence<DOMString>) urls;
             DOMString                          username;
             (DOMString or RTCOAuthCredential)     credential;
             RTCIceCredentialType               credentialType = "password";
};

Dictionary RTCIceServer Members

urls of type (DOMString or sequence<DOMString>), required

STUN or TURN URI(s) as defined in [[!RFC7064]] and [[!RFC7065]] or other URI types.

username of type DOMString

If this RTCIceServer object represents a TURN server, then this attribute specifies the username to use with that TURN server.

credential of type (DOMString or RTCOAuthCredential)

If this RTCIceServer object represents a TURN server, then this attribute specifies the credential to use with that TURN server.

If credentialType is "password", credential is a DOMString, and represents a long-term authentication password, as described in [[!RFC5389]], Section 10.2.

If credentialType is "oauth", credential is a RTCOAuthCredential, which contains the OAuth access token and MAC key.

credentialType of type RTCIceCredentialType, defaulting to "password"

If this RTCIceServer object represents a TURN Server, then this attribute specifies how credential should be used when that TURN server requests authorization.

Examples

An example array of RTCIceServer objects is:

[
{ urls: "stun:stun1.example.net" },
{ urls: ["turns:turn.example.org", "turn:turn.example.net"],
  username: "user",
  credential: "myPassword",
  credentialType: "password" },
     { urls: "turns:turn2.example.net",
       username: "22BIjxU93h/IgwEb",
       credential: {
                       macKey: "WmtzanB3ZW9peFhtdm42NzUzNG0=",
                       accessToken: "AAwg3kPHWPfvk9bDFL936wYvkoctMADzQ5VhNDgeMR3+ZlZ35byg972fW8QjpEl7bx91YLBPFsIhsxloWcXPhA=="
                     },
       credentialType: "oauth" },
     }
]
      // Example to demonstrate use of RTCIceCandidateComplete
// Include some helper functions
import {trace, errorHandler, mySendLocalCandidate, myIceGathererStateChange,
  myIceTransportStateChange, myDtlsTransportStateChange} from 'helper';

// Create ICE gather options
var gatherOptions = {
  gatherPolicy: "relay",
  iceServers: [
    { urls: "stun:stun1.example.net" },
    { urls: "turn:turn.example.org", username: "user", credential: "myPassword",
      credentialType: "password" }
   ]
};
// Create IceGatherer object
var iceGatherer = new RTCIceGatherer(gatherOptions);

// Handle state changes
iceGatherer.onstatechange = function(event) {
  myIceGathererStateChange("iceGatherer", event.state);
};

// Prepare to signal local candidates
iceGatherer.onlocalcandidate = function(event) {
  mySendLocalCandidate(event.candidate);
};

// Start gathering
iceGatherer.gather();

// Set up response function
mySignaller.onResponse = function(responseSignaller, response) {
  // We may get N responses
  // ... deal with the N responses as shown in Example 5 of Section 3.11.
};

mySignaller.send({
  ice: iceGatherer.getLocalParameters()
});
                
      // Helper functions used in all the examples (helper.js)
export function trace(text) {
  // This function is used for logging.
  text = text.trimRight();
  if (window.performance) {
    var now = (window.performance.now() / 1000).toFixed(3);
    console.log(now + ": " + text);
  } else {
    console.log(text);
  }
}

export function errorHandler(error) {
  trace("Error encountered: " + error.name);
}

export function mySendLocalCandidate(candidate, component, kind, parameters) {
  // Set default values
  kind = kind || "all";
  component = component || "rtp";
  parameters = parameters || null;

  // Signal the local candidate
  mySignaller.mySendLocalCandidate({
    candidate: candidate,
    component: component,
    kind: kind,
    parameters: parameters
  });
}

export function myIceGathererStateChange(name, state) {
  switch (state) {
    case "new":
      trace("IceGatherer: " + name + " Has been created");
      break;
    case "gathering":
      trace("IceGatherer: " + name + " Is gathering candidates");
      break;
    case "complete":
      trace("IceGatherer: " + name + " Has finished gathering (for now)");
      break;
    case "closed":
      trace("IceGatherer: " + name + " Is closed");
      break;
    default:
      trace("IceGatherer: " + name + " Invalid state");
  }
}

export function myIceTransportStateChange(name, state) {
  switch (state) {
    case "new":
      trace("IceTransport: " + name + " Has been created");
      break;
    case "checking":
      trace("IceTransport: " + name + " Is checking");
      break;
    case "connected":
      trace("IceTransport: " + name + " Is connected");
      break;
    case "disconnected":
      trace("IceTransport: " + name + " Is disconnected");
      break;
    case "completed":
      trace("IceTransport: " + name + " Has finished checking (for now)");
      break;
    case "failed":
      trace("IceTransport: " + name + " Has failed");
      break;
    case "closed":
      trace("IceTransport: " + name + " Is closed");
      break;
    default:
      trace("IceTransport: " + name + " Invalid state");
  }
}

export function myDtlsTransportStateChange(name, state){
  switch(state){
  case "new":
     trace('DtlsTransport: ' + name + ' Has been created');
     break;
  case "connecting":
     trace('DtlsTransport: ' + name + ' Is connecting');
     break;
  case "connected":
     trace('DtlsTransport: ' + name + ' Is connected');
     break;
  case "failed":
     trace('DtlsTransport: ' + name + ' Has failed');
     break;
  case "closed":
     trace('DtlsTransport: ' + name + ' Is closed');
     break;
  default:
     trace('DtlsTransport: ' + name + ' Invalid state');
  }
}
                

RTCIceTransport Interface

The RTCIceTransport allows an application access to information about the Interactive Connectivity Establishment (ICE) transport over which packets are sent and received. In particular, ICE manages peer-to-peer connections which involve state which the application may want to access.

Overview

An RTCIceTransport instance is associated to a transport object (such as RTCDtlsTransport), and provides RTC related methods to it.

Operation

An RTCIceTransport instance is constructed (optionally) from an RTCIceGatherer. An RTCIceTransport object in the closed state can be garbage-collected when it is no longer referenced.

Interface Definition

[ Constructor (optional RTCIceGatherer gatherer), Exposed=Window]
interface RTCIceTransport : RTCStatsProvider {
    readonly        attribute RTCIceGatherer?      iceGatherer;
    readonly        attribute RTCIceRole           role;
    readonly        attribute RTCIceComponent      component;
    readonly        attribute RTCIceTransportState state;
    sequence<RTCIceCandidate> getRemoteCandidates ();
    RTCIceCandidatePair?      getSelectedCandidatePair ();
    undefined                 start (RTCIceGatherer gatherer, RTCIceParameters remoteParameters, optional RTCIceRole role = "controlled");
    undefined                 stop ();
    RTCIceParameters?         getRemoteParameters ();
    RTCIceTransport           createAssociatedTransport ();
    undefined                 addRemoteCandidate (RTCIceGatherCandidate remoteCandidate);
    undefined                 setRemoteCandidates (sequence<RTCIceCandidate> remoteCandidates);
                    attribute EventHandler         onstatechange;
                    attribute EventHandler         oncandidatepairchange;
};

Constructors

If gatherer.state is closed or gatherer.component is rtcp, throw an InvalidStateError.

RTCIceTransport
Parameter Type Nullable Optional Description
gatherer RTCIceGatherer

Attributes

iceGatherer of type RTCIceGatherer, readonly , nullable

The iceGatherer attribute is set to the value of gatherer if passed in the constructor or in the latest call to start().

role of type RTCIceRole, readonly

The current role of the ICE transport.

component of type RTCIceComponent, readonly

The component-id of the RTCIceTransport object. In RTCIceTransport objects returned by createAssociatedTransport(), the value of component is rtcp. In all other RTCIceTransport objects, the value of component is rtp.

state of type RTCIceTransportState, readonly

The current state of the ICE transport.

onstatechange of type EventHandler

This event handler, of event handler event type statechange, MUST be fired any time the RTCIceTransportState changes.

oncandidatepairchange of type EventHandler

This event handler, of event handler type icecandidatepairchange, uses the RTCIceCandidatePairChangedEvent interface. It MUST be supported by all objects implementing the RTCIceTransport interface. It is called any time the selected RTCIceCandidatePair changes.

Methods

getRemoteCandidates

Retrieve the sequence of candidates associated with the remote RTCIceTransport. Only returns the candidates previously added using setRemoteCandidates() or addRemoteCandidate(). If there are no remote candidates, an empty list is returned.

No parameters.
Return type: sequence<RTCIceCandidate>
getSelectedCandidatePair

Retrieves the selected candidate pair on which packets are sent. If there is no selected pair yet, or consent [[!RFC7675]] is lost on the selected pair, NULL is returned.

No parameters.
Return type: RTCIceCandidatePair, nullable
start

As noted in [[!RFC5245]] Section 7.1.2.3, an incoming connectivity check utilizes the local/remote username fragment and the local password, whereas an outgoing connectivity check utilizes the local/remote username fragment and the remote password. Since start() provides role information, as well as the remote username fragment and password, once start() is called an RTCIceTransport object can respond to incoming connectivity checks based on its configured role. Since start() enables candidate pairs to be formed, it also enables initiating connectivity checks.

When start() is called, the following steps MUST be run:

  1. If gatherer.component has a value different from component, throw an InvalidParameters.
  2. If state or gatherer.state is closed, throw an InvalidStateError.
  3. If remoteParameters.usernameFragment or remoteParameters.password is unset, throw an InvalidParameters.
  4. If start() is called again and role is changed, throw an InvalidParameters.
  5. If start() is called again with the same values of gatherer and remoteParameters, this has no effect.
  6. If start() is called for the first time and either gatherer was not passed in the constructor or the value of gatherer is unchanged, if there are remote candidates, set state to checking and start connectivity checks. If there are no remote candidates, state remains new.
  7. If start() is called for the first time and the value of gatherer passed as an argument is different from that passed in the constructor, flush local candidates. If there are remote candidates, set state to checking and start connectivity checks. If there are no remote candidates, state remains new.
  8. If start() is called again with the same value of gatherer but the value of remoteParameters has changed, local candidates are kept, remote candidates are flushed, candidate pairs are flushed and state transitions to new.
  9. If start() is called again with a new value of gatherer but the value of remoteParameters is unchanged, local candidates are flushed, candidate pairs are flushed, new candidate pairs are formed with existing remote candidates, and state transitions to checking.
  10. If start() is called again with new values of gatherer and remoteParameters, local candidates are flushed, remote candidates are flushed, candidate pairs are flushed and state transitions to new.
Parameter Type Nullable Optional Description
gatherer RTCIceGatherer
remoteParameters RTCIceParameters
role RTCIceRole = controlled
Return type: undefined
stop

Irreversibly stops the RTCIceTransport. When stop is called, the following steps MUST be run:

  1. Let iceTransport be the RTCIceTransport object on which the stop method is invoked.
  2. If iceTransport.state is closed, abort these steps.
  3. Set iceTransport.state to closed.
  4. Let controller be the RTCIceTransportController object that iceTransport has been added to.
  5. Remove iceTransport from controller.
  6. Fire a simple event statechange at iceTransport.
No parameters.
Return type: undefined
getRemoteParameters()

Obtains the current ICE parameters of the remote RTCIceTransport.

No parameters.
Return type: RTCIceParameters, nullable
createAssociatedTransport

Create an associated RTCIceTransport for RTCP. If called more than once for the same component, or if state is closed, throw an InvalidStateError. If called when component is rtcp, throw an InvalidStateError.

No parameters.
Return type: RTCIceTransport
addRemoteCandidate

Add a remote candidate associated with the remote RTCIceTransport. If state is closed, throw an InvalidStateError. When the remote RTCIceGatherer emits its final candidate, addRemoteCandidate() should be called with an RTCIceCandidateComplete dictionary as an argument, so that the local RTCIceTransport can know there are no more remote candidates expected, and can enter the completed state.

Parameter Type Nullable Optional Description
remoteCandidate RTCIceGatherCandidate
Return type: undefined
setRemoteCandidates

Set the sequence of candidates associated with the remote RTCIceTransport. If state is closed, throw an InvalidStateError.

Parameter Type Nullable Optional Description
remoteCandidates sequence<RTCIceCandidate>
Return type: undefined

RTCIceComponent Enum

RTCIceComponent contains the component-id of the RTCIceTransport, which will be rtp unless RTP and RTCP are not multiplexed and the RTCIceTransport object was returned by createAssociatedTransport().

enum RTCIceComponent {
    "rtp",
    "rtcp"
};
Enumeration description
rtp

The RTP component ID, defined (as '1') in [[!RFC5245]] Section 4.1.1.1. Protocols multiplexed with RTP (e.g. SCTP data channel) share its component ID.

rtcp

The RTCP component ID, defined (as '2') in [[!RFC5245]] Section 4.1.1.1.

RTCIceRole Enum

RTCIceRole contains the current role of the ICE transport.

enum RTCIceRole {
    "controlling",
    "controlled"
};
Enumeration description
controlling

controlling state

controlled

controlled state

RTCIceTransportState Enum

RTCIceTransportState represents the current state of the ICE transport.

enum RTCIceTransportState {
    "new",
    "checking",
    "connected",
    "completed",
    "disconnected",
    "failed",
    "closed"
};
Enumeration description
new

The RTCIceTransport object is waiting for remote candidates to be supplied. In this state the RTCIceTransport object can respond to incoming connectivity checks.

checking

The RTCIceTransport has received at least one remote candidate, and a local and remote RTCIceCandidateComplete dictionary was not added as the last candidate. In this state the RTCIceTransport is checking candidate pairs but has not yet found a successful candidate pair, or consent checks [[!RFC7675]] have failed on all previously successful candidate pairs.

connected

The RTCIceTransport has received a response to an outgoing connectivity check, or has received incoming DTLS/media after a successful response to an incoming connectivity check, but is still checking other candidate pairs to see if there is a better connection. In this state outgoing media is permitted. If consent checks [[!RFC7675]] fail on the connection in use, and there are no other successful candidate pairs available, then the state transitions to checking (if there are candidate pairs remaining to be checked) or disconnected (if there are no candidate pairs to check, but the peer is still gathering and/or waiting for additional remote candidates).

completed

A local and remote RTCIceCandidateComplete dictionary was added as the last candidate to the RTCIceTransport and all appropriate candidate pairs have been tested and at least one functioning candidate pair has been found. If consent checks [[!RFC7675]] subsequently fail on all successful candidate pairs, the state transitions to failed.

disconnected

Connectivity is currently lost for this RTCIceTransport. The RTCIceTransport has received at least one local and remote candidate, and a local and remote RTCIceCandidateComplete dictionary was not added as the last candidate, but all appropriate candidate pairs thus far have been tested and failed, or consent checks [[!RFC7675]] once successful, have repeatedly failed to receive a response. At the implementation's discretion, this state may be entered prior to consent failure, and therefore could resolve itself without action. Other candidate pairs may become available for testing as new candidates are trickled, and a temporary consent failure could resolve itself, therefore the failedstate has not been reached.

failed

A local and remote RTCIceCandidateComplete dictionary was added as the last candidate to the RTCIceTransport and all appropriate candidate pairs have either failed connectivity checks or have lost consent.

closed

The RTCIceTransport has shut down and is no longer responding to STUN requests.

Some example transitions might be:

The non-normative RTCIceTransportState transition diagram
Non-normative ICE transport state transition diagram

RTCIceCandidatePairChangedEvent

The icecandidatepairchange event of the RTCIceTransport object uses the RTCIceCandidatePairChangedEvent interface.

Firing an RTCIceCandidatePairChangedEvent event named e with an RTCIceCandidatePair pair means that an event with the name e, which does not bubble (except where otherwise stated) and is not cancelable (except where otherwise stated), and which uses the RTCIceCandidatePairChangedEvent interface with pair set to the selected RTCIceCandidatePair, MUST be created and dispatched at the given target.

        [ Constructor (DOMString type, RTCIceCandidatePairChangedEventInit eventInitDict), Exposed=Window]
interface RTCIceCandidatePairChangedEvent : Event {
    readonly        attribute RTCIceCandidatePair pair;
};

Constructors

RTCIceCandidatePairChangedEvent
Parameter Type Nullable Optional Description
type DOMString
eventInitDict RTCIceCandidatePairChangedEventInit

Attributes

pair of type RTCIceCandidatePair, readonly

The pair attribute is the selected RTCIceCandidatePair that caused the event.

The RTCIceCandidatePairChangedEventInit dictionary provides information on the newly selected RTCIceCandidatePair.

        dictionary RTCIceCandidatePairChangedEventInit : EventInit {
             required RTCIceCandidatePair pair;
};

Dictionary RTCIceCandidatePairChangedEventInit Members

pair of type RTCIceCandidatePair, required

The pair attribute is the selected RTCIceCandidatePair that caused the event.

RTCIceCandidatePair Dictionary

The RTCIceCandidatePair contains the currently selected ICE candidate pair.

dictionary RTCIceCandidatePair {
             required RTCIceCandidate local;
             required RTCIceCandidate remote;
};

Dictionary RTCIceCandidatePair Members

local of type RTCIceCandidate, required

The local ICE candidate.

remote of type RTCIceCandidate, required

The remote ICE candidate.

Example

      // Example to demonstrate forking when RTP and RTCP are not multiplexed,
// so that both RTP and RTCP IceGatherer and IceTransport objects are needed.
// Include some helper functions
import {trace, errorHandler, mySendLocalCandidate, myIceGathererStateChange,
  myIceTransportStateChange, myDtlsTransportStateChange} from 'helper';

// Create ICE gather options
var gatherOptions = {
  gatherPolicy: "relay",
  iceServers: [
    { urls: "stun:stun1.example.net" },
    { urls: "turn:turn.example.org", username: "user", credential: "myPassword",
      credentialType: "password" }
   ]
};

// Create ICE gatherer objects
var iceRtpGatherer = new RTCIceGatherer(gatherOptions);
var iceRtcpGatherer = iceRtpGatherer.createAssociatedGatherer();

// Prepare to signal local candidates
iceRtpGatherer.onlocalcandidate = function(event) {
  mySendLocalCandidate(event.candidate, "rtp", "audio",
    iceRtpGatherer.getLocalParameters());
};

iceRtcpGatherer.onlocalcandidate = function(event) {
  mySendLocalCandidate(event.candidate, "rtcp", "audio",
    iceRtpGatherer.getLocalParameters());
};

// Start gathering
iceRtpGatherer.gather();
iceRtcpGatherer.gather();

// Initialize the ICE transport arrays
var iceRtpTransports = [];
var iceRtcpTransports = [];

// Set up response function
mySignaller.onResponse = function(responseSignaller, response) {
  // We may get N responses

  // Create the ICE RTP and RTCP transports
  var iceRtpTransport = new RTCIceTransport(iceRtpGatherer);
  var iceRtcpTransport = iceRtpTransport.createAssociatedTransport();

  // Start the RTP and RTCP ICE transports so that outgoing ICE connectivity checks can begin
  // The RTP and RTCP ICE parameters are the same, so only the RTP parameters are used
  iceRtpTransport.start(iceRtpGatherer, response.icertp, RTCIceRole.controlling);
  iceRtcpTransport.start(iceRtcpGatherer, response.icertp, RTCIceRole.controlling);

  iceRtpTransports.push(iceRtpTransport);
  iceRtcpTransports.push(iceRtcpTransport);

  // Prepare to add ICE candidates signalled by the remote peer
  responseSignaller.onRemoteCandidate = function(remote) {
    // Locate the ICE transport that the signaled candidate relates to by matching
   //  the userNameFragment.
    var transports;
    if (remote.component === "rtp") {
      transports = iceRtpTransports;
    } else {
      transports = iceRtcpTransports;
    }

    for (var j = 0; j < iceTransport.length; j++) {
      var transport = transports[j];
      if (transport.getRemoteParameters().userNameFragment === remote.parameters.userNameFragment)
        transport.addRemoteCandidate(remote.candidate);
      }
    }
  };
};

mySignaller.send({
  // The RTP and RTCP parameters are identical, so no need to send both
  icertp: iceRtpGatherer.getLocalParameters()
});
                

RTCDtlsTransport Interface

The RTCDtlsTransport object includes information relating to Datagram Transport Layer Security (DTLS) transport.

Overview

An RTCDtlsTransport instance is associated to an RTCRtpSender, an RTCRtpReceiver, or an RTCSctpTransport instance.

Operation

A RTCDtlsTransport instance is constructed using an RTCIceTransport and a sequence of RTCCertificate objects. Although any given DTLS connection will use only one certificate, multiple certificates can be provided that support different algorithms. The final certificate will be selected based on the DTLS handshake, which establishes which certificates are allowed. An RTCDtlsTransport object in the closed or failed states can be garbage-collected when it is no longer referenced.

Since the Datagram Transport Layer Security (DTLS) negotiation occurs between transport endpoints determined via ICE, implementations of this specification MUST support multiplexing of STUN, TURN, DTLS and RTP and/or RTCP. This multiplexing, originally described in [[!RFC5764]] Section 5.1.2, is updated in [[!RFC7983]].

A newly constructed RTCDtlsTransport MUST listen and respond to incoming DTLS packets before start() is called. However, to complete the negotiation it is necessary to verify the remote fingerprint, which is an attribute of the remoteParameters argument passed to start(). To verify the remote fingerprint, compute the fingerprint value for the selected remote certificate using the signature digest algorithm, and compare it against remoteParameters.fingerprints. If the selected remote certificate RTCDtlsFingerprint.value matches remoteParameters.fingerprints[j].value and RTCDtlsFingerprint.algorithm matches remoteParameters.fingerprints[j].algorithm for any value of j, the remote fingerprint is verified. After the DTLS handshake exchange completes (but before the remote fingerprint is verified) incoming media packets may be received. A modest buffer MUST be provided to avoid loss of media prior to remote fingerprint validation (which can begin after start() is called).

Interface Definition

        [ Constructor (RTCIceTransport transport, sequence<RTCCertificate> certificates), Exposed=Window]
interface RTCDtlsTransport : RTCStatsProvider  {
    readonly        attribute RTCIceTransport          transport;
    readonly        attribute RTCDtlsTransportState    state;
    sequence<RTCCertificate>     getCertificates ();
    RTCDtlsParameters     getLocalParameters ();
    RTCDtlsParameters?    getRemoteParameters ();
    sequence<ArrayBuffer> getRemoteCertificates ();
    undefined             start (RTCDtlsParameters remoteParameters);
    undefined             stop ();
                    attribute EventHandler             onstatechange;
                    attribute EventHandler             onerror;
};

Constructors

When the constructor is invoked, the following steps MUST be run:

  1. Let transport be the first argument.

  2. If transport.state is closed throw an InvalidStateError and abort these steps.

  3. Let certificates be the second argument.
  4. If certificates is non-null, check that the expires attribute of each RTCCertificate object is in the future. If a certificate has expired, throw an InvalidParameters and abort these steps.

  5. Let dtlsTransport be a new RTCDtlsTransport object with certificates.

  6. Let dltsTransport have [[\SendHeaderExtensions]] and [[\ReceiveHeaderExtensions]] internal slots initialized to null.

RTCDtlsTransport
Parameter Type Nullable Optional Description
transport RTCIceTransport
certificates sequence<RTCCertificate>

Attributes

transport of type RTCIceTransport, readonly

The associated RTCIceTransport instance.

state of type RTCDtlsTransportState, readonly

The current state of the DTLS transport.

onstatechange of type EventHandler

This event handler, of event handler event type statechange, MUST be fired any time the RTCDtlsTransportState changes.

onerror of type EventHandler

This event handler, of event handler event type error, MUST be fired after a DTLS error. An implementation SHOULD provide more details on DTLS errors as follows:

  1. A fingerprint validation failure is indicated by setting error.name to "fingerprint-failure".
  2. Reception of a DTLS alert is indicated by setting error.name to "dtls-alert-received".
  3. Sending of a DTLS alert is indicated by setting error.name to "dtls-alert-sent".
  4. The DTLS alert value is provided by setting error.message (defined in [[!HTML5]] Section 6.1.3.6.2) to "DTLS Alert: ".

Methods

getCertificates()

Returns the certificates provided in the constructor.

No parameters.
Return type: sequence<RTCCertificate>
getLocalParameters()

Obtains the DTLS parameters of the local RTCDtlsTransport upon construction. If multiple certificates were provided in the constructor, then multiple fingerprints will be returned, one for each certificate. getLocalParameters().role always returns the default role of a newly constructed RTCDtlsTransport; for a browser this will be auto.

No parameters.
Return type: RTCDtlsParameters
getRemoteParameters()

Obtains the remote DTLS parameters passed in the start() method. Prior to calling start(), null is returned.

No parameters.
Return type: RTCDtlsParameters, nullable
getRemoteCertificates()

Returns the certificate chain in use by the remote side, with each certificate encoded in binary Distinguished Encoding Rules (DER) [[!X690]]. getRemoteCertificates() returns an empty list prior to selection of the remote certificate, which is completed by the time state transitions to connected.

No parameters.
Return type: sequence<ArrayBuffer>
start

Start DTLS transport negotiation with the parameters of the remote DTLS transport, including verification of the remote fingerprint, then once the DTLS transport session is established, negotiate a DTLS-SRTP [[!RFC5764]] session to establish keys so as protect media using SRTP [[!RFC3711]]. Since symmetric RTP [[!RFC4961]] is utilized, the DTLS-SRTP session is bi-directional.

Only a single DTLS transport can be multiplexed over an ICE transport. Therefore if a RTCDtlsTransport object dtlsTransportB is constructed with an RTCIceTransport object iceTransport previously used to construct another RTCDtlsTransport object dtlsTransportA, then if dtlsTransportB.start() is called prior to having called dtlsTransportA.stop(), then throw an InvalidStateError.

If start is called after a previous start call, or if state is closed, throw an InvalidStateError.

If all of the values of remoteParameters.fingerprints[j].algorithm are unsupported, where j goes from 0 to the number of fingerprints, throw a NotSupportedError.

Parameter Type Nullable Optional Description
remoteParameters RTCDtlsParameters
Return type: undefined
stop

Stops and closes the RTCDtlsTransport object. Calling stop() when state is closed has no effect.

No parameters.
Return type: undefined

RTCDtlsParameters Dictionary

The RTCDtlsParameters dictionary includes information relating to DTLS configuration.

dictionary RTCDtlsParameters {
             RTCDtlsRole                  role = "auto";
             required sequence<RTCDtlsFingerprint> fingerprints;
};

Dictionary RTCDtlsParameters Members

role of type RTCDtlsRole, defaulting to "auto"

The DTLS role, with a default of auto.

fingerprints of type sequence<RTCDtlsFingerprint>, required

Sequence of fingerprints, one fingerprint for each certificate.

RTCDtlsFingerprint Dictionary

The RTCDtlsFingerprint dictionary includes the hash function algorithm and certificate fingerprint as described in [[!RFC4572]].

dictionary RTCDtlsFingerprint {
             required DOMString algorithm;
             required DOMString value;
};

Dictionary RTCDtlsFingerprint Members

algorithm of type DOMString, required

One of the the hash function algorithms defined in the 'Hash function Textual Names' registry, initially specified in [[!RFC4572]] Section 8. As noted in [[!JSEP]] Section 5.2.1, the digest algorithm used for the fingerprint matches that used in the certificate signature.

value of type DOMString, required

RTCDtlsRole Enum

RTCDtlsRole indicates the role of the DTLS transport.

enum RTCDtlsRole {
    "auto",
    "client",
    "server"
};
Enumeration description
auto

The DLTS role is determined based on the resolved ICE role: the ICE controlled role acts as the DTLS client and the ICE controlling role acts as the DTLS server.

client

The DTLS client role.

server

The DTLS server role.

DTLS role determination

To diagnose DTLS role issues, an application may wish to determine the desired and actual DTLS role of an RTCDtlsTransport. For a browser implementing ORTC, a RTCDtlsTransport object assumes a DTLS role of auto upon construction. This implies that the DTLS role is determined by the ICE role. Since getLocalParameters().role always returns the role assigned to an RTCDtlsTransport object upon construction (auto for a browser), the getLocalParameters method cannot be used to determine the desired or actual role of an RTCDtlsTransport.

An application can determine the desired role of an RTCDtlsTransport from the value of remoteParameters.role passed to RTCDtlsTransport.start(remoteParameters). If remoteParameters.role is server then the desired role of the RTCDtlsTransport is client. If remoteParameters.role is client then the desired role of the RTCDtlsTransport is server.

The RTCDtlsTransport.transport.onstatechange EventHandler can be used to determine whether an RTCDtlsTransport transitions to the desired role as expected. When RTCDtlsTransport.transport.state transitions to connected, if RTCDtlsTransport.transport.role is controlled then the role of the RTCDtlsTransport is client. If RTCDtlsTransport.transport.role is controlling then the role of the RTCDtlsTransport is server.

RTCDtlsTransportState Enum

RTCDtlsTransportState indicates the state of the DTLS transport.

enum RTCDtlsTransportState {
    "new",
    "connecting",
    "connected",
    "closed",
    "failed"
};
Enumeration description
new

The RTCDtlsTransport object has been created and has not started negotiating yet.

connecting

DTLS is in the process of negotiating a secure connection and verifying the remote fingerprint. Once a secure connection is negotiated (but prior to verification of the remote fingerprint, enabled by calling start()), incoming data can flow through (and media, once DTLS-SRTP key derivation is completed).

connected

DTLS has completed negotiation of a secure connection and verified the remote fingerprint. Outgoing data and media can now flow through.

closed

The DTLS connection has been closed intentionally via a call to stop() or receipt of a close_notify alert. Calling transport.stop() will also result in a transition to the closed state.

failed

The DTLS connection has been closed as the result of an error (such as receipt of an error alert or a failure to validate the remote fingerprint).

Examples

      // This is an example of how to offer ICE and DTLS parameters and
// ICE candidates and get back ICE and DTLS parameters and ICE candidates,
// and start both ICE and DTLS, when RTP and RTCP are multiplexed.
// Assume that we have a way to signal (mySignaller).
// Include some helper functions
import {trace, errorHandler, mySendLocalCandidate, myIceGathererStateChange,
  myIceTransportStateChange, myDtlsTransportStateChange} from 'helper';

function initiate(mySignaller) {
  // Prepare the ICE gatherer
  var gatherOptions = {
    gatherPolicy: "all",
    iceServers: [
      { urls: "stun:stun1.example.net" },
      { urls: "turn:turn.example.org", username: "user", credential: "myPassword",
        credentialType: "password" }
     ]
  };
  var iceGatherer = new RTCIceGatherer(gatherOptions);
  iceGatherer.onlocalcandidate = function(event) {
    mySignaller.mySendLocalCandidate(event.candidate);
  };

  // Start gathering
  iceGatherer.gather();

  // Initialize the ICE and DTLS transport arrays
  var iceTransports = [];
  var dtlsTransports = [];

  // Create the DTLS certificate and parameters
  var certs;
  var dtlsParameters = {};
  var keygenAlgorithm = { name: "ECDSA", namedCurve: "P-256" };
  RTCCertificate.generateCertificate(keygenAlgorithm).then(function(certificate){
    certs[0] = certificate;
    // Obtain the fingerprint of the created certificate
    dtlsParameters.fingerprints[0] = certificate.fingerprint;
  }, function(){
    trace('Certificate could not be created');
  });
  // Prepare to handle remote ICE candidates
  mySignaller.onRemoteCandidate = function(remote) {
    // Figure out which IceTransport a remote candidate relates to by matching
    // the userNameFragment/password
    var j = 0;
    for (j = 0; j < iceTransport.length; j++) {
      var transport = iceTransports[j];
      if (transport.getRemoteParameters().userNameFragment === remote.parameters.userNameFragment)
        transport.addRemoteCandidate(remote.candidate);
      }
    }  };
  // ... construct RtpSender/RtpReceiver objects as in Section 6.6 Examples 8 and 9.

  mySignaller.mySendInitiate({
    ice: iceGatherer.getLocalParameters(),
    dtls: dtlsParameters,
    // ... marshall RtpSender/RtpReceiver capabilities as in Section 6.6 Examples 8 and 9.
  }, function(remote) {
    // Create the ICE and DTLS transports
    var iceTransport = new RTCIceTransport(iceGatherer);
    iceTransport.start(iceGatherer, remote.ice, RTCIceRole.controlling);
    iceTransports.push(iceTransport);
    // Construct a RTCDtlsTransport object with the same certificate and fingerprint
    // as in the Offer so that the remote peer can verify it.
    var dtlsTransport = new RTCDtlsTransport(iceTransport, certs);
    dtlsTransport.start(remote.dtls);
    dtlsTransports.push(dtlsTransport);

    // ... configure RtpSender/RtpReceiver objects as in Section 6.6 Examples 8 and 9.
  });
}
                
      // This is an example of how to answer with ICE and DTLS
// and DTLS parameters and ICE candidates and start both ICE and DTLS,
// assuming that RTP and RTCP are multiplexed.
// Include some helper functions
import {trace, errorHandler, mySendLocalCandidate, myIceGathererStateChange,
  myIceTransportStateChange, myDtlsTransportStateChange} from 'helper';

// Assume that remote info is signalled to us.
function accept(mySignaller, remote) {
  // Prepare the ICE gatherer
  var gatherOptions = {
    gatherPolicy: "all",
    iceServers: [
      { urls: "stun:stun1.example.net" },
      { urls: "turn:turn.example.org", username: "user", credential: "myPassword",
        credentialType: "password" }
     ]
  };
  var iceGatherer = new RTCIceGatherer(gatherOptions);
  iceGatherer.onlocalcandidate = function(event) {
    mySignaller.mySendLocalCandidate(event.candidate);
  };

  // Start gathering
  iceGatherer.gather();

  // Create the DTLS certificate
  var certs;
  var keygenAlgorithm = { name: "ECDSA", namedCurve: "P-256" };
  RTCCertificate.generateCertificate(keygenAlgorithm).then(function(certificate){
    certs[0] = certificate;
  }, function(){
    trace('Certificate could not be created');
  });

  // Create ICE and DTLS transports
  var ice = new RTCIceTransport(iceGatherer);
  var dtls = new RTCDtlsTransport(ice, certs);

  // Prepare to handle remote candidates
  mySignaller.onRemoteCandidate = function(remote) {
    ice.addRemoteCandidate(remote.candidate);
  };
  // ... create RtpSender/RtpReceiver objects as in Section 6.6 Examples 8 and 9.

  mySignaller.mySendAccept({
    ice: iceGatherer.getLocalParameters(),
    dtls: dtls.getLocalParameters()
    // ... marshall RtpSender/RtpReceiver capabilities as in Section 6.6 Examples 8 and 9.
  });

  // Start the ICE transport with an implicit gather policy of "all"
  ice.start(iceGatherer, remote.ice, RTCIceRole.controlled);

  // Start the DTLS transport
  dtls.start(remote.dtls);

  // ... configure RtpSender/RtpReceiver objects as in Section 6.6 Examples 8 and 9.
}
                

RTCRtpSender Interface

The RTCRtpSender includes information relating to the RTP sender.

Overview

An RTCRtpSender instance is associated to a sending MediaStreamTrack and provides RTC related methods to it.

Operation

A RTCRtpSender instance is constructed from an MediaStreamTrack object or kind and associated to an RTCDtlsTransport. An RTCRtpSender object can be garbage-collected once stop() is called and it is no longer referenced.

Interface Definition

        [ Constructor ((MediaStreamTrack or DOMString) trackOrKind, optional RTCDtlsTransport transport, optional RTCDtlsTransport rtcpTransport), Exposed=Window]
interface RTCRtpSender : RTCStatsProvider {
    readonly        attribute MediaStreamTrack?  track;
    readonly        attribute RTCDtlsTransport?  transport;
    readonly        attribute RTCDtlsTransport? rtcpTransport;
    readonly        attribute DOMString kind;
    undefined                 setTransport (RTCDtlsTransport transport, optional RTCDtlsTransport rtcpTransport);
    Promise<undefined>  setTrack (MediaStreamTrack? track);  // deprecated
    Promise<undefined>  replaceTrack (MediaStreamTrack? track);
    static RTCRtpCapabilities getCapabilities (DOMString kind);
    Promise<undefined>  send (RTCRtpSendParameters parameters);
    undefined                 stop ();
                    attribute EventHandler      onssrcconflict;
};

Constructors

When the constructor is invoked, the user agent MUST run the following steps:

  1. Let the first argument be trackOrKind.
  2. If trackOrKind is a DOMString and is not a supported MediaStreamTrack kind, throw a TypeError and abort these steps.
  3. If trackOrKind is a MediaStreamTrack and trackOrKind.readyState is ended, throw an InvalidStateError and abort these steps.
  4. Let transport be the second argument.
  5. Let rtcpTransport be the third argument.
  6. If transport is unset, and rtcpTransport is set, throw an InvalidParameters and abort these steps.
  7. If transport is set and transport.state is closed, throw an InvalidStateError and abort these steps.
  8. If rtcpTransport is set and rtcpTransport.state is closed, throw an InvalidStateError and abort these steps.
  9. Construct an RTCRtpSender with transport (if provided) and rtcpTransport (if provided) and let sender be the result.
  10. Let sender have an [[\SenderStopped]] internal slot, initialized to false.
  11. Let sender have a [[\SenderKind]] internal slot.
  12. Let sender have a [[\SenderTrack]] internal slot.
  13. If trackOrKind is a MediaStreamTrack initialize sender's [[\SenderTrack]] slot to trackOrKind and sender's [[\SenderKind]] slot to trackOrKind.kind.
  14. If trackOrKind is a DOMString initialize sender's [[\SenderTrack]] internal slot to null and sender's [[\SenderKind]] slot to trackOrKind.
RTCRtpSender
Parameter Type Nullable Optional Description
trackOrKind (MediaStreamTrack or DOMString)
transport RTCDtlsTransport
rtcpTransport RTCDtlsTransport

Attributes

track of type MediaStreamTrack, readonly , nullable

The associated MediaStreamTrack instance. If track is ended, or if track.muted is set to true, the RTCRtpSender sends silence (audio) or a black frame (video). If track is set to null then the RTCRtpSender does not send RTP.

transport of type RTCDtlsTransport, readonly , nullable

The RTCDtlsTransport instance over which RTCP is sent and received (if provided). When BUNDLE is used, many RTCRtpSender objects will share one rtcpTransport and will all send and receive RTCP over the same RTCDtlsTransport. When RTCP mux is used, rtcpTransport will be null, and both RTP and RTCP traffic will flow over the RTCDtlsTransport transport.

rtcpTransport of type RTCDtlsTransport, readonly , nullable

The associated RTCP RTCDtlsTransport instance if one was provided in the constructor. When RTCP mux is used, rtcpTransport will be null, and both RTP and RTCP traffic will flow over the RTCDtlsTransport transport.

kind of type DOMString, readonly

The value of kind or track.kind passed in the constructor.

onssrcconflict of type EventHandler

The onssrcconflict event handler, of event handler type RTCSsrcConflictEvent, is fired if an SSRC conflict is detected within the RTP session or an SSRC misconfiguration is detected after send() or receive() returns or when setTransport is called. In this situation, the RTCRtpSender automatically sends an RTCP BYE on the conflicted SSRC, if RTP packets were sent using that SSRC.

Methods

setTransport()

Attempts to replace the the RTP RTCDtlsTransport transport (if set) and RTCP RTCDtlsTransport rtcpTransport (if used) with the transport(s) provided.

When the setTransport method is invoked, the user agent MUST run the following steps:

  1. Let sender be the RTCRtpSender object on which setTransport() is invoked.

  2. If sender's [[\SenderStopped]] slot is true, throw an InvalidStateError and abort these steps.

  3. Let withTransport and withRtcpTransport be the arguments to this method.

  4. If withTransport is null and withRtcpTransport is set, throw an OperationError and abort these steps.

  5. If withTransport is set and withTransport.transport.component is rtcp, throw an InvalidParameters.

  6. If withRtcpTransport is set and withRtcpTransport.transport.component is rtp, throw an InvalidParameters.

  7. If withTransport is set and withTransport.state is closed, throw an InvalidStateError.

  8. If withRtcpTransport is set and withRtcpTransport.state is closed, throw an InvalidStateError.

  9. Set transport to withTransport and rtcpTransport to withRtcpTransport.

  10. If transport is set and transport.state is not failed, seamlessly send over the new transport(s).

Parameter Type Nullable Optional Description
transport RTCDtlsTransport
rtcpTransport RTCDtlsTransport
Return type: undefined
setTrack

setTrack Attempts to replace the track being sent with another track provided (or with a null track). The deprecated setTrack method operates identically to the replaceTrack method.

Parameter Type Nullable Optional Description
track MediaStreamTrack
Return type: Promise<undefined>
replaceTrack

Attempts to replace the track being sent with another track provided (or with a null track).

When the replaceTrack method is invoked, the user agent MUST run the following steps:

  1. Let p be a new promise.

  2. Let sender be the RTCRtpSender object on which replaceTrack() is invoked.

  3. If sender's [[\SenderStopped]] slot is true, reject p with a newly created InvalidStateError.
  4. Let withTrack be the argument to this method.

  5. If withTrack is non-null and withTrack.kind differs from sender.kind, reject p with a newly created TypeError.

  6. Run the following steps:

    1. Set the track attribute to withTrack. If withTrack is null, the sender stops sending. Otherwise, have the sender seamlessly switch to transmitting withTrack in place of what it is sending.

    2. Resolve p with undefined.

Parameter Type Nullable Optional Description
track MediaStreamTrack
Return type: Promise<undefined>
getCapabilities(), static

Obtains the sender capabilities, based on kind. Browsers MUST support kind values of "audio" and "video". If there are no capabilities corresponding to the value of kind, getCapabilities returns null. Capabilities that can apply to multiple values of kind (such as retransmission [[!RFC4588]], redundancy [[RFC2198]] and Forward Error Correction) have RTCRtpCapabilities.RTCRtpCodecCapability[i].kind set to the value of the kind argument.

Parameter Type Nullable Optional Description
kind DOMString
Return type: RTCRtpCapabilities
send

Attempts to set the parameters controlling the sending of media.

When the send() method is invoked, the user agent MUST run the following steps:

  1. Let sender be the RTCRtpSender object on which send() is invoked.

  2. Let p be a new promise.

  3. If sender's [[\SenderStopped]] slot is true, reject p with a newly created InvalidStateError and abort these steps.

  4. If transport is unset, reject p with a newly created TypeError and abort these steps.

  5. Let withParameters be the argument to this method.

  6. If rtcpTransport is unset and withParameters.rtcp.mux is set to false, reject p with a newly created TypeError and abort these steps.

  7. Complete validation checks on withParameters.
  8. Run the following steps:

    1. If send() is called for the first time, start sending. If send() was called previously, have the sender switch to sending using withParameters.

    2. Resolve p with undefined.

Parameter Type Nullable Optional Description
parameters RTCRtpSendParameters
Return type: Promise<undefined>
stop

The stop method irreversibly stops the RTCRtpSender. When stop called, the following steps MUST be run:

  1. Let sender be the RTCRtpSender on which stop is invoked.
  2. If sender's [[\SenderStopped]] slot is true, abort these steps.
  3. Let parameters be the argument provided to sender.send(parameters) the last time it was invoked.

  4. Stop sending media with sender.

  5. Send an RTCP BYE for each SSRC in parameters.encodings[i].ssrc, parameters.encodings[i].fec.ssrc and parameters.encodings[i].rtx.ssrc where i goes from 0 to encodings.length-1.

  6. Remove parameters.headerExtensions from sender.transport's [[\SenderHeaderExtensions]] internal slot.

  7. Set sender's [[\SenderStopped]] slot to true.
No parameters.
Return type: undefined

Parameters validation

To Complete validation checks on the argument to send or receive, the User Agent MUST run the following steps:

  1. Let withParameters be the argument to send or receive.

  2. For send, let kind be the value of track.kind and let sender be the RTCRtpSender on which the send method is invoked. For receive, let kind be the first argument passed to the RTCRtpReceiver constructor and let receiver be the RTCRtpReceiver on which the receive method is invoked.

  3. For send, let transport be the value of sender.transport. Let capabilities be the value of RTCRtpSender.getCapabilities(kind).

  4. For receive, let transport be the value of receiver.transport. Let capabilities be the value of RTCRtpReceiver.getCapabilities(kind).

  5. For each value of i from 0 to the number of codecs, check that each value of withParameters.codecs[i].payloadType is set. If any value is unset, reject p with a newly created TypeError and abort all of these steps.

  6. For each value of i from 0 to the number of codecs:

    1. Let codec be withParameters.codecs[i].

    2. Let clockRate be codec.clockRate.

    3. Let name be codec.name.

    4. If name or clockrate is unset, throw a TypeError and abort all of these steps.

    5. If name is not equal to "red", "rtx" or a forward error correction codec ("ulpfec" [[RFC5109]] or "flexfec" [[FLEXFEC]]), check whether name is equal to capabilities.codecs[j].name and if capabilities.codecs[j].clockRate is set, check whether clockRate is equal to capabilities.codecs[j].clockRate for any value of j from 0 to the number of codecs.

    6. If a match is found for a value of j, check that:

      1. If codec.channels is set, check that it is less than or equal to capabilities.codecs[j].channels. If not, reject p with a newly created NotSupportedError and abort all of these steps.

      2. Each of the values of codec.rtcpFeedback[k].type is included in capabilities.codecs[j].rtcpFeedback.type where k goes from 0 to the number of feedback mechanisms. If not, reject p with a newly created NotSupportedError and abort all of these steps.

      3. Each of the values of codec.parameters[k] is a valid value as indicated by capabilities.codecs[j].parameters where k goes from 0 to the number of codecs. If not, reject p with a newly created NotSupportedError and abort all of these steps.

    7. If a match is not found for any value of j, reject p with a newly created TypeError and abort all of these steps.

  7. For each value of i from 0 to the number of encodings:

    1. Let payloadType be withParameters.encodings[i].codecPayloadType.

    2. If payloadType is set, check whether payloadType is equal to withParameters.codecs[j].payloadType for values of j from 0 to the number of codecs. If a match is found for any value of j, check whether withParameters.codecs[j].name is equal to "red", "cn", "telephone-event", "rtx" or a forward error correction codec ("ulpfec" [[RFC5109]] or "flexfec" [[FLEXFEC]]). If so, reject p with a newly created InvalidParameters and abort these steps.

    3. If no match is found, reject p with a newly created InvalidParameters and abort all of these steps.

    4. Let ssrc be withParameters.encodings[i].ssrc.

    5. Let dep be withParameters.encodings[i].dependencyEncodingIds.

    6. If ssrc is set and dep is unset, check that ssrc is unique. If not, reject p with a newly created NotSupportedError and abort all of these steps.

  8. For each value of i from 0 to the number of header extensions:

    1. Let headerExtension be withParameters.headerExtensions[i].

    2. Let uri be headerExtension.uri.

    3. Let id be headerExtension.id.

    4. If uri or id is unset, reject p with a newly created TypeError and abort all of these steps.

    5. Check whether uri is equal to capabilities.headerExtensions[j].uri for any value of j from 0 to the number of header extensions.

    6. If no match is found, reject p with a newly created InvalidParameters and abort all of these steps.

    7. Check whether id is equal to withParameters.headerExtensions[j].id for each value of j from 0 to the number of header extensions.

    8. If matches are found and j != i, reject p with a newly created InvalidParameters and abort all of these steps.

    9. Check whether uri is equal to withParameters.headerExtensions[j].uri for any value of j from 0 to the number of header extensions.

    10. If matches are found and j != i, reject p with a newly created InvalidParameters and abort all of these steps.

    11. For receive, check whether MID header extensions with different values of id have been configured on other RTCRtpReceivers sharing the RTCDtlsTransport transport. If conflicts are found, reject p with a newly created InvalidParameters and abort all of these steps.

RTCSsrcConflictEvent

The ssrcconflict event of the RTCRtpSender object uses the RTCSsrcConflictEvent interface.

Firing an RTCSsrcConflictEvent event named e with an ssrc means that an event with the name e, which does not bubble (except where otherwise stated) and is not cancelable (except where otherwise stated), and which uses the RTCSsrcConflictEvent interface with the ssrc attribute set to the conflicting SSRC MUST be created and dispatched at the given target.

        [ Constructor (DOMString type, RTCSsrcConflictEventInit eventInitDict), Exposed=Window]
interface RTCSsrcConflictEvent : Event {
    readonly        attribute unsigned long ssrc;
};

Constructors

RTCSsrcConflictEvent
Parameter Type Nullable Optional Description
type DOMString
eventInitDict RTCSsrcConflictEventInit

Attributes

ssrc of type unsigned long, readonly

The ssrc attribute represents the conflicting SSRC that caused the event.

The RTCSsrcConflictEventInit dictionary includes the ssrc attribute representing the conflicting SSRC that caused the event.

dictionary RTCSsrcConflictEventInit : EventInit {
             required unsigned long ssrc;
};

Dictionary RTCSsrcConflictEventInit Members

ssrc of type unsigned long, required

The ssrc attribute represents the conflicting SSRC that caused the event.

RTCRtpReceiver Interface

The RTCRtpReceiver includes information relating to the RTP receiver.

Overview

An RTCRtpReceiver instance produces an associated receiving MediaStreamTrack and provides RTC related methods to it.

Operation

A RTCRtpReceiver instance is constructed from a value of kind and an RTCDtlsTransport object.

An RTCRtpReceiver object can be garbage-collected once stop() is called and it is no longer referenced.

Interface Definition

        [ Constructor (DOMString kind, optional RTCDtlsTransport transport, optional RTCDtlsTransport rtcpTransport), Exposed=Window]
interface RTCRtpReceiver : RTCStatsProvider {
    readonly        attribute MediaStreamTrack  track;
    readonly        attribute RTCDtlsTransport?  transport;
    readonly        attribute RTCDtlsTransport? rtcpTransport;
    undefined       setTransport (RTCDtlsTransport transport, optional RTCDtlsTransport rtcpTransport);
    static RTCRtpCapabilities     getCapabilities (DOMString kind);
    Promise<undefined>      receive (RTCRtpReceiveParameters parameters);
    sequence<RTCRtpContributingSource> getContributingSources ();
    sequence<RTCRtpSynchronizationSource> getSynchronizationSources ();
    undefined                     stop ();
};

Constructors

When the constructor is invoked, the user agent MUST run the following steps:

  1. Let the first argument be kind.
  2. If kind is not a supported MediaStreamTrack kind, throw a TypeError and abort these steps.
  3. Let transport be the second argument.
  4. Let rtcpTransport be the third argument.
  5. If transport is unset, and rtcpTransport is set, throw an InvalidParameters and abort these steps.
  6. If transport is set and transport.state is closed, throw an InvalidStateError and abort these steps.
  7. If rtcpTransport is set and rtcpTransport.state is closed, throw an InvalidStateError and abort these steps.
  8. Construct an RTCRtpReceiver with transport (if provided) and rtcpTransport (if provided) and let receiver be the result.
  9. Let receiver have an [[\ReceiverStopped]] internal slot, initialized to false.
  10. Let receiver have a [[\ReceiverKind]] internal slot, initialized to kind.
  11. Let receiver have a [[\ReceiverTrack]] internal slot, initialized to a newly created MediaStreamTrack of kind kind.
  12. Set the muted attribute of receiver's [[\ReceiverTrack]] slot to false.
RTCRtpReceiver
Parameter Type Nullable Optional Description
kind DOMString
transport RTCDtlsTransport
rtcpTransport RTCDtlsTransport

Attributes

track of type MediaStreamTrack, readonly

The track attribute is the MediaStreamTrack instance that is associated with this RTCRtpReceiver object receiver. When one of the SSRCs for RTP source media streams received by receiver is removed (either due to reception of a BYE or via timeout), the mute event is fired at track. If and when packets are received again, the unmute event is fired at track.

Note that track.stop() is final, although clones are not affected. Since receiver.track.stop() does not implicitly stop receiver, Receiver Reports continue to be sent. On getting, the attribute MUST return the value of the [[\ReceiverTrack]] slot.

Prior to verification of the remote DTLS fingerprint within the RTCDtlsTransport transport (if set), and rtcpTransport (if set), track MUST NOT emit media for rendering.
transport of type RTCDtlsTransport, readonly, nullable

The associated RTP RTCDtlsTransport instance.

rtcpTransport of type RTCDtlsTransport, readonly , nullable

The RTCDtlsTransport instance over which RTCP is sent and received. When BUNDLE is used, multiple RTCRtpReceiver objects will share one rtcpTransport and will send and receive RTCP over the same RTCDtlsTransport. When RTCP mux is used, rtcpTransport will be null, and both RTP and RTCP traffic will flow over the RTCDtlsTransport transport.

Methods

setTransport

setTransport() attempts to replace the RTP RTCDtlsTransport transport (and if used) the RTCP RTCDtlsTransport rtcpTransport with the transport(s) provided.

When the setTransport() method is invoked, the user agent MUST run the following steps:

  1. Let receiver be the RTCRtpReceiver object on which setTransport() is invoked.

  2. If receiver's [[\ReceiverStopped]] slot is true, throw an InvalidStateError.
  3. Let withTransport and withRtcpTransport be the arguments to this method.

  4. If withTransport is null and withRtcpTransport is set, throw an OperationError and abort these steps.

  5. If withTransport is set and withTransport.transport.component is rtcp, throw an InvalidParameters.

  6. If withRtcpTransport is set and withRtcpTransport.transport.component is rtp, throw an InvalidParameters.

  7. If withTransport is set and withTransport.state is closed, throw an InvalidStateError.

  8. If withRtcpTransport is set and withRtcpTransport.state is closed, throw an InvalidStateError.

  9. Check whether MID header extensions with different values of id have been configured on other RTCRtpReceivers sharing the RTCDtlsTransport withTransport. If conflicts are found, throw an InvalidParameters and abort all of these steps.

  10. Set transport to withTransport and rtcpTransport to withRtcpTransport.

  11. If transport is set and transport.state is not failed, seamlessly receive over the new transport(s).

Parameter Type Nullable Optional Description
transport RTCDtlsTransport
rtcpTransport RTCDtlsTransport
Return type: undefined
getCapabilities, static

getCapabilities() obtains the receiver capabilities, based on kind. Browsers MUST support kind values of "audio" and "video". If there are no capabilities corresponding to the value of kind, getCapabilities returns null. Capabilities that can apply to multiple values of kind (such as retransmission [[!RFC4588]], redundancy [[RFC2198]] and Forward Error Correction) have RTCRtpCapabilities.RTCRtpCodecCapability[i].kind set to the value of the kind argument.

Parameter Type Nullable Optional Description
kind DOMString
Return type: RTCRtpCapabilities
receive

Attempts to set the parameters controlling the receiving of media.

When the receive() method is invoked, the user agent MUST run the following steps:

  1. Let receiver be the RTCRtpReceiver object on which receive is invoked.

  2. Let p be a new promise.

  3. If receiver's [[\ReceiverStopped]] slot is true, reject p with a newly created InvalidStateError and abort these steps.

  4. If transport is not set, reject p with a newly created TypeError and abort these steps.

  5. Let withParameters be the argument to this method.

  6. If rtcpTransport is not set and withParameters.rtcp.mux is set to false, reject p with InvalidParameters and abort these steps.

  7. Let kind be the first argument passed in the RTCRtpReceiver constructor.

  8. Complete validation checks on withParameters.
  9. As described in Section 6.5.1, fill the ssrc_table, muxId_table and pt_table entries and check for conflicts. If conflicts are found, reject p and abort these steps.

  10. Run the following steps:

    1. If receive() is called for the first time, start receiving. If receive() was called previously, have the receiver switch to receiving using withParameters.

    2. Resolve p with undefined.

Parameter Type Nullable Optional Description
parameters RTCRtpReceiveParameters
Return type: Promise<undefined>
getContributingSources

Returns an RTCRtpContributingSource for each unique CSRC identifier received by this RTCRtpReceiver. The browser MUST keep information from RTP packets received in the last 10 seconds. If no contributing sources are available, an empty list is returned.

No parameters.
Return type: sequence<RTCRtpContributingSource>
getSynchronizationSources

Returns an RTCRtpSynchronizationSource for each unique SSRC identifier received by this RTCRtpReceiver in the last 10 seconds.

No parameters.
Return type: sequence<RTCRtpSynchronizationSource>
stop

The stop method irreversibly stops the RTCRtpReceiver receiver on which it is invoked, but does not cause the "onended" event to fire for receiver.track.

While receiver.track.stop() is also irreversible, it does not affect track clones and also does not stop receiver so that Receiver Reports continue to be sent.

When stop is called, the following steps MUST be run:

  1. Let receiver be the RTCRtpReceiver on which stop is invoked.
  2. If receiver's [[\ReceiverStopped]] slot is true, abort these steps.
  3. Let parameters be the argument provided to receiver.receive(parameters) the last time it was invoked.

  4. Stop receiving media with receiver.

  5. Remove parameters.headerExtensions from receiver.transport's [[\ReceiveHeaderExtensions]] internal slot.

  6. Set receiver's [[\ReceiverStopped]] slot to true.
No parameters.
Return type: undefined

RTCRtpSynchronizationSource and RTCRtpContributingSource Dictionaries

The RTCRtpContributingSource and RTCRtpSynchronizationSource dictionaries contain information about a given contributing source (CSRC) or synchronization source (SSRC) respectively, including the most recent time a packet that the source contributed to was played out. The browser MUST keep information from RTP packets received in the previous 10 seconds. When the first frame contained in an RTP packet is delivered to the RTCRtpReceiver's MediaStreamTrack for playout, the user agent MUST queue a task to update the relevant information for the RTCRtpContributingSource and RTCRtpSynchronizationSource dictionaries based on the contents of the packet. The information relevant to the RTCRtpSynchronizationSource dictionary corresponding to the SSRC identifier is updated each time, and if the RTP packet contains CSRC identifiers, then the information relevant to the RTCRtpContributingSource dictionaries corresponding to those CSRC identifiers is also updated.

As stated in the conformance section, requirements phrased as algorithms may be implemented in any manner so long as the end result is equivalent. So, an implementation does not need to literally queue a task for every packet, as long as the end result is that within a single event loop task execution, all returned RTCRtpSynchronizationSource and RTCRtpContributingSource dictionaries for a particular RTCRtpReceiver contain information from a single point in the RTP stream.
dictionary RTCRtpContributingSource {
    required DOMHighResTimeStamp timestamp;
    required unsigned long       source;
             double              audioLevel;
};

Dictionary RTCRtpContributingSource Members

timestamp of type DOMHighResTimeStamp, required

The timestamp of type DOMHighResTimeStamp [[!HIGHRES-TIME]], indicating the most recent time of playout of an RTP packet containing the source. The timestamp is defined in [[!HIGHRES-TIME]] and corresponds to a local clock.

source of type unsigned long, required

The CSRC or SSRC identifier of the contributing or synchronization source.

audioLevel of type double

This is a value between 0..1 (linear), where 1.0 represents 0 dBov, 0 represents silence, and 0.5 represents approximately 6 dBSPL change in the sound pressure level from 0 dBov.

For CSRCs, this MUST be converted from the level value defined in [[!RFC6465]] if the RFC 6465 header extension is present, otherwise this member MUST be absent.

For SSRCs, this MUST be converted from the level value defined in [[!RFC6464]] if the RFC 6464 header extension is present, otherwise the user agent must compute the value from the audio data (the member must never be absent).

Both RFCs define the level as an integral value from 0 to 127 representing the audio level in negative decibels relative to the loudest signal that the system could possibly encode. Thus, 0 represents the loudest signal the system could possibly encode, and 127 represents silence.

To convert these values to the linear 0..1 range, a value of 127 is converted to 0, and all other values are converted using the equation: 10^(-rfc_level/20).

dictionary RTCRtpSynchronizationSource : RTCRtpContributingSource {
    boolean voiceActivityFlag;
};

Dictionary RTCRtpSynchronizationSource Members

voiceActivityFlag of type boolean

Whether the last RTP packet played from this source contains voice activity (true) or not (false). If the RFC 6464 extension header was not present, or if the peer has signaled that it is not using the V bit by setting the "vad" extension attribute to "off", as described in [[!RFC6464]], Section 4, voiceActivityFlag will be absent.

RTP matching rules

In ORTC, RTP packets are delivered to RTCRtpReceiver objects by the RTCRtpListener. When the RTCRtpListener receives an RTP packet over an RTCDtlsTransport, it attempts to determine which RTCRtpReceiver object to deliver the packet to, based on the values of the SSRC and payload type fields in the RTP header, as well as the value of the MID RTP header extension, if present. If the RTCRtpReceiver object to deliver the RTP packet to cannot be determined, the unhandledrtp event is fired.

[[!BUNDLE]] Section 10.2 describes the algorithm used in WebRTC for routing of RTP streams received over a shared transport to an SDP m-line (representing an RTCRtpSender/RTCRtpReceiver pair), using three tables: the ssrc_table which maps SSRC values to RTCRtpReceiver objects, the muxId_table which maps values of the MID header extension to RTCRtpReceiver objects and the pt_table which maps payload type values to RTCRtpReceiver objects.

Table entries referencing the RTCRtpReceiver object receiver are added when receiver.receive(parameters) is called. When receiver.receive(parameters) is called again, changes are made to table entries. When receiver.stop is called, all entries referencing receiver are removed.

When multiple RTCRtpReceiver or RTCRtpSender objects share a RTCDtlsTransport, this implies that they also share a single SSRC [[!RFC3550]] and header extension [[!RFC5285]] numbering space. The restrictions arising from this are described in [[!BUNDLE]] Sections 10.1 and 10.1.1.

ORTC routing tables

Since ORTC does not utilize RTCRtpTransceiver objects, this section provides a (non-normative) example of how an RTCRtpListener implementation can emulate the behavior described in [[!BUNDLE]] Section 10.2.

When receive is called, to fill the routing tables and check for conflicts, run the following steps:

  1. Let receiver be the RTCRtpReceiver object on which the receive method was called.

  2. Let withParameters be the first argument.
  3. MuxId table:
    1. If withParameters.muxId is set and muxId_table[withParameters.muxId] is unset, set muxId_table[withParameters.muxId] to receiver.

    2. If withParameters.muxId is set and muxId_table[withParameters.muxId] is set to a value other than receiver, reject receive with InvalidParameters and abort these steps.

  4. SSRC table:
  5. For values of i from 0 to encodings.length-1:

    1. If withParameters.encodings[i].ssrc is set and ssrc_table[withParameters.encodings[i].ssrc] is unset, set ssrc_table[withParameters.encodings[i].ssrc] to receiver.

    2. If withParameters.encodings[i].ssrc is set and ssrc_table[withParameters.encodings[i].ssrc] is set to a value other than receiver, reject receive with InvalidParameters and abort these steps.

    3. If withParameters.encodings[i].rtx.ssrc is set and ssrc_table[withParameters.encodings[i].rtx.ssrc] is unset, set ssrc_table[withParameters.encodings[i].rtx.ssrc] to receiver.

    4. If withParameters.encodings[i].rtx.ssrc is set and ssrc_table[withParameters.encodings[i].rtx.ssrc] is set to a value other than receiver, reject receive with InvalidParameters and abort these steps.

    5. If withParameters.encodings[i].fec.ssrc is set and ssrc_table[withParameters.encodings[i].fec.ssrc] is unset, set ssrc_table[withParameters.encodings[i].fec.ssrc] to receiver.

    6. If withParameters.encodings[i].fec.ssrc is set and ssrc_table[withParameters.encodings[i].fec.ssrc] is set to a value other than receiver, reject receive with InvalidParameters and abort these steps.

  6. payload type table:
    1. If withParameters.encodings[i].ssrc is unset for all values of i from 0 to encodings.length-1, then for values of j from 0 to codecs.length-1:

      1. If pt_table[withParameters.codecs[j].payloadType] is unset, set pt_table[withParameters.codecs[j].payloadType] to receiver.

      2. If pt_table[withParameters.codecs[j].payloadType] is set to a value other than receiver, reject receive with InvalidParameters and abort these steps.

RTP packet handling

When an RTP packet arrives, the implementation determines the RTCRtpReceiver rtp_receiver to send it to as follows:

If ssrc_table[packet.ssrc] is set:

  1. Check whether the value of packet.pt is equal to one of the values of parameters.codecs[j].payloadType for the RTCRtpReceiver object rtp_receiver, where j varies from 0 to codecs.length-1.
  2. If packet.pt does not match, fire the unhandledrtp event and abort these steps.
  3. Set rtp_receiver to ssrc_table[packet.ssrc].
  4. Route the packet to rtp_receiver and abort these steps.

Else if packet.muxId is set:

  1. If muxId_table[packet.muxId] is unset, fire the unhandledrtp event, and abort these steps.
  2. Check whether the value of packet.pt is equal to one of the values of parameters.codecs[j].payloadType for the RTCRtpReceiver object rtp_receiver, where j varies from 0 to codecs.length-1.
  3. If packet.pt does not match, fire the unhandledrtp event and abort these steps.
  4. Set rtp_receiver to muxId_table[packet.muxId].
  5. Set ssrc_table[packet.ssrc] to rtp_receiver.
  6. Route the packet to rtp_receiver and abort these steps.

Else if pt_table[packet.pt] is set:

  1. Set rtp_receiver to pt_table[packet.pt].
  2. Set ssrc_table[packet.ssrc] to rtp_receiver.
  3. Route the packet to rtp_receiver and abort these steps.

Else if no matches are found in the ssrc_table, muxId_table or pt_table, fire the unhandledrtp event.

RTCP packet handling

RTCP packets arriving on a RTCDtlsTransport are decrypted and the algorithm described in [[!BUNDLE]] Section 10.2 is used to route the RTCP packets to the appropriate RTCRtpSender and RTCRtpReceiver objects. The RTCRtpSender and RTCRtpReceiver objects then examine the RTCP packets to determine the information relevant to their operation and the statistics maintained by them.

RTCP packets should be queued for 30 seconds so that RTCRtpSender and RTCRtpReceiver objects on the related RTCDTlsTransport have access to those packets until the packet is removed from the queue, should the RTCRtpSender or RTCRtpReceiver objects need to examine them.

Since statistics are retrieved from objects within the ORTC API, and information within RTCP packets is used to maintain some of the statistics, the handling of RTCP packets is important to the operation of the Statistics API.

Examples

      // Assume we already have a way to signal, a transport
// (RTCDtlsTransport), and audio and video tracks. This is an example
// of how to offer them and get back an answer with audio and
// video tracks, and begin sending and receiving them.
// The example assumes that RTP and RTCP are multiplexed.
function myInitiate(mySignaller, transport, audioTrack, videoTrack) {
  var audioSender = new RTCRtpSender(audioTrack, transport);
  var videoSender = new RTCRtpSender(videoTrack, transport);
  var audioReceiver = new RTCRtpReceiver("audio", transport);
  var videoReceiver = new RTCRtpReceiver("video", transport);

  // Retrieve the audio and video receiver capabilities
  var recvAudioCaps = RTCRtpReceiver.getCapabilities("audio");
  var recvVideoCaps = RTCRtpReceiver.getCapabilities("video");

  // Retrieve the audio and video sender capabilities
  var sendAudioCaps = RTCRtpSender.getCapabilities("audio");
  var sendVideoCaps = RTCRtpSender.getCapabilities("video");

  mySignaller.myOfferTracks({
    // The initiator offers its receiver and sender capabilities.
    recvAudioCaps: recvAudioCaps,
    recvVideoCaps: recvVideoCaps,
    sendAudioCaps: sendAudioCaps,
    sendVideoCaps: sendVideoCaps
  }, function(answer) {
    // The responder answers with its receiver capabilities

    // Derive the send and receive parameters (see Section 19.3)
    var audioSendParams = myCapsToSendParams(sendAudioCaps, answer.recvAudioCaps);
    var videoSendParams = myCapsToSendParams(sendVideoCaps, answer.recvVideoCaps);
    var audioRecvParams = myCapsToRecvParams(recvAudioCaps, answer.sendAudioCaps);
    var videoRecvParams = myCapsToRecvParams(recvVideoCaps, answer.sendVideoCaps);
    audioSender.send(audioSendParams).then(function() {
      trace("Set audio sender parameters");
      }, function() {
        trace("Could not set audio sender parameters");
      }
    );
    videoSender.send(videoSendParams).then(function() {
      trace("Set video sender parameters");
      }, function() {
        trace("Could not set video sender parameters");
      }
    );
    audioReceiver.receive(audioRecvParams).then(function() {
      trace("Set audio receiver parameters");
      }, function() {
        trace("Could not set audio receiver parameters");
      }
    );
    videoReceiver.receive(videoRecvParams).then(function() {
      trace("Set video receiver parameters");
      }, function() {
        trace("Could not set video receiver parameters");
      }
    );
    // Now we can render/play
    // audioReceiver.track and videoReceiver.track.
  });
}
                
      // Assume we already have a way to signal, a transport (RTCDtlsTransport)
// and audio and video tracks. This is an example of how to answer an
// offer with audio and video tracks, and begin sending and receiving them.
// The example assumes that RTP and RTCP are multiplexed.
function myAccept(mySignaller, remote, transport, audioTrack, videoTrack) {
  var audioSender = new RTCRtpSender(audioTrack, transport);
  var videoSender = new RTCRtpSender(videoTrack, transport);
  var audioReceiver = new RTCRtpReceiver("audio", transport);
  var videoReceiver = new RTCRtpReceiver("video", transport);

  // Retrieve the send and receive capabilities
  var recvAudioCaps = RTCRtpReceiver.getCapabilities("audio");
  var recvVideoCaps = RTCRtpReceiver.getCapabilities("video");
  var sendAudioCaps = RTCRtpSender.getCapabilities("audio");
  var sendVideoCaps = RTCRtpSender.getCapabilities("video");

  mySignaller.myAnswerTracks({
    recvAudioCaps: recvAudioCaps,
    recvVideoCaps: recvVideoCaps,
    sendAudioCaps: sendAudioCaps,
    sendVideoCaps: sendVideoCaps
  });

  // Derive the send and receive parameters using Javascript functions
  var audioSendParams = myCapsToSendParams(sendAudioCaps, remote.recvAudioCaps);
  var videoSendParams = myCapsToSendParams(sendVideoCaps, remote.recvVideoCaps);
  var audioRecvParams = myCapsToRecvParams(recvAudioCaps, remote.sendAudioCaps);
  var videoRecvParams = myCapsToRecvParams(recvVideoCaps, remote.sendVideoCaps);
  audioSender.send(audioSendParams).then(function() {
    trace("Set audio sender parameters");
    }, function() {
      trace("Could not set audio sender parameters");
    }
  );
  videoSender.send(videoSendParams).then(function() {
    trace("Set video sender parameters");
    }, function() {
      trace("Could not set video sender parameters");
    }
  );
  audioReceiver.receive(audioRecvParams).then(function() {
    trace("Set audio receiver parameters");
    }, function() {
      trace("Could not set audio receiver parameters");
    }
  );
  videoReceiver.receive(videoRecvParams).then(function() {
    trace("Set video receiver parameters");
    }, function() {
      trace("Could not set video receiver parameters");
    }
  );
  // Now we can render/play
  // audioReceiver.track and videoReceiver.track.
}
                

RTCIceTransportController Interface

The RTCIceTransportController object assists in the managing of ICE freezing and bandwidth estimation.

Overview

An RTCIceTransportController object provides methods to add and retrieve RTCIceTransport objects with a component of rtp (associated RTCIceTransport objects with a component of rtcp are included implicitly).

Operation

An RTCIceTransportController instance is automatically constructed.

Interface Definition

[Constructor(), Exposed=Window]
interface RTCIceTransportController {
    undefined                 addTransport (RTCIceTransport transport, optional unsigned long index);
    sequence<RTCIceTransport> getTransports ();
};

Methods

addTransport

Adds transport to the RTCIceTransportController object for the purposes of managing ICE freezing and sharing bandwidth estimation. Since addTransport manages ICE freezing, candidate pairs that are not in the frozen state maintain their state when addTransport(transport) is called. RTCIceTransport objects will be unfrozen according to their index. transport is inserted at index, or at the end if index is not specified. If index is greater than the current number of RTCIceTransports with a component of rtp, throw an InvalidParameters. If transport.state is closed, throw an InvalidStateError. If transport has already been added to another RTCIceTransportController object, or if transport.component is rtcp, throw an InvalidStateError.

Parameter Type Nullable Optional Description
transport RTCIceTransport
index unsigned long
Return type: undefined
getTransports

Returns the RTCIceTransport objects with a component of rtp. If addTransport() has not been called, an empty list is returned.

No parameters.
Return type: sequence<RTCIceTransport>

Example

      // This is an example of how to utilize distinct ICE transports for Audio and Video
// as well as for RTP and RTCP. If both sides can multiplex audio/video
// and RTP/RTCP then the multiplexing will occur.
//
// Assume we have an audioTrack and a videoTrack to send.
//
// Include some helper functions
import {trace, errorHandler, mySendLocalCandidate, myIceGathererStateChange,
  myIceTransportStateChange, myDtlsTransportStateChange} from 'helper';
// Create the ICE gather options
var gatherOptions = {
  gatherPolicy: "all",
  iceServers: [
    { urls: "stun:stun1.example.net" },
    { urls: "turn:turn.example.org", username: "user", credential: "myPassword",
      credentialType: "password" }
   ]
};

// Create the RTP and RTCP ICE gatherers for audio and video
var audioRtpIceGatherer = new RTCIceGatherer(gatherOptions);
var audioRtcpIceGatherer = audioRtpIceGatherer.createAssociatedGatherer();
var videoRtpIceGatherer = new RTCIceGatherer(gatherOptions);
var videoRtcpIceGatherer = videoRtpIceGatherer.createAssociatedGatherer();

// Set up the ICE gatherer error handlers
audioRtpIceGatherer.onerror = errorHandler;
audioRtcpIceGatherer.onerror = errorHandler;
videoRtpIceGatherer.onerror = errorHandler;
videoRtcpIceGatherer.onerror = errorHandler;

// Create the RTP and RTCP ICE transports for audio and video
var audioRtpIceTransport = new RTCIceTransport(audioRtpIceGatherer);
var audioRtcpIceTransport = audioRtpIceTransport.createAssociatedTransport();
var videoRtpIceTransport = new RTCIceTransport(videoRtpIceGatherer);
var videoRtcpIceTransport = videoRtpIceTransport.createAssociatedTransport();

// Enable local ICE candidates to be signaled to the remote peer.
audioRtpIceGatherer.onlocalcandidate = function(event) {
  mySendLocalCandidate(event.candidate, "rtp", "audio");
};
audioRtcpIceGatherer.onlocalcandidate = function(event) {
  mySendLocalCandidate(event.candidate, "rtcp", "audio");
};
videoRtpIceGatherer.onlocalcandidate = function(event) {
  mySendLocalCandidate(event.candidate, "rtp", "video");
};
videoRtcpIceGatherer.onlocalcandidate = function(event) {
  mySendLocalCandidate(event.candidate, "rtcp", "video");
};

// Start gathering
audioRtpIceGatherer.gather();
audioRtcpIceGatherer.gather();
videoRtpIceGatherer.gather();
videoRtcpIceGatherer.gather();

// Set up the ICE state change event handlers
audioRtpIceTransport.onstatechange = function(event) {
  myIceTransportStateChange("audioRtpIceTransport", event.state);
};
audioRtcpIceTransport.onstatechange = function(event) {
  myIceTransportStateChange("audioRtcpIceTransport", event.state);
};
videoRtpIceTransport.onstatechange = function(event) {
  myIceTransportStateChange("videoRtpIceTransport", event.state);
};
videoRtcpIceTransport.onstatechange = function(event) {
  myIceTransportStateChange("videoRtcpIceTransport", event.state);
};

// Prepare to add ICE candidates signaled by the remote peer on any of the ICE transports
mySignaller.onRemoteCandidate = function(remote) {
  switch (remote.kind) {
    case "audio":
      if (remote.component === "rtp") {
        audioRtpIceTransport.addRemoteCandidate(remote.candidate);
      } else {
        audioRtcpIceTransport.addRemoteCandidate(remote.candidate);
      }
      break;
    case "video":
      if (remote.component === "rtp") {
        videoRtpIceTransport.addRemoteCandidate(remote.candidate);
      } else {
        videoRtcpIceTransport.addRemoteCandidate(remote.candidate);
      }
      break;
    default:
      trace("Invalid media type received: " + remote.kind);
  }
};
// Create the DTLS certificate
var certs;
var keygenAlgorithm = { name: "ECDSA", namedCurve: "P-256" };
RTCCertificate.generateCertificate(keygenAlgorithm).then(function(certificate){
  certs[0] = certificate;
}, function(){
  trace('Certificate could not be created');
});

// Create the DTLS transports (using the same certificate)
var audioRtpDtlsTransport = new RTCDtlsTransport(audioRtpIceTransport, certs);
var audioRtcpDtlsTransport = new RTCDtlsTransport(audioRtcpIceTransport, certs);
var videoRtpDtlsTransport = new RTCDtlsTransport(videoRtpIceTransport, certs);
var videoRtcpDtlsTransport = new RTCDtlsTransport(videoRtcpIceTransport, certs);

// Create the sender and receiver objects
var audioSender = new RTCRtpSender(audioTrack, audioRtpDtlsTransport, audioRtcpDtlsTransport);
var videoSender = new RTCRtpSender(videoTrack, videoRtpDtlsTransport, videoRtcpDtlsTransport);
var audioReceiver = new RTCRtpReceiver("audio", audioRtpDtlsTransport, audioRtcpDtlsTransport);
var videoReceiver = new RTCRtpReceiver("video", videoRtpDtlsTransport, videoRtcpDtlsTransport);

// Retrieve the receiver and sender capabilities
var recvAudioCaps = RTCRtpReceiver.getCapabilities("audio");
var recvVideoCaps = RTCRtpReceiver.getCapabilities("video");
var sendAudioCaps = RTCRtpSender.getCapabilities("audio");
var sendVideoCaps = RTCRtpSender.getCapabilities("video");

// Exchange ICE/DTLS parameters and Send/Receive capabilities

mySignaller.myOfferTracks({
  // Indicate that the initiator would prefer to multiplex both A/V and RTP/RTCP
  bundle: true,
  // Indicate that the initiator is willing to multiplex RTP/RTCP without A/V mux
  rtcpMux: true,
  // Offer the ICE parameters
  audioRtpIce: audioRtpIceGatherer.getLocalParameters(),
  audioRtcpIce: audioRtcpIceGatherer.getLocalParameters(),
  videoRtpIce: videoRtpIceGatherer.getLocalParameters(),
  videoRtcpIce: videoRtcpIceGatherer.getLocalParameters(),
  // Offer the DTLS parameters
  audioRtpDtls: audioRtpDtlsTransport.getLocalParameters(),
  audioRtcpDtls: audioRtcpDtlsTransport.getLocalParameters(),
  videoRtpDtls: videoRtpDtlsTransport.getLocalParameters(),
  videoRtcpDtls: videoRtcpDtlsTransport.getLocalParameters(),
  // Offer the receiver and sender audio and video capabilities.
  recvAudioCaps: recvAudioCaps,
  recvVideoCaps: recvVideoCaps,
  sendAudioCaps: sendAudioCaps,
  sendVideoCaps: sendVideoCaps
}, function(answer) {
  // The responder answers with its preferences, parameters and capabilities
  // Since we didn"t create transport arrays, we are assuming that there
  // is no forking (only one response)
  //
  // Derive the send and receive parameters, assuming that RTP/RTCP mux will be enabled.
  var audioSendParams = myCapsToSendParams(sendAudioCaps, answer.recvAudioCaps);
  var videoSendParams = myCapsToSendParams(sendVideoCaps, answer.recvVideoCaps);
  var audioRecvParams = myCapsToRecvParams(recvAudioCaps, answer.sendAudioCaps);
  var videoRecvParams = myCapsToRecvParams(recvVideoCaps, answer.sendVideoCaps);
  //
  // If the responder wishes to enable bundle, we will enable it
  if (answer.bundle) {
    // Since bundle implies RTP/RTCP multiplexing, we only need a single
    // ICE transport and DTLS transport. No need for the ICE transport controller.
    audioRtpIceTransport.start(audioRtpIceGatherer, answer.audioRtpIce, RTCIceRole.controlling);
    audioRtpDtlsTransport.start(remote.audioRtpDtls);
    //
    // Replace the transport on the Sender and Receiver objects
    //
    audioSender.setTransport(audioRtpDtlsTransport);
    videoSender.setTransport(audioRtpDtlsTransport);
    audioReceiver.setTransport(audioRtpDtlsTransport);
    videoReceiver.setTransport(audioRtpDtlsTransport);
    // If BUNDLE was requested, then also assume RTP/RTCP mux
    answer.rtcpMux = true;
  } else {
    var controller = new RTCIceTransportController();
    if (answer.rtcpMux) {
      // The peer doesn"t want BUNDLE, but it does want to multiplex RTP/RTCP
      // Now we need audio and video ICE transports
      // as well as an ICE Transport Controller object
      controller.addTransport(audioRtpIceTransport);
      controller.addTransport(videoRtpIceTransport);
      // Start the audio and video ICE transports
      audioRtpIceTransport.start(audioRtpIceGatherer, answer.audioRtpIce, RTCIceRole.controlling);
      videoRtpIceTransport.start(videoRtpIceGatherer, answer.videoRtpIce, RTCIceRole.controlling);
      // Start the audio and video DTLS transports
      audioRtpDtlsTransport.onerror = errorHandler;
      audioRtpDtlsTransport.start(answer.audioRtpDtls);
      videoRtpDtlsTransport.onerror = errorHandler;
      videoRtpDtlsTransport.start(answer.videoRtpDtls);
      // Replace the transport on the Sender and Receiver objects
      //
      audioSender.setTransport(audioRtpDtlsTransport);
      videoSender.setTransport(videoRtpDtlsTransport);
      audioReceiver.setTransport(audioRtpDtlsTransport);
      videoReceiver.setTransport(videoRtpDtlsTransport);
    } else {
      // We arrive here if the responder does not want BUNDLE
      // or RTP/RTCP multiplexing
      //
      // Now we need all the audio and video RTP and RTCP ICE transports
      // as well as an ICE Transport Controller object
      controller.addTransport(audioRtpIceTransport);
      controller.addTransport(videoRtpIceTransport);
      // Start the ICE transports
      audioRtpIceTransport.start(audioRtpIceGatherer, answer.audioRtpIce, RTCIceRole.controlling);
      audioRtcpIceTransport.start(audioRtcpIceGatherer, answer.audioRtcpIce,
        RTCIceRole.controlling);
      videoRtpIceTransport.start(videoRtpIceGatherer, answer.videoRtpIce, RTCIceRole.controlling);
      videoRtcpIceTransport.start(videoRtcpIceGatherer, answer.videoRtcpIce,
        RTCIceRole.controlling);
      // Start the DTLS transports that are needed
      audioRtpDtlsTransport.start(answer.audioRtpDtls);
      audioRtcpDtlsTransport.start(answer.audioRtcpDtls);
      videoRtpDtlsTransport.start(answer.videoRtpDtls);
      videoRtcpDtlsTransport.start(answer.videoRtcpDtls);
      // Disable RTP/RTCP multiplexing
      audioSendParams.rtcp.mux = false;
      videoSendParams.rtcp.mux = false;
      audioRecvParams.rtcp.mux = false;
      videoRecvParams.rtcp.mux = false;
    }
  }
  // Set the audio and video send and receive parameters.
  audioSender.send(audioSendParams).then(function() {
    trace("Set audio sender parameters");
    }, function() {
      trace("Could not set audio sender parameters");
    }
  );
  videoSender.send(videoSendParams).then(function() {
    trace("Set video sender parameters");
    }, function() {
      trace("Could not set video sender parameters");
    }
  );
  audioReceiver.receive(audioRecvParams).then(function() {
    trace("Set audio receiver parameters");
    }, function() {
      trace("Could not set audio receiver parameters");
    }
  );
  videoReceiver.receive(videoRecvParams).then(function() {
    trace("Set video receiver parameters");
    }, function() {
      trace("Could not set video receiver parameters");
    }
  );
// Now we can render/play audioReceiver.track and videoReceiver.track
                

RTCRtpListener Interface

The RTCRtpListener listens to RTP packets received from the RTCDtlsTransport, determining whether an incoming RTP stream is configured to be processed by an existing RTCRtpReceiver object. If no match is found, the unhandledrtp event is fired. This can be due to packets having an unknown SSRC, payload type or any other error that makes it impossible to attribute an RTP packet to a specific RTCRtpReceiver object. The event is not fired once for each arriving packet; multiple discarded packets for the same SSRC SHOULD result in a single event.

Note that application handling of the unhandledrtp event may not be sufficient to enable the unhandled RTP stream to be rendered. The amount of buffering to be provided for unhandled RTP streams is not mandated by this specification and is recommended to be strictly limited to protect against denial of service attacks. Therefore an application attempting to create additional RTCRtpReceiver objects to handle the incoming RTP stream may find that portions of the incoming RTP stream were lost due to insufficient buffers, and therefore could not be rendered.

Overview

An RTCRtpListener instance is associated to an RTCDtlsTransport.

Operation

An RTCRtpListener instance is constructed from an RTCDtlsTransport object.

Interface Definition

[ Constructor (RTCDtlsTransport transport), Exposed=Window]
interface RTCRtpListener {
    readonly        attribute RTCDtlsTransport transport;
                    attribute EventHandler     onunhandledrtp;
};

Constructors

RTCRtpListener
Parameter Type Nullable Optional Description
transport RTCDtlsTransport

Attributes

transport of type RTCDtlsTransport, readonly

The RTP RTCDtlsTransport instance.

onunhandledrtp of type EventHandler

The event handler which handles the RTCRtpUnhandledEvent, which is fired when the RTCRtpListener detects an RTP stream that is not configured to be processed by an existing RTCRtpReceiver object.

RTCRtpUnhandledEvent

The unhandledrtp event of the RTCRtpListener object uses the RTCRtpUnhandledEvent interface.

Firing an RTCRtpUnhandledEvent event named e means that an event with the name e, which does not bubble (except where otherwise stated) and is not cancelable (except where otherwise stated), and which uses the RTCRtpUnhandledEvent interface MUST be created and dispatched at the given target.

        [ Constructor (DOMString type, RTCRtpUnhandledEventInit eventInitDict), Exposed=Window]
interface RTCRtpUnhandledEvent : Event {
    readonly        attribute DOMString     muxId;
    readonly        attribute DOMString     rid;
    readonly        attribute payloadtype   payloadType;
    readonly        attribute unsigned long ssrc;
};

Constructors

RTCRtpUnhandledEvent
Parameter Type Nullable Optional Description
type DOMString
eventInitDict RTCRtpUnhandledEventInit

Attributes

muxId of type DOMString, readonly

The value of the MID RTP header extension [[!BUNDLE]] in the RTP stream triggering the unhandledrtp event. If receive() has not been called, the MID header extension cannot be decoded, so that muxId will be unset.

rid of type DOMString, readonly

The value of the RID RTP header extension [[!RID]] in the RTP stream triggering the unhandledrtp event. If receive() has not been called, the RID header extension cannot be decoded, so that rid will be unset.

payloadType of type payloadtype, readonly

The Payload Type value in the RTP stream triggering the unhandledrtp event.

ssrc of type unsigned long, readonly

The SSRC in the RTP stream triggering the unhandledrtp event.

The RTCRtpUnhandledEventInit dictionary provides information on the RTP packet causing the RTCRtpUnhandledEvent.

dictionary RTCRtpUnhandledEventInit : EventInit {
             DOMString     muxId;
             DOMString     rid;
             required payloadtype   payloadType;
             required unsigned long ssrc;
};

Dictionary RTCRtpUnhandledEventInit Members

muxId of type DOMString

If present, the value of the MID RTP header extension [[!BUNDLE]] in the RTP stream triggering the unhandledrtp event.

rid of type DOMString

If present, the value of the RID RTP header extension [[!RID]] in the RTP stream triggering the unhandledrtp event.

payloadType of type payloadtype, required

The Payload Type value in the RTP stream triggering the unhandledrtp event.

ssrc of type unsigned long, required

The SSRC in the RTP stream triggering the unhandledrtp event.

Dictionary Object

typedef object Dictionary;
Throughout this specification, the identifier Dictionary is used to refer to the object type.

payloadtype Type

typedef octet payloadtype;
Throughout this specification, the identifier payloadtype is used to refer to the octet type.

Dictionaries related to Rtp

RTCRtpCapabilities Dictionary

The RTCRtpCapabilities object expresses the capabilities of RTCRtpSender and RTCRtpReceiver objects. Features which are mandatory to implement in [[!RTP-USAGE]], such as RTP/RTCP multiplexing [[!RFC5761]], audio/video multiplexing [[!RTP-MULTI-STREAM]] and reduced size RTCP [[!RFC5506]] are assumed to be available and are therefore not included in RTCRtpCapabilities, although these parameters may be set via send() or receive().

dictionary RTCRtpCapabilities {
             required sequence<RTCRtpCodecCapability> codecs;
             sequence<RTCRtpHeaderExtension> headerExtensions;
             sequence<DOMString>             fecMechanisms;
};

Dictionary RTCRtpCapabilities Members

codecs of type sequence<RTCRtpCodecCapability>, required

Supported codecs.

headerExtensions of type sequence<RTCRtpHeaderExtension>

Supported RTP header extensions.

fecMechanisms of type sequence<DOMString>

Supported Forward Error Correction (FEC) mechanisms and combinations. Supported values are "red" [[!RFC2198]], "red+ulpfec" [[RFC5109]] and "flexfec" [[FLEXFEC]]. Note that supported mechanisms also need to be included within RTCRtpCapabilities.codecs[]. [[FEC]] summarizes requirements relating to FEC mechanisms.

RTCRtcpFeedback Dictionary

RTCRtcpFeedback provides information on RTCP feedback messages.

dictionary RTCRtcpFeedback {
             required DOMString type;
             DOMString parameter;
};

Dictionary RTCRtcpFeedback Members

type of type DOMString, required

Valid values for type are the "RTCP Feedback" Attribute Values enumerated in [[!IANA-SDP-14]] ("ack", "ccm", "nack", etc.), as well as "goog-remb" [[REMB]] and "transport-cc" [[TRANSPORT-CC]].

parameter of type DOMString

For a type value of "ack" or "nack", valid values for parameter are the "ack" and "nack" Attribute Values enumerated in [[!IANA-SDP-15]] ("sli", "rpsi", etc.). For the Generic NACK feedback message defined in [[!RFC4585]] Section 6.2.1, the type attribute is set to "nack" and the parameter attribute is unset. For a type value of "ccm", valid values for parameter are the "Codec Control Messages" enumerated in [[!IANA-SDP-19]] ("fir", "tmmbr" (includes "tmmbn"), etc.).

RTCRtpCodecCapability Dictionary

The RTCRtpCodecCapability dictionary provides information on the capabilities of a codec. Exactly one RTCRtpCodecCapability will be present for each supported combination of parameters that requires a distinct value of preferredPayloadType. For example:

  1. Multiple "h264" codecs, each with their own distinct packetization-mode values.
  2. "cn" codecs, each with distinct clockRate values.
dictionary RTCRtpCodecCapability {
             required DOMString                 name;
             DOMString                 mimeType;
             required DOMString                 kind;
             unsigned long             clockRate;
             required payloadtype               preferredPayloadType;
             unsigned long             maxptime;
             unsigned long             ptime;
             unsigned long             channels;
             sequence<RTCRtcpFeedback> rtcpFeedback;
             Dictionary                parameters;
             Dictionary                options;
             unsigned short            maxTemporalLayers = 0;
             unsigned short            maxSpatialLayers = 0;
             boolean                   svcMultiStreamSupport;
};

Dictionary RTCRtpCodecCapability Members

name of type DOMString, required

The MIME media subtype. Valid subtypes are listed in [[!IANA-RTP-2]].

mimeType of type DOMString

The codec MIME media type/subtype. Valid media types and subtypes are listed in [[IANA-RTP-2]].

kind of type DOMString, required

The media supported by the codec: "audio", "video", etc.

clockRate of type unsigned long

Codec clock rate expressed in Hertz. If unset, the codec is applicable to any clock rate.

preferredPayloadType of type payloadtype, required

The preferred RTP payload type for the codec denoted by RTCRtpCodecCapability.name. This attribute was added to make it possible for the sender and receiver to pick a matching payload type when creating sender and receiver parameters. When returned by RTCRtpSender.getCapabilities(), RTCRtpCapabilities.codecs.preferredPayloadtype represents the preferred RTP payload type for sending. When returned by RTCRtpReceiver.getCapabilities(), RTCRtpCapabilities.codecs.preferredPayloadtype represents the preferred RTP payload type for receiving. To avoid payload type conflicts, each value of preferredPayloadType MUST be unique.

maxptime of type unsigned long

The maximum packetization time supported by the RTCRtpReceiver.

ptime of type unsigned long

The preferred duration of media represented by a packet in milliseconds for the RTCRtpSender or RTCRtpReceiver.

channels of type unsigned long

The number of channels supported (e.g. two for stereo). For video, this attribute is unset.

rtcpFeedback of type sequence<RTCRtcpFeedback>

Transport layer and codec-specific feedback messages for this codec.

parameters of type Dictionary

Codec-specific parameters that must be signaled to the remote party.

options of type Dictionary

Codec-specific parameters that may be optionally signalled and are available as additional supported information or settings about the codec.

maxTemporalLayers of type unsigned short, defaulting to 0

Maximum number of temporal layer extensions supported by this codec (e.g. a value of 1 indicates support for up to 2 temporal layers). A value of 0 indicates no support for temporal scalability.

maxSpatialLayers of type unsigned short, defaulting to 0

Maximum number of spatial layer extensions supported by this codec (e.g. a value of 1 indicates support for up to 2 spatial layers). A value of 0 indicates no support for spatial scalability.

svcMultiStreamSupport of type boolean

Whether the implementation can send/receive SVC layers utilizing distinct SSRCs. Unset for audio codecs. For video codecs, only set if the codec supports scalable video coding with MRST.

Codec capability options

The capability options of commonly implemented codecs are provided below.

If a defined codec option is unset when returned from RTCRtpReceiver/Sender.getCapabilities(), then the engine does not allow adjusting the option. If set when returned from RTCRtpReceiver/Sender.getCapabilities() then the default value for the engine is given.

Opus

The following capability options are defined for Opus:

Property Name Values Receiver/Sender Notes
complexity unsigned long Sender Indicates the default value for the encoder's computational complexity. The supported range is 0-10 with 10 representing the highest complexity.
signal DOMString Sender Indicates the default value for the type of signal being encoded. Possible values are "auto", "music" and "voice".
application DOMString Sender Indicates the default value for the encoder's intended application. Possible values are "voip", "audio" and "lowdelay".
packetlossperc unsigned long Sender Indicates the default value for the encoder's expected packet loss percentage. Possible values are 0-100.
predictiondisabled boolean Sender Indicates the default value for whether prediction is disabled, making frames almost complete independent (if true) or not (if false).

Codec capability parameters

The capability parameters for commonly implemented codecs are provided below.

If a defined codec capability parameter is unset when returned from RTCRtpReceiver/Sender.getCapabilities(), then the engine does not allow adjusting the parameter. If set when returned from RTCRtpReceiver/Sender.getCapabilities() then the default value for the engine is given.

Opus

The following optional capability parameters are defined for "opus", as noted in [[!RFC7587]] Section 6.1:

Property Name Values Receiver/Sender Notes
maxplaybackrate unsigned long Receiver A hint about the maximum output sampling rate that the receiver is capable of rendering in Hz.
sprop-maxcapturerate unsigned long Sender A hint about the maximum input sampling rate that the sender is likely to produce.
maxaveragebitrate unsigned long Receiver Specifies the maximum average receive bitrate of a session in bits per second (bits/s).
cbr boolean Receiver Specifies if the decoder prefers the use of constant bitrate (if true) or variable bitrate (if false).
useinbandfec boolean Receiver/Sender For a receiver, specifies if the decoder has the capability to take advantage of Opus in-band fec (if true) or not (if false). For a sender, specifies if the encoder supports DTX (if true) or not (if false).
usedtx boolean Receiver/Sender For a receiver, specifies if the decoder prefers the use of DTX (if true) or not (if false). For a sender, specifies if the encoder supports DTX (if true) or not (if false).

VP8

The following receiver capability parameters are defined for "vp8", as noted in [[RFC7741]] Section 6.1:

Property Name Values Receiver/Sender Notes
max-fr unsigned long Receiver This parameter indicates the maximum frame rate in frames per second that the decoder is capable of decoding.
max-fs unsigned long long Receiver This parameter indicates the maximum frame size in macroblocks that the decoder is capable of decoding.

H.264

The following capability parameters are defined for "h264", as noted in [[RFC6184]] Section 8.1, and [[!RFC7742]] Section 6.2.

Property Name Values Receiver/Sender Notes
profile-level-id DOMString Receiver/Sender This parameter is encoded as a string representation of 6 upper case hexadecimal digits, representing the profile-level-id parameter described in [[RFC6184]] Section 8.1. It represents the maximum capability of the decoder (for an RTCRtpReceiver) or the encoder (for an RTCRtpSender). It MUST be supported, as noted in [[!RFC7742]] Section 6.2.
packetization-mode unsigned short Receiver/Sender An unsigned short, ranging from 0 to 2, indicating a supported packetization-mode value. As noted in [[!RFC7742]] Section 6.2, support for a value of 1 is mandatory.
max-mbps, max-smbps, max-fs, max-cpb, max-dpb, max-br unsigned long long Receiver As noted in [[!RFC7742]] Section 6.2, these optional parameters allow the implementation to specify that the decoder can support certain features of H.264 at higher rates and values than those signalled with profile-level-id.

RTX

The following capability parameters are defined for "rtx", as noted in [[!RFC4588]] Section 8.6:

Property Name Values Receiver/Sender Notes
apt payloadtype Receiver/Sender As defined in [[!RFC4588]], the associated payload type of the original stream being retransmitted. There will be an "rtx" entry in RTCRtpCapabilities.codecs[] for each media codec that can be retransmitted, each with their own apt parameter. This makes it possible to support "capabilities exchange" signaling as well enabling implementations to indicate which media codecs support retransmission.
rtx-time unsigned long Sender As defined in [[!RFC4588]], the default time in milliseconds (measured from the time a packet was first sent) that the sender keeps an RTP packet in its buffers available for retransmission.

RED

As defined in [[!RFC2198]] Section 5, "red" has no codec-specific capability parameters.

Ulpfec

As noted in [[RFC5109]], "ulpfec" has no codec-specific capability parameters.

Flexfec

The following capability parameters are defined for "flexfec", as noted in [[FLEXFEC]] Section 5.1.1:

Property Name Values Receiver/Sender Notes
repair-window unsigned long long Sender The default time that spans the source packets and the corresponding repair packets, in microseconds.
L unsigned long Sender The default number of columns of the source block that are protected by this FEC block.
D unsigned long Sender The default number of rows of the source block that are protected by this FEC block.
ToP unsigned short Sender The default type of protection for the sender: 0 for 1-D interleaved FEC protection, 1 for 1-D non-interleaved FEC protection, and 2 for 2-D parity FEC protection. The value of 3 is reserved for future use.

RTCRtpParameters Dictionary

RTCRtpParameters contains the RTP stack settings used by both senders and receivers.

dictionary RTCRtpParameters {
             DOMString                                 muxId = "";
    required sequence<RTCRtpCodecParameters>           codecs;
    required sequence<RTCRtpHeaderExtensionParameters> headerExtensions;
    required RTCRtcpParameters                         rtcp;
};

Dictionary RTCRtpParameters Members

muxId of type DOMString, defaulting to ""

The muxId assigned to the RTP stream, if any. In an RTCRtpReceiver or RTCRtpSender, this corresponds to MID RTP header extension defined in [[!BUNDLE]]. This is a stable identifier that permits the track corresponding to an RTP stream to be identified, rather than relying on an SSRC. An SSRC is randomly generated and can change arbitrarily due to conflicts with other SSRCs, whereas the muxId has a value whose meaning can be defined in advance between RTP sender and receiver, assisting in RTP demultiplexing. Since muxId is included in RTCRtpParameters, if it is desired to send simulcast streams with different muxId values for each stream, then multiple RTCRtpSender objects are needed.

codecs of type sequence<RTCRtpCodecParameters>, required

The codecs to send or receive (could include "red" [[RFC2198]], "rtx" [[!RFC4588]] and "cn" [[RFC3389]]). codecs MUST be set for an RTCRtpParameters object to be a valid argument passed to send() or receive().

headerExtensions of type sequence<RTCRtpHeaderExtensionParameters>, required

Configured header extensions. If unset, no header extensions are configured.

rtcp of type RTCRtcpParameters, required

Parameters to configure RTCP. If unset, the default values described in Section 9.6.1 are assumed.

RTCRtpSendParameters Dictionary

RTCRtpSendParameters contains the RTP stack settings used by senders.

dictionary RTCRtpSendParameters : RTCRtpParameters {
             required sequence<RTCRtpEncodingParameters>        encodings;
             RTCDegradationPreference                  degradationPreference = "balanced";
};

Dictionary RTCRtpSendParameters Members

encodings of type sequence<RTCRtpEncodingParameters>

The "encodings" or "layers" to be used for things like simulcast, Scalable Video Coding, RTX, FEC, etc. A sender MAY send fewer layers than what is specified in encodings[], but MUST NOT send more. When unset in a call to send(), the browser behaves as though a single encodings[0] entry was provided, with encodings[0].ssrc set to a browser-determined value, encodings[0].active set to true, encodings[0].codecPayloadType set to codecs[j].payloadType where j is the index of the first codec that is not "cn", "telephone-event", "red", "rtx" or a forward error correction codec ("ulpfec" [[RFC5109]] or "flexfec" [[FLEXFEC]]), and all the other parameters.encodings[0] attributes (e.g. fec, rtx, priority, maxBitrate, resolutionScale, etc.) unset. When unset in a call to receive(), the behavior is described in Section 6.5.

degradationPreference of type RTCDegradationPreference

When bandwidth is constrained and the RTCRtpSender needs to choose between degrading resolution or degrading framerate, degradationPreference indicates which is preferred.

RTCRtpReceiveParameters Dictionary

RTCRtpReceiveParameters contains the RTP stack settings used by receivers.

dictionary RTCRtpReceiveParameters : RTCRtpParameters {
             required sequence<RTCRtpDecodingParameters>        encodings;
};

Dictionary RTCRtpReceiveParameters Members

encodings of type sequence<RTCRtpDecodingParameters>, required

The "encodings" or "layers" to be used for things like simulcast, Scalable Video Coding, RTX, FEC, etc. When unset in a call to receive(), the behavior is described in Section 6.5.

RTCDtxStatus Enum

enum RTCDtxStatus {
         "disabled",
         "enabled"
         };
Enumeration description
disabled

Discontinuous transmission is disabled.

enabled

Discontinuous transmission is enabled if negotiated.

RTCDegradationPreference Enum

RTCDegradationPreference can be used to indicate the desired choice between degrading resolution and degrading framerate when bandwidth is constrained.

enum RTCDegradationPreference {
    "maintain-framerate",
    "maintain-resolution",
    "balanced"
};
Enumeration description
maintain-framerate

Degrade resolution in order to maintain framerate.

maintain-resolution

Degrade framerate in order to maintain resolution.

balanced

Degrade a balance of framerate and resolution.

RTCRtcpParameters Dictionary

RTCRtcpParameters provides information on RTCP settings.

dictionary RTCRtcpParameters {
             unsigned long ssrc;
             DOMString     cname;
             boolean       reducedSize = false;
             boolean       mux = true;
};

Dictionary RTCRtcpParameters Members

ssrc of type unsigned long

The SSRC to be used in the "SSRC of packet sender" field defined in [[!RFC3550]] Section 6.4.2 (Receiver Report) and [[!RFC4585]] Section 6.1 (Feedback Messages), as well as the "SSRC" field defined in [[!RFC3611]] Section 2 (Extended Reports). It can only be set for an RTCRtpReceiver. Other than for debugging, or situations where receive() is called before send() on the same RTCDtlsTransport it is best to leave it unset, in which case ssrc is chosen by the browser, though the chosen value is not reflected in RTCRtcpParameters.ssrc. If the browser chooses the ssrc it may change it in event of a collision, as described in [[!RFC3550]]. Where send(parameters) is called before receive() on the same RTCDtlsTransport, the browser can choose one of the SSRCs allocated to an RTCRtpSender of the same kind. Where receive() is called first, a random SSRC value can be chosen.

cname of type DOMString

The Canonical Name (CNAME) used by RTCP (e.g. in SDES messages). Guidelines for CNAME generation are provided in [[!RTP-USAGE]] Section 4.9 and [[!RFC7022]]. By default, ORTC implementations SHOULD set the CNAME to be the same within all RTCRtcpParameter objects created within the same Javascript sandbox. For backward compatibility with WebRTC 1.0, applications MAY set the CNAME only for an RTCRtpReceiver; if unset, the CNAME is chosen by the browser.

reducedSize of type boolean, defaulting to false

Whether reduced size RTCP [[!RFC5506]] is configured (if true) or compound RTCP as specified in [[!RFC3550]] (if false). The default is false.

mux of type boolean, defaulting to true

Whether RTP and RTCP are multiplexed, as specified in [[!RFC5761]]. The default is true. If set to false, the RTCIceTransport MUST have an associated RTCIceTransport object with a component of rtcp, in which case RTCP will be sent on the associated RTCIceTransport.

RTCRtpCodecParameters Dictionary

RTCRtpCodecParameters provides information on codec settings.

dictionary RTCRtpCodecParameters {
    required DOMString                 name;
             DOMString                 mimeType;
    required payloadtype               payloadType;
             unsigned long             clockRate;
             unsigned long             maxptime;
             unsigned long             ptime;
             unsigned long             channels;
             sequence<RTCRtcpFeedback> rtcpFeedback;
             Dictionary                parameters;
};

Dictionary RTCRtpCodecParameters Members

name of type DOMString, required

The codec MIME subtype. Valid subtypes are listed in [[!IANA-RTP-2]].

mimeType of type DOMString

The codec MIME media type/subtype. Valid media types and subtypes are listed in [[IANA-RTP-2]].

payloadType of type payloadtype, required

The value that goes in the RTP Payload Type Field [[!RFC3550]]. The payloadType MUST always be provided, and MUST be unique.

clockRate of type unsigned long

Codec clock rate expressed in Hertz.

maxptime of type unsigned long

The maximum packetization time set on the RTCRtpSender. Not specified if unset. If ptime is also set, maxptime is ignored.

ptime of type unsigned long

The duration of media represented by a packet in milliseconds for the RTCRtpSender. If unset, the RTCRtpSender may select any value up to maxptime.

channels of type unsigned long

The number of channels supported (e.g. two for stereo). If unset for audio, use the codec default. For video, this can be left unset.

rtcpFeedback of type sequence<RTCRtcpFeedback>

Transport layer and codec-specific feedback messages for this codec.

parameters of type Dictionary

Codec-specific parameters available for signaling.

Codec parameters

The parameters of common codecs are described below.

Opus

The following settings are defined for "opus":

Property Name Values Receiver/Sender Notes
maxplaybackrate unsigned long Sender The maximum output sampling rate of the encoder in Hz.
sprop-maxcapturerate unsigned long Receiver The maximum input sampling rate produced by the sender.
cbr boolean Sender Specifies if the encoder is configured to generate constant bitrate (if true) or variable bitrate (if false).
useinbandfec boolean Sender Specifies if the encoder is configured to generate Opus in-band fec (if true) or not (if false).
usedtx boolean Sender Specifies if the encoder is configured to use DTX (if true) or not (if false).
complexity unsigned long Sender Configures the encoder's computational complexity. The supported range is 0-10 with 10 representing the highest complexity.
signal DOMString Sender Configures the type of signal being encoded. Possible values are "auto", "music" and "voice".
application DOMString Sender Configures the encoder's intended application. Possible values are "voip", "audio" and "lowdelay".
packetlossperc unsigned long Sender Configures the encoder's expected packet loss percentage. Possible values are 0-100.
predictiondisabled boolean Sender Configures whether prediction is disabled, making frames almost complete independent (if true) or not (if false).

VP8

The following settings are defined for "vp8":

Property Name Values Receiver/Sender Notes
max-fr unsigned long Sender This parameter indicates the maximum frame rate in frames per second that the decoder is capable of decoding.
max-fs unsigned long long Sender This parameter indicates the maximum frame size in macroblocks that the decoder is capable of decoding.

H.264

The following settings are defined for "h264":

Property Name Values Receiver/Sender Notes
profile-level-id DOMString Sender This parameter, encoded as a string of 6 upper case hexadecimal digits, indicates the configuration of the stream to be sent, as described in [[RFC6184]] Section 8.2.2. It MUST be supported, as noted in [[!RFC7742]] Section 6.2.
packetization-mode unsigned short Sender An unsigned short ranging from 0 to 2, indicating the packetization-mode value to be used by the sender. This setting MUST be supported, as noted in [[!RFC7742]] Section 6.2. A value of 1 is assumed if packetization-mode is not set.
max-mbps, max-smbps, max-fs, max-cpb, max-dpb, max-br unsigned long long Sender These optional settings allow the sender to restrict its output to the maximum values indicated by the receiver.

RTX

The following settings are defined for "rtx", as noted in [[!RFC4588]] Section 8.6:

Property Name Values Receiver/Sender Notes
apt payloadtype Receiver/Sender As defined in [[!RFC4588]], the associated payload type of the original stream being retransmitted. There will be an "rtx" entry in RTCRtpParameters.codecs[] for each media codec that can be retransmitted, each with their own apt parameter.
rtx-time unsigned long Receiver As defined in [[!RFC4588]], the time in milliseconds (measured from the time a packet was first sent) that the sender keeps an RTP packet in its buffers available for retransmission.

RED

The following setting is defined for "red", as noted in [[!RFC2198]] Section 5:

Property Name Values Receiver/Sender Notes
payloadTypes sequence<payloadtype> Sender/Receiver A sequence of payload types to be encapsulated in RED, each of which MUST be unique. If payloadTypes is unset, this means that any codec other than "red" or "rtx" can be encapsulsated in RED.

Ulpfec

As noted in [[RFC5109]], "ulpfec" has no codec-specific settings.

Flexfec

The following settings are defined for "flexfec", as noted in [[FLEXFEC]] Section 5.1.1:

Property Name Values Receiver/Sender Notes
repair-window unsigned long long Receiver The time that spans the source packets and the corresponding repair packets, in microseconds.
L unsigned long Sender The number of columns of the source block that are protected by this FEC block.
D unsigned long Sender The number of rows of the source block that are protected by this FEC block.
ToP unsigned short Sender The type of protection applied by the sender: 0 for 1-D interleaved FEC protection, 1 for 1-D non-interleaved FEC protection, and 2 for 2-D parity FEC protection. The value of 3 is reserved for future use.

RTCRtpCodingParameters Dictionary

RTCRtpCodingParameters provides information relating to both encoding and decoding.

dictionary RTCRtpCodingParameters {
             unsigned long       ssrc;
             payloadtype         codecPayloadType;
             RTCRtpFecParameters fec;
             RTCRtpRtxParameters rtx;
             boolean             active = true;
             DOMString           rid;
             DOMString           encodingId;
             sequence<DOMString> dependencyEncodingIds;
};

Dictionary RTCRtpCodingParameters Members

ssrc of type unsigned long

The SSRC for this layering/encoding. Multiple RTCRtpCodingParameters dictionaries can share the same ssrc value (useful, for example, to indicate that different RTX payload types associated to different codecs are carried over the same stream). If ssrc is unset in the parameters argument to receive(), the next unhandled SSRC will match, and an RTCRtpUnhandledEvent will not be fired. If ssrc is unset in the parameters argument to send(), the browser will choose, and the chosen value is not reflected in ssrc. If the browser chooses the ssrc, it may change it due to a collision without firing an RTCSsrcConflictEvent. If ssrc is set in the parameters argument to send() and an SSRC conflict is detected within the RTP session, then an RTCSsrcConflictEvent is fired (see Section 5.4).

codecPayloadType of type payloadtype

For per-encoding codec specifications, give the codec payload type here. If unset, the browser will choose the first codec in parameters.codecs[] of the appropriate kind.

fec of type RTCRtpFecParameters

Specifies the FEC mechanism if set.

rtx of type RTCRtpRtxParameters

Specifies the RTX [[!RFC4588]] parameters if set.

active of type boolean, defaulting to true

For an RTCRtpSender, indicates whether this encoding is actively being sent. Setting it to false causes this encoding to no longer be sent. Setting it to true causes this encoding to be sent. For an RTCRtpReceiver, indicates that this encoding is being decoded. Setting it to false causes this encoding to no longer be decoded. Setting it to true causes this encoding to be decoded. Setting active to false is different than omitting the encoding, since it can keep resources available to re-activate more quickly than re-adding the encoding. As noted in [[RFC3264]] Section 5.1, RTCP is still sent, regardless of the value of the active attribute.

rid of type DOMString

If set, this RTP encoding will be sent or received with RID header extension as defined by [[!RID]].

encodingId of type DOMString

An identifier for the encoding object. This identifier should be unique within the scope of the localized sequence of RTCRtpCodingParameters for any given RTCRtpParameters object. Values MUST be composed only of alphanumeric characters (a-z, A-Z, 0-9) up to a maximum of 16 characters. For a codec (such as VP8 or VP9) using SRST transport which requires a compliant decoder to be able to to decode anything that an encoder can send, it is not required that the encodingId and dependencyEncodingIds be set in order to enable a receiver to decode scalable video coding.

dependencyEncodingIds of type sequence<DOMString>

The encodingIds on which this layer depends. Within this specification encodingIds are permitted only within the same RTCRtpCodingParameters sequence. In the future if MST were to be supported, then if searching within an encodings[] sequence did not produce a match, then a global search would be carried out. In order to send scalable video coding (SVC), both the encodingId and dependencyEncodingIds are required.

RTCRtpEncodingParameters Dictionary

RTCRtpEncodingParameters provides information relating to an encoding. Note that all encoding parameters (such as maxBitrate, maxFramerate and resolutionScale) are applied prior to codec-specific constraints.

dictionary RTCRtpEncodingParameters : RTCRtpCodingParameters {
             RTCDtxStatus        dtx;
             RTCPriorityType     priority = "low";
             unsigned long       maxBitrate;
             double              resolutionScale;
             double              framerateScale;
             double              maxFramerate;
};

Dictionary RTCRtpEncodingParameters Members

dtx of type RTCDtxStatus

This member is typically only used if the sender's kind is audio. Indicates whether discontinuous transmission will be used. Setting it to disabled causes discontinuous transmission to be turned off. Setting it to enabled causes discontinuous transmission to be turned on only when enabling enabling codec-specific DTX functionality or the CN codec.

priority of type RTCPriorityType, defaulting to low

Indicates the priority of this encoding. It is specified in [[RTCWEB-TRANSPORT]], Section 4. For scalable video coding, this parameter is only relevant for the base layer.

maxBitrate of type unsigned long

Ramp up resolution/quality/framerate until this bitrate, if set; if unset, there is no maximum bitrate. maxBitrate is computed the same way as the Transport Independent Application Specific Maximum (TIAS) bandwidth defined in [[RFC3890]] Section 6.2.2, which is the maximum bandwidth needed without counting IP or other transport layers like TCP or UDP. Summed when using dependent layers. This attribute is ignored in scalable video coding.

resolutionScale of type double

If sender.track.kind is "video", the encoder will scale down the resolution of sender.track in each dimension before sending. For example, if the value is 2.0, the video will be scaled down by a factor of at least 2 in each dimension, resulting in sending a video no greater than one quarter size. If the value is 1.0 or unset, the sender will attempt to encode with the resolution of track. For scalable video coding, resolutionScale refers to the aggregate scale down of this layer when combined with all dependent layers.

If resolutionScale is less than 1.0, reject the promise with RangeError when send() or receive() is called. If sender.track.kind is "audio", the value is ignored.

framerateScale of type double

Inverse of the input framerate fraction to be encoded. Example: 1.0 = full framerate, 2.0 = one half of the full framerate. For scalable video coding, framerateScale refers to the inverse of the aggregate fraction of input framerate achieved by this layer when combined with all dependent layers.

maxFramerate of type double

The maximum framerate to use for this encoding, in frames per second. This attribute is not used for scalable video coding. If framerateScale is set, then maxFramerate is ignored.

RTCRtpDecodingParameters Dictionary

RTCRtpDecodingParameters provides information used in decoding.

dictionary RTCRtpDecodingParameters: RTCRtpCodingParameters {
};

Dictionary RTCRtpDecodingParameters Members

Summary Table

Usage of the attributes is defined in the table below:

Attribute Type Receiver/Sender
ssrc unsigned long Receiver/Sender
codecPayloadType payloadtype Receiver/Sender
fec RTCRtpFecParameters Receiver/Sender
rtx RTCRtpRtxParameters Receiver/Sender
dtx RTCDtxStatus Sender
priority RTCPriorityType Sender
maxBitrate unsigned long Sender
resolutionScale double Sender
framerateScale double Sender
maxFramerate double Sender
active boolean Receiver/Sender
rid DOMString Receiver/Sender
encodingId DOMString Receiver/Sender
dependencyEncodingIds sequence<DOMString> Receiver/Sender

Examples

Basic Example

          // Send a thumbnail along with regular size, prioritizing the thumbnail (ssrc: 2)
var encodings = [{ ssrc: 1, priority: 1.0 }];
var encodings = [{ ssrc: 2, priority: 10.0 }];

// Sign Language (prefer  framerate)
var encodings = [{ degradationPreference: "maintain-framerate" }];

// Screencast (prefer resolution)
var encodings = [{ degradationPreference: "maintain-resolution" }];

// Remote Desktop (High framerate, must not downscale)
var encodings = [{ degradationPreference: "maintain-framerate" }];

// Audio more important than video
var audioEncodings = [{ priority: 10.0 }];
var videoEncodings = [{ priority: 0.1 }];

// Video more important than audio
var audioEncodings = [{ priority: 0.1 }];
var videoEncodings = [{ priority: 10.0 }];

// Crank up the quality
var encodings = [{ maxBitrate: 10000000 }];

// Keep the bandwidth low
var encodings = [{ maxBitrate: 100000 }];
                    

Temporal Scalability

// Example of 3-layer temporal scalability encoding with base framerate
// one quarter of the input, and ehancement layers providing one half
// and all of the input framerate
var encodings = [
  {encodingId: 'T0', framerateScale: 4.0},
  {encodingId: 'T1', framerateScale: 2.0, dependencyEncodingIds: ['T0']},
  {encodingId: 'T2', dependencyEncodingIds: ['T0', 'T1']} 
];

// Example of 3-layer temporal scalability with all but the base layer disabled
var encodings = [
  {encodingId: 'T0', framerateScale: 4.0, active: true}, 
  {encodingId: 'T1', framerateScale: 2.0, dependencyEncodingIds: ['T0'], active: false},
  {encodingId: 'T2', dependencyEncodingIds: ['T0', 'T1'], active: false}
];

Below is a representation of a 3-layer temporal scalability encoding. In the diagram, I0 is the base layer I-frame, and P0 represents base-layer P-frames. P1 represents the first temporal enhancement layer, and P2 represents the second temporal enhancement layer.

3-layer temporal scalability encoding
3-layer temporal scalability encoding

Spatial Simulcast

// Example of 3-layer spatial simulcast with all but the lowest resolution layer disabled
var encodings = [
  {rid: 'f', active: false},
  {rid: 'h', active: false, resolutionScale: 2.0},
  {rid: 'q', active: true, resolutionScale: 4.0}
];

// Example of 3-layer framerate simulcast with the middle layer disabled
var encodings = [
  {rid: 'f', active: true, maxFramerate: 60},
  {rid: 'h', active: false, maxFramerate: 30},
  {rid: 'q', active: true, maxFramerate: 15}
];

// Example of 2-layer spatial simulcast combined with 2-layer temporal scalability
// Low resolution base layer has half the input framerate, half the input resolution
// High resolution base layer has half the input framerate, full resolution
// Temporal enhancement layers have full input framerate
var encodings = [
  {rid: 'H', encodingId: 'H0', resolutionScale: 2.0, framerateScale: 2.0},
  {rid: 'F', encodingId: 'F0', framerateScale: 2.0}, 
  {rid: 'H', encodingId: 'H1', resolutionScale: 2.0, dependencyEncodingIds: ['H0']},
  {rid: 'F', encodingId: 'F1', dependencyEncodingIds: ['F0']}
];
                    

Below is a representation of 2-layer temporal scalability combined with 2-layer spatial simulcast. Solid arrows represent temporal prediction. In the diagram, I0 is the base-layer I-frame, and P0 represents base-layer P-frames. EI0 is an enhanced resolution base-layer I-frame, and EP0 represents P-frames within the enhanced resolution base layer. P1 represents the first temporal enhancement layer, and EP1 represents a temporal enhancement to the enhanced resolution simulcast base-layer.

2-layer spatial simulcast and temporal scalability encoding
2-layer spatial simulcast and temporal scalability encoding

Spatial Scalability

// Example of 3-layer spatial scalability encoding with the base layer having
// one quarter input resolution and enhancement layers yielding one half and
// full resolution
var encodings = [
  {encodingId: 'q', resolutionScale: 4.0},
  {encodingId: 'h', resolutionScale: 2.0, dependencyEncodingIds: ['q']},
  {encodingId: 'f', dependencyEncodingIds: [['q', 'h']}

// Example of 3-layer spatial scalability with all but the base layer disabled
var encodings = [
  {encodingId: 'q', resolutionScale: 4.0, active: true},
  {encodingId: 'h', resolutionScale: 2.0, active: false},
  {encodingId: 'f', active: false}
]

// Example of 2-layer spatial scalability combined with 2-layer temporal scalability
// Base layer has one half input framerate and half resolution
// Temporal enhancement layer has full input framerate, half resolution
// Spatial enhancement to the base layer has half input framerate, full resolution
// Temporal enhancement to the spatial enhancement layer has full framerate and resolution
var encodings = [
  {encodingId: 'H0', resolutionScale: 2.0, framerateScale: 2.0}, 
  {encodingId: 'H1', resolutionScale: 2.0, dependencyEncodingIds: ['H0']},
  {encodingId: 'F0', framerateScale: 2.0, dependencyEncodingIds: ['H0']},
  {encodingId: 'F1', dependencyEnodingIds: ['F0', 'H1']}
];
                    

Below is a representation of 2-layer temporal scalability combined with 2-layer spatial scalability. Solid arrows represent temporal prediction and dashed arrows represent inter-layer prediction. In the diagram, I0 is the base-layer I-frame, and EI0 is an intra spatial enhancement. P0 represents base-layer P-frames, and P1 represents the first temporal enhancement layer. EP0 represents a resolution enhancement to the base-layer P frames, and EP1 represents a resolution enhancement to the second temporal layer P-frames.

2-layer spatial and temporal scalability encoding
2-layer spatial and temporal scalability encoding

RTCPriorityType Enum

RTCPriorityType can be used to indicate the relative priority of various flows. This allows applications to indicate to the browser whether a particular media flow is high, medium, low or of very low importance to the application. WebRTC uses the priority and Quality of Service (QoS) framework described in [[RTCWEB-TRANSPORT]] and [[!TSVWG-RTCWEB-QOS]] to provide priority and DSCP marketing for packets that will help provide QoS in some networking environments. Applications that use this API should be aware that often better overall user experience is obtained by lowering the priority of things that are not as important rather than raising the the priority of the things that are.

The priority API is marked as a feature at risk, since there is no clear commitment from ORTC implementers.

enum RTCPriorityType {
    "very-low",
    "low",
    "medium",
    "high"
};
Enumeration description
very-low

See [[RTCWEB-TRANSPORT]], Section 4.

low

See [[RTCWEB-TRANSPORT]], Section 4.

medium

See [[RTCWEB-TRANSPORT]], Section 4.

high

See [[RTCWEB-TRANSPORT]], Section 4.

RTX/FEC

RTCRtpFecParameters Dictionary

The RTCRtpFecParameters dictionary contains information relating to Forward Error Correction (FEC) settings.

dictionary RTCRtpFecParameters {
             unsigned long ssrc;
             required DOMString     mechanism;
};

Dictionary RTCRtpFecParameters Members

ssrc of type unsigned long

The SSRC to use for FEC. If unset in an RTCRtpSender object, the browser will choose.

mechanism of type DOMString, required

The Forward Error Correction (FEC) mechanism to use: "red", "red+ulpfec" or "flexfec".

RTCRtpRtxParameters Dictionary

The RTCRtpRtxParameters dictionary contains information relating to retransmission (RTX) settings.

dictionary RTCRtpRtxParameters {
             unsigned long ssrc;
};

Dictionary RTCRtpRtxParameters Members

ssrc of type unsigned long

The SSRC to use for retransmission, as specified in [[!RFC4588]]. If unset when passed to RTCRtpSender.send(), the browser will choose.

Example

Below is an example of how to configure an RTCRtpReceiver to receive video encoded in VP8 or VP9, along with retransmission and forward error correction. In the example, forward error correction is encapsulated in RED, and it is possible to retransmit RED packets. The configuration enables VP8 or VP9 to be received either with or without RED encapsulation. The configuration of an RTCRtpSender would be more prescriptive, at a given time indicating a single encoding: that VP8 or VP9 video should be sent encapsulated within RED or without RED encapsulation.

// Example of RTX and RED + ulpfec
//
// SDP from createOffer() in WebRTC 1.0
//
//   m=video 62125 UDP/TLS/RTP/SAVPF 100 101 116 117 96
//   a=sendonly
//   a=rtpmap:100 VP8/90000
//   a=rtpmap:101 VP9/90000
//   a=rtpmap:116 red/90000
//   a=rtpmap:117 ulpfec/90000
//   a=rtpmap:96 rtx/90000
//   a=fmtp:96 apt=100
//   a=rtpmap:97 rtx/90000
//   a=fmtp:97 apt=101
//   a=rtpmap:98 rtx/90000
//   a=fmtp:98 apt=116
//   a=ssrc-group:FID 2224031971 3254585230
//   a=ssrc:2224031971 cname:oC/i06PA+Lda+t1P
//   a=ssrc:3254585230 cname:oC/i06PA+Lda+t1P
//
//   Define RTCRtpCodecParameters
//
var codecs = [
//   Define VP9 codec parameters
  {
    name: "vp9",
    payloadType: 101,
    clockRate: 90000
  },
//   Define VP8 codec parameters
  {
    name: "vp8",
    payloadType: 100,
    clockRate: 90000
  },
//   Define retransmission of VP9
  {
    name: "rtx",
    payloadType: 97,
    clockrate: 90000,
    parameters: {
      apt: 101
    }
  },
//   Define retransmission of VP8
  {
    name: "rtx",
    payloadType: 96,
    clockrate: 90000,
    parameters: {
      apt: 100
    }
  },
//   Define RED codec parameters
  {
    name: "red",
    payloadType: 116,
    clockRate: 90000,
    parameters: {
      payloadTypes: []
    }
  },
//   Define ulpfec codec parameters
  {
    name: "ulpfec",
    payloadType: 117,
    clockRate: 90000
  },
//   Define RTX codec parameters
  {
    name: "rtx",
    payloadType: 98,
    clockrate: 90000,
    parameters: {
      apt: 116
    }
  }
];
//
//   Define rtx parameters
var rtxParams = {
  ssrc: 3254585230
};
//   Define FEC parameters for "red+ulpfec"
var redulpfec = {
  ssrc: 3254585230,
  mechanism: "red+ulpfec"
};
//   Define RTCRtpEncodingParameters
//
var encodings = [
//   Define VP8 encoding parameters (without RED)
  {
    ssrc: 2224031971,
    codecPayloadType: 100,
    rtx: rtxParams
  },
//   Define VP8 encoding parameters with RED
  {
    ssrc:  2224031971,
    codecPayloadType: 100,
    fec: redulpfec,
    rtx: rtxParams
  },
//   Define VP9 encoding parameters (without RED)
  {
    ssrc:  2224031971,
    codecPayloadType: 101,
    rtx: rtxParams
  },
//   Define VP9 encoding parameters with RED
  {
    ssrc:  2224031971,
    codecPayloadType: 101,
    fec: redulplfec,
    rtx: rtxParams
  }
];
                    

RTP header extensions

RTCRtpHeaderExtension Dictionary

The RTCRtpHeaderExtension dictionary provides information relating to supported header extensions.

dictionary RTCRtpHeaderExtension {
             required DOMString      kind;
             required DOMString      uri;
             required unsigned short preferredId;
             boolean        preferredEncrypt = false;
};

Dictionary RTCRtpHeaderExtension Members

kind of type DOMString, required

The media supported by the header extension: "audio" for an audio codec, "video" for a video codec, etc.

uri of type DOMString, required

The URI of the RTP header extension, as defined in [[!RFC5285]].

preferredId of type unsigned short, required

The preferred ID value that goes in the packet.

preferredEncrypt of type boolean, defaulting to false

If true, it is preferred that the value in the header be encrypted as per [[!RFC6904]]. Default is to prefer unencrypted.

RTCRtpHeaderExtensionParameters Dictionary

The RTCRtpHeaderExtensionParameters dictionary enables a header extension to be configured for use within an RTCRtpSender or RTCRtpReceiver. In order to provide the equivalent of the "direction" parameter defined in [[!RFC5285]] Section 5, an application can do the following:

  1. sendonly: Include the header extension only when calling send.
  2. recvonly: Include the header extension only when calling receive.
  3. sendrecv: Include the header extension when calling send and receive.
  4. inactive: Don't include the header extension when calling either send or receive.
dictionary RTCRtpHeaderExtensionParameters {
    required DOMString      uri;
    required unsigned short id;
             boolean        encrypt = false;
             Dictionary     parameters;
};

Dictionary RTCRtpHeaderExtensionParameters Members

uri of type DOMString, required

The URI of the RTP header extension, as defined in [[!RFC5285]].

id of type unsigned short, required

The value that goes in the packet.

encrypt of type boolean, defaulting to false

If true, the value in the header is encrypted as per [[!RFC6904]]. Default is unencrypted.

parameters of type Dictionary

Configuration parameters for the header extension. An example is the "vad" extension attribute in the client-to-mixer header extension, described in [[!RFC6464]] Section 4.

At the time of publication there were no implementations of the parameters dictionary. Most header extensions do not require configuration parameters, and the ORTC Lib implementation assumes that the "V" bit from [[!RFC6464]] is always enabled so that a vad parameter is unnecessary.

Registrations

Registered RTP header extensions are listed in [[!IANA-RTP-10]]. Header extensions mentioned in [[!RTP-USAGE]] and [[!RID]] include:

Header Extension Reference Attributes Notes
Transmission Time Offset [[RFC5450]] None This extension indicates the transmission time offset.
Rapid Synchronization [[RFC6051]] None This extension enables carriage of an NTP-format timestamp, as defined in [[!RFC6051]] Section 3.3.
Client-to-Mixer Audio Level [[!RFC6464]] boolean vad This extension indicates the audio level of the audio sample carried in an RTP packet. For an RTCRtpSender, the vad attribute indicates whether the V bit is in use (true) or not (false). For an RTCRtpReceiver, the vad attribute indicates whether the V bit is provided to the application (true) in RTCRtpContributingSource.voiceActivityFlag or is unset (false).
Mixer-to-Client Audio Level [[RFC6465]] None This extension indicates the audio level of individual conference participants.
Absolute Send Time [[ABS-SEND-TIME]] None This extension indicates the absolute send time.
CVO [[!TS26.114]] Section 7.4.5 None The Coordination of Video Orientation (CVO) extension indicates whether the receiver needs to change the orientation in which it renders the stream.
MID [[!BUNDLE]] None This extension defines a track identifier which can be used to identify the track corresponding to an RTP stream.
RID [[!RID]] None This extension defines an identifier used to carry the rid.

RTCDtmfSender Interface

Overview

An RTCDtmfSender instance allows sending DTMF tones to/from the remote peer, as per [[!RFC4733]].

Operation

An RTCDtmfSender object is constructed from an RTCRtpSender sender.

Interface Definition

[ Constructor (RTCRtpSender sender), Exposed=Window]
interface RTCDtmfSender {
    readonly        attribute boolean      canInsertDTMF;
    readonly        attribute RTCRtpSender sender;
    readonly        attribute DOMString    toneBuffer;
    undefined insertDTMF (DOMString tones, optional unsigned long duration = 100, optional unsigned long interToneGap = 70);
                    attribute EventHandler ontonechange;
};

Constructors

If sender.track.kind is not "audio", throw an InvalidParameters.

RTCDtmfSender
Parameter Type Nullable Optional Description
sender RTCRtpSender

Attributes

canInsertDTMF of type boolean, readonly

Whether the RTCDtmfSender is capable of sending DTMF.

sender of type RTCRtpSender, readonly

The RTCRtpSender instance

toneBuffer of type DOMString, readonly

The toneBuffer attribute returns a list of the tones remaining to be played out. For the syntax, content, and interpretation of this list, see insertDTMF.

ontonechange of type EventHandler

The ontonechange event handler uses the RTCDTMFToneChangeEvent interface to return the character for each tone as it is played out. The event type of the ontonechange event handler is tonechange.

Methods

insertDTMF

The insertDTMF() method is used to send DTMF tones. The tones parameter is treated as a series of characters. The characters 0 through 9, A through D, #, and * generate the associated DTMF tones. The characters a to d MUST be normalized to uppercase on entry and are equivalent to A to D. As noted in [[!RFC7874]] Section 3, support for the characters 0 through 9, A through D, #, and * are required. The character ',' MUST be supported, and indicates a delay of 2 seconds before processing the next character in the tones parameter. All other characters (and only those other characters) MUST be considered unrecognized.

The duration parameter indicates the duration in ms to use for each character passed in the tones parameters. The duration cannot be more than 6000 ms or less than 40 ms. The default duration is 100 ms for each tone.

The interToneGap parameter indicates the gap between tones in ms. The user agent clamps it to at least 30 ms and at most 6000 ms. The default value is 70 ms.

Implementations MAY increase the duration and interToneGap times to cause the times that DTMF start and stop to align with the boundaries of RTP packets but it MUST not increase either of them by more than the duration of a single RTP audio packet.

When the insertDTMF() method is invoked, the user agent MUST run the following steps:

  1. let sender be the RTCRtpSender used to send DTMF.
  2. If sender's [[\SenderStopped]] slot is true, throw an InvalidStateError and abort these steps.
  3. If sender.send has not been called, throw an InvalidStateError and abort these steps.
  4. Let parameters be the argument provided to sender.send the last time it was called.
  5. If parameters.codecs[j] is not equal to "telephone-event" for any value of j, throw an InvalidStateError and abort these steps.
  6. Let tones be the method's first argument.
  7. If tones contains any unrecognized characters, throw an InvalidCharacterError and abort these steps.
  8. Set the object's toneBuffer attribute to tones.
  9. If the value of the duration parameter is less than 40, set it to 40. If, on the other hand, the value is greater than 6000, set it to 6000.
  10. If the value of the interToneGap parameter is less than 30, set it to 30. If, on the other hand, the value is greater than 6000, set it to 6000.
  11. If toneBuffer is an empty string, abort these steps.
  12. If a Playout task is scheduled to be run, abort these steps; otherwise queue a task that runs the following steps (Playout task):
    1. If sender's [[\SenderStopped]] slot is true, abort these steps.
    2. If toneBuffer is an empty string, fire an event named tonechange with an empty string at the RTCDtmfSender object and abort these steps.
    3. Remove the first character from toneBuffer and let that character be tone.
    4. If tone is "," delay sending tones for 2000 ms on the associated RTP media stream, and queue a task to be executed in 2000 ms from now that runs the steps labelled Playout task.
    5. If tone is not "," start playout of tone for duration ms on the associated RTP media stream, using the appropriate codec, then queue a task to be executed in duration + interToneGap ms from now that runs the steps labelled Playout task.
    6. Fire an event named tonechange with a string consisting of tone at the RTCDtmfSender object.

Since insertDTMF replaces the tone buffer, in order to add to the DTMF tones being played, it is necessary to call insertDTMF with a string containing both the remaining tones (stored in toneBuffer) and the new tones appended together.

Calling insertDTMF with an empty tones parameter can be used to cancel all tones queued to play after the currently playing tone.

Parameter Type Nullable Optional Description
tones DOMString
duration unsigned long = 100
interToneGap unsigned long = 70
Return type: undefined

RTCDTMFToneChangeEvent

The tonechange event uses the RTCDTMFToneChangeEvent interface.

Firing a tonechange event named e with a DOMString tone means that an event with the name e, which does not bubble (except where otherwise stated) and is not cancelable (except where otherwise stated), and which uses the RTCDTMFToneChangeEvent interface with the tone attribute set to tone, MUST be created and dispatched at the given target.

        [ Constructor (DOMString type, RTCDTMFToneChangeEventInit eventInitDict), Exposed=Window]
interface RTCDTMFToneChangeEvent : Event {
    readonly        attribute DOMString tone;
};

Constructors

RTCDTMFToneChangeEvent
Parameter Type Nullable Optional Description
type DOMString
eventInitDict RTCDTMFToneChangeEventInit

Attributes

tone of type DOMString, readonly

The tone attribute contains the character for the tone (including ",") that has just begun playout (see insertDTMF ). If the value is the empty string, it indicates that the toneBuffer is an empty string and that the previous tones have completed playback.

The RTCDTMFToneChangeEventInit dictionary provides information on the DTMF tone causing a tonechange event.

dictionary RTCDTMFToneChangeEventInit : EventInit {
             required DOMString tone;
};

Dictionary RTCDTMFToneChangeEventInit Members

tone of type DOMString, defaulting to ""

The tone attribute contains the character for the tone (including ",") that has just begun playout (see insertDTMF ). If the value is the empty string, it indicates that the toneBuffer is an empty string and that the previous tones have completed playback.

RTCDTMFSender Interface

Overview

An RTCDTMFSender instance allows sending DTMF tones to/from the remote peer in a manner identical to that of the RTCDtmfSender interface.

Operation

An RTCDTMFSender object is constructed from an RTCRtpSender sender, as with RTCDtmfSender. If sender.track.kind is not "audio", throw an InvalidParameters.

Interface Definition

The RTCDTMFSender interface is identical to the RTCDtmfSender interface aside from spelling.

Examples

Examples assume that sendObject is an RTCRtpSender object.

Sending the DTMF signal "1234" with 500 ms duration per tone:

var sender = new RTCDtmfSender(sendObject);
if (sender.canInsertDTMF) {
    var duration = 500;
    sender.insertDTMF("1234", duration);
} else 
    trace("DTMF function not available");

Send the DTMF signal "123" and abort after sending "2".

var sender = new RTCDtmfSender(sendObject);
if (sender.canInsertDTMF) {
  sender.ontonechange = function (e) {
      if (e.tone == "2")
          // empty the buffer to not play any tone after "2"
          sender.insertDTMF("");
  };
  sender.insertDTMF("123");
} else
    trace("DTMF function not available");

Send the DTMF signal "1234", and light up the active key using lightKey(key) while the tone is playing (assuming that lightKey("") will darken all the keys):

var sender = new RTCDtmfSender(sendObject);
if (sender.canInsertDTMF) {
  var duration = 500;
  sender.ontonechange = function (e) {
      if (!e.tone)
          return;
      // light up the key when playout starts
      lightKey(e.tone);
      // turn off the light after tone duration
      setTimeout(lightKey, duration, "");
  };
  sender.insertDTMF(sender.toneBuffer + "1234");
} else
    trace("DTMF function not available");

It is always safe to append to the tone buffer. This example appends before any tone playout has started as well as during playout.

var sender = new RTCDtmfSender(sendObject);
if (sender.canInsertDTMF) {
  sender.insertDTMF("123");
  // append more tones to the tone buffer before playout has begun
  sender.insertDTMF(sender.toneBuffer + "456");

  sender.ontonechange = function (e) {
      if (e.tone == "1")
          // append more tones when playout has begun
          sender.insertDTMF(sender.toneBuffer + "789");
  };
} else
    trace("DTMF function not available");    

Send a 1-second "1" tone followed by a 2-second "2" tone:

var sender = new RTCDtmfSender(sendObject);
if (sender.canInsertDTMF) {
  sender.ontonechange = function (e) {
      if (e.tone == "1")
          sender.insertDTMF(sender.toneBuffer + "2", 2000);
  };
  sender.insertDTMF(sender.toneBuffer + "1", 1000);
} else
    trace("DTMF function not available");

RTCDataChannel Interface

Overview

An RTCDataChannel object allows sending data messages to/from the remote peer.

Operation

An RTCDataChannel object is constructed from a RTCDataTransport object (providing the transport for the data channel) and an RTCDataChannelParameters object. An RTCDataChannel object can be garbage-collected once readyState is closed and it is no longer referenced.

Interface Definition

The RTCDataChannel interface represents a bi-directional data channel between two peers. Each RTCDataChannel has an associated underlying data transport that is used to transport actual data to the other peer. The transport properties of the underlying data transport, such as in order delivery settings and reliability mode, are configured by the peer as the channel is created. The properties of a channel cannot change after the channel has been created.

An RTCDataChannel can be configured to operate in different reliability modes. A reliable channel ensures that the data is delivered at the other peer through retransmissions. An unreliable channel is configured to either limit the number of retransmissions (maxRetransmits) or set a time during which transmissions (including retransmissions) are allowed (maxPacketLifeTime). These properties can not be used simultaneously and an attempt to do so will result in an error. Not setting any of these properties results in a reliable channel.

There are two ways to establish a connection with RTCDataChannel. The first way is to construct an RTCDataChannel at one of the peers with the RTCDataChannelParameters.negotiated attribute unset or set to its default value false. This will announce the new channel in-band and trigger an ondatachannel event with the corresponding RTCDataChannel object at the other peer.

The second way is to let the application negotiate the RTCDataChannel. To do this, create an RTCDataChannel object with the RTCDataChannelParameters negotiated dictionary member set to true, and signal out-of-band (e.g. via a web server) to the other side that it should create a corresponding RTCDataChannel with the RTCDataChannelParameters negotiated member set to true and the same id. This will connect the two separately created RTCDataChannel objects. The second way makes it possible to create channels with asymmetric properties and to create channels in a declarative way by specifying matching ids.

        [ Constructor (RTCDataTransport transport, RTCDataChannelParameters parameters), Exposed=Window]
interface RTCDataChannel : EventTarget {
    readonly        attribute RTCDataTransport    transport;
    readonly        attribute RTCDataChannelState readyState;
    readonly        attribute unsigned long       bufferedAmount;
                    attribute unsigned long       bufferedAmountLowThreshold;
                    attribute DOMString           binaryType;
    RTCDataChannelParameters getParameters ();
    undefined                close ();
                    attribute EventHandler        onopen;
                    attribute EventHandler        onbufferedamountlow;
                    attribute EventHandler        onerror;
                    attribute EventHandler        onclose;
                    attribute EventHandler        onmessage;
    undefined                send (USVString data);
    undefined                send (Blob data);
    undefined                send (ArrayBuffer data);
    undefined                send (ArrayBufferView data);
};

Constructors

When the constructor is invoked, the following steps MUST be run:

  1. Let transport be the first argument.
  2. If transport's state attribute is closed, throw an InvalidStateError.

  3. Let parameters be the second argument.
  4. Let channel be a newly created RTCDataChannel object.

  5. Let channel have a [[\DataChannelLabel]] internal slot initialized to parameters' label member.

  6. If [[\DataChannelLabel]] is longer than 65535 bytes, throw a TypeError.
  7. Let channel have a [[\MaxPacketLifeTime]] internal slot initialized to parameters' maxPacketLifeTime member, if present, otherwise null.

  8. Let channel have a [[\ReadyState]] internal slot initialized to connecting.

  9. Let channel have a [[\MaxRetransmits]] internal slot initialized to parameters' maxRetransmits member, if present, otherwise null.

  10. Let channel have an [[\Ordered]] internal slot initialized to parameters' ordered member.

  11. Let channel have a [[\DataChannelProtocol]] internal slot initialized to parameters' protocol member.

  12. If [[\DataChannelProtocol]] is longer than 65535 bytes long, throw a TypeError.

  13. Let channel have a [[\Negotiated]] internal slot initialized to parameters' negotiated member.

  14. Let channel have an [[\DataChannelId]] internal slot initialized to parameters' id member, if it is present, otherwise null.

    Application developers providing an id member and negotiating in-band should have IDs selected based on the DTLS role, as specified in [[!DATA-PROT]].
  15. If [[\Negotiated]] is true and [[\DataChannelId]] is null, throw a TypeError.

  16. If channel's [[\DataChannelId]] slot is equal to 65535, which is greater than the maximum allowed ID of 65534 but still qualifies as an unsigned short, throw a TypeError.

  17. Let channel have an [[\DataChannelPriority]] internal slot initialized to parameters' priority member.

  18. If both channel's [[\MaxPacketLifeTime]] and [[\MaxRetransmits]] internal slots are set (not null), throw a TypeError.

  19. If a setting, either [[\MaxPacketLifeTime]] or [[\MaxRetransmits]] has been set to indicate unreliable mode, and that value exceeds the maximum value supported by the user agent, the value MUST be set to the user agents maximum value.

  20. If channel's [[\DataChannelId]] slot is null and the DTLS role of the SCTP transport has already been negotiated, then initialize channel's [[\DataChannelId]] internal slot to a value generated by the user agent, according to [[!DATA-PROT]], and skip to the next step. If no available ID could be generated, or if the value of channel's [[\DataChannelId]] slot is being used by an existing RTCDataChannel, throw an OperationError exception.

    If the channel's [[\DataChannelId]] internal slot is null after this step, it will be populated once the DTLS role is determined.
  21. Create channel's associated underlying data transport and configure it according to the relevant properties of channel.

RTCDataChannel
Parameter Type Nullable Optional Description
transport RTCDataTransport
parameters RTCDataChannelParameters

Attributes

transport of type RTCDataTransport, readonly

The readonly attribute referring to the related transport object.

readyState of type RTCDataChannelState, readonly

The readyState attribute represents the state of the RTCDataChannel object. On getting, it MUST return the value of the RTCDataChannel object's [[\ReadyState]] internal slot.

bufferedAmount of type unsigned long, readonly

The bufferedAmount attribute MUST return the number of bytes of application data (UTF-8 text and binary data) that have been queued using send() but that, as of the last time the event loop started executing a task, had not yet been transmitted to the network. This includes any text sent during the execution of the current task, regardless of whether the user agent is able to transmit text asynchronously with script execution. This does not include framing overhead incurred by the protocol, or buffering done by the operating system or network hardware. If the channel is closed, this attribute's value will only increase with each call to the send() method (the attribute does not reset to zero once the channel closes).

bufferedAmountLowThreshold of type unsigned long

The bufferedAmountLowThreshold attribute sets the threshold at which the bufferedAmount is considered to be low. When the bufferedAmount decreases from above this threshold to equal or below it, the bufferedamountlow event fires. The bufferedAmountLowThreshold is initially zero on each new RTCDataChannel, but the application may change its value at any time.

binaryType of type DOMString

The binaryType attribute MUST, on getting, return the value to which it was last set. On setting, the user agent MUST set the IDL attribute to the new value. When an RTCDataChannel object is constructed, the binaryType attribute MUST be initialized to the string 'blob'. This attribute controls how binary data is exposed to scripts. See the [[WEBSOCKETS-API]] for more information.

onopen of type EventHandler

This event handler, of event handler type open, MUST be supported by all objects implementing the RTCDataChannel interface.

onbufferedamountlow of type EventHandler

The event type of this event handler is bufferedamountlow.

onerror of type EventHandler

This event handler, of event handler type error, MUST be supported by all objects implementing the RTCDataChannel interface. One reason an error event can be fired is if the value of parameters passed in the constructor is subsequently determined to be invalid. This can happen if the RTCDataChannel [[\Negotiated]] internal slot is set to false and then a call to RTCDtlsTransport.start() causes the DTLS role to be set to a value inconsistent with the value of the RTCDataChannel [[\DataChannelId]] internal slot, as noted in [[!DATA-PROT]] Section 4.

onclose of type EventHandler

This event handler, of event handler type close, MUST be supported by all objects implementing the RTCDataChannel interface.

onmessage of type EventHandler

This event handler, of event handler event type message, MUST be fired to allow a developer's JavaScript to receive data from a remote peer.

Event Argument Description
Object data The received remote data.

Methods

getParameters

Returns the RTCDataChannelParameters applying to this data channel. When the getParameters method is called, the user agent MUST run the following steps:

  1. Let channel be the RTCDataChannel object for which parameters are to be returned.
  2. Let parameters be a new RTCDataChannelParameters dictionary.
  3. Set parameters's label member to the value of channel's [[\DataChannelLabel]] internal slot, which MUST have the value to which it was set when channel was constructed.
  4. Set parameters's ordered member to the value of channel's [[\Ordered]] internal slot, which MUST have the value to which it was set when channel was constructed.
  5. Set parameters's maxPacketLifetime member to the value of channel's [[\MaxPacketLifetime]] internal slot, which MUST have the value to which it was set when channel was constructed.
  6. Set parameters's maxRetransmits member to the value of channel's [[\MaxRetransmits]] internal slot, which MUST have the value to which it was set when channel was constructed.
  7. Set parameters's protocol member to the value of channel's [[\DataChannelProtocol]] internal slot, which MUST have the value to which it was set when channel was constructed.
  8. Set parameters's negotiated member to the value of channel's [[\Negotiated]] internal slot, which MUST have the value to which it was set when channel was constructed.
  9. Set parameters's id member to the value of channel's [[\DataChannelId]] internal slot.
  10. Set parameters's label member to the value of channel's [[\DataChannelLabel]] internal slot, which MUST have the value to which it was set when channel was constructed.
  11. Set parameters's priority member to the value of channel's [[\DataChannelPriority]] internal slot, which MUST have the value to which it was set when channel was constructed.
  12. Return parameters.
No parameters.
close

Closes the RTCDataChannel. It may be called regardless of whether the RTCDataChannel object was created by this peer or the remote peer. When the close method is called, the user agent MUST run the following steps:

1. Let channel be the RTCDataChannel object which is about to be closed.

2. If channel's [[\ReadyState]] slot is closing or closed, then abort these steps.

3. Set channel's [[\ReadyState]] slot to closing.

4. If the closing procedure has not started yet, start it.

No parameters.
Return type: undefined
send

Run the steps described by the send() algorithm with argument type string object.

Parameter Type Nullable Optional Description
data USVString
Return type: undefined
send

Run the steps described by the send() algorithm with argument type Blob object.

Parameter Type Nullable Optional Description
data Blob
Return type: undefined
send

Run the steps described by the send() algorithm with argument type ArrayBuffer object.

Parameter Type Nullable Optional Description
data ArrayBuffer
Return type: undefined
send

Run the steps described by the send() algorithm with argument type ArrayBufferView object.

Parameter Type Nullable Optional Description
data ArrayBufferView
Return type: undefined

The send() method is overloaded to handle different data argument types. When any version of the method is called, the user agent MUST run the following steps:

  1. Let channel be the RTCDataChannel on which data is to be sent.

  2. If channel's [[\ReadyState]] internal slot is not open, throw an InvalidStateError.

  3. Execute the sub step that corresponds to the type of the methods argument:

    • string object:

      Let data be the object and increase the bufferedAmount attribute by the number of bytes needed to express data as UTF-8.

    • Blob object:

      Let data be the raw data represented by the Blob object and increase the bufferedAmount attribute by the size of data, in bytes.

    • ArrayBuffer object:

      Let data be the data stored in the buffer described by the ArrayBuffer object and increase the bufferedAmount attribute by the length of the ArrayBuffer in bytes.

    • ArrayBufferView object:

      Let data be the data stored in the section of the buffer described by the ArrayBuffer object that the ArrayBufferView object references and increase the bufferedAmount attribute by the length of the ArrayBufferView in bytes.

  4. If the size of data exceeds the value of the [[\MaxMessageSize]] slot of channel's associated RTCSctpTransport, throw a TypeError.

  5. Queue data for transmission on channel's underlying data transport. If queuing data is not possible because not enough buffer space is available, throw an OperationError.

    The actual transmission of data occurs in parallel. If sending data leads to an SCTP-level error, the application will be notified asynchronously through onerror.

RTCDataTransport Interface

interface RTCDataTransport : RTCStatsProvider {
};

RTCDataChannelState Enum

The RTCDataChannelState provides information on the state of the data channel.

enum RTCDataChannelState {
    "connecting",
    "open",
    "closing",
    "closed"
};
Enumeration description
connecting

The user agent is attempting to establish the underlying data transport. This is the initial state of an RTCDataChannel object dispatched as part of an RTCDataChannelEvent.

open

The underlying data transport is established and communication is possible.

closing

The procedure to close down the underlying data transport has started.

closed

The underlying data transport has been closed or could not be established.

RTCDataChannelParameters Dictionary

The RTCDataChannelParameters dictionary describes the configuration of the RTCDataChannel. An RTCDataChannel can be configured to operate in different reliability modes. A reliable channel ensures that the data is delivered at the other peer through retransmissions. An unreliable channel is configured to either limit the number of retransmissions (maxRetransmits) or set a time during which transmissions (including retransmissions) are allowed (maxPacketLifeTime). These properties can not be used simultaneously and an attempt to do so will result in an error. Not setting any of these properties results in a reliable channel.

dictionary RTCDataChannelParameters {
             USVString      label = "";
             boolean        ordered = true;
             unsigned long  maxPacketLifetime;
             unsigned long  maxRetransmits;
             USVString      protocol = "";
             boolean        negotiated = false;
             [EnforceRange]
             unsigned short id;
             RTCPriorityType priority = "low";
};

Dictionary RTCDataChannelParameters Members

label of type USVString, defaulting to ""

The label attribute represents a label that can be used to distinguish this RTCDataChannel object from other RTCDataChannel objects. For an SCTP data channel, the label is carried in the DATA_CHANNEL_OPEN message defined in [[!DATA-PROT]] Section 5.1.

ordered of type boolean, defaulting to true

The ordered attribute is set to true if the RTCDataChannel is ordered, and false if out of order delivery is allowed. Default is true.

maxPacketLifetime of type unsigned long

The maxPacketLifetime attribute represents the length of the time window (in milliseconds) during which retransmissions may occur in unreliable mode.

maxRetransmits of type unsigned long

The maxRetransmits attribute represents the maximum number of retransmissions that are attempted in unreliable mode. The attribute MUST be initialized to null by default.

protocol of type USVString, defaulting to ""

The name of the sub-protocol used with this RTCDataChannel if any, or the empty string otherwise (in which case the protocol is unspecified). Sub-protocols are registered in the 'Websocket Subprotocol Name Registry' created in [[RFC6455]] Section 11.5.

negotiated of type boolean, defaulting to false

The negotiated attribute is set to true if this RTCDataChannel was negotiated by the application, or false otherwise. The attribute MUST be initialized to false by default. If set to true, the application developer MUST signal to the remote peer to construct an RTCDataChannel object with the same id for the data channel to be open. As noted in [[!DATA-PROT]], DATA_CHANNEL_OPEN is not sent to the remote peer nor is DATA_CHANNEL_ACK expected in return. If set to false, the remote party will receive an ondatachannel event with a system constructed RTCDataChannel object.

id of type unsigned short

The id attribute represents the identifier for this RTCDataChannel. The id was either assigned by the user agent at channel creation time or was selected by the script. For SCTP, the id represents a stream identifier, as discussed in [[!DATA]] Section 6.5.

priority of type RTCPriorityType, defaulting to low

The priority of this RTCDataChannel.

RTCSctpTransport Interface

The RTCSctpTransport includes information relating to Stream Control Transmission Protocol (SCTP) transport.

Overview

An RTCSctpTransport inherits from an RTCDataTransport object, which is associated to an RTCDataChannel object.

Operation

An RTCSctpTransport is constructed from an RTCDtlsTransport object, and optionally a port number (with a default of 5000, or the next unused port). An RTCSctpTransport object can be garbage-collected once stop() is called and it is no longer referenced.

Interface Definition

        [ Constructor (RTCDtlsTransport transport, optional unsigned short port), Exposed=Window]
interface RTCSctpTransport : RTCDataTransport {
    readonly        attribute RTCDtlsTransport      transport;
    readonly        attribute RTCSctpTransportState state;
    readonly        attribute unsigned short        port;
    static RTCSctpCapabilities getCapabilities ();
    undefined                  start (RTCSctpCapabilities remoteCaps, optional unsigned short remotePort);
    undefined                  stop ();
                    attribute EventHandler          ondatachannel;
                    attribute EventHandler          onstatechange;
};

Constructors

To construct an RTCSctpTransport, run the following steps:

  1. Let transport be the first argument.
  2. If transport.state is closed throw an InvalidStateError.
  3. Let port be the second argument.
  4. If port is set and is already in use, throw an InvalidStateError.

  5. Let sctpTransport be a new RTCSctpTransport object.

  6. Let sctpTransport have an [[\SctpTransportState]] internal slot initialized to new.

  7. Let canSendSize be the number of bytes that this client can send (i.e. the size of the local send buffer) or 0 if the implementation can handle messages of any size.

  8. Let sctpTransport have a [[\MaxMessageSize]] internal slot initialized to canSendSize.

  9. Return sctpTransport.

RTCSctpTransport
Parameter Type Nullable Optional Description
transport RTCDtlsTransport
port unsigned short

Attributes

transport of type RTCDtlsTransport, readonly

The RTCDtlsTransport instance the RTCSctpTransport object is sending over.

state of type RTCSctpTransportState, readonly

The current state of the SCTP transport. On getting, it MUST return the value of the [[\SctpTransportState]] internal slot.

port of type unsigned short, readonly

The local SCTP port number used by the data channel.

ondatachannel of type EventHandler

The ondatachannel event handler, of type datachannel, MUST be supported by all objects implementing the RTCSctpTransport interface. If the remote peer sets the [[\Negotiated]] internal slot of its RTCDataChannel to false, then the event will fire indicating a new RTCDataChannel object has been constructed to connect with the RTCDataChannel constructed by the remote peer.

onstatechange of type EventHandler

This event handler, of event handler event type statechange, MUST be fired any time the [[\SctpTransportState]] internal slot changes.

Methods

getCapabilities(), static

Retrieves the RTCSctpCapabilities of the RTCSctpTransport. When the getCapabilities method is called the user agent MUST run the following steps:

  1. Let capabilities be a new RTCSctpCapabilities dictionary.

  2. Set capabilities's maxMessageSize member to the number of bytes that this client can send (i.e. the size of the local send buffer) or 0 if the implementation can handle messages of any size.

  3. Return capabilities.

No parameters.
Return type: RTCSctpCapabilities
start

Starts the RTCSctpTransport instance and causes an SCTP INIT request to be issued over the RTCDtlsTransport from the local RTCSctpTransport to the remote RTCSctpTransport (causing the [[\SctpTransportState]] internal slot to transition to to connecting), where the remote RTCSctpTransport responds with an SCTP INIT-ACK. Since both local and remote parties must mutually create an RTCSctpTransport, SCTP SO (Simultaneous Open) is used to establish a connection over SCTP. If the [[\SctpTransportState]] internal slot is not new throw an InvalidStateError. If remotePort is not provided, a default value of port is assumed. If the remote port is in use, throw an InvalidStateError.

When the start method is called, the user agent MUST update the [[\MaxMessageSize]] internal slot of the RTCSctpTransport by running the following steps:

  1. Let sctpTtransport be the RTCSctpTransport object to be updated.

  2. Let remoteCaps be the first argument.
  3. Let remoteMaxMessageSize be the value of remoteCaps's maxMessageSize member or 65536 if it is unset or null.

  4. Let canSendSize be the number of bytes that this client can send (i.e. the size of the local send buffer) or 0 if the implementation can handle messages of any size.

  5. If both remoteMaxMessageSize and canSendSize are 0, set the [[\MaxMessageSize]] internal slot to the positive Infinity value.

  6. Else, if either remoteMaxMessageSize or canSendSize is 0, set the [[\MaxMessageSize]] internal slot to the larger of the two.

  7. Else, set [[\MaxMessageSize]] internal slot to the smaller of remoteMaxMessageSize or canSendSize.

Parameter Type Nullable Optional Description
remoteCaps RTCSctpCapabilities
remotePort unsigned short
Return type: undefined
stop

Stops the RTCSctpTransport instance.

No parameters.
Return type: undefined

RTCSctpTransportState Enum

RTCSctpTransportState indicates the state of the SCTP transport.

enum RTCSctpTransportState {
    "new",
    "connecting",
    "connected",
    "closed"
};
Enumeration description
new

The RTCSctpTransport object has been constructed but the start method has not been called so the RTCSctpTransport has not started negotiating yet.

connecting

The start method has been called and the RTCSctpTransport is in the process of negotiating an association.

connected

The RTCSctpTransport has completed negotiation of an association.

closed

A task is queued to update the [[\SctpTransportState]] slot to closed when a SHUTDOWN or ABORT chunk is received or when the SCTP association has been closed intentionally, such as by a call to stop.

RTCSctpCapabilities Dictionary

The RTCSctpCapabilities dictionary provides information about the capabilities of the RTCSctpTransport.

dictionary RTCSctpCapabilities {
             required unsigned long maxMessageSize;
};

Dictionary RTCSctpCapabilities Members

maxMessageSize of type unsigned long, required

The maximum size of data that the implementation can send or 0 if the implementation can handle messages of any size.

RTCDataChannelEvent

The datachannel event uses the RTCDataChannelEvent interface.

Firing a datachannel event named e with a RTCDataChannel channel means that an event with the name e, which does not bubble (except where otherwise stated) and is not cancelable (except where otherwise stated), and which uses the RTCDataChannelEvent interface with the channel attribute set to channel, MUST be created and dispatched at the given target.

        [ Constructor (DOMString type, RTCDataChannelEventInit eventInitDict), Exposed=Window]
interface RTCDataChannelEvent : Event {
    readonly        attribute RTCDataChannel channel;
};

Constructors

RTCDataChannelEvent
Parameter Type Nullable Optional Description
type DOMString
eventInitDict RTCDataChannelEventInit

Attributes

channel of type RTCDataChannel, readonly

The channel attribute represents the RTCDataChannel object associated with the event.

The RTCDataChannelEventInit dictionary includes information on the configuration of the data channel.

dictionary RTCDataChannelEventInit : EventInit {
             required RTCDataChannel channel;
};

Dictionary RTCDataChannelEventInit Members

channel of type RTCDataChannel, required

The RTCDataChannel object associated with the event.

Examples

// Include some helper functions
import {trace, errorHandler, mySendLocalCandidate, myIceGathererStateChange,
  myIceTransportStateChange, myDtlsTransportStateChange} from 'helper';

function initiate(mySignaller) {
  // Prepare the ICE gatherer
  var gatherOptions = {
    gatherPolicy: "all",
    iceServers: [
      { urls: "stun:stun1.example.net" },
      { urls: "turn:turn.example.org", username: "user", credential: "myPassword",
        credentialType: "password" }
     ]
  };
  var iceGatherer = new RTCIceGatherer(gatherOptions);
  // Handle state changes
  iceGatherer.onstatechange = function(event) {
    myIceGathererStateChange("iceGatherer", event.state);
  };
  // Handle errors
  iceGatherer.onerror = errorHandler;
  // Prepare to signal local candidates
  iceGatherer.onlocalcandidate = function(event) {
    mySignaller.mySendLocalCandidate(event.candidate);
  };

  // Start gathering
  iceGatherer.gather();
  // Create ICE transport
  var ice = new RTCIceTransport(iceGatherer);
  // Prepare to handle remote ICE candidates
  mySignaller.onRemoteCandidate = function(remote) {
    ice.addRemoteCandidate(remote.candidate);
  };

  // Create the DTLS certificate
  var certs;
  var keygenAlgorithm = { name: "ECDSA", namedCurve: "P-256" };
  RTCCertificate.generateCertificate(keygenAlgorithm).then(function(certificate){
    certs[0] = certificate;
  }, function(){
    trace('Certificate could not be created');
  });

  // Create DTLS and SCTP transport
  var dtls = new RTCDtlsTransport(ice, certs);
  var sctp = new RTCSctpTransport(dtls);

  // Construct RTCDataChannelParameters dictionary
  var parameters = {
    label: "channel1",
    ordered: true,
    protocol: "ship",
    negotiated: false
  };

  mySignaller.sendInitiate({
    ice: iceGatherer.getLocalParameters(),
    dtls: dtls.getLocalParameters(),
    sctpCapabilities: RTCSctpTransport.getCapabilities(),
    port: sctp.port,
    // ... marshall RtpSender/RtpReceiver capabilities as in Section 6.6 Examples 8 and 9.
  }, function(remote) {
    // Start the ICE, DTLS and SCTP transports
    ice.start(iceGatherer, remote.ice, RTCIceRole.controlling);
    dtls.start(remote.dtls);
    sctp.start(remote.sctpCapabilities, remote.port);
    // Create the data channel object
    var channel = new RTCDataChannel(sctp, parameters);
    channel.send("foo");
    // ... configure RtpSender/RtpReceiver objects as in Section 6.6 Examples 8 and 9.
  });
}
// This is an example of how to answer
// Include some helper functions
import {trace, errorHandler, mySendLocalCandidate, myIceGathererStateChange,
  myIceTransportStateChange, myDtlsTransportStateChange} from 'helper';

function accept(mySignaller, remote) {
  var gatherOptions = {
    gatherPolicy: "all",
    iceServers: [
      { urls: "stun:stun1.example.net" },
      { urls: "turn:turn.example.org", username: "user", credential: "myPassword",
        credentialType: "password" }
     ]
  };
  var iceGatherer = new RTCIceGatherer(gatherOptions);
  // Handle state changes
  iceGatherer.onstatechange = function(event) {
    myIceGathererStateChange("iceGatherer", event.state);
  };
  // Handle errors
  iceGatherer.onerror = errorHandler;
  // Prepare to signal local candidates
  iceGatherer.onlocalcandidate = function(event) {
    mySignaller.mySendLocalCandidate(event.candidate);
  };

   // Start gathering
  iceGatherer.gather();
  // Create ICE transport
  var ice = new RTCIceTransport(iceGatherer);
  // Prepare to handle remote ICE candidates
  mySignaller.onRemoteCandidate = function(remote) {
    ice.addRemoteCandidate(remote.candidate);
  };

   // Create the DTLS certificate
  var certs;
  var keygenAlgorithm = { name: "ECDSA", namedCurve: "P-256" };
  RTCCertificate.generateCertificate(keygenAlgorithm).then(function(certificate){
    certs[0] = certificate;
  }, function(){
    trace('Certificate could not be created');
  });

  // Create DTLS and SCTP transport
  var dtls = new RTCDtlsTransport(ice, certs);
  var sctp = new RTCSctpTransport(dtls);

  mySignaller.sendAccept({
    ice: iceGatherer.getLocalParameters(),
    dtls: dtls.getLocalParameters(),
    sctpCapabilities: RTCSctpTransport.getCapabilities(),
    port: sctp.port,
    // ... marshall RtpSender/RtpReceiver capabilities as in Section 6.6 Examples 8 and 9.
  });

   // Start the ICE, DTLS and SCTP transports
  ice.start(iceGatherer, remote.ice, RTCIceRole.controlled);
  dtls.start(remote.dtls);
  // Start the SctpTransport
  sctp.start(remote.sctpCapabilities, remote.port);

  // ... configure RtpSender/RtpReceiver objects as in Section 6.6 Examples 8 and 9.

  // Assume in-band signalling. We could also have sent
  // RTCDataChannelParameters in signalling and constructed
  // the data channel with negotiated: true.

  sctp.ondatachannel = function(channel) {
    channel.onmessage = function(message) {
      if (message === "foo") {
        channel.send("bar");
      }
    };
  };
}
                

RTCQuicTransport Interface

The RTCQuicTransport includes information relating to QUIC transport.

Overview

An RTCQuicTransport instance is associated to one or more RTCQuicStream instances.

The QUIC API presented in this and the subsequent section is at a lower level of maturity than the rest of the ORTC API, with no shipping implementations. It represents a preliminary proposal based on work-in-progress within the IETF QUIC WG. Since the QUIC protocol specification is still in its early stages, both the protocol and API are likely to change significantly going forward (such as changes to support uni-directional streams). Since the W3C WEBRTC WG is considering new work to support QUIC, these sections could also potentially be moved to a separate document.

Operation

A RTCQuicTransport instance is constructed using an RTCIceTransport and a sequence of RTCCertificate objects. Although any given QUIC connection will use only one certificate, multiple certificates can be provided that support different algorithms. The final certificate will be selected based on the QUIC handshake, which establishes which certificates are allowed. An RTCQuicTransport object in the closed or failed states can be garbage-collected when it is no longer referenced.

The QUIC negotiation occurs between transport endpoints determined via ICE. The QUICv1 transport protocol, described in [[!RFC9000]], supports multiplexing of a single QUIC connection with STUN, TURN, DTLS, RTP and RTCP. Issues relating to multiplexing are described in [[RFC7983bis]].

A newly constructed RTCQuicTransport MUST listen and respond to incoming QUIC packets before start() is called. However, to complete the negotiation it is necessary to verify the remote fingerprint, which is an attribute of the remoteParameters argument passed to start(). To verify the remote fingerprint, compute the fingerprint value for the selected remote certificate using the signature digest algorithm, and compare it against remoteParameters.fingerprints. If the selected remote certificate RTCDtlsFingerprint.value matches remoteParameters.fingerprints[j].value and RTCDtlsFingerprint.algorithm matches remoteParameters.fingerprints[j].algorithm for any value of j, the remote fingerprint is verified. After the QUIC handshake exchange completes (but before the remote fingerprint is verified) incoming media packets may be received. A modest buffer MUST be provided to avoid loss of media prior to remote fingerprint validation (which can begin after start() is called).

Interface Definition

        [ Constructor (RTCIceTransport transport, sequence<RTCCertificate> certificates), Exposed=Window]
interface RTCQuicTransport : RTCStatsProvider {
    readonly        attribute RTCIceTransport          transport;
    readonly        attribute RTCQuicTransportState    state;
    RTCQuicParameters     getLocalParameters ();
    RTCQuicParameters?    getRemoteParameters ();
    sequence<RTCCertificate> getCertificates ();
    sequence<ArrayBuffer> getRemoteCertificates ();
    void                  start (RTCQuicParameters remoteParameters);
    void                  stop ();
    RTCQuicStream         createStream ();
                    attribute EventHandler             onstatechange;
                    attribute EventHandler             onerror;
                    attribute EventHandler             onstream;
};

Constructors

If an attempt is made to construct a RTCQuicTransport instance from an RTCIceTransport in the closed state, throw an InvalidStateError. If certificates is non-empty, check that the expires attribute of each RTCCertificate object is in the future. If a certificate has expired, throw an InvalidParameter; otherwise, store the certificates.

RTCQuicTransport
Parameter Type Nullable Optional Description
transport RTCIceTransport
certificates sequence<RTCCertificate>

Attributes

transport of type RTCIceTransport, readonly

The associated RTCIceTransport instance.

state of type RTCQuicTransportState, readonly

The current state of the QUIC transport.

onstatechange of type EventHandler

This event handler, of event handler event type statechange, MUST be fired any time the RTCQuicTransportState changes.

onerror of type EventHandler

This event handler, of event handler event type error, MUST be fired on reception of a QUIC error; an implementation SHOULD include QUIC error information in error.message (defined in [[!HTML5]] Section 6.1.3.6.2).

onstream of type EventHandler

This event handler, of event handler event type quicstream, MUST be fired on when a remote RTCQuicStream is created.

Methods

getLocalParameters

getLocalParameters() obtains the QUIC parameters of the local RTCQuicTransport upon construction. If multiple certificates were provided in the constructor, then multiple fingerprints will be returned, one for each certificate. getLocalParameters().role always returns the default role of a newly constructed RTCQuicTransport; for a browser this will be auto.

No parameters.
Return type: RTCQuicParameters
getRemoteParameters

getRemoteParameters() obtains the remote QUIC parameters passed in the start method. Prior to calling start, null is returned.

No parameters.
Return type: RTCQuicParameters, nullable
getCertificates

getCertificates() returns the certificates provided in the constructor.

No parameters.
Return type: sequence<RTCCertificate>
getRemoteCertificates

getRemoteCertificates() returns the certificate chain in use by the remote side, with each certificate encoded in binary Distinguished Encoding Rules (DER) [[!X690]]. getRemoteCertificates() returns an empty list prior to selection of the remote certificate, which is completed once RTCQuicTransportState transitions to connected.

No parameters.
Return type: sequence<ArrayBuffer>
start

Start QUIC transport negotiation with the parameters of the remote QUIC transport, including verification of the remote fingerprint. Only a single QUIC transport can be multiplexed over an ICE transport. Therefore if a RTCQuicTransport object quicTransportB is constructed with an RTCIceTransport object iceTransport previously used to construct another RTCQuicTransport object quicTransportA, then if quicTransportB.start() is called prior to having called quicTransportA.stop(), then throw an InvalidStateError.

If start is called after a previous start call, or if state is closed, throw an InvalidStateError.

If all of the values of remoteParameters.fingerprints[j].algorithm are unsupported, where j goes from 0 to the number of fingerprints, throw a NotSupportedError.

Parameter Type Nullable Optional Description
remoteParameters RTCQuicParameters
Return type: void
stop

Stops and closes the RTCQuicTransport object. Calling stop() when state is closed has no effect.

No parameters.
Return type: void
createStream

Creates an RTCQuicStream object. Since [[RFC9000]] only defines reliable QUIC streams, createStream only supports creation of reliable streams.

When createStream is called, the user agent MUST run the following steps:

  1. Let transport be the RTCQuicTransport on which createStream is invoked.
  2. If transport.state is closed throw an InvalidStateError.
  3. Let parameters be the first argument.
  4. Let stream be a newly created RTCQuicStream object.

  5. Let stream have a [[\QuicStreamState]] internal slot initialized to new.

  6. Let stream have a [[\Readable]] internal slot initialized to false.

  7. Let stream have a [[\Writeable]] internal slot initialized to false.

  8. Let stream have a [[\MaxWriteBufferedAmount]] internal slot initialized to the maximum write buffer size.

  9. Let stream have a [[\MaxReadBufferedAmount]] internal slot initialized to the maximum read buffer size.

  10. Let stream have a [[\TargetReadBufferedAmount]] internal slot initialized to the maximum read buffer size.

  11. Let stream have a [[\WriteBufferedAmount]] internal slot initialized to zero.

  12. Let stream have a [[\ReadBufferedAmount]] internal slot initialized to zero.

  13. Return stream and continue the following steps in the background.

  14. Create stream's associated underlying data transport.

No parameters.
Return type: RTCQuicStream

RTCQuicParameters Dictionary

The RTCQuicParameters dictionary includes information relating to QUIC configuration.

dictionary RTCQuicParameters {
             RTCQuicRole                  role = "auto";
             required sequence<RTCDtlsFingerprint> fingerprints;
};

Dictionary RTCQuicParameters Members

role of type RTCQuicRole, defaulting to "auto"

The QUIC role, with a default of auto.

fingerprints of type sequence<RTCDtlsFingerprint>, required

Sequence of fingerprints, one fingerprint for each certificate.

RTCQuicStreamEvent

The quicstream event uses the RTCQuicStreamEvent interface.

Firing a quicstream event named e with a RTCQuicStream stream means that an event with the name e, which does not bubble (except where otherwise stated) and is not cancelable (except where otherwise stated), and which uses the RTCQuicStreamEvent interface with the stream attribute set to stream, MUST be created and dispatched at the given target.

        [ Constructor (DOMString type, RTCQuicStreamEventInit eventInitDict), Exposed=Window]
interface RTCQuicStreamEvent : Event {
    readonly        attribute RTCQuicStream stream;
};

Constructors

RTCQuicStreamEvent
Parameter Type Nullable Optional Description
type DOMString
eventInitDict RTCQuicStreamEventInit

Attributes

stream of type RTCQuicStream, readonly

The stream attribute represents the RTCQuicStream object associated with the event.

The RTCQuicStreamEventInit dictionary includes information on the configuration of the QUIC stream.

dictionary RTCQuicStreamEventInit : EventInit {
             required RTCQuicStream stream;
};

Dictionary RTCQuicStreamEventInit Members

stream of type RTCQuicStream, required

The RTCQuicStream object associated with the event.

RTCQuicRole Enum

RTCQuicRole indicates the role of the QUIC transport.

enum RTCQuicRole {
    "auto",
    "client",
    "server"
};
Enumeration description
auto

The QUIC role is determined based on the resolved ICE role: the ICE controlled role acts as the QUIC client and the ICE controlling role acts as the QUIC server.

client

The QUIC client role.

server

The QUIC server role.

QUIC role determination

To diagnose QUIC role issues, an application may wish to determine the desired and actual QUIC role of an RTCQuicTransport. For a browser implementing ORTC, a RTCQuicTransport object assumes a QUIC role of auto upon construction. This implies that the QUIC role is determined by the ICE role. Since getLocalParameters().role always returns the role assigned to an RTCQuicTransport object upon construction (auto for a browser), the getLocalParameters method cannot be used to determine the desired or actual role of an RTCQuicTransport.

An application can determine the desired role of an RTCQuicTransport from the value of remoteParameters.role passed to RTCQuicTransport.start(remoteParameters). If remoteParameters.role is server then the desired role of the RTCQuicTransport is client. If remoteParameters.role is client then the desired role of the RTCQuicTransport is server.

The RTCQuicTransport.transport.onstatechange EventHandler can be used to determine whether an RTCQuicTransport transitions to the desired role. When RTCQuicTransport.transport.state transitions to connected, if RTCQuicTransport.transport.role is controlled then the role of the RTCQuicTransport is client. If RTCQuicTransport.transport.role is controlling then the role of the RTCQuicTransport is server.

RTCQuicTransportState Enum

RTCQuicTransportState indicates the state of the QUIC transport.

enum RTCQuicTransportState {
    "new",
    "connecting",
    "connected",
    "closed",
    "failed"
};
Enumeration description
new

The RTCQuicTransport object has been created and has not started negotiating yet.

connecting

QUIC is in the process of negotiating a secure connection and verifying the remote fingerprint. Once a secure connection is negotiated (but prior to verification of the remote fingerprint, enabled by calling start()), incoming data can flow through.

connected

QUIC has completed negotiation of a secure connection and verified the remote fingerprint. Outgoing data and media can now flow through.

closed

The QUIC connection has been closed intentionally via a call to stop() or receipt of a close_notify alert. Calling transport.stop() will also result in a transition to the closed state.

failed

The QUIC connection has been closed as the result of an error (such as receipt of an error alert or a failure to validate the remote fingerprint).

Examples

// Include some helper functions
import {trace, errorHandler, mySendLocalCandidate, myIceGathererStateChange,
  myIceTransportStateChange, myDtlsTransportStateChange} from 'helper';

function initiate(mySignaller) {
  // Prepare the ICE gatherer
  var gatherOptions = {
    gatherPolicy: "all",
    iceServers: [
      { urls: "stun:stun1.example.net" },
      { urls: "turn:turn.example.org", username: "user", credential: "myPassword",
        credentialType: "password" }
     ]
  };
  var iceGatherer = new RTCIceGatherer(gatherOptions);
  // Handle state changes
  iceGatherer.onstatechange = function(event) {
    myIceGathererStateChange("iceGatherer", event.state);
  };
  // Handle errors
  iceGatherer.onerror = errorHandler;
  // Prepare to signal local candidates
  iceGatherer.onlocalcandidate = function(event) {
    mySignaller.mySendLocalCandidate(event.candidate);
  };

  // Start gathering
  iceGatherer.gather();
  // Create ICE transport
  var ice = new RTCIceTransport(iceGatherer);
  // Prepare to handle remote ICE candidates
  mySignaller.onRemoteCandidate = function(remote) {
    ice.addRemoteCandidate(remote.candidate);
  };

  // Create the DTLS certificate
  var certs;
  var keygenAlgorithm = { name: "ECDSA", namedCurve: "P-256" };
  RTCCertificate.generateCertificate(keygenAlgorithm).then(function(certificate){
    certs[0] = certificate;
  }, function(){
    trace('Certificate could not be created');
  });

  // Create DTLS and QUIC transport
  var dtls = new RTCDtlsTransport(ice, certs);
  var quic = new RTCQuicTransport(ice, certs);

  mySignaller.sendInitiate({
    ice: iceGatherer.getLocalParameters(),
    dtls: dtls.getLocalParameters(),
    quic: quic.getLocalParameters(),
    // ... marshall RtpSender/RtpReceiver capabilities as illustrated in Section 6.5 Example 9.
  }, function(remote) {
    // Start the ICE, DTLS and QUIC transports
    ice.start(iceGatherer, remote.ice, RTCIceRole.controlling);
    dtls.start(remote.dtls);
    quic.start(remote.quic);
    // ... configure RtpSender/RtpReceiver objects as illustrated in Section 6.5 Example 9.
  });
}
// This is an example of how to answer
// Include some helper functions
import {trace, errorHandler, mySendLocalCandidate, myIceGathererStateChange,
  myIceTransportStateChange, myDtlsTransportStateChange} from 'helper';

function accept(mySignaller, remote) {
  var gatherOptions = {
    gatherPolicy: "all",
    iceServers: [
      { urls: "stun:stun1.example.net" },
      { urls: "turn:turn.example.org", username: "user", credential: "myPassword",
        credentialType: "password" }
     ]
  };
  var iceGatherer = new RTCIceGatherer(gatherOptions);
  // Handle state changes
  iceGatherer.onstatechange = function(event) {
    myIceGathererStateChange("iceGatherer", event.state);
  };
  // Handle errors
  iceGatherer.onerror = errorHandler;
  // Prepare to signal local candidates
  iceGatherer.onlocalcandidate = function(event) {
    mySignaller.mySendLocalCandidate(event.candidate);
  };

   // Start gathering
  iceGatherer.gather();
  // Create ICE transport
  var ice = new RTCIceTransport(iceGatherer);
  // Prepare to handle remote ICE candidates
  mySignaller.onRemoteCandidate = function(remote) {
    ice.addRemoteCandidate(remote.candidate);
  };

   // Create the DTLS certificate
  var certs;
  var keygenAlgorithm = { name: "ECDSA", namedCurve: "P-256" };
  RTCCertificate.generateCertificate(keygenAlgorithm).then(function(certificate){
    certs[0] = certificate;
  }, function(){
    trace('Certificate could not be created');
  });

  // Create DTLS and SCTP transport
  var dtls = new RTCDtlsTransport(ice, certs);
  var quic = new RTCQuicTransport(ice, certs);

  mySignaller.sendAccept({
    ice: iceGatherer.getLocalParameters(),
    dtls: dtls.getLocalParameters(),
    quic: quic.getLocalParameters(),
    // ... marshall RtpSender/RtpReceiver capabilities as illustrated in Section 6.5 Example 9.
  });

   // Start the ICE, DTLS and SCTP transports
  ice.start(iceGatherer, remote.ice, RTCIceRole.controlled);
  dtls.start(remote.dtls);
  // Start the QuicTransport
  quic.start(remote.quic);

  // ... configure RtpSender/RtpReceiver objects as illustrated in Section 6.5 Example 9.

}
                

RTCQuicStream Interface

The RTCQuicStream includes information relating to a QUIC stream.

Overview

An RTCQuicStream instance is associated to an RTCQuicTransport instance.

Operation

An RTCQuicStream instance is constructed using the RTCQuicTransport.createStream method.

Interface Definition

        [ Exposed=Window ]
interface RTCQuicStream {
    readonly        attribute RTCQuicTransport    transport;
    readonly        attribute RTCQuicStreamState  state;
    readonly        attribute unsigned long       readBufferedAmount;
    readonly        attribute unsigned long       maxReadBufferedAmount;
    readonly        attribute unsigned long       targetReadBufferedAmount;
    readonly        attribute unsigned long       writeBufferedAmount;
    readonly        attribute unsigned long       maxWriteBufferedAmount;
    long                  readInto (Uint8Array data);
    void                  write (Uint8Array data);
    void                  finish ();
    void                  reset ();
    Promise<void>   waitForReadable(unsigned long amount);
    Promise<void>   waitForWritable(unsigned long amount, optional unsigned long targetWriteBufferedAmount);
    void                  setTargetReadBufferedAmount(unsigned long amount);
                    attribute EventHandler        onstatechange;
};

Attributes

transport of type RTCQuicTransport, readonly

The readonly attribute referring to the related RTCQuicTransport object.

state of type RTCQuicStreamState, readonly

The state attribute represents the state of the RTCQuicStream object. On getting it MUST return the value of the RTCQuicStream's [[\QuicStreamState]] internal slot.

onstatechange of type EventHandler

This event handler, of event handler event type statechange, MUST be fired any time the RTCQuicStreamState changes.

readBufferedAmount of type unsigned long, readonly

The readBufferedAmount attribute represents the number of bytes buffered for access by readInto but that, as of the last time the event loop started executing a task, had not yet been read. This does not include framing overhead incurred by the protocol, or buffers associated with the network hardware. On getting, it MUST return the value of the RTCQuicStream's [[\ReadBufferedAmount]] internal slot. If the RTCQuicStream is in the closed state, this attribute's value will only decrease with each call to the readInto method (the attribute does not reset to zero once the RTCQuicStream closes).

maxReadBufferedAmount of type unsigned long, readonly

The maxReadBufferedAmount attribute represents the maximum number of bytes that the implementation allows to be buffered for access by readInto. On getting, it MUST return the value of the RTCQuicStream's [[\MaxReadBufferedAmount]] internal slot.

targetReadBufferedAmount of type unsigned long, readonly

The targetReadBufferedAmount attribute represents the target number of bytes in the read buffer, which enables control of back-pressure on the sender when the target number of bytes is read. On getting, it MUST return the value of the RTCQuicStream's [[\TargetReadBufferedAmount]] internal slot.

writeBufferedAmount of type unsigned long, readonly

The writeBufferedAmount attribute represents the number of bytes of application data that have been queued using write but that, as of the last time the event loop started executing a task, had not yet been transmitted to the network. This includes any data sent during the execution of the current task, regardless of whether the user agent is able to transmit text asynchronously with script execution. This does not include framing overhead incurred by the protocol, or buffering done by the operating system or network hardware. On getting, it MUST return the value of the RTCQuicStream's [[\WriteBufferedAmount]] internal slot. If the RTCQuicStream is in the closed state, this attribute's value will only increase with each call to the write method (the attribute does not reset to zero once the RTCQuicStream closes).

maxWriteBufferedAmount of type unsigned long, readonly

The maxWriteBufferedAmount attribute represents the maximum number of bytes that the implementation allows to be buffered by write. On getting, it MUST return the value of the RTCQuicStream's [[\MaxWriteBufferedAmount]] internal slot.

Methods

readInto

Reads from RTCQuicStream into the buffer specified by the first argument and returns the number of bytes read; a negative number indicates end-of-file. If there is no data to be read then readInto returns zero. When the readInto method is called, the user agent MUST run the following steps:

  1. Let stream be the RTCQuicStream object on which readInto is invoked.
  2. If stream's [[\Readable]] slot is false, throw an InvalidStateError, then abort these steps.
  3. Let data be the first argument.
  4. If the read buffer is empty and end-of-file has been encountered, return a negative number, set stream's [[\Readable]] slot to false and abort these steps.
  5. Transfer data from the read buffer into data.
  6. Decrease the value of stream's [[\ReadBufferedAmount]] slot by the length of data in bytes.
  7. Return the length of data in bytes.
Parameter Type Nullable Optional Description
data Uint8Array
Return type: long
write

When the write method is called, the user agent MUST run the following steps:

  1. Let data be the first argument.
  2. Let stream be the RTCQuicStream object on which data is to be sent.
  3. If stream's [[\Writeable]] slot is false, throw an InvalidStateError and abort these steps.
  4. If the length of data added to [[\WriteBufferedAmount]] exceeds [[\MaxWriteBufferedAmount]], throw an OperationError and abort these steps.
  5. Increase the value of stream's [[\WriteBufferedAmount]] slot by the length of data in bytes.
  6. Queue data for transmission on stream's underlying data transport.
    The actual transmission of data occurs in parallel. If sending data leads to a QUIC-level error, the application will be notified asynchronously through the RTCQuicTransport's onerror EventHandler.
Parameter Type Nullable Optional Description
data Uint8Array
Return type: void
finish

Intitiates the closing procedure for the RTCQuicStream. It may be called regardless of whether the RTCQuicStream object was created by the local or remote peer. When the finish() method is called, the user agent MUST run the following steps:

  1. Let stream be the RTCQuicStream object which is about to be closed.
  2. If stream's [[\QuicStreamState]] is new, set stream's [[\QuicStreamState]] to closed, and abort these steps.
  3. If stream's [[\QuicStreamState]] is closed, then abort these steps.
  4. Set stream's [[\Writeable]] slot to false.
  5. Set stream's [[\QuicStreamState]] slot to closing.
  6. If the closing procedure has not started yet, start it by sending a STREAM frame with the FIN bit set.
No parameters.
Return type: void
reset

Resets the RTCQuicStream. It may be called regardless of whether the RTCQuicStream object was created by the local or remote peer. When the reset() method is called, the user agent MUST run the following steps:

  1. Let stream be the RTCQuicStream object which is about to be reset.
  2. If stream's [[\QuicStreamState]] is new, set stream's [[\QuicStreamState]] to closed, and abort these steps.
  3. If stream's [[\QuicStreamState]] slot is closed, then abort these steps.
  4. Set stream's [[\Writeable]] and [[\Readable]] slots to false.
  5. Set stream's [[\QuicStreamState]] slot to closing.
  6. If the closing procedure has not started yet, start it by sending a RST_STREAM frame.
No parameters.
Return type: void
waitForReadable

waitForReadable resolves the promise when the data queued in the read buffer increases above the amount provided as an argument. If waitForReadable is called multiple times, multiple promises could be resolved when the read buffer increases above the amount provided for each promise. Promises won't be rejected, and a promise might never be resolved in the case that the read buffer never increases above the amount specified. When the waitForReadable method is called, the user agent MUST run the following steps:

  1. Let stream be the RTCQuicStream on which waitForReadable is invoked.
  2. Let p be a new promise.
  3. If stream's [[\Readable]] slot is false, reject p with a newly created InvalidStateError and abort these steps.
  4. Let amount be the first argument.
  5. If amount is larger than the value of stream's [[\TargetReadBufferedAmount]] slot, reject p with a newly created OperationError.
  6. When [[\ReadBufferedAmount]] increases from below the value of amount to greater than or equal to it, resolve p with undefined.
Parameter Type Nullable Optional Description
amount unsigned long
Return type: Promise<void>
waitForWritable

waitForWritable resolves the promise when the data queued in the write buffer falls below a threshold computed from the arguments to the method. If waitForWritable is called multiple times, multiple promises could be resolved when the write buffer falls below the threshold for each promise. Promises won't be rejected, and a promise might never be resolved in the case that the write buffer never falls below the threshold. When the waitForWritable method is called, the user agent MUST run the following steps:

  1. Let stream be the RTCQuicStream object on which waitForWritable was invoked.
  2. Let amount be the first argument.
  3. Let p be a new promise.
  4. If stream's [[\Writeable]] slot is false, reject p with a newly created InvalidStateError and abort these steps.
  5. Let target be the second argument, if provided. If the second argument is not provided, let target be the value of stream's [[\MaxWriteBufferedAmount]] slot.
  6. Let p be a new promise.
  7. If amount is larger than target then reject p with a newly created OperationError.
  8. Let threshold be target minus amount.
  9. When stream's [[\WriteBufferedAmount]] slot decreases from above threshold to less than or equal to it, resolve p with undefined.
Parameter Type Nullable Optional Description
amount unsigned long
targetWriteBufferedAmount unsigned long
Return type: Promise<void>
setTargetReadBufferedAmount

setTargetReadBufferedAmount sets the value of the RTCQuicStream's [[\TargetReadBufferedAmount]] internal slot, which represents the target number of bytes in the RTCQuicStream's receive buffer. When the setTargetReadBufferedAmount method is called, the user agent MUST run the following steps:

  1. Let stream be the RTCQuicStream on which setTargetReadBufferedAmount is invoked.
  2. Let amount be the first argument.
  3. If amount is greater than the stream's [[\MaxReadBufferedAmount]] slot, throw an OperationError and abort these steps.
  4. Set stream's [[\TargetReadBufferedAmount]] slot to amount.
  5. If amount is less than stream's [[\ReadBufferedAmount]] slot, apply backpressure until [[\ReadBufferedAmount]] becomes less than or equal to amount.
Parameter Type Nullable Optional Description
amount unsigned long
Return type: void

RTCQuicStreamState Enum

The RTCQuicStreamState provides information on the state of the QUIC stream.

enum RTCQuicStreamState {
    "new",
    "opening",
    "open",
    "closing",
    "closed"
};
Enumeration description
new

The user agent has not yet attempted to establish the underlying stream transport. This is the initial state of an RTCQuicStream object, corresponding to the "idle" state in [[RFC9000]] Section 10.2.

opening

The underlying QUIC stream has queued a STREAM frame for transmission, but has not yet received an acknowledgement. On transitioning to the opening state, the [[\Writeable]] slot is set to true.

open

The underlying QUIC stream has received a STREAM, MAX_STREAM_DATA or STREAM_BLOCKED frame, or has sent a STREAM frame and received an acknowledgement, as described in [[RFC9000]] Section 10.2. This is the initial state of an RTCQuicStream object dispatched as a part of an RTCQuicStreamEvent. On transitioning to the open state, the [[\Readable]] and [[\Writeable]] slots are set to true.

closing

The procedure to close down the QUIC stream has started. The reset method has been called, causing a RST_STREAM frame to be queued for transmission and the read and write buffers to be cleared. Alternatively, the finish method has been called, causing a STREAM frame with the FIN flag set to be queued for transmission. However, a RST_STREAM frame or STREAM frame with the FIN flag set has not yet been received. Alternatively, the QUIC stream has received a RST_STREAM frame (causing the read and write buffers to be cleared) or a STREAM frame with the FIN flag set.

closed

The QUIC stream has been closed or could not be established. A RST_STREAM frame has been received and a RST_STREAM frame has been queued for transmission in response or a FIN flag in a STREAM frame has been received and a FIN flag in a STREAM frame has been queued for transmission in response. Alternatively:

  1. A RST_STREAM frame has been sent and a RST_STREAM frame or a STREAM frame within the FIN flag set has been received, OR
  2. A STREAM frame with the FIN flag set has been sent and a RST_STREAM frame has been received, OR
  3. A STREAM frame with the FIN flag set has been sent and a STREAM frame with the FIN flag set has been received.

On transitioning to the closed state, the [[\Readable]] and [[\Writeable]] slots are set to false.

RTCQuicStreamState transition diagram
RTCQuicStreamState transition diagram

Statistics API

The Statistics API enables retrieval of statistics relating to RTCRtpSender, RTCRtpReceiver, RTCDtlsTransport, RTCIceGatherer, RTCIceTransport and RTCSctpTransport objects. For detailed information on the Statistics API, consult [[!WEBRTC-STATS]].

The RTCStatsProvider interface enables the retrieval of statistics.

interface RTCStatsProvider {
    Promise<RTCStatsReport> getStats ();
};

Methods

getStats

Gathers stats for the given object and reports the result asynchronously. If the object has not yet begun to send or receive data, the returned stats will reflect this. If the object is in the closed state, the returned stats will reflect the stats at the time the object transitioned to the closed state.

When the getStats method is invoked, the user agent MUST queue a task to run the following steps:

  1. Let p be a new promise.

  2. Return, but continue the following steps in the background.

  3. Start gathering the stats.

  4. When the relevant stats have been gathered, return a new RTCStatsReport object, representing the gathered stats.

No parameters.
Return type: Promise<RTCStatsReport>

RTCStatsReport Interface

The getStats() method delivers a successful result in the form of a RTCStatsReport object. An RTCStatsReport represents a map between strings, identifying the inspected objects (RTCStats.id), and their corresponding RTCStats objects.

An RTCStatsReport may be composed of several RTCStats objects, each reporting stats for one underlying object. One achieves the total for the object by summing over all stats of a certain type; for instance, if an RTCRtpSender object is sending RTP streams involving multiple SSRCs over the network, the RTCStatsReport may contain one RTCStats object per SSRC (which can be distinguished by the value of the ssrc stats attribute).

[Exposed=Window]
interface RTCStatsReport {
    readonly maplike<DOMString, object>;
};

This interface has "entries", "forEach", "get", "has", "keys", "values", @@iterator methods and a "size" getter brought by readonly maplike.

Use these to retrieve the various dictionaries descended from RTCStats that this stats report is composed of. The set of supported property names [[!WEBIDL-1]] is defined as the ids of all the RTCStats-derived dictionaries that have been generated for this stats report.

Methods

RTCStats

Getter to retrieve the RTCStats objects that this stats report is composed of.

The set of supported property names [[!WEBIDL]] is defined as the ids of all the RTCStats objects that has been generated for this stats report. The order of the property names is left to the user agent.

Parameter Type Nullable Optional Description
id DOMString
Return type: getter

RTCStats Dictionary

An RTCStats dictionary represents the stats gathered by inspecting a specific object. The RTCStats dictionary is a base type that specifies as set of default attributes, such as timestamp and type. Specific stats are added by extending the RTCStats dictionary.

Note that while stats names are standardized, any given implementation may be using experimental values or values not yet known to the Web application. Thus, applications MUST be prepared to deal with unknown stats.

Statistics need to be synchronized with each other in order to yield reasonable values in computation; for instance, if "bytesSent" and "packetsSent" are both reported, they both need to be reported over the same interval, so that "average packet size" can be computed as "bytes / packets" - if the intervals are different, this will yield errors. Thus implementations MUST return synchronized values for all stats in an RTCStats dictionary.

dictionary RTCStats {
             DOMHighResTimeStamp timestamp;
             RTCStatsType        type;
             DOMString           id;
};

Dictionary RTCStats Members

timestamp of type DOMHighResTimeStamp

The timestamp, of type DOMHighResTimeStamp [[!HIGHRES-TIME]], associated with this object. The time is relative to the UNIX epoch (Jan 1, 1970, UTC). The timestamp for local measurements corresponds to the local clock and for remote measurements corresponds to the timestamp indicated in the incoming RTCP Sender Report (SR), Receiver Report (RR) or Extended Report (XR).

type of type RTCStatsType

The type of this object.

The type attribute MUST be initialized to the name of the most specific type this RTCStats dictionary represents.

id of type DOMString

A unique id that is associated with the object that was inspected to produce this RTCStats object. Two RTCStats objects, extracted from two different RTCStatsReport objects, MUST have the same id if they were produced by inspecting the same underlying object. User agents are free to pick any format for the id as long as it meets the requirements above.

RTCStatsType Enum

For ORTC, RTCStatsType is equal to one of the values defined in [[!WEBRTC-STATS]] Section 6.1:

"inbound-rtp"

Statistics for the inbound RTP stream. It is accessed via the RTCInboundRTPStreamStats defined in [[!WEBRTC-STATS]] Section 7.3. Local inbound RTP statistics can be obtained from the RTCRtpReceiver object; remote inbound RTP statistics can be obtained from the RTCRtpSender object.

"outbound-rtp"

Statistics for the outbound RTP stream. It is accessed via the RTCOutboundRTPStreamStats defined in [[!WEBRTC-STATS]] Section 7.4. Local outbound RTP statistics can be obtained from the RTCRtpSender object; remote outbound RTP statistics can be obtained from the RTCRtpReceiver object.

"data-channel"

Statistics relating to each RTCDataChannel id. It is accessed via the RTCDataChannelStats defined in [[!WEBRTC-STATS]] Section 7.8.

"track"

Statistics relating to the MediaStreamTrack object. It is accessed via the RTCMediaStreamTrackStats defined in [[!WEBRTC-STATS]] Section 7.7.

"transport"

Transport statistics related to the RTCDtlsTransport object. It is accessed via the RTCTransportStats defined in [[!WEBRTC-STATS]] Sections 7.9.

"candidate-pair"

ICE candidate pair statistics related to RTCIceTransport objects. It is accessed via the RTCIceCandidatePairStats defined in [[!WEBRTC-STATS]] Section 7.11.

"local-candidate"

ICE local candidate statistics, related to RTCIceGatherer objects. It is accessed via the RTCIceCandidateStats for the local candidate, defined in [[!WEBRTC-STATS]] Section 7.10.

"remote-candidate"

ICE remote candidate statistics, related to RTCIceTransport objects. It is accessed via the RTCIceCandidateStats for the remote candidate, defined in [[!WEBRTC-STATS]] Section 7.10.

"certificate"

Information about a certificate used by an RTCDtlsTransport object. It is accessed via the RTCCertificateStats defined in [[!WEBRTC-STATS]] Sections 7.12.

Mandatory To Implement Stats

The stats listed in [[!WEBRTC-STATS]] are intended to cover a wide range of use cases. Not all of them have to be implemented by every ORTC implementation.

An ORTC implementation MUST support generating statistics of the types described in [[!WEBRTC10]] Section 8.6, with the exception of RTCPeerConnectionStats, when the corresponding objects exist, with the attributes that are listed when they are valid for that object. An implementation MAY support generating any other statistic defined in [[!WEBRTC-STATS]], and MAY generate statistics that are not documented.

Example

Consider the case where the user is experiencing bad sound and the application wants to determine if the cause of it is packet loss. The following example code might be used:

var mySender = new RTCRtpSender(myTrack);
var myPreviousReport = null;

// ... wait a bit
setTimeout(function() {
  mySender.getStats().then(function(report) {
    processStats(report);
    myPreviousReport = report;
  });
}, aBit);

function processStats(currentReport) {
  if (myPreviousReport === null) return;

  // currentReport + myPreviousReport are an RTCStatsReport interface
  // compare the elements from the current report with the baseline
  for (var i in currentReport) {
    var now = currentReport[i];
    if (now.type !== "outboundrtp") continue;

    // get the corresponding stats from the previous report
    base = myPreviousReport[now.id];

    // base + now will be of RTCRtpStreamStats dictionary type
    if (base) {
      remoteNow = currentReport[now.associateStatsId];
      remoteBase = myPreviousReport[base.associateStatsId];
      var packetsSent = now.packetsSent - base.packetsSent;
      var packetsReceived = remoteNow.packetsReceived - remoteBase.packetsReceived;
      // if fractionLost is > 0.3, we have probably found the culprit
      var fractionLost = (packetsSent - packetsReceived) / packetsSent;
    }
  }
}
                

Identity

The Identity API is marked as a feature at risk, since there is no clear commitment from implementers.

Overview

An RTCIdentity instance enables authentication of an RTCDtlsTransport using a web-based Identity Provider (IdP). The initiator acts as the Authenticating Party (AP) and obtains an identity assertion from the IdP which is then conveyed in signaling. The responder acts as the Relying Party (RP) and verifies the assertion.

The interaction with the IdP is designed to decouple the browser from any particular identity provider; the browser need only know how to load the IdP's JavaScript, the location of which is determined by the IdP's identity, and the generic interface to generating and validating assertions. The IdP provides whatever logic is necessary to bridge the generic protocol to the IdP's specific requirements. Thus, a single browser can support any number of identity protocols, including being forward compatible with IdPs which did not exist at the time the browser was written.

Operation

An RTCIdentity instance is constructed from an RTCDtlsTransport object.

RTCIdentity Interface

The Identity API is described below.

[ Constructor (RTCDtlsTransport transport)]
interface RTCIdentity {
    undefined       setIdentityProvider (DOMString provider, optional RTCIdentityProviderOptions options);
    Promise<DOMString> getIdentityAssertion ();
    readonly        attribute Promise<RTCIdentityAssertion> peerIdentity;
    readonly        attribute RTCDtlsTransport              transport;
    readonly        attribute DOMString?                    idpLoginUrl;
    readonly        attribute DOMString?                    idpErrorInfo;
};

Constructors

RTCIdentity
Parameter Type Nullable Optional Description
transport RTCDtlsTransport

Attributes

peerIdentity of type Promise<RTCIdentityAssertion>, readonly

A promise that resolves with the identity of the peer if the identity is successfully validated.

This promise is rejected if an identity assertion is present in a remote session description and validation of that assertion fails for any reason. If the promise is rejected, a new unresolved value is created, unless a target peer identity has been established. If this promise successfully resolves, the value will not change.

transport of type RTCDtlsTransport, readonly

The RTCDtlsTransport to be authenticated.

idpLoginUrl of type DOMString, readonly, nullable

The URL that an application can navigate to so that the user can login to the IdP, as described in .

idpErrorInfo of type DOMString, readonly, nullable

An attribute that the IdP can use to pass additional information back to the applications about the error. The format of this string is defined by the IdP and may be JSON.

Methods

setIdentityProvider

Sets the identity provider to be used for a given RTCIdentity object. Applications need not make this call; if the browser is already configured for an IdP, then that configured IdP might be used to get an assertion.

When the setIdentityProvider method is invoked, the user agent MUST run the following steps:

  1. If the RTCIdentity object's transport.state attribute is closed, throw an InvalidStateError.

  2. If options.protocol includes the the character '/' or '\', throw a SyntaxError.

  3. Set the current identity provider values to the tuple (provider, options).

  4. If any identity provider value has changed, discard any stored identity assertion.

Identity provider information is not used until an identity assertion is required in response to a call to getIdentityAssertion.

Parameter Type Nullable Optional Description
provider DOMString
options RTCIdentityProviderOptions
Return type: undefined
getIdentityAssertion

Initiates the process of obtaining an identity assertion. Applications need not make this call. It is merely intended to allow them to start the process of obtaining identity assertions before a call is initiated. If an identity is needed, either because the browser has been configured with a default identity provider or because the setIdentityProvider method was called, then an identity will be automatically requested when an offer or answer is created.

When getIdentityAssertion is invoked, queue a task to run the following steps:

  1. If the RTCIdentity object's transport.state attribute is closed, throw an InvalidStateError.

  2. Request an identity assertion from the IdP.

  3. Resolve the promise with the base64 and JSON encoded assertion.

No parameters.
Return type: Promise<DOMString>

Identity Provider Selection

An IdP is used to generate an identity assertion as follows:

  1. If the setIdentityProvider() method has been called, the IdP provided shall be used.
  2. If the setIdentityProvider() method has not been called, then the user agent MAY use an IdP configured into the browser.

In order to verify assertions, the IdP domain name and protocol are taken from the domain and protocol fields of the identity assertion.

Instantiating an IdP Proxy

Instantiating an IdP proxy is described in [[WEBRTC-IDENTITY]] Section 4.2.

Implementing an IdP Securely

Aspects of IdP security are described in [[WEBRTC-IDENTITY]] Section 4.2.1.

Registering an IdP Proxy

Registration of an IdP proxy is described in [[WEBRTC-IDENTITY]] Section 5.

Interface Exposed by Identity Providers

The RTCIdentityProvider callback functions are called by RTCDtlsTransport to acquire or validate identity assertions.

Requesting Identity Assertions

The identity assertion request process is triggered by a call to getIdentityAssertion. When this call is invoked and an identity provider has been set, the following steps are executed:

  1. The RTCIdentity instantiates an IdP as described in Identity Provider Selection and Registering an IdP Proxy. If the IdP cannot be loaded, instantiated, or the IdP proxy is not registered, this process fails.

  2. The RTCIdentity invokes the generateAssertion method on the RTCIdentityProvider methods registered by the IdP.

    The RTCIdentity generates the contents parameter to this method as described in [[!RTCWEB-SECURITY-ARCH]]. The value of contents includes the fingerprint of the certificate that was selected or generated during the construction of the RTCDtlsTransport RTCIdentity.transport. The origin parameter contains the origin of the script that triggers this behavior. The usernameHint value is the same value that is provided to setIdentityProvider, if any such value was provided.

  3. The IdP proxy returns a Promise to the RTCIdentity. The IdP proxy is expected to generate the identity assertion asynchronously.

    If the user has been authenticated by the IdP, and the IdP is able to generate an identity assertion, the IdP resolves the promise with an identity assertion in the form of an RTCIdentityAssertionResult.

    This step depends entirely on the IdP. The methods by which an IdP authenticates users or generates assertions is not specified, though they could involve interacting with the IdP server or other servers.

  4. If the IdP proxy produces an error or returns a promise that does not resolve to a valid RTCIdentityAssertionResult (see ), then assertion generation fails.

  5. The RTCIdentity MAY store the identity assertion for future use. If a fresh identity assertion is needed for any reason, applications can create a new RTCIdentity.

If assertion generation fails, then the promise for the corresponding function call is rejected with a newly created OperationError.

User Login Procedure

User login proceeds as described in [[WEBRTC-IDENTITY]] Section 6.1. IdP errors are handled as described in [[WEBRTC-IDENTITY]] Section 8.

Verifying Identity Assertions

Identity assertion validation happens when RTCIdentity.transport.start() is called. The process runs asynchronously, meaning that validation of an identity assertion might not block the transition of RTCIdentity.transport.state to connected.

The identity assertion request process involves the following asynchronous steps:

  1. The RTCIdentity awaits any prior identity validation. Only one identity validation can run at a time for an RTCIdentity instance.

  2. The RTCIdentity loads the identity assertion from the session description and decodes the base64 value, then parses the resulting JSON. The idp parameter of the resulting dictionary contains a domain and an optional protocol value that identifies the IdP, as described in [[!RTCWEB-SECURITY-ARCH]].

  3. If the identity assertion is malformed, or if protocol includes the character '/' or '\', this process fails.

  4. The RTCIdentity instantiates the identified IdP as described in and . If the IdP cannot be loaded, instantiated or the IdP proxy is not registered, this process fails.

  5. The RTCIdentity invokes the validateAssertion method registered by the IdP.

    The assertion parameter is taken from the decoded identity assertion. The origin parameter contains the origin of the script that calls the RTCIdentity method that triggers this behavior.

  6. The IdP proxy returns a promise and performs the validation process asynchronously.

    The IdP proxy verifies the identity assertion using whatever means necessary. Depending on the authentication protocol this could involve interacting with the IdP server.

  7. If the IdP proxy produces an error or returns a promise that does not resolve to a valid RTCIdentityValidationResult (see ), then identity validation fails.

  8. Once the assertion is successfully verified, the IdP proxy resolves the promise with an RTCIdentityValidationResult containing the validated identity and the original contents that are the payload of the assertion.

  9. The RTCIdentity decodes the contents attribute of RTCIdentityValidationResult and validates that it contains a fingerprint value for the remote certificate. This ensures that the certificate used by the remote peer for communications is covered by the identity assertion.

    A user agent is required to fail to communicate with peers that offer a certificate that doesn't match.

    The user agent decodes contents using the format described in [[!RTCWEB-SECURITY-ARCH]]. However the IdP MUST treat contents as opaque and return the same string to allow for future extensions.

  10. The RTCIdentity validates that the domain portion of the identity matches the domain of the IdP as described in [[!RTCWEB-SECURITY-ARCH]]. If this check fails then the identity validation fails.

  11. The RTCIdentity resolves the peerIdentity attribute with a new instance of RTCIdentityAssertion that includes the IdP domain and peer identity.

  12. The user agent MAY display identity information to a user in its UI. Any user identity information that is displayed in this fashion MUST use a mechanism that cannot be spoofed by content.

If identity validation fails, the peerIdentity promise is rejected with a newly created OperationError.

If identity validation fails and there is a target peer identity for the RTCDtlsTransport, the promise returned MUST be rejected with the same DOMException.

If identity validation fails and there is no a target peer identity, the value of the peerIdentity MUST be set to a new, unresolved promise instance. This permits the use of renegotiation (or a subsequent answer, if the session description was a provisional answer) to resolve or reject the identity.

Example

The identity system is designed so that applications need not take any special action in order for users to generate and verify identity assertions; if a user has configured an IdP into their browser, then the browser will automatically request/generate assertions and the other side will automatically verify them and display the results. However, applications may wish to exercise tighter control over the identity system as shown by the following examples.

This example shows how to configure the identity provider and protocol, and consume identity assertions.

        // Set ICE gather options and construct the RTCIceGatherer object, assuming that
// we are using RTP/RTCP mux and A/V mux so that only one RTCIceTransport is needed.
// Include some helper functions
import {trace, errorHandler, mySendLocalCandidate, myIceGathererStateChange,
  myIceTransportStateChange, myDtlsTransportStateChange} from 'helper';
var gatherOptions = {
  gatherPolicy: "all",
  iceServers: [
    { urls: "stun:stun1.example.net" },
    { urls: "turn:turn.example.org", username: "user", credential: "myPassword",
      credentialType: "password" }
   ]
};
var iceGatherer = new RTCIceGatherer(gatherOptions);
iceGatherer.onlocalcandidate = function(event) {
  mySendLocalCandidate(event.candidate);
};
// Start gathering
iceGatherer.gather();
// Construct the ICE transport
var ice = new RTCIceTransport(iceGatherer);
// Create the DTLS certificate
var certs;
var keygenAlgorithm = { name: "ECDSA", namedCurve: "P-256" };
RTCCertificate.generateCertificate(keygenAlgorithm).then(function(certificate){
  certs[0] = certificate;
}, function(){
  trace('Certificate could not be created');
});

// Create the RTCDtlsTransport object.
var dtls = new RTCDtlsTransport(ice, certs);
var identity = new RTCIdentity(dtls);
identity
  .getIdentityAssertion("example.com", "default", "alice@example.com")
  .then(signalAssertion(assertion), function(e) {
    trace("Could not obtain an Identity Assertion. idp: " + e.idp + " Protocol: "
      + e.protocol + " loginUrl: " + e.loginUrl);
  });

function signalAssertion(assertion) {
  mySignalInitiate({
    myAssertion: assertion,
    ice: iceGatherer.getLocalParameters(),
    dtls: dtls.getLocalParameters()
  }, function(response) {
    ice.start(iceGatherer, response.ice, RTCIceRole.controlling);
    // Call dtls.start() before setIdentityAssertion so the peer assertion can be validated.
    dtls.start(response.dtls);
    identity.setIdentityAssertion(response.myAssertion).then(function(peerAssertion) {
      trace("Peer identity assertion validated. idp: " + peerAssertion.idp + " name: "
        + peerAssertion.name);
    }, function(e) {
      trace("Could not validate peer assertion. idp: " + e.idp + " Protocol: " + e.protocol);
    });
  });
}
                    

Certificate Management

Overview

The RTCCertificate interface represents a certificate used to authenticate communications. In addition to the visible properties, internal slots contain a handle to the generated private keying materal ([[\KeyingMaterial]]) and a certificate ([[\Certificate]]]]).

Certificates are provided in the constructors of RTCDtlsTransport and RTCQuicTransport objects, and are used to authenticate to a peer. This makes it possible to support forking, where the offerer creates multiple RTCDtlsTransport or RTCQuicTransport objects using the same local certificate and fingerprint. Also, an RTCCertificate can be persisted in [[INDEXEDDB]] and reused, so as to avoid the cost of key generation.

RTCCertificateExpiration Dictionary

RTCCertificateExpiration is used to set an expiration date on certificates generated by generateCertificate.

dictionary RTCCertificateExpiration {
    [EnforceRange]
    DOMTimeStamp expires;
};
expires

An optional expires attribute MAY be added to the definition of the algorithm that is passed to generateCertificate. If this parameter is present it indicates the maximum time that the RTCCertificate is valid for relative to the current time.

When generateCertificate is called with an object argument, the user agent attempts to convert the object into an RTCCertificateExpiration. If this is unsuccessful, immediately return a promise that is rejected with a newly created TypeError and abort processing.

A user agent generates a certificate that has an expiration date set to the current time plus the value of the expires attribute. The expires attribute of the returned RTCCertificate is set to the expiration time of the certificate. A user agent MAY choose to limit the value of the expires attribute.

RTCCertificate Interface

The RTCCertificate interface is described below.

[Exposed=Window]
        interface RTCCertificate {
    readonly        attribute DOMTimeStamp       expires;
    static sequence<AlgorithmIdentifier> getSupportedAlgorithms();
    sequence<RTCDtlsFingerprint> getFingerprints ();
    static Promise<RTCCertificate> generateCertificate (AlgorithmIdentifier keygenAlgorithm);
};

Attributes

expires of type DOMTimeStamp, readonly

The expires attribute indicates the date and time in milliseconds relative to 1970-01-01T00:00:00Z after which the certificate will be considered invalid by the browser. After this time, attempts to construct an object using this certificate will fail.

Note that this value might not be reflected in a notAfter parameter in the certificate itself.

Methods

getSupportedAlgorithms

Returns a sequence providing a representative set of supported certificate algorithms. At least one algorithm MUST be returned.

For example, the "RSASSA-PKCS1-v1_5" algorithm dictionary, RsaHashedKeyGenParams, contains fields for the modulus length, public exponent, and hash algorithm. Implementations are likely to support a wide range of modulus lengths and exponents, but a finite number of hash algorithms. So in this case, it would be reasonable for the implementation to return one AlgorithmIdentifier for each supported hash algorithm that can be used with RSA, using default/recommended values for modulusLength and publicExponent (such as 1024 and 65537, respectively).

No parameters.
Return type: sequence<AlgorithmIdentifier>
getFingerprints

Returns the list of certificate fingerprints, one of which is computed with the digest algorithm used in the certificate signature.

No parameters.
Return type: sequence<RTCDtlsFingerprint>
generateCertificate, static

The generateCertificate method causes the user agent to create and store an X.509 certificate [[!X509V3]] and corresponding private key. A handle to information is provided in the form of the RTCCertificate interface. The returned RTCCertificate can be used to control the certificates that are offered in DTLS or QUIC.

The keygenAlgorithm argument is used to control how the private key associated with the certificate is generated. The keygenAlgorithm argument uses the WebCrypto [[!WebCryptoAPI]] AlgorithmIdentifier type. The keygenAlgorithm value MUST be a valid argument to window.crypto.subtle.generateKey; that is, the value MUST produce a non-error result when normalized according to the WebCrypto algorithm normalization process [[!WebCryptoAPI]] with an operation name of generateKey and a [[supportedAlgorithms]] value specific to production of certificates for RTCDtlsTransport. If the algorithm normalization process produces an error, the call to generateCertificate() MUST be rejected with that error.

Signatures produced by the generated key are used to authenticate the DTLS or QUIC connection. The identified algorithm (as identified by the name of the normalized AlgorithmIdentifier) MUST be an asymmetric algorithm that can be used to produce a signature.

The certificate produced by this process also contains a signature. The validity of this signature is only relevant for compatibility reasons. Only the public key and the resulting certificate fingerprint are used by RTCDtlsTransport or RTCQuicTransport, but it is more likely that a certificate will be accepted if the certificate is well formed. The browser selects the algorithm used to sign the certificate; a browser SHOULD select SHA-256 [[!FIPS-180-4]] if a hash algorithm is needed.

The resulting certificate MUST NOT include information that can be linked to a user or user agent. Randomized values for distinguished name and serial number SHOULD be used.

An optional expires attribute MAY be added to the keygenAlgorithm parameter. If this contains a DOMTimeStamp value, it indicates the maximum time that the RTCCertificate is valid for relative to the current time. A user agent sets the expires attribute of the returned RTCCertificate to the current time plus the value of the expires attribute. However, a user agent MAY choose to limit the period over which an RTCCertificate is valid.

A user agent MUST reject a call to generateCertificate() with a DOMError of type "NotSupportedError" if the keygenAlgorithm parameter identifies an algorithm that the user agent cannot or will not use to generate a certificate for RTCDtlsTransport.

The following values MUST be supported by a user agent: { name: "RSASSA-PKCS1-v1_5", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: "SHA-256" }, and { name: "ECDSA", namedCurve: "P-256" }.

It is expected that a user agent will have a small or even fixed set of values that it will accept.

Parameter Type Nullable Optional Description
keygenAlgorithm AlgorithmIdentifier
Return type: Promise<RTCCertificate>

For the purposes of this API, the [[\Certificate]] slot contains unstructured binary data. No mechanism is provided for applications to access the [[\KeyingMaterial]] internal slot. Implementations MUST support applications storing and retrieving RTCCertificate objects from persistent storage. In implementations where an RTCCertificate might not directly hold private keying material (it might be stored in a secure module), a reference to the private key can be held in the [[\KeyingMaterial]] internal slot, allowing the private key to be stored and used.

When a user agent is required to obtain a structured clone [[!HTML51]] of an RTCCertificate object, it performs the following steps:

  1. Let input and memory be the corresponding inputs defined by the internal structured cloning algorithm, where input represents an RTCCertificate object to be cloned.
  2. Let output be a newly constructed RTCCertificate object.
  3. Copy the value of the expires attribute from input to output.
  4. Let the [[\Certificate]] internal slot of output be set to the result of invoking the internal structured clone algorithm recursively on the corresponding internal slots of input, with the slot contents as the new "input" argument and memory as the new "memory" argument.
  5. Let the [[\KeyingMaterial]] internal slot of output refer to the same private keying material represented by the [[\KeyingMaterial]] internal slot of input.

Privacy and Security Considerations

This section is non-normative; it specifies no new behaviour, but instead summarizes information already present in other parts of the specification. The overall security considerations of the APIs and protocols used in ORTC are described in [[RTCWEB-SECURITY-ARCH]].

Impact on same origin policy

The ORTC API enables real-time communication between browsers and other devices, including other browsers.

This means that data and media can be shared between applications running in different browsers, or between an application running in the same browser and something that is not a browser. This is an extension to the Web model which has had barriers against sending data between entities with different origins.

The ORTC specification provides no user prompts or chrome indicators for communication; it assumes that once the Web page has been allowed to access media, it is free to share that media with other entities as it chooses. Peer-to-peer exchanges of data via datachannels can therefore occur without any user explicit consent or involvement. Similarly, a server-mediated exchange (e.g. via Web Sockets) could occur without user involvement.

The peerIdentity mechanism loads and executes JavaScript code from a third-party server acting as an identity provider. That code is executed in a separate JavaScript realm and does not affect the protections afforded by the same origin policy.

Revealing IP addresses

Even without ORTC, the Web server providing a Web application will know the public IP address to which the application is delivered. Setting up communications exposes additional information about the browser’s network context to the web application, and may include the set of (possibly private) IP addresses available to the browser for WebRTC use. Some of this information has to be passed to the corresponding party to enable the establishment of a communication session.

Revealing IP addresses can leak location and means of connection; this can be sensitive. Depending on the network environment, it can also increase the fingerprinting surface and create persistent cross-origin state that cannot easily be cleared by the user.

A connection will always reveal the IP addresses proposed for communication to the corresponding party. The application can limit this exposure by choosing not to use certain addresses using the settings exposed by the RTCIceGatherPolicy dictionary, and by using relays (for instance TURN servers) rather than direct connections between participants. One will normally assume that the IP address of TURN servers is not sensitive information. These choices can for instance be made by the application based on whether the user has indicated consent to start a media connection with the other party.

Mitigating the exposure of IP addresses to the application itself requires limiting the IP addresses that can be used, which will impact the ability to communicate on the most direct path between endpoints. Browsers are encouraged to provide appropriate controls for deciding which IP addresses are made available to applications, based on the security posture desired by the user. The choice of which addresses to expose is controlled by local policy (see [[RTCWEB-IP-HANDLING]] for details).

Impact on local network

Since the browser is an active platform executing in a trusted network environment (inside the firewall), it is important to limit the damage that the browser can do to other elements on the local network, and it is important to protect data from interception, manipulation and modification by untrusted participants.

Mitigations include:

These measures are specified in the relevant IETF documents.

Confidentiality of Communications

The fact that communication is taking place cannot be hidden from adversaries that can observe the network, so this has to be regarded as public information.

A mechanism, peerIdentity, is provided that gives Javascript the option of requesting media that the same javascript cannot access, but can only be sent to certain other entities.

Persistent information

As described above, the list of IP addresses exposed by the ORTC API can be used as a persistent cross-origin state.

Beyond IP addresses, the ORTC API exposes information about the underlying media system via the RTCRtpSender.getCapabilities and RTCRtpReceiver.getCapabilities methods, including detailed and ordered information about the codecs that the system is able to produce and consume. That information is in most cases persistent across time and origins, and increases the fingerprint surface of a given device.

When establishing DTLS connections, the ORTC API can generate certificates that can be persisted by the application (e.g. in IndexedDB). These certificates are not shared across origins, and get cleared when persistent storage is cleared for the origin.

Event summary

The following events fire on RTCIceGatherer objects:

Event name Interface Fired when...
icecandidateerror RTCIceGathererIceErrorEvent The RTCIceGatherer object has experienced an ICE gathering failure (such as an authentication failure with TURN credentials).
statechange Event The RTCIceGathererState changed.
icecandidate RTCIceGatherer A new RTCIceGatherCandidate is made available to the script.

The following events fire on RTCIceTransport objects:

Event name Interface Fired when...
statechange Event The RTCIceTransportState changed.
icecandidatepairchange RTCIceCandidatePairChangedEvent The selected RTCIceCandidatePair changed.

The following events fire on RTCDtlsTransport objects:

Event name Interface Fired when...
error ErrorEvent The RTCDtlsTransport object has received a DTLS Alert.
statechange Event The RTCDtlsTransportState changed.

The following events fire on RTCQuicTransport objects:

Event name Interface Fired when...
error ErrorEvent The RTCQuicTransport object has encountered an error.
statechange Event The RTCQuicTransportState changed.
quicstream RTCQuicStreamEvent A new RTCQuicStream is dispatched to the script in response to the remote peer creating a QUIC stream.

The following events fire on RTCQuicStream objects:

The following events fire on RTCRtpSender objects:

Event name Interface Fired when...
statechange Event The RTCQuicStreamState changed.
Event name Interface Fired when...
ssrcconflict RTCSsrcConflictEvent An SSRC conflict has been detected within the RTP session.

The following events fire on RTCRtpListener objects:

Event name Interface Fired when...
unhandledrtp RTCRtpUnhandledEvent The RTCRtpListener object has received an RTP packet that it cannot deliver to an RTCRtpReceiver object.

The following events fire on RTCDTMFSender and RTCDtmfSender objects:

Event name Interface Fired when...
tonechange Event The RTCDtmfSender object has either just begun playout of a tone (returned as the tone attribute) or just ended playout of a tone (returned as an empty value in the tone attribute).

The following events fire on RTCDataChannel objects:

Event name Interface Fired when...
open Event The RTCDataChannel object's underlying data transport has been established (or re-established).
message MessageEvent [[!webmessaging]] A message was successfully received.
bufferedamountlow Event The RTCDataChannel object's bufferedAmount decreases from above its bufferedAmountLowThreshold to less than or equal to its bufferedAmountLowThreshold.
error ErrorEvent An error has been detected within the RTCDataChannel object. This is not used for programmatic exceptions.
close Event The RTCDataChannel object's underlying data transport has been closed.

The following events fire on RTCSctpTransport objects:

Event name Interface Fired when...
datachannel RTCDataChannelEvent A new RTCDataChannel is dispatched to the script in response to the other peer creating a channel.
statechange Event The RTCSctpTransportState changed.

WebRTC 1.0 Compatibility

It is a goal of the ORTC API to provide the functionality of the WebRTC 1.0 API [[!WEBRTC10]], as well as to enable the WebRTC 1.0 API to be implemented on top of the ORTC API, utilizing a Javascript "shim" library. This section discusses WebRTC 1.0 compatibility issues that have been encountered by ORTC API implementers.

replaceTrack/setTrack

WebRTC 1.0 supports the replaceTrack method, whereas ORTC originally supported the setTrack method. In order to provide backward compatibility, this specification has added replaceTrack as an alias for setTrack.

RTCDTMFSender/RTCDtmfSender

WebRTC 1.0 supports the RTCDTMFSender interface, whereas ORTC originally supported the RTCDtmfSender interface. In order to provide backward compatibility, this specification has added support for the RTCDTMFSender interface.

In WebRTC 1.0 the RTCDTMFSender is an extension of RTCRtpSender whereas in ORTC it is created with an RTCRtpSender. The WebRTC 1.0 behaviour can be emulated by providing a getter for RTCRtpSender.dtmf attribute.

BUNDLE

Via the use of [[!BUNDLE]] it is possible for WebRTC 1.0 implementations to multiplex audio and video on the same RTP session. Within ORTC API, equivalent behavior can be obtained by constructing multiple RTCRtpReceiver and RTCRtpSender objects from the same RTCDtlsTransport object. As noted in [[!RTP-USAGE]] Section 4.4, support for audio/video multiplexing is required, as described in [[!RTP-MULTI-STREAM]].

Voice Activity Detection

[[!WEBRTC10]] Section 4.2.4 defines the RTCOfferOptions dictionary, which includes the voiceActivityDetection attribute, which determines whether Voice Activity Detection (VAD) is enabled within the Offer produced by createOffer(). The effect of setting voiceActivityDetection to true is to include the Comfort Noice (CN) codec defined in [[!RFC3389]] within the Offer.

Within ORTC API, equivalent behavior can be obtained by configuring the Comfort Noise (CN) codec for use within RTCRtpParameters, and/or configuring a codec with built-in support for Discontinuous Operation (DTX), such as Opus. As noted in [[!RFC7874]] Section 3, support for CN is required.

H.264/AVC

[[RFC6184]] Section 8.1 defines the level-asymmetry-allowed SDP parameter supported by some WebRTC 1.0 API implementations. Within ORTC API, the profile-level-id capability is supported for both the RTCRtpSender and RTCRtpReceiver, and the profile-level-id setting is provided for the RTCRtpSender. Since in ORTC API sender and receiver profile-level-id capabilities are independent and there is no profile-level-id setting for an RTCRtpReceiver, ORTC API assumes that implementations support level asymmetry. Therefore a WebRTC 1.0 API shim library for ORTC API should provide a level-asymmetry-allowed value of 1.

Identity and non-multiplexed RTP/RTCP

Where RTP and RTCP are not multiplexed, distinct RTCIceTransport, RTCDtlsTransport and RTCIdentity objects can be constructed for RTP and RTCP. While it is possible for getIdentityAssertion() to be called with different values of provider, protocol and username for the RTP and RTCP RTCIdentity objects, application developers desiring backward compatibility with WebRTC 1.0 are strongly discouraged from doing so, since this is likely to result in an error.

Also, where RTP and RTCP are not multiplexed, it is possible that the assertions for both the RTP and RTCP will be validated, but that the identities will not be equivalent. Applications requiring backward compatibility with WebRTC 1.0 are advised to consider this an error. However, if backward compatibility with WebRTC 1.0 is not required the application can consider an alternative, such as ignoring the RTCP identity assertion.

Examples

Simple Peer-to-peer Example

This example code provides a basic audio and video session between two browsers.


    

QUIC Examples

This example shows how an RTCQuicTransport can be established between browsers.

// Include some helper functions
import {trace, errorHandler, mySendLocalCandidate, myIceGathererStateChange,
  myIceTransportStateChange, myDtlsTransportStateChange} from 'helper';

function initiate(mySignaller) {
  // Prepare the IceGatherer
  var gatherOptions = {
    gatherPolicy: "all",
    iceServers: [
      { urls: "stun:stun1.example.net" },
      { urls: "turn:turn.example.org", username: "user", credential: "myPassword",
        credentialType: "password" }
     ]
  };
  var iceGatherer = new RTCIceGatherer(gatherOptions);
  // Handle state changes
  iceGatherer.onstatechange = function(event) {
    myIceGathererStateChange("iceGatherer", event.state);
  };
  // Handle errors
  iceGatherer.onerror = errorHandler;
  // Prepare to signal local candidates
  iceGatherer.onlocalcandidate = function(event) {
    mySignaller.mySendLocalCandidate(event.candidate);
  };

  // Start gathering
  iceGatherer.gather();
  // Create the IceTransport
  var ice = new RTCIceTransport(iceGatherer);
  // Prepare to handle remote ICE candidates
  mySignaller.onRemoteCandidate = function(remote) {
    ice.addRemoteCandidate(remote.candidate);
  };

  // Create the certificate
  var certs;
  var keygenAlgorithm = { name: "ECDSA", namedCurve: "P-256" };
  RTCCertificate.generateCertificate(keygenAlgorithm).then(function(certificate){
    certs[0] = certificate;
  }, function(){
    trace('Certificate could not be created');
  });

  // Create the DtlsTransport and QuicTransport
  var dlts = new RTCDtlsTransport(ice, certs);
  var quic = new RTCQuicTransport(ice, certs);

  mySignaller.sendInitiate({
    ice: iceGatherer.getLocalParameters(),
    dlts: dtls.getLocalParameters(),
    quic: quic.getLocalParameters(),
    // ... marshall RtpSender/RtpReceiver capabilities as in Section 6.6 Examples 8 and 9.
  }, function(remote) {
    // Start the IceTransport, DtlsTransport and QuicTransport
    ice.start(iceGatherer, remote.ice, RTCIceRole.controlling);
    dtls.start(remote.dtls);
    quic.start(remote.quic);
    // ... configure RtpSender/RtpReceiver objects as in Section 6.6 Examples 8 and 9.
  });
}
// This is an example of how to answer
// Include some helper functions
import {trace, errorHandler, mySendLocalCandidate, myIceGathererStateChange,
  myIceTransportStateChange, myDtlsTransportStateChange} from 'helper';

function accept(mySignaller, remote) {
  var gatherOptions = {
    gatherPolicy: "all",
    iceServers: [
      { urls: "stun:stun1.example.net" },
      { urls: "turn:turn.example.org", username: "user", credential: "myPassword",
        credentialType: "password" }
     ]
  };
  var iceGatherer = new RTCIceGatherer(gatherOptions);
  // Handle state changes
  iceGatherer.onstatechange = function(event) {
    myIceGathererStateChange("iceGatherer", event.state);
  };
  // Handle errors
  iceGatherer.onerror = errorHandler;
  // Prepare to signal local candidates
  iceGatherer.onlocalcandidate = function(event) {
    mySignaller.mySendLocalCandidate(event.candidate);
  };

   // Start gathering
  iceGatherer.gather();
  // Create the IceTransport
  var ice = new RTCIceTransport(iceGatherer);
  // Prepare to handle remote ICE candidates
  mySignaller.onRemoteCandidate = function(remote) {
    ice.addRemoteCandidate(remote.candidate);
  };

   // Create the certificate
  var certs;
  var keygenAlgorithm = { name: "ECDSA", namedCurve: "P-256" };
  RTCCertificate.generateCertificate(keygenAlgorithm).then(function(certificate){
    certs[0] = certificate;
  }, function(){
    trace('Certificate could not be created');
  });

  // Create the DtlsTransport and QuicTransport
  var dtls = new RTCDtlsTransport(ice, certs);
  var quic = new RTCQuicTransport(ice, certs);

  mySignaller.sendAccept({
    ice: iceGatherer.getLocalParameters(),
    dtls: dtls.getLocalParameters(),
    quic: quic.getLocalParameters(),
    // ... marshall RtpSender/RtpReceiver capabilities as in Section 6.6 Examples 8 and 9.
  });

   // Start the IceTransport and DtlsTransport
  ice.start(iceGatherer, remote.ice, RTCIceRole.controlled);
  dtls.start(remote.dtls);
  // Start the QuicTransport
  quic.start(remote.quic);

  // ... configure RtpSender/RtpReceiver objects as in Section 6.6 Examples 8 and 9.

}
                

Determining common capabilities

Several of the examples reference myCapsToSendParams, which returns sender parameters based on the intersection of the capabilities of the RTCRtpSender and RTCRtpReceiver. This section provides an example of what such a library function might do.

RTCRtpCapabilities function getCommonCapabilities(RTCRtpCapabilities 
   localCapabilities, RTCRtpCapabilities remoteCapabilities) {
// Function returning the common capabilities, based on the local sender and
// remote receiver capabilities. An implementation is available here:
// https://webrtc.github.io/adapter/adapter-latest.js
//
// Steps to determine the common capabilities of the local sender and
// remote receiver:
// 1. Determine the common codecs.
// 2. For each common codec, determine the common headerExtensions and
//    rtcpFeedback mechanisms.
// 3. For each common audio codec, determine:
//    a. For channels, the minimum of the local and remote values.
//    b. For maxptime, the minimum of the local and remote maxptime.
//    c. For ptime, the remote ptime if it is less than the computed maxptime
//       in step b); otherwise choose the local ptime.
// 4. For each common codec, determine the common parameters, such as:
//    a. For H.264/AVC, the minimum of the local and remote
//       profile-level-id (the packetization-mode must match for it
//       to be considered a common codec).
//    b. For Opus, usedtx and useinbandfec set to one if both sides
//       support that, otherwise zero.
// 5. Determine the common robustness (forward error correction and 
//    retransmission) mechanisms.
// 6. Determine the payloadType to be used, based on the remote
//    preferredPayloadType.
}

RTCRtpSendParameters function myCapsToSendParams(RTCRtpCapabilities sendCaps,
   RTCRtpCapabilities remoteRecvCaps) {
// Find the common capabilities
   var commonCaps = getCommonCapabilities(sendCaps, remoteRecvCaps); 
// Use the common capabilities to build the RTCRtpSendParameters
// 1. Populate the codecs list
// 2. Populate the headerExtensions
// 3. Set RTCRtcpParameters to their default values.
// 4. Return RTCRtpSendParameters enabling the jointly supported features
//    and codecs.
   var sendParams = {};
// Populate the codecs list and header extensions
   sendParams.codecs = commonCaps.codecs;
   sendParams.headerExtensions = commonCaps.headerExtensions;
   sendParams.rtcp = {reducedSize: false, mux: true};
// Do not set any encodings
   sendParams.encodings = {};
// Set degradationPreference to its default value
   sendParams.degradationPreference = "balanced";
   return sendParams;
}

RTCRtpReceiveParameters function myCapsToRecvParams(RTCRtpCapabilities recvCaps,
   RTCRtpCapabilities remoteSendCaps) {
// Find the common capabilities
   var commonCaps = getCommonCapabilities(remoteSendCaps, recvCaps);
// Use the common capabilities to build the RTCRtpReceiveParameters
// 1. Populate the codecs list
// 2. Populate the headerExtensions
// 3 Set RTCRtcpParameters to their default values.
// 4. Return RTCRtpReceiveParameters enabling the jointly supported features
//    and codecs.
   var receiveParams = {};
// Populate the codecs list and headerExtensions
   receiveParams.codecs = commonCaps.codecs;
   receiveParams.headerExtensions = commonCaps.headerExtensions;
   receiveParams.rtcp = {reducedSize: false, mux: true};
// Do not set any encodings
   receiveParams.encodings = {};
   return receiveParams;
}
            

Acknowledgements

The editor wishes to thank Erik Lagerway (former Chair of the ORTC CG and Co-chair of the WEBRTC WG) for his support. Substantial text in this specification was provided by many people including Peter Thatcher, Martin Thomson, Iñaki Baz Castillo, Jose Luis Millan, Christoph Dorn, Roman Shpount, Emil Ivov, Shijun Sun and Jason Ausborn. Special thanks to Peter Thatcher for his design contributions relating to many of the objects in the current specification, and to Philipp Hancke, Lennart Grahl, Jxck and Iñaki Baz Castillo for their detailed review.

Change Log

This section will be removed before publication.

Changes since 01 February 2018

  1. Update finding common capabilities example, as noted in: Issue 569
  2. Add checks for header extension conflicts, as noted in: Issue 803
  3. Update RTCIdentity (now in Section 14) to reference [[WEBRTC-IDENTITY]], as noted in: Issue 813
  4. Update the RTCDataChannel interface to match WebRTC 1.0, as noted in: Issue 817
  5. Update the RTCSctpTransport interface to match WebRTC 1.0, as noted in: Issue 820
  6. Clarify the operation of the RTCCertificate keying material internal slot, as noted in: Issue 832
  7. Update mandatory-to-implement statistics, as noted in: Issue 833
  8. Separate RTCRtpSendParameters and RTCRtpReceiveParameters, as noted in: Issue 835
  9. Update RID usage in examples, as noted in: Issue 865

Changes since 22 September 2017

  1. Add error checks in send, as noted in: Issue 473
  2. Support priority in RTCDataChannel, as noted in: Issue 623
  3. Fix issues with maxMessageSize in RTCSctpCapabilities, as noted in: Issue 626
  4. Clarify handling of unsupported fingerprint algorithms, as noted in: Issue 752
  5. Add [Exposed] to interfaces, as noted in: Issue 766
  6. Clarify operation of the RTCRtpSender and RTCRtpReceiver constructor, as noted in: Issue 778
  7. Clarify definition of RTCQuicStreamState, as noted in: Issue 788
  8. Reference WebRTC 1.0 for definitions of RTCIceCredentialType and RTCOauthCredential, as noted in: Issue 792
  9. Allow construction of an RTCRtpReceiver object without a transport, as noted in: Issue 801
  10. Clarify track.muted default in RTCRtpReceiver constructor, as noted in: Issue 807
  11. Allow null transport argument to setTransport, as noted in: Issue 808
  12. Update the RTCRtpContributingSource and RTCRtpSynchronizationSource dictionaries to match WebRTC 1.0, as noted in: Issue 809
  13. Update the RTCCertificate interface to match WebRTC 1.0, as noted in: Issue 812

Changes since 01 May 2017

  1. Add checks in the send method, as noted in: Issue 564
  2. Add support for reliable QUIC data exchange, as noted in: Issue 584
  3. Add a compliance section, as noted in: Issue 586
  4. Change type of maxFramerate to double, as noted in: Issue 687
  5. Change codec parameter names from camelCase to SDP-style names, as noted in: Issue 689
  6. Clarify operation of RTCDtlsTransport.getLocalParameters, as noted in: Issue 690
  7. Reference WebIDL definition of ArrayBuffer, as noted in: Issue 692
  8. Define getCertificates() method and remove certificates attribute, as noted in: Issue 696
  9. Clarify sender settings for "flexfec", as noted in: Issue 698
  10. Add a Privacy and Security section, as noted in: Issue 705
  11. Mark getAlgorithm as a "feature at risk", as noted in: Issue 707
  12. Mark the QoS/Priority API as a "feature at risk", as noted in: Issue 708
  13. Add validation steps in the RTCDataChannel constructor, as noted in: Issue 717
  14. Update contributing and synchronization sources for compatibility with WebRTC 1.0, as noted in: Issue 718
  15. Update DTMF support for compatibility with WebRTC 1.0, as noted in: Issue 719
  16. Synchronize with WebRTC 1.0 changes to ICE, as noted in: Issue 720
  17. Clarify key shortening behavior with use of OAuth credentials, as noted in: Issue 721
  18. Enable setTrack/replaceTrack argument to be null, as noted in: Issue 722
  19. Update with WebRTC 1.0 changes to RTCRtpParameters, as noted in: Issue 723
  20. Add support for DTLS error reporting, as noted in: Issue 724
  21. Fix race conditions in the DTMF examples, as noted in: Issue 732
  22. Change numChannels to channels, as noted in: Issue 738
  23. Clarify behavior of getCapabilities, as noted in: Issue 740
  24. Remove the nohost gathering policy, as noted in: Issue 742
  25. Add support for the getDefaultIceServers method, as noted in: Issue 743
  26. Update RTCStatsType values based on WebRTC 1.0, as noted in: Issue 745
  27. Add validation steps in the RTCIceGatherer constructor, as noted in: Issue 748

Changes since 02 December 2016

  1. Updated the RTP matching rules (Section 6.5) to address issues Issue 368 and Issue 547.
  2. Clarified handling of H.264 packetizationMode in RTCRtpCodecCapability, as noted in: Issue 567
  3. Provided updated guidance on use of multiple encodings as noted in: Issue 568
  4. Added support for replaceTrack, as noted in: Issue 614
  5. Updated Oauth token auth support, as noted in: Issue 618
  6. Enabled setting of the RTCSctpTransport remote port, as noted in: Issue 625
  7. Changed the maxMessageSize attribute type to unsigned long, as noted in: Issue 626
  8. Clarified handling of RTX in RTCRtpCapabilities.codecs, as noted in: Issue 627
  9. Clarified RTCSctpTransportState definitions, as noted in: Issue 635
  10. Changed RTCIceComponent values to lower case, as noted in: Issue 636
  11. Described the firing of the mute and unmute events, as noted in: Issue 639
  12. Added optional H.264 codec settings, as noted in: Issue 641
  13. Updated Section 6.5.3 to refer to RTCP packet routing specification, as noted in: Issue 643
  14. Updated Examples 21 and 22 to reflect updated RTCSctpTransport API, as noted in: Issue 648
  15. Provided details on the operation of RTCIceTransport.stop, as noted in: Issue 651
  16. Clarified the purpose of RTCRtpCodecCapabilities.fecMechanisms, as noted in: Issue 655
  17. Allowed an RTCRtpSender to be constructed with a MediaStreamTrack or kind, as noted in: Issue 656
  18. Clarified when multiple RTCRtpCodecCapability entries are provided for the same codec, as noted in: Issue 662
  19. Marked Identity as a "feature at risk", as noted in: Issue 668
  20. Updated Statistics API to track changes to WebRTC Statistics specification, as noted in: Issue 672
  21. Allow construction of an RTCRtpSender without an RTP DtlsTransport, as noted in: Issue 679
  22. Clarify syntax of fingerprint, as noted in: Issue 683

Changes since 20 August 2016

  1. Clarified operation of resolutionScale, as noted in: Issue 362
  2. Clarified meaning of the disconnected state, as noted in: Issue 565
  3. Changed profileLevelId to a DOMString, as noted in: Issue 587
  4. Enabled setTrack() to replace a track that is "ended", as noted in: Issue 589
  5. Clarified operation of setTransport(), as noted in: Issue 591
  6. Clarified behavior of RTCRtpReceiver.stop(), as noted in: Issue 596
  7. Clarified behavior of RTCRtpSender.track.stop(), as noted in: Issue 597
  8. Aligned ORTC with WebRTC 1.0 DTMF API, as noted in: Issue 604
  9. Clarified state transitions of the RTCIceGatherer, as noted in: Issue 606
  10. Clarified behavior of RTCIceTransport.start(), as noted in: Issue 607
  11. Clarified required attributes of an RTCIceCandidate, as noted in: Issue 608
  12. Enable setTrack(null), as noted in: Issue 615
  13. Clarified meaning of sender.track set to null, as noted in: Issue 616

Changes since 04 May 2016

  1. Clarified support for simulcast reception and MRST SVC codecs, as noted in: Issue 175
  2. Clarified handling of media prior to remote fingerprint verification, as noted in: Issue 200
  3. Simplified text relating to event handlers, as noted in: Issue 309
  4. Clarified meaning of RTCRtpCodecCapability.options, as noted in: Issue 412
  5. Clarified exceptions and error conditions in the RTCDtmfSender, as noted in: Issue 446
  6. Provided rtcp.ssrc advice for implementations, as noted in: Issue 462
  7. Clarified effect of RTCRtpReceiver.track.stop(), as noted in: Issue 498
  8. Summarized header extension parameters implementation experience, as noted in: Issue 502
  9. Updated text relating to consent failures, as noted in: Issue 517
  10. Clarified muxId usage, as noted in: Issue 528
  11. Clarified meaning of name, as noted in: Issue 529
  12. Updated ICE transition diagram, as noted in: Issue 535
  13. Clarified "rtx" entries in RTCRtpCodecCapability and RTCRtpCodecParameters, as noted in: Issue 539
  14. Updated text relating to "server could not be reached", as noted in: Issue 542
  15. Corrected codec name usage, as noted in: Issue 544 and Issue 548
  16. Clarified that codecPayloadType can be unset, as noted in: Issue 545
  17. Converted figures to SVG format with figure/caption markup, as noted in: Issue 572

Changes since 01 March 2016

  1. Added the gather() method, as noted in: Issue 165
  2. Removed "public" from RTCIceGatherPolicy, as noted in: Issue 224
  3. Removed the minQuality attribute, as noted in: Issue 351
  4. Made send() and receive() asynchronous, as noted in: Issue 399, Issue 463, Issue 468 and Issue 469
  5. Provided additional information on ICE candidate errors, as noted in: Issue 402
  6. Added state attribute to RTCSctpTransport, as noted in: Issue 403
  7. Provided an example of RTX/RED/FEC configuration, as noted in: Issue 404
  8. Clarified payloadType uniqueness, as noted in: Issue 405
  9. Updated the list of header extensions, as noted in: Issue 409
  10. Added "goog-remb" to the list of feedback mechanisms, as noted in: Issue 410
  11. Added kind argument to the RTCRtpReceiver constructor, as noted in: Issue 411
  12. Clarified send() restrictions on kind, as noted in: Issue 414
  13. Added getAlgorithm() method, as noted in: Issue 427
  14. Changed RTCDataChannel protocol and label to USVString, as noted in: Issue 429
  15. Clarified nullable attributes and methods returning empty lists, as noted in: Issue 433
  16. Clarified support for the "direction" parameter, as noted in: Issue 442
  17. Clarified the apt capability of the "red" codec, as noted in: Issue 444
  18. Clarified usage of RTCRtpEncodingParameters attributes, as noted in: Issue 445
  19. Clarified firing of onssrcconflict event, as noted in: Issue 448
  20. Clarified that CNAME is only set on an RTCRtpSender, as noted in: Issue 450
  21. Updated references, as noted in: Issue 457
  22. Described behavior of send() and receive() with unset RTCRtpEncodingParameters, as noted in: Issue 461
  23. Corrected dictionary initialization in the examples, noted in: Issue 464 and Issue 465
  24. Corrected use of enums in the examples, noted in: Issue 466
  25. Clarified handling of identity constraints, as noted in: Issue 467 and Issue 468
  26. Clarified use of RTCRtpEncodingParameters, as noted in: Issue 470
  27. Changed hostCandidate type, as noted in: Issue 474
  28. Renamed state change event handlers to onstatechange, as noted in: Issue 475
  29. Updated description of RTCIceGatherer closed state, as noted in: Issue 476
  30. Updated description of RTCIceTransport object, as noted in: Issue 477
  31. Updated description of relatedPort, as noted in: Issue 484
  32. Updated description of RTCIceParameters, as noted in: Issue 485
  33. Clarified exceptions in RTCDataChannel construction, as noted in: Issue 492
  34. Provided a reference to error.message, as noted in: Issue 495
  35. Clarified RTCRtpReceiver description, as noted in: Issue 496
  36. Clarified default for clockRate attribute, as noted in: Issue 500
  37. Removed use of "null if unset", as noted in: Issue 503
  38. Updated RTCSctpTransport constructor, as noted in: Issue 504
  39. Clarified behavior of getCapabilities(), as noted in: Issue 509
  40. Addressed issues with RTCDataChannelParameters, as noted in: Issue 519

Changes since 20 November 2015

  1. Clarified unhandledrtp event contents prior to calling receive(), as noted in: Issue 243
  2. Added support for ptime, as noted in: Issue 160
  3. Clarified behavior of send() when encodings is unset, as noted in: Issue 187
  4. Fixed invalid import in examples, as noted in: Issue 250
  5. Added support for Forward Error Correction (FEC), as noted in: Issue 253
  6. Added support for "V" bit in RTCRtpContributingSource, as noted in: Issue 263
  7. Added definition of maxBitrate, as noted in: Issue 267
  8. Clarified definition of audioLevel, as noted in: Issue 377
  9. Use USVString for datachannel.send(), as noted in: PR 387
  10. Clarified requirements for DTMF A-D tone support, as noted in: Issue 391
  11. Changed RTCRtpContributingSource from an interface to a dictionary, as noted in: Issue 289
  12. Added support for maxFramerate encoding parameter, as noted in: Issue 412
  13. Clarified behavior of getRemoteCertificates(), as noted in: Issue 378
  14. Added support for remote peer ICE-lite implementation, as noted in: Issue 293
  15. Clarified RTCDtlsTransportState definition, as noted in: Issue 294
  16. Added explanation for unset iceServers, as noted in: Issue 302
  17. Sync of certificate management API with WebRTC 1.0 changes, as noted in: Issue 303
  18. Added "public" to RTCIceGatherPolicy, as noted in: Issue 305
  19. Fixed problems in Examples 6, 7, 22 and 24, as noted in: Issue 310
  20. Clarified value of the component attribute, as noted in: Issue 314
  21. Clarified behavior with multiple local or remote certificates, as noted in: Issue 317
  22. Added credentialType attribute to Examples, as noted in: Issue 323
  23. Clarified alert handling in RTCDtlsTransportState, as noted in: Issue 327
  24. Added example RTCIceTransportState transitions, as noted in: Issue 332
  25. Clarified object garbage collection, as noted in: Issue 338
  26. Fixed certificate example errors, as noted in: Issue 340
  27. Clarified RTP matching rules, as noted in: Issue 344
  28. Clarified value of rtcpTransport for BUNDLE and RTP/RTCP mux use, as noted in: Issue 349
  29. Fixed markup issues in respec, as noted in: Issue 345
  30. Addressed issues with document anchor links, as noted in: Issue 353
  31. Clarified meaning of active for an RTCRtpReceiver, as noted in: Issue 355
  32. Updated RTCDataChannel event table, as noted in: Issue 358
  33. Clarified behavior of resolutionScale, as noted in: Issue 362
  34. Updated RTP matching rules in Section 6.5 to support FEC/RTX/RED, as noted in: Issue 368
  35. Clarified certificate checking behavior, as noted in: Issue 372
  36. Clarified encodingId syntax, as noted in: Issue 375
  37. Added url to RTCIceGathererEvent, as noted in: Issue 376
  38. Added RangeError for resolutionScale <1.0, as noted in: Issue 379
  39. Added clarification on level asymmetry, as noted in: Issue 382
  40. Clarified DTMF tone requirements, as noted in: Issue 384
  41. Clarified Generic NACK settings, as noted in: Issue 395

Changes since 05 October 2015

  1. Added support for Opus capabilities and settings, as noted in: Issue 252
  2. Added payloadType attribute to RTCRtpRtxParameters, as noted in: Issue 254
  3. Clarified meaning of unset RTCRtpCodecCapability.clockRate, as noted in: Issue 255
  4. Updated VP8 and H.264 capabilities and added VP8 and H.264 settings, as noted in: Issue 258
  5. Added RTX codec parameters, as noted in: Issue 259
  6. Added RED codec parameters, as noted in: Issue 260
  7. Substituted degradationPreference for framerateBias and moved it to RTCRtpParameters, as noted in: Issue 262
  8. Added RID support to the unhandledrtp event, as noted in: Issue 265
  9. Updated references, as noted in: Issue 268
  10. Changed codec parameter and option names to camelCase, as noted in: Issue 273
  11. Added section of codec options, as noted in: Issue 274
  12. Clarified meaning of codec capabilities and options, as noted in: Issue 275 and Issue 277
  13. Clarified behavior in RTCRtpSender constructor and setTrack() when track.readyState is "ended", as noted in: Issue 278

Changes since 22 June 2015

  1. Added support for the WebRTC 1.0 certificate management API, as noted in: Issue 195
  2. Added certificate argument to the RTCDtlsTransport constructor, as noted in: Issue 218
  3. Added the failed state to RTCDtlsTransportState, as noted in: Issue 219
  4. Changed getNominatedCandidatePair to getSelectedCandidatePair, as noted in: Issue 220
  5. Added support for WebRTC 1.0 RTCIceCredentialType, as noted in: Issue 222
  6. Clarified behavior of createAssociatedGatherer(), as noted in: Issue 223
  7. Changed spelling from "iceservers" to "iceServers" for consistency with WebRTC 1.0, as noted in: Issue 225
  8. Added support for SCTP port numbers, as noted in: Issue 227
  9. Changed "outbound-rtp" to "outboundrtp" within the Statistics API, as noted in: Issue 229
  10. Changed maxPacketLifetime and maxRetransmits from unsigned short to unsigned long, as noted in: Issue 231
  11. Clarified DataChannel negotiation, as noted in: Issue 233
  12. Added getContributingSources() method, as noted in: Issue 236
  13. Fixes to Examples 5 and 6, as noted in: Issue 237 and Issue 239
  14. Clarified behavior of RTCDataChannel.send(), as noted in: Issue 240
  15. Fixed typos in Example 11, as noted in: Issue 241 and Issue 248
  16. Added text relating to RTCDataChannel exceptions and errors, as noted in: Issue 242
  17. Reconciliation of RTCRtpEncodingParameters dictionary with WebRTC 1.0, as noted in: Issue 249

Changes since 7 May 2015

  1. Addressed Philipp Hancke's review comments, as noted in: Issue 198
  2. Added the failed state to RTCIceTransportState, as noted in: Issue 199
  3. Added text relating to handling of incoming media packets prior to remote fingerprint verification, as noted in: Issue 200
  4. Added a complete attribute to the RTCIceCandidateComplete dictionary, as noted in: Issue 207
  5. Updated the description of RTCIceGatherer.close() and the closed state, as noted in: Issue 208
  6. Updated Statistics API error handling to reflect proposed changes to the WebRTC 1.0 API, as noted in: Issue 214
  7. Updated Section 10 (RTCDtmfSender) to reflect changes in the WebRTC 1.0 API, as noted in: Issue 215
  8. Clarified state transitions due to consent failure, as noted in: Issue 216
  9. Added a reference to [[FEC]], as noted in: Issue 217

Changes since 25 March 2015

  1. sender.setTrack() updated to return a Promise, as noted in: Issue 148
  2. Added RTCIceGatherer as an optional argument to the RTCIceTransport constructor, as noted in: Issue 174
  3. Clarified handling of contradictory RTP/RTCP multiplexing settings, as noted in: Issue 185
  4. Clarified error handling relating to RTCIceTransport, RTCDtlsTransport and RTCIceGatherer objects in the closed state, as noted in: Issue 186
  5. Added component attribute and createAssociatedGatherer() method to the RTCIceGatherer object, as noted in: Issue 188
  6. Added close() method to the RTCIceGatherer object as noted in: Issue 189
  7. Clarified behavior of TCP candidate types, as noted in: Issue 190
  8. Clarified behavior of iceGatherer.onlocalcandidate, as noted in: Issue 191
  9. Updated terminology in Section 1.1 as noted in: Issue 193
  10. Updated RTCDtlsTransportState definitions, as noted in: Issue 194
  11. Updated RTCIceTransportState definitions, as noted in: Issue 197

Changes since 22 January 2015

  1. Updated Section 6.5 on RTP matching rules, as noted in: Issue 48
  2. Further updates to the Statistics API, reflecting: Issue 85
  3. Added support for maxptime, as noted in: Issue 160
  4. Revised the text relating to RTCDtlsTransport.start(), as noted in: Issue 168
  5. Clarified pre-requisites for insertDTMF(), based on: Issue 178
  6. Added Section 6.5.3 and updated Section 9.5.1 to clarify aspects of RTCP sending and receiving, based on: Issue 180
  7. Fixed miscellaneous typos, as noted in: Issue 183
  8. Added informative reference to [[RFC3264]] Section 5.1, as noted in: Issue 184

Changes since 14 October 2014

  1. Update to the Statistics API, reflecting: Issue 85
  2. Update on 'automatic' use of scalable video coding, as noted in: Issue 156
  3. Update to the H.264 parameters, as noted in: Issue 158
  4. Update to the 'Big Picture', as noted in: Issue 159
  5. Changed 'RTCIceTransportEvent' to 'RTCIceGathererEvent' as noted in: Issue 161
  6. Update to RTCRtpUnhandledEvent as noted in: Issue 163
  7. Added support for RTCIceGatherer.state as noted in: Issue 164
  8. Revised the text relating to RTCIceTransport.start() as noted in: Issue 166
  9. Added text relating to DTLS interoperability with WebRTC 1.0, as noted in: Issue 167
  10. Added a reference to the ICE consent specification, as noted in: Issue 171

Changes since 20 August 2014

  1. Address questions about RTCDtlsTransport.start(), as noted in: Issue 146
  2. Address questions about RTCRtpCodecCapability.preferredPayloadType, as noted in: Issue 147
  3. Address questions about RTCRtpSender.setTrack() error handling, as noted in: Issue 148
  4. Address 'automatic' use of scalable video coding (in RTCRtpReceiver.receive()) as noted in: Issue 149
  5. Renamed RTCIceListener to RTCIceGatherer as noted in: Issue 150
  6. Added text on multiplexing of STUN, TURN, DTLS and RTP/RTCP, as noted in: Issue 151
  7. Address issue with queueing of candidate events within the RTCIceGatherer, as noted in: Issue 152
  8. Clarify behavior of RTCRtpReceiver.getCapabilities(kind), as noted in: Issue 153

Changes since 16 July 2014

  1. Clarification of the ICE restart issue, as noted in : Issue 93
  2. Clarified onerror usage in sender and receiver objects, as noted in: Issue 95
  3. Clarified SST-MS capability issue noted in: Issue 108
  4. Clarification of send() and receive() usage as noted in: Issue 119
  5. Changed ICE state diagram as noted in: Issue 122
  6. Removed getParameters methods and changed send() method as noted in: Issue 136
  7. Changed definition of framerateScale and resolutionScale as noted in: Issue 137
  8. Substituted muxId for receiverId as noted in: Issue 138 and Issue 140
  9. Clarified the setting of track.kind as described in: Issue 141
  10. Added SSRC conflict event to the RTCRtpSender, as described in: Issue 143
  11. Addressed the "end of candidates" issues noted in: Issue 142 and Issue 144

Changes since 16 June 2014

  1. Added section on WebRTC 1.0 compatibility issues, responding to Issue 66
  2. Added Identity support, as described in Issue 78
  3. Reworked getStats() method, as described in Issue 85
  4. Removed ICE restart method described in Issue 93
  5. Addressed CNAME and synchronization context issues described in Issue 94
  6. Fixed WebIDL issues noted in Issue 97
  7. Addressed NITs described in Issue 99
  8. DTLS transport issues fixed as described in Issue 100
  9. ICE transport issues fixed as described in Issue 101
  10. ICE transport controller fixes made as described in Issue 102
  11. Sender and Receiver object fixes made as described in Issue 103
  12. Fixed RTCRtpEncodingParameters default issues described in Issue 104
  13. Fixed 'Big Picture' issues descibed in Issue 105
  14. Fixed RTCRtpParameters default issues described in Issue 106
  15. Added a multi-stream capability, as noted in Issue 108
  16. Removed quality scalability capabilities and parameters, as described in Issue 109
  17. Added scalability examples as requested in Issue 110
  18. Addressed WebRTC 1.0 Data Channel compatibility issue described in Issue 111
  19. Removed header extensions from RTCRtpCodecParameters as described in Issue 113
  20. Addressed RTP/RTCP non-mux issues with IdP as described in Issue 114
  21. Added getParameter methods to RTCRtpSender and RTCRtpReceiver objects, as described in Issue 116
  22. Added layering diagrams as requested in Issue 117
  23. Added a typedef for payloadtype, as described in Issue 118
  24. Moved onerror from the RTCIceTransport object to the RTCIceListener object as described in Issue 121
  25. Added explanation of Voice Activity Detection (VAD), responding to Issue 129
  26. Clarified the meaning of maxTemporalLayers and maxSpatialLayers, as noted in Issue 130
  27. Added [[!RFC6051]] to the list of header extensions and removed RFC 5450, as noted in Issue 131
  28. Addressed ICE terminology issues, as described in Issue 132
  29. Separated references into Normative and Informative, as noted in Issue 133

Changes since 14 May 2014

  1. Added support for non-multiplexed RTP/RTCP and ICE freezing, as described in Issue 57
  2. Added support for getRemoteCertificates(), as described in Issue 67
  3. Removed filterParameters() and createParameters() methods, as described in Issue 80
  4. Partially addressed capabilities issues, as described in Issue 84
  5. Addressed WebIDL type issues described in Issue 88
  6. Addressed Overview section issues described in Issue 91
  7. Addressed readonly attribute issues described in Issue 92
  8. Added ICE restart method to address the issue described in Issue 93
  9. Added onerror eventhandler to sender and receiver objects as described in Issue 95

Changes since 29 April 2014

  1. ICE restart explanation added, as described in Issue 59
  2. Fixes for error handling, as described in Issue 75
  3. Fixes for miscellaneous NITs, as described in Issue 76
  4. Enable retrieval of the SSRC to be used by RTCP, as described in Issue 77
  5. Support for retrieval of audio and video capabilities, as described in Issue 81
  6. getStats interface updated, as described in Issue 82
  7. Partially addressed SVC issues described in Issue 83
  8. Partially addressed statistics update issues described in Issue 85

Changes since 12 April 2014

  1. Fixes for error handling, as described in Issue 26
  2. Support for contributing sources removed (re-classified as a 1.2 feature), as described in Issue 27
  3. Cleanup of DataChannel construction, as described in Issue 60
  4. Separate proposal on simulcast/layering, as described in Issue 61
  5. Separate proposal on quality, as described in Issue 62
  6. Fix for TCP candidate type, as described in Issue 63
  7. Fix to the fingerprint attribute, as described in Issue 64
  8. Fix to RTCRtpFeatures, as described in Issue 65
  9. Support for retrieval of remote certificates, as described in Issue 67
  10. Support for ICE error handling, described in Issue 68
  11. Support for Data Channel send rate control, as described in Issue 69
  12. Support for capabilities and settings, as described in Issue 70
  13. Removal of duplicate RTCIceListener functionality, as described in Issue 71
  14. ICE gathering state added, as described in Issue 72
  15. Removed ICE role from the ICE transport constructor, as described in Issue 73

Changes since 13 February 2014

  1. Support for contributing source information added, as described in Issue 27
  2. Support for control of quality, resolution, framerate and layering added, as described in Issue 31
  3. RTCRtpListener object added and figure in Section 1 updated, as described in Issue 32
  4. More complete support for RTP and Codec Parameters added, as described in Issue 33
  5. Data Channel transport problem fixed, as described in Issue 34
  6. Various NITs fixed, as described in Issue 37
  7. RTCDtlsTransport operation and interface definition updates, as described in: Issue 38
  8. Default values of some dictionary attributes added, to partially address the issue described in: Issue 39
  9. Support for ICE TCP added, as described in Issue 41
  10. Fixed issue with sequences as attributes, as described in Issue 43
  11. Fix for issues with onlocalcandidate, as described in Issue 44
  12. Initial stab at a Stats API, as requested in Issue 46
  13. Added support for ICE gather policy, as described in Issue 47

Changes since 07 November 2013

  1. RTCTrack split into RTCRtpSender and RTCRtpReceiver objects, as proposed on 06 January 2014.
  2. RTCConnection split into RTCIceTransport and RTCDtlsTransport objects, as proposed on 09 January 2014.
  3. RTCSctpTransport object added, as described in Issue 25
  4. RTCRtpHeaderExtensionParameters added, as described in Issue 28
  5. RTCIceListener added, in order to support parallel forking, as described in Issue 29
  6. DTMF support added, as described in Issue 30