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.
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.
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.
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 13, the Identity API is described in Section 14, the Certificate API is described in Section 15, an event summary is provided in Section 16, WebRTC 1.0 compatibility issues are discussed in Section 17, and complete examples are provided in Section 18.
The EventHandler
interface represents a callback used for event handlers as defined in [[!HTML5]].
The concepts queue a task and fires a simple event are defined in [[!HTML5]].
The terms event, event handlers and event handler event types are defined in [[!HTML5]].
The terms MediaStream and MediaStreamTrack are defined in [[!GETUSERMEDIA]].
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 [[GROUPING]] Section 3.7, refers to an 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 [[GROUPING]] 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.
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.
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.
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.
The component-id of the RTCIceGatherer
object. In RTCIceGatherer
objects returned by createAssociatedGatherer()
the value of component is "RTCP". In all
other RTCIceGatherer
objects, the value of component is "RTP".
The current state of the ICE gatherer.
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.
Obtain the ICE parameters of the RTCIceGatherer
.
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.
Create an associated RTCIceGatherer
for RTCP, with the same
RTCIceParameters
and RTCIceGatherOptions
.
If state is "closed", throw an InvalidStateError
exception.
If an RTCIceGatherer
calls the method more than once,
or if component is "RTCP", throw
an InvalidStateError
exception.
This event handler, of event handler type gathererstatechange
,
uses the RTCIceGathererStateChangedEvent
interface.
It MUST be supported by
all objects implementing the RTCIceGatherer
interface.
It is called any time the RTCIceGathererState
changes.
This event handler, of event handler type error
,
MUST be supported by all objects
implementing the RTCIceGatherer
interface.
If TURN credentials are invalid, then this event MUST
be fired.
This event handler, of event handler event type icecandidate
, uses
the RTCIceGathererEvent
interface.
It MUST be supported by all objects implementing the
RTCIceGatherer
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.
The local RTCIceParameters object includes the ICE username fragment and password. The
RTCIceParameters
object corresponding to a remote peer may also include
an iceLite attribute (set to "true" if the remote peer only supports ICE-lite).
ICE username.
ICE password.
If only ICE-lite is supported by the remote peer (true) or not (false or unset).
Since [[!RTCWEB-TRANSPORT]] Section 3.4 requires browser support for full ICE not ICE-lite,
getLocalParameters().iceLite
MUST NOT be set.
The RTCIceCandidate object includes information relating to an ICE candidate.
{ foundation: "abcd1234", priority: 1694498815, ip: "192.0.2.33", protocol: "udp", port: 10000, type: "host" };
A unique identifier that allows ICE to correlate candidates that appear on multiple RTCIceTransport
s.
The assigned priority of the candidate. This is automatically populated by the browser.
The IP address of the candidate.
The protocol of the candidate (UDP/TCP).
The port for the candidate.
The type of candidate.
The type of TCP candidate.
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 set to the empty string.
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 null.
The RTCIceProtocol includes the protocol of the ICE candidate.
A UDP candidate, as described in [[!RFC5245]].
A TCP candidate, as described in [[!RFC6544]].
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.
An active TCP candidate is one for which the transport will attempt to open an outbound connection but will not receive incoming connection requests.
A passive TCP candidate is one for which the transport will receive incoming connection attempts but not attempt a connection.
An so candidate is one for which the transport will attempt to open a connection simultaneously with its peer.
The RTCIceCandidateType includes the type of the ICE candidate.
A host candidate.
A server reflexive candidate.
A peer reflexive candidate.
A relay candidate.
RTCIceCandidateComplete is a dictionary signifying that all RTCIceCandidate
s are gathered.
This attribute is always present and set to true, indicating that ICE candidate gathering is complete.
RTCIceGathererState represents the current state of the ICE gatherer.
The object was just created, and no gathering has occurred yet.
Since RTCIceGatherer
objects gather upon construction, this state will only exist
momentarily.
The RTCIceGatherer
is in the process of gathering candidates (which includes adding new candidates and
removing invalidated candidates).
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.
The RTCIceGatherer
has been closed intentionally (by calling close()
) or as the result of an error.
The icegathererstatechange
event of the RTCIceGatherer
object uses
the RTCIceGathererStateChangedEvent
interface.
Firing an
RTCIceGathererStateChangedEvent
event named
e with an RTCIceGathererState
state 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
RTCIceGathererStateChangedEvent
interface with the
state attribute set to the new RTCIceGathererState
,
MUST be
created and dispatched at the given target.
The state attribute is the new
RTCIceGathererState
that caused the event.
The state attribute is the new
RTCIceGathererState
that caused the event.
The icecandidate
event of the RTCIceGatherer
object uses
the RTCIceGathererEvent
interface.
Firing an
RTCIceGathererEvent
event named
e with an RTCIceCandidate
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.
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.
The ICE candidate that caused the event.
RTCIceGatherOptions provides options relating to the gathering of ICE candidates.
The ICE gather policy.
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 denotes the policy relating to the gathering of ICE candidates.
The ICE gatherer gathers all types of candidates when this value is specified.
The ICE gatherer gathers all ICE candidate types except for host candidates.
The ICE gatherer MUST only gather media relay candidates such as candidates passing through a TURN server. This can be used to reduce leakage of IP addresses in certain use cases.
The ICE gatherer MUST filter out candidates with private IP addresses [[!RFC1918]]. This prevents exposure of internal network details, at the cost of requiring relay usage even for intranet calls, if the Network Address Translator (NAT) does not allow hairpinning as described in [[RFC4787]], section 6.
RTCIceCredentialType represents the type of credential used by a TURN server.
The credential is a long-term authentication password, as described in [[!RFC5389]], Section 10.2.
The credential is an access token, as described in [[RFC7635]], Section 6.2.
The RTCIceServer is used to provide STUN or TURN server configuration. 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.
An example of an array of RTCIceServer
objects:
[ { urls: "stun:stun1.example.net" }, { urls: "turn:turn.example.org", username: "user", credential: "myPassword", credentialType: "password" } ]
STUN or TURN URI(s) as defined in [[!RFC7064]] and [[!RFC7065]] or other URI types.
If this RTCIceServer
object represents a TURN server, then this attribute specifies
the username to use with that TURN server.
If this RTCIceServer
represents a TURN server, then this attribute specifies the credential to use with that TURN server.
If this RTCIceServer
object represents a TURN Server, then this
attribute specifies how credential should be used when that TURN server requests authorization.
// 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 = new RTCIceGatherOptions(); gatherOptions.gatherPolicy = RTCIceGatherPolicy.relay; gatherOptions.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.ongathererstatechange = function(event) { myIceGathererStateChange("iceGatherer", event.state); }; // Prepare to signal local candidates iceGatherer.onlocalcandidate = function(event) { mySendLocalCandidate(event.candidate); }; // 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 || RTCIceComponent.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 RTCIceGathererState.new: trace("IceGatherer: " + name + " Has been created"); break; case RTCIceGathererState.gathering: trace("IceGatherer: " + name + " Is gathering candidates"); break; case RTCIceGathererState.complete: trace("IceGatherer: " + name + " Has finished gathering (for now)"); break; case RTCIceGathererState.closed: trace("IceGatherer: " + name + " Is closed"); break; default: trace("IceGatherer: " + name + " Invalid state"); } } export function myIceTransportStateChange(name, state) { switch (state) { case RTCIceTransportState.new: trace("IceTransport: " + name + " Has been created"); break; case RTCIceTransportState.checking: trace("IceTransport: " + name + " Is checking"); break; case RTCIceTransportState.connected: trace("IceTransport: " + name + " Is connected"); break; case RTCIceTransportState.disconnected: trace("IceTransport: " + name + " Is disconnected"); break; case RTCIceTransportState.completed: trace("IceTransport: " + name + " Has finished checking (for now)"); break; case RTCIceTransportState.failed: trace("IceTransport: " + name + " Has failed"); break; case RTCIceTransportState.closed: trace("IceTransport: " + name + " Is closed"); break; default: trace("IceTransport: " + name + " Invalid state"); } } export function myDtlsTransportStateChange(name, state){ switch(state){ case RTCDtlsTransportState.new: trace('DtlsTransport: ' + name + ' Has been created'); break; case RTCDtlsTransportState.connecting: trace('DtlsTransport: ' + name + ' Is connecting'); break; case RTCDtlsTransportState.connected: trace('DtlsTransport: ' + name + ' Is connected'); break; case RTCDtlsTransportState.failed: trace('DtlsTransport: ' + name + ' Has failed'); break; case RTCDtlsTransportState.closed: trace('DtlsTransport: ' + name + ' Is closed'); break; default: trace('DtlsTransport: ' + name + ' Invalid state'); } }
The RTCIceTransport includes information relating to Interactive Connectivity Establishment (ICE).
An RTCIceTransport
instance is associated to a transport object (such as RTCDtlsTransport
),
and provides RTC related methods to it.
An RTCIceTransport
instance is constructed (optionally) from an RTCIceGatherer
.
If gatherer.state is "closed" or gatherer.component is "RTCP", then throw an InvalidStateError
exception.
An RTCIceTransport
object in the "closed" state can be garbage-collected
when it is no longer referenced.
The iceGatherer attribute is set to the value of gatherer if passed in the constructor or in the latest call to start()
.
The current role of the ICE transport.
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".
The current state of the ICE transport.
Retrieve the sequence of candidates associated with the remote
RTCIceTransport
. Only returns the candidates previously
added using setRemoteCandidates()
or addRemoteCandidate()
.
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.
The first time start()
is called, candidate connectivity checks are started and the
ICE transport attempts to connect to the remote RTCIceTransport
.
If start()
is called with invalid parameters, throw an InvalidParameters
exception.
For example, if gatherer.component has a value different from iceTransport.component,
throw an InvalidParameters
exception. If state or gatherer.state is "closed",
throw an InvalidStateError
exception. When start()
is called again,
RTCIceTransportState
transitions to the "connected" state, all remote candidates
are flushed, and addRemoteCandidate()
or setRemoteCandidates()
must be called
to add the remote candidates back or replace them.
If a newly constructed RTCIceGatherer
object is passed as an argument when start()
is called again, an ICE restart as defined in [[!RFC5245]] Section 9.2.1.1 occurs.
Since start()
does not change the username fragment and password of gatherer,
if start()
is called again with the same value of gatherer,
the existing local candidates are reused and the ICE username fragment and password remains unchanged.
However, other aspects of the behavior are not currently defined.
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, as well as initiating connectivity checks.
Stops and closes the current object. Also removes the object from the
RTCIceTransportController
.
Calling stop()
when state is "closed" has no effect.
Obtain the current ICE parameters of the remote RTCIceTransport
.
Create an associated RTCIceTransport
for RTCP.
If called more than once for the same component, or if state is "closed",
throw an InvalidStateError
exception. If called when
component is "RTCP",
throw an InvalidStateError
exception.
Add a remote candidate associated with the remote RTCIceTransport
.
If state is "closed", throw an InvalidStateError
exception.
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.
Set the sequence of candidates associated with the remote RTCIceTransport
.
If state is "closed", throw an InvalidStateError
exception.
This event handler, of event handler type icestatechange
,
uses the RTCIceTransportStateChangedEvent
interface.
It MUST be supported by
all objects implementing the RTCIceTransport
interface.
It is called any time the RTCIceTransportState
changes.
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.
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()
.
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.
The RTCP component ID, defined (as '2') in [[!RFC5245]] Section 4.1.1.1.
RTCIceRole contains the current role of the ICE transport.
controlling state
controlled state
RTCIceTransportState represents the current state of the ICE transport.
The RTCIceTransport
object is waiting for remote candidates to be supplied.
In this state the object can respond to incoming connectivity checks.
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
a previously successful candidate pair.
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.
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.
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 now failed). Other candidate pairs may become available for testing as new candidates
are trickled, and therefore the "failed" state has not been reached.
A local and remote RTCIceCandidateComplete
dictionary was added as the last candidate
to the RTCIceTransport
and all appropriate candidate pairs have been tested and failed.
The RTCIceTransport
has shut down and is no longer responding to STUN requests.
Some example transitions might be:
new
new
, remote candidates received):
checking
checking
, found usable connection):
connected
checking
, checks fail but gathering still in progress):
disconnected
checking
, gave up): failed
disconnected
, new local candidates):
checking
connected
, finished all checks):
completed
completed
, lost connectivity):
disconnected
new
closed
The non-normative ICE state transitions are:
The icestatechange
event of the RTCIceTransport
object uses
the RTCIceTransportStateChangedEvent
interface.
Firing an
RTCIceTransportStateChangedEvent
event named
e with an RTCIceTransportState
state 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
RTCIceTransportStateChangedEvent
interface with the
state attribute set to the new RTCIceTransportState
,
MUST be
created and dispatched at the given target.
The state attribute is the new
RTCIceTransportState
that caused the event.
The state attribute is the new
RTCIceTransportState
that caused the event.
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 the
pair attribute set to the selected RTCIceCandidatePair
,
MUST be
created and dispatched at the given target.
The pair attribute is the selected
RTCIceCandidatePair
that caused the event.
The pair attribute is the selected
RTCIceCandidatePair
that caused the event.
The RTCIceCandidatePair contains the currently selected ICE candidate pair.
The local ICE candidate.
The remote ICE candidate.
// 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 = new RTCIceGatherOptions(); gatherOptions.gatherPolicy = RTCIceGatherPolicy.relay; gatherOptions.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, RTCIceComponent.RTP, "audio", iceRtpGatherer.getLocalParameters()); }; iceRtcpGatherer.onlocalcandidate = function(event) { mySendLocalCandidate(event.candidate, RTCIceComponent.RTCP, "audio", iceRtpGatherer.getLocalParameters()); }; // 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 === RTCIceComponent.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() });
The RTCDtlsTransport object includes information relating to Datagram Transport Layer Security (DTLS) transport.
An RTCDtlsTransport
instance is associated to an RTCRtpSender
,
an RTCRtpReceiver
, or an RTCSctpTransport
instance.
A RTCDtlsTransport
instance is constructed using an RTCIceTransport
and a sequence of RTCCertificate
objects. 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 exception; otherwise, store the certificates.
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 dependent on remoteParameters, 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).
If an attempt is made to construct a RTCDtlsTransport
instance from an RTCIceTransport
in the "closed" state,
an InvalidStateError
exception is thrown.
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 being revised in [[MUX-FIXES]].
An RTCDtlsTransport
object in the "closed" or "failed" states can be garbage-collected
when it is no longer referenced.
The certificates provided in the constructor.
The associated RTCIceTransport
instance.
The current state of the DTLS transport.
Obtain the DTLS parameters of the local RTCDtlsTransport
.
If multiple certificates were provided in the constructor, then multiple
fingerprints will be returned, one for each certificate.
Obtain the remote DTLS parameters passed in the start()
method.
Prior to calling start()
, null is returned.
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 RTCDtlsTransportState
transitions to "connected".
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.
If remoteParameters is invalid, throw
an InvalidParameters
exception. If start()
is called
after a previous start()
call, or if state is "closed",
throw an InvalidStateError
exception.
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
exception.
Stops and closes the RTCDtlsTransport
object.
Calling stop()
when state is "closed" has no effect.
This event handler, of event handler type dtlsstatechange
,
uses the RTCDtlsTransportStateChangedEvent
interface.
It MUST be supported by
all objects implementing the RTCDtlsTransport
interface.
It is called any time the RTCDtlsTransportState
changes.
This event handler, of event handler type error
,
MUST be supported by all objects implementing the RTCDtlsTransport
interface.
This event MUST be fired on reception of a DTLS error alert; an implementation
SHOULD include DTLS error alert information in error.message.
The RTCDtlsParameters object includes information relating to DTLS configuration.
The DTLS role, with a default of auto.
Sequence of fingerprints, one fingerprint for each certificate.
The RTCDtlsFingerprint object includes the hash function algorithm and certificate fingerprint as described in [[!RFC4572]].
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.
The value of the certificate fingerprint in lowercase hex string as expressed utilizing the syntax of 'fingerprint' in [[!RFC4572]] Section 5.
RTCDtlsRole indicates the role of the DTLS transport.
The DTLS role is determined based on the resolved ICE role: the
"controlled" role acts as the DTLS client,
the "controlling" role acts as the DTLS server. Since RTCDtlsRole
is initialized to "auto" on construction of an RTCDtlsTransport
object,
transport.getLocalParameters().RTCDtlsRole
will have an initial value of "auto".
The DTLS client role.
A transition to "client" will occur if
start(remoteParameters)
is called with remoteParameters.RTCDtlsRole
having a value of "server". If RTCDtlsRole
had previously had a value of "server" (e.g. due to
the RTCDtlsTransport
having previously received packets from a DTLS client), then the
DTLS session is reset prior to transitioning to the "client" role.
The DTLS server role. If RTCDtlsRole
has a value of "auto" and the RTCDtlsTransport
receives a DTLS client_hello packet,
RTCDtlsRole
will transition to "server", even before start()
is called. A transition from "auto"
to "server" will also occur if start(remoteParameters)
is called with remoteParameters.RTCDtlsRole
having a value of "client".
RTCDtlsTransportState indicates the state of the DTLS transport.
The RTCDtlsTransport
object has been created and has not started negotiating yet.
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).
DTLS has completed negotiation of a secure connection and verified the remote fingerprint. Outgoing data and media can now flow through.
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.
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).
The dtlsstatechange event of the RTCDtlsTransport
object uses
the RTCDtlsTransportStateChangedEvent
interface.
Firing an
RTCDtlsTransportStateChangedEvent
event named
e with an RTCDtlsTransportState
state 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
RTCDtlsTransportStateChangedEvent
interface with the
state attribute set to the new RTCDtlsTransportState
,
MUST be
created and dispatched at the given target.
The state attribute is the new
RTCDtlsTransportState
that caused the event.
The state attribute is the new
RTCDtlsTransportState
that caused the event.
// 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 = new RTCIceGatherOptions(); gatherOptions.gatherPolicy = RTCIceGatherPolicy.all; gatherOptions.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); }; // Initialize the ICE and DTLS transport arrays var iceTransports = []; var dtlsTransports = []; // Create the DTLS certificate and parameters var certs; var dtlsParameters = new RTCDtlsParameters(); 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 IceTranport 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); } } }; // ... create RtpSender/RtpReceiver objects as illustrated in Section 6.5 Example 9. mySignaller.mySendInitiate({ "ice": iceGatherer.getLocalParameters(), "dtls": dtlsParameters, // ... marshall RtpSender/RtpReceiver capabilities as illustrated in Section 6.5 Example 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 illustrated in Section 6.5 Example 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) { var gatherOptions = new RTCIceGatherOptions(); gatherOptions.gatherPolicy = RTCIceGatherPolicy.all; gatherOptions.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); }; // 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 illustrated in Section 6.5 Example 9. mySignaller.mySendAccept({ "ice": iceGatherer.getLocalParameters(), "dtls": dtls.getLocalParameters() // ... marshall RtpSender/RtpReceiver capabilities as illustrated in Section 6.5 Example 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 illustrated in Section 6.5 Example 9. }
The RTCRtpSender includes information relating to the RTP sender.
An RTCRtpSender
instance is associated to a sending MediaStreamTrack
and provides RTC related methods to it.
A RTCRtpSender
instance is constructed from an MediaStreamTrack object and
associated to an RTCDtlsTransport
.
If an attempt is made to construct an RTCRtpSender
object with transport.state or rtcpTransport.state "closed",
or if track.readyState is "ended", throw an InvalidStateError
exception.
An RTCRtpSender
object can be garbage-collected once stop()
is called and it is no longer referenced.
The associated MediaStreamTrack
instance.
The RTCDtlsTransport
instance over which RTCP is sent and received.
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.
The associated RTCP RTCDtlsTransport
instance.
Set the RTP RTCDtlsTransport
(and if used) RTCP RTCDtlsTransport
.
If setTransport()
is called with a single argument or if rtcpTransport is not set,
and the last call to sender.send(parameters)
had parameters.rtcp.mux
set to false
, throw an InvalidParameters
exception.
If setTransport()
is called when transport.state or rtcpTransport.state is "closed",
throw an InvalidStateError
exception.
Attempts to replace the track being sent with another track provided.
When the setTrack()
method is invoked, the user agent MUST run the following steps:
Let p be a new promise.
Let withTrack be the argument to this method.
Run the following steps asynchronously:
If withTrack.kind
differs from RTCRtpSender.track.kind
or if withTrack has different peerIdentity
constraints, then reject p with IncompatibleMediaStreamTrackError
and abort these steps.
If withTrack.readyState
is "ended" then reject p with IncompatibleMediaStreamTrackError
and abort these steps.
RTCRtpSender.track
attribute to withTrack,
and have the sender seamlessly
switch to transmitting withTrack in place of what
it is sending. On the remote receiving
end, the track maintains its existing grouping and id until
the connection ends.
Obtain the sender capabilities, based on kind. If kind is
omitted or is set to "", then all capabilities are returned.
Capabilities such as retransmission [[!RFC4588]], redundancy [[RFC2198]], and
Forward Error Correction that do not have an associated value of kind are always
included, regardless of the value of kind passed to getCapabilities()
.
Media to be sent is controlled by parameters. If send()
is called with invalid parameters,
throw an InvalidParameters
exception. If rtcpTransport is not set and
send(parameters)
is called with parameters.rtcp.mux set to "false",
throw an InvalidParameters
exception. If parameters.encodings is unset,
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", "dtmf", "red", "rtx", or a forward error correction codec, and all the other
parameters.encodings[0] attributes (e.g. fec, rtx, priority, maxBitrate, minQuality, resolutionScale,etc.) unset.
Calling send(parameters)
does not update parameters based on what is currently being sent.
The RTCRtpSender
object starts sending when send()
is called for the first time, and changes the sending parameters when send()
is called again.
The RTCRtpSender
object stops sending when stop()
is called.
Stops sending the track on the wire, and sends an RTCP BYE.
Stop is final as in MediaStreamTrack.stop()
This event handler, of event handler type error
,
MUST be supported by all objects implementing the RTCRtpSender
interface.
This event MUST be fired if an issue is found
with the RTCRtpParameters
object passed to
send()
, that is not immediately detected.
This event handler, of event handler type RTCSsrcConflictEvent
,
MUST be supported by all objects implementing the RTCRtpSender
interface.
This event MUST be fired if an SSRC conflict is detected.
On an SSRC conflict, the RTCRtpSender
automatically sends an RTCP BYE on the conflicted SSRC.
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.
The ssrc attribute represents the conflicting SSRC that caused the event.
The ssrc attribute represents the conflicting SSRC that caused the event.
The RTCRtpReceiver includes information relating to the RTP receiver.
An RTCRtpReceiver
instance is associated to a receiving
MediaStreamTrack and provides RTC related methods to it.
A RTCRtpReceiver
instance is constructed from an RTCDtlsTransport
object.
If an attempt is made to construct an RTCRtpReceiver
object with transport.state or rtcpTransport.state "closed",
throw an InvalidStateError
exception.
An RTCRtpReceiver
object can be garbage-collected once stop()
is called and it is no longer referenced.
The associated MediaStreamTrack
instance.
The associated RTP RTCDtlsTransport
instance.
The RTCDtlsTransport
instance over which RTCP is sent and received.
When BUNDLE is used, many RTCRtpReceiver
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.
Set the RTP RTCDtlsTransport
(and if used) RTCP RTCDtlsTransport
.
If setTransport()
is called with a single argument or rtcpTransport is not set,
and the last call to receive(parameters)
had parameters.rtcp.mux
set to false
, throw an InvalidParameters
exception.
If setTransport()
is called and transport.state or rtcpTransport.state is "closed",
throw an InvalidParameters
exception.
Obtain the receiver capabilities, based on kind. If kind is omitted or set to "", then
all capabilities are returned.
Capabilities such as retransmission [[!RFC4588]], redundancy [[RFC2198]], and
Forward Error Correction that do not have an associated value of kind are always
included, regardless of the value of kind passed to getCapabilities()
.
To avoid confusion, getCapabilities(kind)
should return codecs with a matching intrinsic kind value,
as well as codecs with no intrinsic kind
(such as redundancy [[RFC2198]]).
For codecs with no intrinsic kind, RTCRtpCapabilities.RTCRtpCodecCapability[i].kind
returned by getCapabilities(kind)
should be set to the value of kind if kind is
equal to "audio" or "video". If the kind argument was omitted or set to "", then
the value of RTCRtpCapabilities.RTCRtpCodecCapability[i].kind is set to "".
Media to be received is controlled by parameters.
If receive(parameters)
is called with invalid parameters,
throw an InvalidParameters
exception.
If rtcpTransport is not set
and receive(parameters)
is called with parameters.rtcp.mux
set to false
, throw an InvalidParameters
exception.
The receive()
method does not update
parameters based on what is currently being received, so that the value of parameters remains that
last passed to the receive()
method.
The RTCRtpReceiver
object starts receiving when receive()
is called for the first time, and changes the receiving parameters
when receive()
is called again.
The RTCRtpReceiver
object stops receiving when stop()
is called.
After receive()
returns, track is set. The value of track.kind is determined
based on the kind of the codecs provided in parameters.codecs.
If parameters.codecs are all of a single kind then track.kind is set to that kind.
If parameters.codecs are of mixed kind,
throw an InvalidParameters
exception. For this purpose a kind of "" is not considered mixed.
Returns an RTCRtpContributingSource
object for each unique CSRC or SSRC received by this
RTCRtpReceiver
. The browser MUST keep information from RTP packets
received in the last 10 seconds.
Stops receiving the track on the wire. Stop is final like MediaStreamTrack.
This event handler, of event handler type error
,
MUST be supported by all objects implementing the RTCRtpReceiver
interface.
This event MUST be fired if an issue is found with the RTCRtpParameters
object passed to
receive()
, that is not immediately detected.
The RTCRtpContributingSource object contains information
about a contributing source.
Each time an RTP packet is received, the RTCRtpContributingSource
objects are updated.
If the RTP packet contains CSRCs, then the RTCRtpContributingSource
objects corresponding to those
CSRCs are updated, and the level values for those CSRCs are updated based on the mixer-client header extension [[!RFC6464]] if present.
If the RTP packet contains no CSRCs, then the RTCRtpContributingSource
object corresponding to the
SSRC is updated, and the level value for the SSRC is updated based on the client-mixer header extension [[!RFC6464]] if present.
The timestamp of type DOMHighResTimeStamp
[[!HIGHRES-TIME]], indicating the time of reception of the most recent RTP packet
containing the source. The
timestamp is defined in [[!HIGHRES-TIME]] and corresponds to
a local clock.
The CSRC or SSRC value of the contributing source.
The audio level contained in the last RTP packet received from this source. If the source was set from an SSRC, this will be the level value in [[!RFC6464]]. If the source was set from a CSRC, this will be the level value in [[!RFC6465]]. Both [[!RFC6464]] and [[!RFC6465]] define the level as a integral value from 0 to 127 representing the audio level in negative decibels relative to the loudest signal that they system could possibly encode. Thus, 0 represents the loudest signal the system could possibly encode, and 127 represents silence.
Whether the last RTP packet received from this source contains voice activity ("true") or not ("false"). Since the "V" bit is supported in [[!RFC6464]] but not [[!RFC6465]], the voiceActivityFlag attribute will only be set when receivers enable the client-mixer header extension (setting the vad attribute to "true"), and when RTP packets are received from senders enabling the client-mixer header extension (setting the vad attribute to "true").
// 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(transport); var videoReceiver = new RTCRtpReceiver(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 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); videoSender.send(videoSendParams); audioReceiver.receive(audioRecvParams); videoReceiver.receive(videoRecvParams); // 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(transport); var videoReceiver = new RTCRtpReceiver(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 defined in Section 17.2. 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); videoSender.send(videoSendParams); audioReceiver.receive(audioRecvParams); videoReceiver.receive(videoRecvParams); // Now we can render/play // audioReceiver.track and videoReceiver.track. }
The RTCIceTransportController object assists in the managing of ICE freezing and bandwidth estimation.
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).
An RTCIceTransportController
instance is automatically constructed.
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 RTCIceTransport
s
with a component of "RTP",
throw an InvalidParameters
exception.
If transport.state
is "closed", throw an InvalidStateError
exception.
If transport has already been added to another
RTCIceTransportController
object,
or if transport.component
is "RTCP", throw an InvalidStateError
exception.
Returns the RTCIceTransport
objects with a component of "RTP".
// 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 = new RTCIceGatherOptions(); gatherOptions.gatherPolicy = RTCIceGatherPolicy.all; gatherOptions.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, RTCIceComponent.RTP, "audio"); }; audioRtcpIceGatherer.onlocalcandidate = function(event) { mySendLocalCandidate(event.candidate, RTCIceComponent.RTCP, "audio"); }; videoRtpIceGatherer.onlocalcandidate = function(event) { mySendLocalCandidate(event.candidate, RTCIceComponent.RTP, "video"); }; videoRtcpIceGatherer.onlocalcandidate = function(event) { mySendLocalCandidate(event.candidate, RTCIceComponent.RTCP, "video"); }; // Set up the ICE state change event handlers audioRtpIceTransport.onicestatechange = function(event) { myIceTransportStateChange("audioRtpIceTransport", event.state); }; audioRtcpIceTransport.onicestatechange = function(event) { myIceTransportStateChange("audioRtcpIceTransport", event.state); }; videoRtpIceTransport.onicestatechange = function(event) { myIceTransportStateChange("videoRtpIceTransport", event.state); }; videoRtcpIceTransport.onicestatechange = 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 === RTCIceComponent.RTP) { audioRtpIceTransport.addRemoteCandidate(remote.candidate); } else { audioRtcpIceTransport.addRemoteCandidate(remote.candidate); } break; case "video": if (remote.component === RTCIceComponent.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(audioRtpDtlsTransport, audioRtcpDtlsTransport); var videoReceiver = new RTCRtpReceiver(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(videoRtpDtlsTransport); audioReceiver.setTransport(audioRtpDtlsTransport); videoReceiver.setTransport(videoRtpDtlsTransport); // 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); videoSender.send(videoSendParams); audioReceiver.receive(audioRecvParams); videoReceiver.receive(videoRecvParams); }); // Now we can render/play audioReceiver.track and videoReceiver.track
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.
An RTCRtpListener
instance is associated to an RTCDtlsTransport
.
RTCRtpListener instance is constructed from an RTCDtlsTransport
object.
When the RTCRtpListener
object receives an RTP packet over an RTCDtlsTransport
,
the RTCRtpListener
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.
The RTCRtpListener
maintains three tables in order to facilitate matching: 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.
For an RTCRtpReceiver
object receiver, table entries are added when
receiver.receive()
is called, and are removed when receiver.stop()
is called.
If receiver.receive()
is called again, all entries referencing receiver are removed
prior to adding new entries.
SSRC table: Set ssrc_table[parameters.encodings[i].ssrc
] to
receiver for each entry where parameters.encodings[i].ssrc
is set,
for values of i from 0 to the number of encodings.
Set ssrc_table[parameters.encodings[i].rtx.ssrc
] to
receiver for each entry where parameters.encodings[i].rtx.ssrc
is set,
for values of i from 0 to the number of encodings.
Set ssrc_table[parameters.encodings[i].fec.ssrc
] to
receiver for each entry where parameters.encodings[i].fec.ssrc
is set,
for values of i from 0 to the number of encodings.
If ssrc_table[ssrc] is already set to a value other than receiver,
then receiver.receive()
will throw an InvalidParameters
exception.
muxId table: If parameters.muxId
is set, muxId_table[parameters.muxId] is set
to receiver.
If muxId_table[muxId] is already set to a value other than receiver, then
receiver.receive()
will throw an InvalidParameters
exception.
payload type table: If parameters.muxId is unset and parameters.encodings[i].ssrc
is unset for all values of i from 0 to the number of encodings,
then add entries to pt_table by setting
pt_table[parameters.codecs[j].payloadType
] to receiver,
for values of j from 0 to the number of codecs.
If pt_table[pt] is already set to a value other than receiver, or
parameters.codecs[j].payloadType
is unset for any value of j from 0 to the number of codecs,
then receiver.receive()
will throw an InvalidParameters
exception.
If parameters.encodings[i].rtx.payloadType
is set, set
pt_table[parameters.encodings[i].rtx.payloadType
] to receiver,
for values of i from 0 to the number of encodings.
If pt_table[parameters.encodings[i].rtx.payloadType
] is already set,
and parameters.encodings[i].rtx.payloadType is not equal to parameters.codecs[k].payloadType
where k is the value for the "rtx" codec, then receiver.receive()
will throw an
InvalidParameters
exception.
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: set rtp_receiver to ssrc_table[packet.ssrc] and check
whether the value of packet.pt is equal to one of the values of parameters.codecs[j].payloadtype
for rtp_receiver,
where j varies from 0 to the number of codecs.
If so, route the packet to rtp_receiver. If packet.pt does not match,
fire the unhandledrtp
event.
Else if packet.muxId is set: If muxId_table[packet.muxId] is unset, fire the unhandledrtp
event, else set
rtp_receiver to muxId_table[packet.muxId] and 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 the number of codecs.
If so, set ssrc_table[packet.ssrc] to rtp_receiver and route the packet to rtp_receiver.
If packet.pt does not match, fire the unhandledrtp
event.
Else if pt_table[packet.pt] is set: set rtp_receiver to pt_table[packet.pt], set ssrc_table[packet.ssrc] to rtp_receiver, set pt_table[packet.pt] to null and route the packet to rtp_receiver. Question: Do we remove all pt_table[packet.pt] entries set to rtp_receiver?
Else if no matches are found in the ssrc_table, muxId_table or pt_table, fire the unhandledrtp
event.
TODO: Revise this Section to include FEC/RTX/RED.
The RTP RTCDtlsTransport
instance.
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.
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.
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.
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.
The Payload Type value in the RTP stream triggering the unhandledrtp
event.
The SSRC in the RTP stream triggering the unhandledrtp
event.
If present, the value of the MID RTP header extension [[!BUNDLE]] in the RTP stream
triggering the unhandledrtp
event.
If present, the value of the RID RTP header extension [[!RID]] in the RTP stream
triggering the unhandledrtp
event.
The Payload Type value in the RTP stream triggering the unhandledrtp
event.
The SSRC in the RTP stream triggering the unhandledrtp
event.
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 features can be set via RTCRtpParameters
.
Supported codecs.
Supported RTP header extensions.
Supported Forward Error Correction (FEC) mechanisms. Values include "red", "red+ulpfec" and "flexfec". [[FEC]] summarizes requirements relating to FEC mechanisms.
RTCRtcpFeedback provides information on RTCP feedback messages.
Valid values for type are the "RTCP Feedback" Attribute Values enumerated in [[!IANA-SDP-14]] ("ack", "ccm", "nack", etc.).
For a type 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 of "ccm", valid values for parameter are the "Codec Control Messages" enumerated in [[!IANA-SDP-19]] ("fir", "tmmbr" (includes "tmmbn"), etc.).
RTCRtpCodecCapability provides information on the capabilities of a codec.
The MIME media type. Valid types are listed in [[!IANA-RTP-2]].
The media supported by the codec: "audio", "video" or "" for both.
Codec clock rate expressed in Hertz. If unset, the codec is applicable to any clock rate.
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 RTCRtpCodecCapability.name should have a unique value of
RTCRtpCodecCapability.preferredPayloadtype.
The maximum packetization time supported by the RTCRtpReceiver
.
The preferred duration of media represented by a packet in milliseconds for the RTCRtpSender
or
RTCRtpReceiver
.
The number of channels supported (e.g. two for stereo). For video, this attribute is unset.
Transport layer and codec-specific feedback messages for this codec.
Codec-specific parameters that must be signaled to the remote party.
Codec-specific parameters available for signaling.
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.
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.
Whether the implementation can send SVC layers utilizing distinct SSRCs. Unset for audio codecs. For video codecs, only set if the codec supports scalable video coding with multiple streams.
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.
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). |
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.
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. |
spropMaxCaptureRate |
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 | Specifies if the decoder has the capability to take advantage of Opus in-band fec (if true) or not (if false). |
useDtx |
boolean
|
Receiver | Specifies if the decoder prefers the use of DTX (if true) or not (if false). |
The following receiver capability parameters are defined for "vp8", as noted in [[VP8-RTP]] Section 6.1:
Property Name | Values | Receiver/Sender | Notes |
---|---|---|---|
maxFr |
unsigned long
|
Receiver | This parameter indicates the maximum frame rate in frames per second that the decoder is capable of decoding. |
maxFs |
unsigned long long
|
Receiver | This parameter indicates the maximum frame size in macroblocks that the decoder is capable of decoding. |
The following capability parameters are defined for "h264", as noted in [[RFC6184]] Section 8.1, and [[!RTCWEB-VIDEO]] Section 6.2.
Property Name | Values | Receiver/Sender | Notes |
---|---|---|---|
profileLevelId |
unsigned long
|
Receiver/Sender |
This parameter describes the maximum capability of the decoder (for an
RTCRtpReceiver ) or the encoder (for an RTCRtpSender ).
It MUST be supported, as noted in [[!RTCWEB-VIDEO]] Section 6.2.
|
packetizationMode | sequence<unsigned short> |
Receiver/Sender | A sequence of unsigned shorts, each ranging from 0 to 2, indicating supported packetizationMode values. As noted in [[!RTCWEB-VIDEO]] Section 6.2, support for packetization-mode 1 is mandatory. |
maxMbps, maxSmbps, maxFs, maxCpb, maxDpb, maxBr |
unsigned long long
|
Receiver | As noted in [[!RTCWEB-VIDEO]] 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. |
The following capability is defined for "rtx", as noted in [[!RFC4588]] Section 8.6:
Property Name | Values | Receiver/Sender | Notes |
---|---|---|---|
rtxTime |
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. |
The following capability 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. |
As noted in [[RFC5109]], "ulpfec" has no codec-specific capability parameters.
The following capabilities are defined for "flexfec", as noted in [[FLEXFEC]] Section 5.1.1:
Property Name | Values | Receiver/Sender | Notes |
---|---|---|---|
repairWindow |
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 contains the RTP stack settings.
The muxId assigned to the RTP stream, if any, empty string if unset.
In an RTCRtpReceiver
or RTCRtpSender
object, 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.
Note that including muxId in RTCRtpParameters
rather than in RTCRtpEncodingParameters
implies that if it is desired to send simulcast streams with different muxId values for each stream, then multiple
RTCRtpSender
objects are needed.
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()
.
Configured header extensions. If unset, no header extensions are configured.
The "encodings" or "layers" to be used for things like simulcast, Scalable Video Coding, RTX, FEC, etc.
When unset, send()
behaves as described in Section 5.3.3, and receive()
as
described in Section 6.3.3.
Parameters to configure RTCP. If unset, the default values described in Section 9.6.1 are assumed.
When bandwidth is constrained and the RTCRtpSender
needs to choose between degrading
resolution or degrading framerate, degradationPreference
indicates which is preferred.
degradationPreference
is ignored in an RTCRtpReceiver
object. If
unset, "balanced" is assumed.
RTCDegradationPreference can be used to indicate the desired choice between degrading resolution and degrading framerate when bandwidth is constrained.
Degrade resolution in order to maintain framerate.
Degrade framerate in order to maintain resolution.
Degrade a balance of framerate and resolution.
RTCRtcpParameters provides information on RTCP settings.
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).
This is only set for an RTCRtpReceiver
.
If unset, ssrc is chosen by the browser, and 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]].
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; if unset, the CNAME is chosen by the browser.
Whether reduced size RTCP [[!RFC5506]] is configured (if true) or compound RTCP as specified in [[!RFC3550]] (if false).
The default is false
.
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 provides information on codec settings.
The MIME media type. Valid types are listed in [[!IANA-RTP-2]]. The name MUST always be provided.
The value that goes in the RTP Payload Type Field [[!RFC3550]]. The payloadType MUST always be provided.
Codec clock rate expressed in Hertz, null if unset.
The maximum packetization time set on the RTCRtpSender
.
Not specified if unset. If ptime is also set, maxptime is ignored.
The duration of media represented by a packet in milliseconds for the RTCRtpSender
.
If unset, the RTCRtpSender
may select any value up to maxptime.
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.
Transport layer and codec-specific feedback messages for this codec.
Codec-specific parameters available for signaling.
The parameters of common codecs are described below.
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. |
spropMaxCaptureRate |
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). |
The following settings are defined for "vp8":
Property Name | Values | Receiver/Sender | Notes |
---|---|---|---|
maxFr |
unsigned long
|
Sender | This parameter indicates the maximum frame rate in frames per second that the decoder is capable of decoding. |
maxFs |
unsigned long long
|
Sender | This parameter indicates the maximum frame size in macroblocks that the decoder is capable of decoding. |
The following settings are defined for "h264":
Property Name | Values | Receiver/Sender | Notes |
---|---|---|---|
profileLevelId |
unsigned long
|
Sender | This parameter indicates the configuration of the stream to be sent, as noted in [[RFC6184]] Section 8.2.2. It MUST be supported, as noted in [[!RTCWEB-VIDEO]] Section 6.2. |
packetizationMode | unsigned short |
Sender | An unsigned short ranging from 0 to 2, indicating the packetizationMode value to be used by the sender. This setting MUST be supported, as noted in [[!RTCWEB-VIDEO]] Section 6.2. |
The following setting is defined for "rtx", as noted in [[!RFC4588]] Section 8.6:
Property Name | Values | Receiver/Sender | Notes |
---|---|---|---|
rtxTime |
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. |
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. |
As noted in [[RFC5109]], "ulpfec" has no codec-specific settings.
The following settings are defined for "flexfec", as noted in [[FLEXFEC]] Section 5.1.1:
Property Name | Values | Receiver/Sender | Notes |
---|---|---|---|
repairWindow |
unsigned long long
|
Receiver | The time that spans the source packets and the corresponding repair packets, in microseconds. |
l |
unsigned long
|
Receiver | The number of columns of the source block that are protected by this FEC block. |
d |
unsigned long
|
Receiver | The number of rows of the source block that are protected by this FEC block. |
toP |
unsigned short
|
Receiver | 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. |
RTCRtpEncodingParameters
provides information relating to the encoding. Note that all encoding parameters
(such as maxBitrate, maxFramerate and resolutionScale) are applied prior to codec-specific constraints.
The SSRC for this layering/encoding.
If ssrc is unset in a RTCRtpEncodingParameters
object passed to the RTCRtpReceiver.receive
method, the
next unhandled SSRC will match, and an RTCRtpUnhandledEvent
will not be fired.
If ssrc is unset in a RTCRtpEncodingParameters
object passed to the RTCRtpSender.send
method, the browser will choose, and the chosen value is not reflected in RTCRtpEncodingParameters.ssrc
.
If the browser chooses the
ssrc, it may change it due to a collision without firing an RTCSsrcConflictEvent
.
If ssrc is set in a RTCRtpEncodingParameters
object passed to the RTCRtpSender.send
method and an
SSRC conflict is detected, then an RTCSsrcConflictEvent
is fired (see Section 6.4).
For per-encoding codec specifications, give the codec Payload Type here. If unset, the browser will choose.
Specifies the FEC mechanism if set.
Specifies the RTX [[!RFC4588]] parameters if set.
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.
This parameter is ignored in an RTCRtpReceiver
object.
Ramp up resolution/quality/framerate until this bitrate, if set. maxBitrate is the
Transport Independent Application Specific (TIAS) maximum 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 parameter is ignored
in scalable video coding, or in an RTCRtpReceiver
object.
If unset, there is no maximum bitrate.
Never send less than this quality. 1.0 = maximum attainable quality.
For scalable video coding, this parameter is only relevant for the base layer.
This parameter is ignored in an RTCRtpReceiver
object.
If the sender's kind is "video", the video's resolution will be
scaled down in each dimension by the given value before sending. For example,
if the value is 2.0, the video will be scaled down by a factor of 2 in each
dimension, resulting in sending a video of one quarter size. If the value is
1.0 (the default), the video will not be affected. A value less than 1.0
will result in a RangeError
exception when send()
or receive()
is called. For scalable video coding, resolutionScale
refers to the aggregate scale down of this layer when combined with all dependent layers.
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.
The maximum framerate to use for this encoding. This setting is not used for scalable video coding. If framerateScale is set, then maxFramerate is ignored.
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. If unset, the default (true) is assumed.
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. If unset, the default (true) is assumed.
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.
An identifier for the encoding object. This identifier should be unique within the scope of the
localized sequence of RTCRtpEncodingParameters
for any given RTCRtpParameters
object.
Values must be composed only of case-sensitive alphanumeric characters (a-z, A-Z, 0-9) up to a maximum of 16 characters.
For a codec (such as VP8) where a compliant decoder is required to be able to decode anything that an encoder can send,
it is not necessary to specify the expected scalable video coding configuration on the receiver via use of encodingId
(or dependencyEncodingIds). Where specified for a receiver, the expected layering is ignored. A sender MAY
send fewer layers than what is specified in RTCRtpEncodingParameters
, but MUST NOT send more.
An RTCRtpSender
places the value of encodingId into the RID header extension [[!RID]].
The encodingId
s on which this layer depends.
Within this specification encodingId
s are permitted only within the
same RTCRtpEncodingParameters
sequence.
In the future if MST were to be supported, then if searching within an
RTCRtpEncodingParameters
sequence did not produce a match, then a global search
would be carried out.
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.
See [[RTCWEB-TRANSPORT]], Section 4.
See [[RTCWEB-TRANSPORT]], Section 4.
See [[RTCWEB-TRANSPORT]], Section 4.
See [[RTCWEB-TRANSPORT]], Section 4.
// 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 (need high framerate, but don't get too bad quality) var encodings = [{ minQuality: 0.2, degradationPreference: "maintain-framerate" }]; // Screencast (High quality, framerate can be low) 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 }];
// Example of 3-layer temporal scalability encoding var encodings = [{ // Base framerate is one quarter of the input framerate encodingId: "0", framerateScale: 4.0 }, { // Temporal enhancement (half the input framerate when combined with the base layer) encodingId: "1", dependencyEncodingIds: ["0"], framerateScale: 2.0 }, { // Another temporal enhancement layer (full input framerate when all layers combined) encodingId: "2", dependencyEncodingIds: ["0", "1"], framerateScale: 1.0 }]; // Example of 3-layer temporal scalability with all but the base layer disabled var encodings = [{ encodingId: "0", framerateScale: 4.0 }, { encodingId: "1", dependencyEncodingIds: ["0"], framerateScale: 2.0, active: false }, { encodingId: "2", dependencyEncodingIds: ["0", "1"], framerateScale: 1.0, 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.
// Example of 3-layer spatial simulcast var encodings = [{ // Simulcast layer at one quarter scale encodingId: "0", resolutionScale: 4.0 }, { // Simulcast layer at one half scale encodingId: "1", resolutionScale: 2.0 }, { // Simulcast layer at full scale encodingId: "2", resolutionScale: 1.0 }]; // Example of 3-layer spatial simulcast with all but the lowest resolution layer disabled var encodings = [{ encodingId: "0", resolutionScale: 4.0 }, { encodingId: "1", resolutionScale: 2.0, active: false }, { encodingId: "2", resolutionScale: 1.0, active: false }]; // Example of 2-layer spatial simulcast combined with 2-layer temporal scalability var encodings = [{ // Low resolution base layer (half the input framerate, half the input resolution) encodingId: "0", resolutionScale: 2.0, framerateScale: 2.0 }, { // Enhanced resolution Base layer (half the input framerate, full input resolution) encodingId: "E0", resolutionScale: 1.0, framerateScale: 2.0 }, { // Temporal enhancement to the low resolution base layer (full input framerate, half resolution) encodingId: "1", dependencyEncodingIds: ["0"], resolutionScale: 2.0, framerateScale: 1.0 }, { // Temporal enhancement to the enhanced resolution base layer (full input framerate and resolution) encodingId: "E1", dependencyEncodingIds: ["E0"], resolutionScale: 1.0, framerateScale: 1.0 }];
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.
// Example of 3-layer spatial scalability encoding var encodings = [{ // Base layer with one quarter input resolution encodingId: "0", resolutionScale: 4.0 }, { // Spatial enhancement layer providing half input resolution when combined with the base layer encodingId: "1", dependencyEncodingIds: ["0"], resolutionScale: 2.0 }, { // Additional spatial enhancement layer providing full input resolution when combined with all layers encodingId: "2", dependencyEncodingIds: ["0", "1"], resolutionScale: 1.0 }] // Example of 3-layer spatial scalability with all but the base layer disabled var encodings = [{ encodingId: "0", resolutionScale: 4.0 }, { encodingId: "1", dependencyEncodingIds: ["0"], resolutionScale: 2.0, active: false }, { encodingId: "2", dependencyEncodingIds: ["0", "1"], resolutionScale: 1.0, active: false }]; // Example of 2-layer spatial scalability combined with 2-layer temporal scalability var encodings = [{ // Base layer (half input framerate, half resolution) encodingId: "0", resolutionScale: 2.0, framerateScale: 2.0 }, { // Temporal enhancement to the base layer (full input framerate, half resolution) encodingId: "1", dependencyEncodingIds: ["0"], resolutionScale: 2.0, framerateScale: 1.0 }, { // Spatial enhancement to the base layer (half input framerate, full resolution) encodingId: "E0", dependencyEncodingIds: ["0"], resolutionScale: 1.0, framerateScale: 2.0 }, { // Temporal enhancement to the spatial enhancement layer (full input framerate, full resolution) encodingId: "E1", dependencyEncodingIds: ["E0", "1"], resolutionScale: 1.0, framerateScale: 1.0 }];
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.
The SSRC to use for FEC.
If unset in an RTCRtpSender
object, the browser will choose.
The Forward Error Correction (FEC) mechanism to use.
The SSRC to use for retransmission, as specified in [[!RFC4588]].
If unset when passed to RTCRtpSender.send()
, the browser will choose.
The payload type to use for retransmission.
If unset, RTCRtpCodecParameters.payloadType
for the "rtx" codec is used by default.
The media supported by the header extension: "audio" for an audio codec, "video" for a video codec, and "" for both.
The URI of the RTP header extension, as defined in [[!RFC5285]].
The preferred ID value that goes in the packet.
If true, it is preferred that the value in the header be encrypted as per [[!RFC6904]]. Default is to prefer unencrypted.
The URI of the RTP header extension, as defined in [[!RFC5285]].
The value that goes in the packet.
If true, the value in the header is encrypted as per [[!RFC6904]]. Default is unencrypted.
Configuration parameters for the header extension. An example is the "vad" attribute in the client-to-mixer header extension, described in [[!RFC6464]] Section 4.
Registered RTP header extensions are listed in [[!IANA-RTP-10]]. Header extensions mentioned in [[!RTP-USAGE]] and [[!RID]] include:
Header Extension | Reference | Attributes | Notes |
---|---|---|---|
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. |
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 encodingId. |
An RTCDtmfSender instance allows sending DTMF tones to/from the remote peer, as per [[!RFC4733]].
An RTCDtmfSender object is constructed from an RTCRtpSender object.
Whether the RTCDtmfSender is capable of sending DTMF.
The insertDTMF()
method is used to send DTMF tones.
Since DTMF tones cannot be sent without configuring the DTMF codec,
if insertDTMF()
is called prior to sender.send(parameters)
, or if
sender.send(parameters)
was called but
parameters did not include the DTMF codec,
throw an InvalidStateError
exception.
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 are equivalent to A to D. The character ',' indicates a delay of 2 seconds before processing the next character in the tones parameter. All other characters MUST be considered unrecognized. As noted in [[RTCWEB-AUDIO]] Section 3, support for the characters 0 through 9, A through D, #, and * are required.
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. It MUST be at least 30 ms. The default value is 70 ms.
The browser 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
method is invoked, the
user agent MUST run the following steps:
insertDTMF()
toneBuffer
attribute to
the value of the first argument, the duration
attribute to the
value of the second argument, and the interToneGap
attribute
to the value of the third argument.
toneBuffer
contains any
unrecognized characters, throw an
InvalidCharacterError
exception and abort these steps.
toneBuffer
is an empty
string, return.
duration
attribute is less
than 40, set it to 40. If, on the other hand, the value is greater
than 6000, set it to 6000.
interToneGap
attribute
is less than 30, set it to 30.
toneBuffer
is an
empty string, fire an event named tonechange
with an
empty string at the RTCDtmfSender
object
and abort these steps.
toneBuffer
and let
that character be tone.
duration
ms on the
associated RTP media stream, using the appropriate codec.
duration
+
interToneGap
ms
from now that runs the steps labelled Playout task.
tonechange
with a
string consisting of tone at the
RTCDtmfSender
object.
Calling insertDTMF()
with an empty
tones parameter can be used to cancel all tones queued to play after
the currently playing tone.
The RTCRtpSender instance
The ontonechange event handler uses the RTCDTMFToneChangeEvent interface to return the character for each tone as it is played out.
The toneBuffer attribute returns a list of the tones remaining to be played out.
The duration attribute returns the current tone duration
value in milliseconds. This value will be the value last set via the
insertDTMF()
method, or the default value of 100 ms if
insertDTMF()
was called without specifying the duration.
The interToneGap attribute returns the current value of
the between-tone gap. This value will be the value last set via the
insertDTMF()
method, or the default value of 70
ms if insertDTMF()
was called without specifying
the interToneGap.
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.
The tone
attribute contains the character for the tone that has just begun
playout (see insertDTMF()
). If the value is the
empty string, it indicates that the previous tone has completed
playback.
The tone 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 are equivalent to A to D. The character ',' indicates a delay of 2 seconds before processing the next character in the tones parameter. Unrecognized characters are ignored.
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 "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); 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, sender.duration, ""); }; sender.insertDTMF("1234");
Send a 1-second "1" tone followed by a 2-second "2" tone:
var sender = new RTCDtmfSender(sendObject); sender.ontonechange = function(e) { if (e.tone === "1") sender.insertDTMF("2", 2000); }; sender.insertDTMF("1", 1000);
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); 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"); } };
Send the DTMF signal "123" and abort after sending "2".
var sender = new RTCDtmfSender(sendObject); sender.ontonechange = function(e) { if (e.tone === "2") { // empty the buffer to not play any tone after "2" sender.insertDTMF(""); } }; sender.insertDTMF("123");
An RTCDataChannel class instance allows sending data messages to/from the remote peer.
An RTCDataChannel
object is constructed from a RTCDataTransport
object and
an RTCDataChannelParameters
object. If parameters is invalid, throw an
InvalidParameters
exception.
An RTCDataChannel
object can be garbage-collected once readyState
is "closed" and it is no longer referenced.
The RTCDataChannel
interface represents a bi-directional data channel between
two peers.
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 dictionary 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.
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.
The readonly attribute referring to the related transport object.
The parameters applying to this data channel.
The readyState
attribute represents the state of the RTCDataChannel object.
It MUST return the value to which the user agent last set it (as defined by the processing model algorithms).
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).
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.
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.
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
is closing or closed, then abort these steps.
3. Set channel's readyState
attribute to closing.
4. If the closing procedure has not started yet, start it.
This event handler, of event handler type open
,
MUST be supported by all objects implementing the RTCDataChannel interface.
The event type of this event handler is bufferedamountlow
.
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
parameters.negotiated
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 parameters.id
, as noted in
[[!DATA-PROT]] Section 4.
This event handler, of event handler type close
,
MUST be supported by all objects implementing the RTCDataChannel interface.
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. |
Run the steps described by the send()
algorithm with argument type string
object.
Run the steps described by the send()
algorithm with argument type Blob
object.
Run the steps described by the send()
algorithm with argument type ArrayBuffer
object.
Run the steps described by the send()
algorithm with argument type ArrayBufferView
object.
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:
Let channel be the RTCDataChannel
object on which data is to be sent.
If channel.readyState attribute
is connecting
, throw an InvalidStateError
exception and abort these steps.
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.
If channel's underlying data transport is not established yet, or if the closing procedure has started, then abort these steps.
Attempt to send data on channel's underlying data transport; if the data cannot be sent, e.g. because it would need to be buffered but the buffer is full, the user agent MUST abruptly close channel's underlying data transport with an error.
The user agent is attempting to establish the underlying data transport. This is the initial state of an RTCDataChannel object.
The underlying data transport is established and communication is possible. This is the initial state of an RTCDataChannel object dispatched as a part of an RTCDataChannelEvent.
The procedure to close down the underlying data transport has started.
The underlying data transport has been closed or could not be established.
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.
The label attribute represents a label that can be used to distinguish this RTCDataChannel object from other RTCDataChannel objects. The attribute MUST return the value to which it was set when the RTCDataChannel object was constructed. For an SCTP data channel, the label is carried in the DATA_CHANNEL_OPEN message defined in [[!DATA-PROT]] Section 5.1.
The ordered
attribute returns true if the RTCDataChannel is ordered, and
false if out of order delivery is allowed. Default is true.
The attribute MUST return the value to which it was set when the
RTCDataChannel was constructed.
The maxPacketLifetime
attribute represents the length of the time window (in milliseconds) during which
retransmissions may occur in unreliable mode, or null if unset.
The attribute MUST return the value to which it was set when the
RTCDataChannel was constructed.
The maxRetransmits
attribute returns the maximum number of
retransmissions that are attempted in unreliable mode, or null if unset.
The attribute MUST be initialized to null by default and
MUST return the
value to which it was set when the RTCDataChannel was constructed.
The name of the sub-protocol used with this RTCDataChannel if any, or the empty string otherwise (in which case the protocol is unspecified). The attribute MUST return the value to which it was set when the RTCDataChannel was constucted. Sub-protocols are registered in the 'Websocket Subprotocol Name Registry' created in [[RFC6455]] Section 11.5.
The negotiated
attribute returns true if this RTCDataChannel
was negotiated by the application, or false otherwise. The attribute MUST
be initialized to false
by default and MUST return the value to which it
was set when the RTCDataChannel was constructed.
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.
The id attribute returns the id for this RTCDataChannel, or null if unset. 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. The attribute MUST return the value to which it was set when the RTCDataChannel was constructed.
The RTCSctpTransport includes information relating to Stream Control Transmission Protocol (SCTP) transport.
An RTCSctpTransport inherits from an RTCDataTransport object, which is associated to an RTCDataChannel object.
An RTCSctpTransport
is constructed from an RTCDtlsTransport
object,
and optionally a port number (with a default of 5000,
or the next unused port). If a port already in use is provided in the constructor, throw an InvalidParameters
exception.
Creation of an RTCSctpTransport
causes an SCTP INIT request to be issued over the RTCDtlsTransport
from the local RTCSctpTransport
to the remote RTCSctpTransport
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.
An RTCSctpTransport
object can be garbage-collected once stop()
is called
and it is no longer referenced.
The RTCDtlsTransport instance the RTCSctpTransport object is sending over.
The SCTP port number used by the data channel.
Retrieves the RTCSctpCapabilities of the RTCSctpTransport instance.
Stops the RTCSctpTransport instance.
The ondatachannel event handler, of type datachannel
, MUST be
supported by all objects implementing the
RTCSctpTransport
interface.
If the remote peers sets RTCDataChannelParameters
.negotiated
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.
Maximum message size.
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.
The channel
attribute
represents the RTCDataChannel
object associated
with the event.
The RTCDataChannel
object associated with the event.
function initiate(signaller) { // Prepare the ICE gatherer var gatherOptions = new RTCIceGatherOptions(); gatherOptions.gatherPolicy = RTCIceGatherPolicy.all; gatherOptions.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); }; // 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 ICE candidates mySignaller.onRemoteCandidate = function(remote) { ice.addRemoteCandidate(remote.candidate); }; var sctp = new RTCSctpTransport(dtls); // Construct RTCDataChannelParameters object var parameters = new RTCDataChannelParameters(); signaller.sendInitiate({ // ... include ICE/DTLS info from other example. "sctpCapabilities": RTCSctpTransport.getCapabilities() }, function(remote) { sctp.start(remote.sctpCapabilities); // Create the data channel object var channel = new RTCDataChannel(sctp, parameters); channel.send("foo"); }); } function accept(signaller, remote) { var gatherOptions = new RTCIceGatherOptions(); gatherOptions.gatherPolicy = RTCIceGatherPolicy.all; gatherOptions.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); }; // 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); }; signaller.sendAccept({ // ... include ICE/DTLS info from other examples. "sctpCapabilities": RTCSctpTransport.getCapabilities() }); // Create the SctpTransport object and start it var sctp = new RTCSctpTransport(dtls); sctp.start(remote.sctpCapabilties); // 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"); } }; }; }
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]].
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:
Let p be a new promise.
Return, but continue the following steps in the background.
Start gathering the stats.
When the relevant stats have been gathered, return a
new RTCStatsReport
object, representing the
gathered stats.
The getStats()
method delivers a successful result in the form of a
RTCStatsReport
object. A
RTCStatsReport
object 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).
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.
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 a
RTCStats
object.
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).
The type of this object.
The type
attribute
MUST be initialized to the name
of the most specific type this RTCStats
dictionary
represents.
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 is equal to one of the following strings defined in [IANA-TOBE]:
"inboundrtp"
Statistics for the inbound RTP stream. It is
accessed via the RTCInboundRTPStreamStats
defined
in [[!WEBRTC-STATS]] Section 4.2.3. Local inbound RTP
statistics can be obtained from the RTCRtpReceiver
object; remote inbound RTP statistics can be obtained from the
RTCRtpSender
object.
"outboundrtp"
Statistics for the outbound RTP stream. It is
accessed via the RTCOutboundRTPStreamStats
defined in
[[!WEBRTC-STATS]] Section 4.2.4. Local outbound RTP
statistics can be obtained from the RTCRtpSender
object; remote outbound RTP statistics can be obtained from the
RTCRtpReceiver
object.
"session"
Statistics relating to RTCDataChannel
objects.
It is accessed via the RTCPeerConnectionStats
defined in [[!WEBRTC-STATS]] Section 4.3.
"datachannel"
Statistics relating to each RTCDataChannel
id.
It is accessed via the RTCDataChannelStats
defined in [[!WEBRTC-STATS]] Section 4.5.
"track"
Statistics relating to the MediaStreamTrack
object.
It is accessed via the RTCMediaStreamTrackStats
defined in [[!WEBRTC-STATS]] Section 4.4.2.
"transport"
Transport statistics related to the RTCDtlsTransport
object.
It is accessed via the RTCTransportStats
and RTCCertificateStats
defined in [[!WEBRTC-STATS]] Sections 4.6 and 4.9.
"candidatepair"
ICE candidate pair statistics related to
RTCIceTransport
objects.
It is accessed via the RTCIceCandidatePairStats
defined in [[!WEBRTC-STATS]] Section 4.8.
"localcandidate"
ICE local candidates, related to
RTCIceGatherer
objects.
It is accessed via the RTCIceCandidateAttributes
defined in [[!WEBRTC-STATS]] Section 4.7.
"remotecandidate"
ICE remote candidate, related to
RTCIceTransport
objects.
It is accessed via the RTCIceCandidateAttributes
defined in [[!WEBRTC-STATS]] Section 4.7.
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.
RTCP packets arriving on an RTCDtlsTransport
are decrypted and a notification is sent to all
RTCRtpSender
and RTCRtpReceiver
objects utilizing
that transport.
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 and all 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.
Relevant SSRC fields within selected RTCP packets are summarized within [[!RFC3550]] Section 6.4.1 (Sender Report), Section 6.4.2 (Receiver Report), Section 6.5 (SDES), Section 6.6 (BYE), [[!RFC4585]] Section 6.1 (Feedback Messages), and [[!RFC3611]] Section 2 (Extended Reports).
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; } } }
An RTCIdentity
instance enables authentication of a DTLS transport using a
web-based identity provider (IdP).
The idea is that 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, so that the browser need only know how to load the IdP's Javascript (which is deterministic from the IdP's identity), and the generic protocol for requesting and verifying 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 Identity Provider API was implemented. The generic protocol details are described in [[!RTCWEB-SECURITY-ARCH]]. This section specifies the procedures required to instantiate the IdP proxy, request identity assertions, and consume the results.
A RTCIdentity instance is constructed from an RTCDtlsTransport object.
In order to communicate with the IdP, the browser instantiates an isolated interpreted context, effectively an invisible IFRAME. The initial contents of the context are loaded from a URI derived from the IdP's domain name, as described in [[!RTCWEB-SECURITY-ARCH]].
For purposes of generating assertions, the IdP shall be chosen as follows:
getIdentityAssertion()
method has been called,
the IdP provided shall be used.
getIdentityAssertion()
method has not been
called, then the browser can 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.
The browser creates an IdP proxy by loading an isolated, invisible
IFRAME with HTML content from the IdP URI. The URI for the IdP is a
well-known URI formed from the domain
and protocol
fields, as specified in [[!RTCWEB-SECURITY-ARCH]].
When an IdP proxy is required, the browser performs the following steps:
sandbox
attribute is set to
"allow-forms allow-scripts allow-same-origin" to limit the
capabilities available to the IdP. The browser MUST prevent the IdP
proxy from navigating the browsing context to a different location.
The browser MUST prevent the IdP proxy from interacting with the user
(this includes, in particular, popup windows and user dialogs).
MessageChannel
[[!webmessaging]] within the context of
the IdP proxy and assigns one port from the channel to a variable
named rtcwebIdentityPort on the window. This
message channel forms the basis of communication between the browser
and the IdP proxy. Since it is an essential security property of the
web sandbox that a page is unable to insert objects into content from
another origin, this ensures that the IdP proxy can trust that
messages originating from window.rtcwebIdentityPort are
from RTCIdentity
and not some other page. This
protection ensures that pages from other origins are unable to
instantiate IdP proxies and obtain identity assertions.
RTCIdentity
object that it is ready by sending a "READY"
message to the message channel port [[!RTCWEB-SECURITY-ARCH]]. Once
this message is received by the RTCIdentity
object, the
IdP is considered ready to receive requests to generate or verify
identity assertions.
[TODO: This is not sufficient unless we expect the IdP to protect this information. Otherwise, the identity information can be copied from a session with "good" properties to any other session with the same fingerprint information. Since we want to reuse credentials, that would be bad.] The identity mechanism MUST provide an indication to the remote side of whether it requires the stream contents to be protected. Implementations MUST have an user interface that indicates the different cases and identity for these.
The identity assertion request process involves the following steps:
RTCIdentity
instantiates an IdP proxy as
described in Identity
Provider Selection section and waits
for the IdP to signal that it is ready.
RTCIdentity
object desires to be bound to the user's
identity.
RTCIdentity
object over the message channel.
RTCIdentity
object MAY store the identity assertion.The format and contents of the messages that are exchanged are described in detail in [[!RTCWEB-SECURITY-ARCH]].
The IdP proxy can return an "ERROR" response. If an error is
encountered, the getIdentityAssertion
Promise MUST
be rejected.
The browser SHOULD limit the time that it will allow for this process. This includes both the loading of the IdP proxy and the identity assertion generation. Failure to do so potentially causes the corresponding operation to take an indefinite amount of time. This timer can be cancelled when the IdP produces a response. The timer running to completion can be treated as equivalent to an error from the IdP.
NOTE: Where RTP and RTCP are not multiplexed, distinct RTCRtpIceTransport
, RTCRtpDtlsTransport
and RTCIdentity
objects can be constructed for RTP and RTCP.
However, 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.
An IdP could respond to a request to generate an identity assertion with a "LOGINNEEDED" error. This indicates that the site does not have the necessary information available to it (such as cookies) to authorize the creation of an identity assertion.
The "LOGINNEEDED" response includes a URL for a page where the
authorization process can be completed. This URL is exposed to the
application through the loginUrl
attribute
of the RTCIdentityError
object.
This URL might be to a page where a user is able to enter their (IdP)
username and password, or otherwise provide any information the IdP
needs to authorize a assertion request.
An application can load the login URL in an IFRAME or popup; the resulting page then provides the user with an opportunity to provide information necessary to complete the authorization process.
Once the authorization process is complete, the page loaded in the IFRAME or popup sends a message using postMessage [[!webmessaging]] to the page that loaded it (through the window.opener attribute for popups, or through window.parent for pages loaded in an IFRAME). The message MUST be the DOMString "LOGINDONE". This message informs the application that another attempt at generating an identity assertion is likely to be successful.
Identity assertion validation happens
when setIdentityAssertion()
is invoked. The process runs
asynchronously.
The identity assertion validation process involves the following steps:
RTCIdentity
instantiates an IdP proxy as
described in Identity
Provider Selection section and waits
for the IdP to signal that it is ready.
RTCIdentity
object over the message channel.
RTCIdentity
object validates that the fingerprint
provided by the IdP in the validation response matches the certificate
fingerprint that is, or will be, used for communications. This is done by
waiting for the DTLS connection to be established and checking
that the certificate fingerprint on the connection matches the one
provided by the IdP.
RTCIdentity
validates that the domain portion
of the identity matches the domain of the IdP as described in [[!RTCWEB-SECURITY-ARCH]].
RTCIdentity
stores the assertion in the
peerIdentity
, and returns an RTCIdentityAssertion
object
when the Promise from setIdentityAssertion()
is fulfilled.
The assertion
information to be displayed MUST contain the domain name of the IdP as
provided in the assertion.
The IdP might fail to validate the identity assertion by providing an "ERROR" response to the validation request. Validation can also fail due to the additional checks performed by the browser. In both cases, the process terminates and no identity information is exposed to the application or the user.
The browser MUST cause the Promise of setIdentityAssertion()
to be rejected if
validation of an identity assertion fails for any reason.
The browser SHOULD limit the time that it will allow for this process. This includes both the loading of the IdP proxy and the identity assertion validation. Failure to do so potentially causes the corresponding operation to take an indefinite amount of time. This timer can be cancelled when the IdP produces a response. The timer running to completion can be treated as equivalent to an error from the IdP.
The format and contents of the messages that are exchanged are described in detail in [[!RTCWEB-SECURITY-ARCH]].
NOTE: 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. For applications requiring backward compatibility with WebRTC 1.0, this MUST be considered an error. However, if backward compatibility with WebRTC 1.0 is not required the application MAY consider an alternative, such as ignoring the RTCP identity assertion.
The Identity API is described below.
peerIdentity contains the peer identity assertion information if an identity assertion was provided and verified. Once this value is set to a non-null value, it cannot change.
The RTCDtlsTransport
to be authenticated.
Sets the identity provider to be used for a given RTCIdentity
object, and initiates the process of obtaining an identity assertion.
When getIdentityAssertion() is invoked, the user agent MUST run the following steps:
If transport.state
is closed
, throw an
InvalidStateError
exception and abort these
steps.
Set the current identity provider values to the triplet
(provider
, protocol
,
username
).
If any identity provider value has changed, discard any stored identity assertion.
Request an identity assertion from the IdP.
If the IdP proxy provides an assertion over the message channel,
the Promise is fulfilled, and the assertion is returned (equivalent to onidentityresult
in the
WebRTC 1.0 API). If the IdP proxy returns an "ERROR" response, the Promise is rejected, and an RTCIdentityError
object is returned,
(equivalent to onidpassertionerror
in the WebRTC 1.0 API).
Validates the identity assertion. If the Promise is fulfilled,
an RTCIdentityAssertion
is returned.
If the Promise is rejected, an RTCIdentityError
object is returned, (equivalent to
onidpvalidationerror
in the WebRTC 1.0 API).
The domain name of the identity provider that is providing the error response.
An IdP that is unable to generate an identity assertion due to a lack of sufficient user authentication information can provide a URL to a page where the user can complete authentication. If the IdP provides this URL, this attribute includes the value provided by the IdP.
The IdP protocol that is in use.
A domain name representing the identity provider.
A representation of the verified peer identity conforming to [[!RFC5322]]. This identity will have been verified via the procedures described in [[!RTCWEB-SECURITY-ARCH]].
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 = new RTCIceGatherOptions(); gatherOptions.gatherPolicy = RTCIceGatherPolicy.all; gatherOptions.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); }; 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); // Need to 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); }); }); }
The RTCCertificate interface enables the certificates used by an RTCDtlsTransport
to be provided in the constructor.
This makes it possible to support forking, where the offerer will create multiple RTCDtlsTransport
objects
using the same local certificate and fingerprint.
The Certificate API is described below.
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 RTCDtlsTransport
object using
this certificate will fail.
Note that this value might not be reflected in
a notAfter
parameter in the certificate itself.
The fingerprint of the certificate. As noted in [[!JSEP]] Section 5.2.1, the digest algorithm used for the fingerprint matches that used in the certificate signature.
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
certificate that is offered in the DTLS session established
by RTCDtlsTransport
.
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 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
, 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.
The following events fire on RTCDtlsTransport
objects:
Event name | Interface | Fired when... |
---|---|---|
error |
Event |
The RTCDtlsTransport object has received a DTLS Alert. |
dtlsstatechange |
RTCDtlsTransportStateChangedEvent |
The RTCDtlsTransportState changed. |
The following events fire on RTCIceTransport
objects:
Event name | Interface | Fired when... |
---|---|---|
icestatechange |
RTCIceTransportStateChangedEvent |
The RTCIceTransportState changed. |
icecandidatepairchange |
RTCIceCandidatePairChangedEvent |
The selected RTCIceCandidatePair changed. |
The following events fire on RTCIceGatherer
objects:
Event name | Interface | Fired when... |
---|---|---|
error |
Event |
The RTCIceGatherer object has experienced an ICE gathering failure (such as an authentication failure with TURN credentials). |
icegatherstatechange |
RTCIceGathererStateChangedEvent |
The RTCIceGathererState changed. |
icecandidate |
RTCIceGatherer |
A new RTCIceGatherCandidate is made available to the script. |
The following events fire on RTCRtpSender
objects:
Event name | Interface | Fired when... |
---|---|---|
error |
Event |
An error has been detected within the RTCRtpSender object. This is not used for programmatic exceptions. |
ssrcconflict |
RTCSsrcConflictEvent |
An SSRC conflict has been detected. |
The following event fires on RTCRtpReceiver
objects:
Event name | Interface | Fired when... |
---|---|---|
error |
Event |
An error has been detected within the RTCRtpReceiver object,
such as an issue with RTCRtpParameters that could not be detected
until media arrival.
This is not used for programmatic exceptions.
|
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
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 |
Event |
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.
|
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.
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]].
[[!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 [[!RTCWEB-AUDIO]] Section 3, support for CN is required.
[[RFC6184]] Section 8.1 defines the level-asymmetry-allowed
SDP parameter
supported by some WebRTC 1.0 API implementations. Within ORTC API, the profileLevelId
capability is supported for both the RTCRtpSender
and RTCRtpReceiver
,
and the profileLevelId
setting is provided for the RTCRtpSender
.
Since in ORTC API sender and receiver profileLevelId
capabilities are independent
and there is no profileLevelId
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
.
This example code provides a basic audio and video session between two browsers.
RTCRtpParameters function myCapsToSendParams(RTCRtpCapabilities sendCaps, RTCRtpCapabilities remoteRecvCaps) { // Function returning the sender RTCRtpParameters, based on the local sender and remote receiver capabilities. // The goal is to enable a single stream audio and video call with minimum fuss. // // Steps to be followed: // 1. Determine the RTP features that the receiver and sender have in common. // 2. Determine the codecs that the sender and receiver have in common. // 3. Within each common codec, determine the common formats, header extensions and rtcpFeedback mechanisms. // 4. Determine the payloadType to be used, based on the receiver preferredPayloadType. // 5. Set RTCRtcpParameters such as mux to their default values. // 6. Return RTCRtpParameters enablig the jointly supported features and codecs. } RTCRtpParameters function myCapsToRecvParams(RTCRtpCapabilities recvCaps, RTCRtpCapabilities remoteSendCaps) { // Function returning the receiver RTCRtpParameters, based on the local receiver and remote sender capabilities. return myCapsToSendParams(remoteSendCaps, recvCaps); }
The editor wishes to thank Erik Lagerway (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, Jxck and Iñaki Baz Castillo for their detailed review.
This section will be removed before publication.
unhandledrtp
event contents prior to calling receive()
, as noted in:
Issue 243
send()
when encodings is unset, as noted in:
Issue 187
RTCRtpContributingSource
, as noted in:
Issue 263
datachannel.send()
, as noted in:
PR 387
RTCRtpContributingSource
from an interface to a dictionary, as noted in:
Issue 289
getRemoteCertificates()
, as noted in:
Issue 378
RTCDtlsTransportState
definition, as noted in:
Issue 294
RTCIceGatherPolicy
, as noted in:
Issue 305
RTCDtlsTransportState
, as noted in:
Issue 327
RTCIceTransportState
transitions, as noted in:
Issue 332
RTCRtpReceiver
, as noted in:
Issue 355
RTCDataChannel
event table, as noted in:
Issue 358
RTCIceGathererEvent
, as noted in:
Issue 376
RangeError
for resolutionScale <1.0, as noted in:
Issue 379
RTCRtpRtxParameters
, as noted in:
Issue 254
RTCRtpCodecCapability.clockRate
, as noted in:
Issue 255
degradationPreference
for framerateBias
and moved it to RTCRtpParameters
, as noted in:
Issue 262
unhandledrtp
event, as noted in:
Issue 265
RTCRtpSender
constructor and setTrack()
when track.readyState
is "ended", as noted in:
Issue 278
RTCDtlsTransport
constructor, as noted in:
Issue 218
RTCDtlsTransportState
, as noted in:
Issue 219
getNominatedCandidatePair
to getSelectedCandidatePair
, as noted in:
Issue 220
RTCIceCredentialType
, as noted in:
Issue 222
createAssociatedGatherer()
, as noted in:
Issue 223
getContributingSources()
method, as noted in:
Issue 236
RTCDataChannel.send()
, as noted in:
Issue 240
RTCDataChannel
exceptions and errors, as noted in:
Issue 242
RTCRtpEncodingParameters
dictionary with WebRTC 1.0, as noted in:
Issue 249
RTCIceTransportState
, as noted in:
Issue 199
RTCIceCandidateComplete
dictionary, as noted in:
Issue 207
RTCIceGatherer.close()
and the "closed" state, as noted in:
Issue 208
sender.setTrack()
updated to return a Promise, as noted in:
Issue 148
RTCIceGatherer
as an optional argument to the RTCIceTransport
constructor, as noted in:
Issue 174
RTCIceTransport
, RTCDtlsTransport
and RTCIceGatherer
objects in the "closed" state, as noted in:
Issue 186
createAssociatedGatherer()
method to
the RTCIceGatherer
object, as noted in:
Issue 188
close()
method to the RTCIceGatherer
object as noted in:
Issue 189
iceGatherer.onlocalcandidate
, as noted in:
Issue 191
RTCDtlsTransportState
definitions, as noted in:
Issue 194
RTCIceTransportState
definitions, as noted in:
Issue 197
RTCDtlsTransport.start()
, as noted in:
Issue 168
insertDTMF()
, based on:
Issue 178
RTCRtpUnhandledEvent
as noted in:
Issue 163
RTCIceGatherer.state
as noted in:
Issue 164
RTCIceTransport.start()
as noted in:
Issue 166
RTCDtlsTransport.start()
, as noted in:
Issue 146
RTCRtpCodecCapability.preferredPayloadType
, as noted in:
Issue 147
RTCRtpSender.setTrack()
error handling, as noted in:
Issue 148
RTCRtpReceiver.receive()
) as noted in:
Issue 149
RTCIceGatherer
as noted in:
Issue 150
RTCIceGatherer
, as noted in:
Issue 152
RTCRtpReceiver.getCapabilities(kind)
, as noted in:
Issue 153
send()
and receive()
usage as noted in:
Issue 119
RTCRtpSender
, as described in:
Issue 143
getStats()
method, as described in
Issue 85
RTCRtpEncodingParameters
default issues described in
Issue 104
RTCRtpParameters
default issues described in
Issue 106
RTCRtpCodecParameters
as described in
Issue 113
RTCRtpSender
and RTCRtpReceiver
objects, as described in
Issue 116
onerror
from the RTCIceTransport
object to the RTCIceListener
object as described in
Issue 121
RTCDtlsTransport
operation and interface definition updates, as described in:
Issue 38
RTCRtpSender
and RTCRtpReceiver
objects, as proposed on
06 January 2014.
RTCIceTransport
and RTCDtlsTransport
objects, as proposed on
09 January 2014.
RTCSctpTransport
object added, as described in
Issue 25