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, representing a callback used for event handlers, and the ErrorEvent
interface are defined in [[!HTML5]].
The concepts queue a task, fires a simple event and networking task source are defined in [[!HTML5]].
The terms event, event handlers and event handler event types are defined in [[!HTML5]].
The terms MediaStream, MediaStreamTrack, and MediaStreamConstraints are defined in [[!GETUSERMEDIA]].
For Scalable Video Coding (SVC), the terms single-session transmission (SST) and multi-session transmission (MST) are defined in [[RFC6190]]. This specification only supports SST but not MST. The term Single Real-time transport protocol stream Single Transport (SRST), defined in [[RFC7656]] Section 3.7, refers to 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 [[RFC7656]] Section 3.7, refers to an implementation that transmits all layers within a single transport, using multiple RTP streams with a distinct SSRC for each layer. This specification supports SVC codecs utilizing SRST transport (such as with H.264/SVC, VP8 and VP9). Also, sending of simulcast is supported. SVC codecs supporting MRST transport (such as H.264/SVC and HEVC) can also be supported, along with reception of simulcast. However, these features should be considered experimental, since implementation experience is limited.
MediaStreamTrack RTCRtpReceiver.track.
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.
[ Constructor (RTCIceGatherOptions options)]
interface RTCIceGatherer : RTCStatsProvider {
readonly attribute RTCIceComponent component;
readonly attribute RTCIceGathererState state;
void close ();
void gather (optional RTCIceGatherOptions options);
RTCIceParameters getLocalParameters ();
sequence<RTCIceCandidate> getLocalCandidates ();
RTCIceGatherer createAssociatedGatherer ();
attribute EventHandler onstatechange;
attribute EventHandler onerror;
attribute EventHandler onlocalcandidate;
};
RTCIceGatherer| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| options | RTCIceGatherOptions |
✘ | ✘ |
component of type RTCIceComponent, readonlyThe component-id of the RTCIceGatherer object. In
RTCIceGatherer objects returned by
createAssociatedGatherer() the value of the
component attribute is RTCP. In all other
RTCIceGatherer objects, the value of the
component attribute is RTP.
state of type RTCIceGathererState, readonlyThe current state of the ICE gatherer.
onstatechange of type EventHandlerThis event handler, of event handler event type
statechange, MUST
be fired any time the RTCIceGathererState changes.
onerror of type EventHandlerThis event handler, of event handler event type
icecandidateerror, MUST be fired if an error occurs in the gathering of ICE
candidates (such as if TURN credentials are invalid).
onlocalcandidate of type EventHandlerThis event handler, of event handler event type
icecandidate, uses the
RTCIceGathererEvent interface.
It receives events when a new local ICE candidate
is available. Since ICE candidate gathering begins
once an RTCIceGatherer object is
created, candidate events are queued
until an onlocalcandidate event handler
is assigned. When the final candidate is gathered,
a candidate event occurs with an
RTCIceCandidateComplete emitted.
closePrunes 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.
void
gatherGather ICE candidates. If options is omitted, utilize the
value of options passed in the constructor. If
state is closed, throw an
InvalidStateError exception.
| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| options | RTCIceGatherOptions |
✘ | ✔ |
void
getLocalParametersObtain the ICE parameters of the RTCIceGatherer.
If state is closed, throw an
InvalidStateError exception.
RTCIceParameters
getLocalCandidatesRetrieve the sequence of valid local candidates associated with the
RTCIceGatherer. This retrieves all unpruned local
candidates currently known (except for peer reflexive candidates), even if
an onlocalcandidate event hasn't been processed yet.
Prior to calling gather() an empty list will be
returned. If state is closed, throw an
InvalidStateError exception.
sequence<RTCIceCandidate>
createAssociatedGathererCreate 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.
RTCIceGatherer
The RTCIceParameters object includes the ICE username
fragment and password and other ICE-related parameters.
dictionary RTCIceParameters {
DOMString usernameFragment;
DOMString password;
boolean iceLite;
};
usernameFragment of type DOMStringICE username fragment.
password of type DOMStringICE password.
iceLite of type booleanIf only ICE-lite is supported (true) or not
(false or unset). Since [[!RTCWEB-TRANSPORT]] Section 3.4
requires browser support for full ICE, iceLite will
only be true for a remote peer such as a gateway.
getLocalParameters().iceLite MUST NOT be set.
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"
};
typedef (RTCIceCandidate or RTCIceCandidateComplete) RTCIceGatherCandidate;
dictionary RTCIceCandidate {
required DOMString foundation;
required unsigned long priority;
required DOMString ip;
required RTCIceProtocol protocol;
required unsigned short port;
required RTCIceCandidateType type;
RTCIceTcpCandidateType tcpType;
DOMString relatedAddress;
unsigned short relatedPort;
};
foundation of type DOMString, requiredA unique identifier that allows ICE to correlate candidates that appear
on multiple RTCIceTransports.
priority of type unsigned long, requiredThe assigned priority of the candidate. This is automatically populated by the browser.
ip of type DOMString, requiredThe IP address of the candidate.
protocol of type RTCIceProtocol, requiredThe protocol of the candidate (UDP/TCP).
port of type unsigned short, requiredThe port for the candidate.
type of type RTCIceCandidateType, requiredThe type of candidate.
tcpType of type RTCIceTcpCandidateTypeThe type of TCP candidate. For UDP candidates, this attribute is unset.
relatedAddress of type DOMStringFor candidates that are derived from others, such as relay or reflexive
candidates, the relatedAddress refers to the
candidate that these are derived from. For host candidates, the
relatedAddress is unset.
relatedPort of type unsigned
shortFor candidates that are derived from others, such as relay or reflexive
candidates, the relatedPort refers to the host
candidate that these are derived from. For host candidates, the
relatedPort is unset.
The RTCIceProtocol includes the protocol of the ICE
candidate.
enum RTCIceProtocol {
"udp",
"tcp"
};
| Enumeration description | |
|---|---|
udp |
A UDP candidate, as described in [[!RFC5245]]. |
tcp |
A TCP candidate, as described in [[!RFC6544]]. |
The RTCIceTcpCandidateType includes the type of the
ICE TCP candidate, as described in [[!RFC6544]]. Browsers MUST gather active TCP
candidates and only active TCP candidates. Servers and other endpoints MAY gather
active, passive or so candidates.
enum RTCIceTcpCandidateType {
"active",
"passive",
"so"
};
| Enumeration description | |
|---|---|
active |
An active TCP candidate is one for which the transport will attempt to open an outbound connection but will not receive incoming connection requests. |
passive |
A passive TCP candidate is one for which the transport will receive incoming connection attempts but not attempt a connection. |
so |
An so candidate is one for which the transport will attempt to open a connection simultaneously with its peer. |
The RTCIceCandidateType includes the type of the ICE
candidate as defined in [[!RFC5245]] section 15.1.
enum RTCIceCandidateType {
"host",
"srflx",
"prflx",
"relay"
};
| Enumeration description | |
|---|---|
host |
A host candidate, as defined in Section 4.1.1.1 of [[!RFC5245]]. |
srflx |
A server reflexive candidate, as defined in Section 4.1.1.2 of [[!RFC5245]]. |
prflx |
A peer reflexive candidate, as defined in Section 4.1.1.2 of [[!RFC5245]]. |
relay |
A relay candidate, as defined in Section 7.1.3.2.1 of [[!RFC5245]]. |
RTCIceCandidateComplete is a dictionary signifying that
all RTCIceCandidates are gathered.
dictionary RTCIceCandidateComplete {
boolean complete = true;
};
complete of type boolean, defaulting to trueThis attribute is always present and set to true,
indicating that ICE candidate gathering is complete.
RTCIceGathererState represents the current state of the
ICE gatherer.
enum RTCIceGathererState {
"new",
"gathering",
"complete",
"closed"
};
| Enumeration description | |
|---|---|
new |
The object has been created but |
gathering |
|
complete |
The |
closed |
The |
The icecandidateerror event of the
RTCIceGatherer object uses the
RTCIceGathererIceErrorEvent interface.
[ Constructor (DOMString type, RTCIceGathererIceErrorEventInit eventInitDict)]
interface RTCIceGathererIceErrorEvent : Event {
readonly attribute RTCIceCandidate? hostCandidate;
readonly attribute DOMString url;
readonly attribute unsigned short errorCode;
readonly attribute USVString errorText;
};
RTCIceGathererIceErrorEvent| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| type | DOMString |
✘ | ✘ | |
| eventInitDict |
RTCIceGathererIceErrorEventInit |
✘ | ✘ |
hostCandidate of type RTCIceCandidate, readonly , nullableThe RTCIceCandidate used to communicate with the
STUN or TURN server. On a multihomed system, multiple interfaces may be
used to contact the server, and this attribute allows the application to
figure out on which one the failure occurred. If the browser is in a
privacy mode disallowing host candidates, this attribute will be null.
If use of multiple interfaces has been prohibited for privacy reasons,
hostCandidate will be null.
url of type DOMString, readonlyThe url attribute is the STUN or TURN URL
identifying the server on which the failure ocurred.
errorCode of type unsigned short, readonlyThe errorCode attribute is the numeric STUN error
code returned by the STUN or TURN server [[STUN-PARAMETERS]].
If no host candidate can reach the server, errorCode
will be set to a value of 701, as this does not conflict with the STUN
error code range, and hostCandidate will be null. This
error is only fired once per server URL while in the
RTCIceGathererState of gathering.
errorText of type USVString, readonlyThe errorText attribute is the STUN reason text
returned by the STUN or TURN server [[STUN-PARAMETERS]].
If the server could not be reached, errorText will
be set to an implementation-specific value providing details about the
error.
dictionary RTCIceGathererIceErrorEventInit : EventInit {
RTCIceCandidate hostCandidate;
DOMString url;
unsigned short errorCode;
USVString errorText;
};
hostCandidate of type RTCIceCandidateThe RTCIceCandidate used to communicate with the
STUN or TURN server.
url of type DOMStringThe url attribute is the STUN or TURN URL identifying the
server on which the failure ocurred.
errorCode of type unsigned shortThe errorCode attribute is the numeric STUN error code
returned by the STUN or TURN server [[STUN-PARAMETERS]].
errorText of type USVStringThe errorText attribute is the STUN reason text returned by
the STUN or TURN server [[STUN-PARAMETERS]].
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.
[ Constructor (DOMString type, RTCIceGathererEventInit eventInitDict)]
interface RTCIceGathererEvent : Event {
readonly attribute RTCIceGatherCandidate candidate;
readonly attribute DOMString url;
};
RTCIceGathererEvent| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| type | DOMString |
✘ | ✘ | |
| eventInitDict | RTCIceGathererEventInit |
✘ | ✘ |
candidate of type RTCIceGatherCandidate, readonlyThe candidate attribute is the
RTCIceGatherCandidate object with the new ICE candidate
that caused the event. If candidate is of type
RTCIceCandidateComplete, there are no additional
candidates.
url of type DOMString, readonlydictionary RTCIceGathererEventInit : EventInit {
RTCIceGatherCandidate candidate;
DOMString url;
};
candidate of type RTCIceGatherCandidateThe ICE candidate that caused the event.
url of type DOMStringRTCIceGatherOptions provides options relating to the
gathering of ICE candidates.
dictionary RTCIceGatherOptions {
RTCIceGatherPolicy gatherPolicy;
sequence<RTCIceServer> iceServers;
};
gatherPolicy of type RTCIceGatherPolicyThe ICE gather policy.
iceServers of type sequence<RTCIceServer>Additional ICE servers to be configured. Since implementations MAY provide default ICE servers, and applications can desire to restrict communications to the local LAN, iceServers need not be set.
RTCIceGatherPolicy denotes the policy relating to the
gathering of ICE candidates.
enum RTCIceGatherPolicy {
"all",
"nohost",
"relay"
};
| Enumeration description | |
|---|---|
all |
The |
nohost |
The |
relay |
The |
RTCIceCredentialType represents the type of credential
used by a TURN server.
enum RTCIceCredentialType {
"password",
"token"
};
| Enumeration description | |
|---|---|
password |
The credential is a long-term authentication password, as described in [[!RFC5389]], Section 10.2. |
token |
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"}
]
dictionary RTCIceServer {
required (DOMString or sequence<DOMString>) urls;
DOMString username;
DOMString credential;
RTCIceCredentialType credentialType = "password";
};
urls of type (DOMString or sequence<DOMString>),
requiredSTUN or TURN URI(s) as defined in [[!RFC7064]] and [[!RFC7065]] or other URI types.
username of type DOMStringIf this RTCIceServer object represents a TURN
server, then this attribute specifies the username to use with that TURN
server.
credential of type DOMStringIf this RTCIceServer represents a TURN server, then
this attribute specifies the credential to use with that TURN server.
credentialType of type RTCIceCredentialType, defaulting to
"password"If this RTCIceServer object represents a TURN
Server, then this attribute specifies how credential
should be used when that TURN server requests authorization.
// Example to demonstrate use of RTCIceCandidateComplete
// Include some helper functions
import {trace, errorHandler, mySendLocalCandidate, myIceGathererStateChange,
myIceTransportStateChange, myDtlsTransportStateChange} from 'helper';
// Create ICE gather options
var gatherOptions = {
gatherPolicy: "relay",
iceServers: [
{ urls: "stun:stun1.example.net" },
{ urls: "turn:turn.example.org", username: "user", credential: "myPassword",
credentialType: "password" }
]
};
// Create IceGatherer object
var iceGatherer = new RTCIceGatherer(gatherOptions);
// Handle state changes
iceGatherer.onstatechange = function(event) {
myIceGathererStateChange("iceGatherer", event.state);
};
// Prepare to signal local candidates
iceGatherer.onlocalcandidate = function(event) {
mySendLocalCandidate(event.candidate);
};
// Start gathering
iceGatherer.gather();
// Set up response function
mySignaller.onResponse = function(responseSignaller, response) {
// We may get N responses
// ... deal with the N responses as shown in Example 5 of Section 3.11.
};
mySignaller.send({
"ice": iceGatherer.getLocalParameters()
});
// Helper functions used in all the examples (helper.js)
export function trace(text) {
// This function is used for logging.
text = text.trimRight();
if (window.performance) {
var now = (window.performance.now() / 1000).toFixed(3);
console.log(now + ": " + text);
} else {
console.log(text);
}
}
export function errorHandler(error) {
trace("Error encountered: " + error.name);
}
export function mySendLocalCandidate(candidate, component, kind, parameters) {
// Set default values
kind = kind || "all";
component = component || "RTP";
parameters = parameters || null;
// Signal the local candidate
mySignaller.mySendLocalCandidate({
"candidate": candidate,
"component": component,
"kind": kind,
"parameters": parameters
});
}
export function myIceGathererStateChange(name, state) {
switch (state) {
case "new":
trace("IceGatherer: " + name + " Has been created");
break;
case "gathering":
trace("IceGatherer: " + name + " Is gathering candidates");
break;
case "complete":
trace("IceGatherer: " + name + " Has finished gathering (for now)");
break;
case "closed":
trace("IceGatherer: " + name + " Is closed");
break;
default:
trace("IceGatherer: " + name + " Invalid state");
}
}
export function myIceTransportStateChange(name, state) {
switch (state) {
case "new":
trace("IceTransport: " + name + " Has been created");
break;
case "checking":
trace("IceTransport: " + name + " Is checking");
break;
case "connected":
trace("IceTransport: " + name + " Is connected");
break;
case "disconnected":
trace("IceTransport: " + name + " Is disconnected");
break;
case "completed":
trace("IceTransport: " + name + " Has finished checking (for now)");
break;
case "failed":
trace("IceTransport: " + name + " Has failed");
break;
case "closed":
trace("IceTransport: " + name + " Is closed");
break;
default:
trace("IceTransport: " + name + " Invalid state");
}
}
export function myDtlsTransportStateChange(name, state){
switch(state){
case "new":
trace('DtlsTransport: ' + name + ' Has been created');
break;
case "connecting":
trace('DtlsTransport: ' + name + ' Is connecting');
break;
case "connected":
trace('DtlsTransport: ' + name + ' Is connected');
break;
case "failed":
trace('DtlsTransport: ' + name + ' Has failed');
break;
case "closed":
trace('DtlsTransport: ' + name + ' Is closed');
break;
default:
trace('DtlsTransport: ' + name + ' Invalid state');
}
}
The RTCIceTransport allows an application access to
information about the Interactive Connectivity Establishment (ICE) transport over
which packets are sent and received. In particular, ICE manages peer-to-peer
connections which involve state which the application may want to access.
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.
[ Constructor (optional RTCIceGatherer gatherer)]
interface RTCIceTransport : RTCStatsProvider {
readonly attribute RTCIceGatherer? iceGatherer;
readonly attribute RTCIceRole role;
readonly attribute RTCIceComponent component;
readonly attribute RTCIceTransportState state;
sequence<RTCIceCandidate> getRemoteCandidates ();
RTCIceCandidatePair? getSelectedCandidatePair ();
void start (RTCIceGatherer gatherer, RTCIceParameters remoteParameters, optional RTCIceRole role = "controlled");
void stop ();
RTCIceParameters? getRemoteParameters ();
RTCIceTransport createAssociatedTransport ();
void addRemoteCandidate (RTCIceGatherCandidate remoteCandidate);
void setRemoteCandidates (sequence<RTCIceCandidate> remoteCandidates);
attribute EventHandler onstatechange;
attribute EventHandler oncandidatepairchange;
};
RTCIceTransport| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| gatherer | RTCIceGatherer |
✘ | ✔ |
iceGatherer of type RTCIceGatherer, readonly , nullableThe iceGatherer attribute is set to the value of
gatherer if passed in the constructor or in the latest call to
start().
role of type RTCIceRole, readonlyThe current role of the ICE transport.
component of type RTCIceComponent, readonlyThe component-id of the RTCIceTransport object. In
RTCIceTransport objects returned by
createAssociatedTransport(), the value of
component is RTCP. In all other
RTCIceTransport objects, the value of
component is RTP.
state of type RTCIceTransportState, readonlyThe current state of the ICE transport.
onstatechange of type EventHandlerThis event handler, of event handler event type
statechange, MUST
be fired any time the RTCIceTransportState changes.
oncandidatepairchange of type EventHandlerThis 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.
getRemoteCandidatesRetrieve the sequence of candidates associated with the remote
RTCIceTransport. Only returns the candidates previously
added using setRemoteCandidates() or
addRemoteCandidate(). If there are no remote
candidates, an empty list is returned.
sequence<RTCIceCandidate>
getSelectedCandidatePairRetrieves 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.
RTCIceCandidatePair, nullable
startAs noted in [[!RFC5245]] Section 7.1.2.3, an incoming connectivity check
utilizes the local/remote username fragment and the local password, whereas
an outgoing connectivity check utilizes the local/remote username fragment
and the remote password. Since start() provides role
information, as well as the remote username fragment and password, once
start() is called an RTCIceTransport
object can respond to incoming connectivity checks based on its
configured role. Since start() enables candidate pairs
to be formed, it also enables initiating connectivity checks.
When start() is called, the following
steps MUST be run:
gatherer.component has a value
different from component, throw an
InvalidParameters exception.
state or gatherer.state
is closed, throw an InvalidStateError
exception.
remoteParameters.usernameFragment
or remoteParameters.password is unset,
throw an InvalidParameters exception.
start() is called again and
role is changed, throw an
InvalidParameters exception.
start() is called again with the same
values of gatherer and
remoteParameters, this has
no effect.
start() is called for the first time
and either gatherer was not
passed in the constructor or the value of
gathererer is unchanged, if
there are remote candidates, set state
to checking and start connectivity checks.
If there are no remote candidates, state
remains new.
start() is called for the first time
and the value of gathererer
passed as an argument is different from that passed
in the constructor, flush local candidates. If there
are remote candidates, set state to
checking and start connectivity checks.
If there are no remote candidates, state
remains new.
start() is called again with the same
value of gathererer but the value
of remoteParameters has changed,
local candidates are kept, remote candidates are flushed,
candidate pairs are flushed and state
transitions to new.
start() is called again with a new value
of gatherer but the value of
remoteParameters is unchanged,
local candidates are flushed, candidate pairs are flushed,
new candidate pairs are formed with existing remote candidates,
and state transitions to checking.
start() is called again with new values of
gatherer and
remoteParameters, local
candidates are flushed, remote candidates are flushed,
candidate pairs are flushed and state transitions
to new.
| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| gatherer | RTCIceGatherer |
✘ | ✘ | |
| remoteParameters | RTCIceParameters |
✘ | ✘ | |
| role | RTCIceRole = controlled |
✘ | ✔ |
void
stopStops and closes the current object. Also removes the object from the
RTCIceTransportController. Calling stop()
when state is closed has no effect.
void
getRemoteParametersObtain the current ICE parameters of the remote
RTCIceTransport.
RTCIceParameters, nullable
createAssociatedTransportCreate 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.
RTCIceTransport
addRemoteCandidateAdd 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.
| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| remoteCandidate | RTCIceGatherCandidate |
✘ | ✘ |
void
setRemoteCandidatesSet the sequence of candidates associated with the remote
RTCIceTransport. If state is
closed, throw an InvalidStateError exception.
| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| remoteCandidates |
sequence<RTCIceCandidate> |
✘ | ✘ |
void
RTCIceComponent contains the component-id of the
RTCIceTransport, which will be RTP unless RTP and
RTCP are not multiplexed and the RTCIceTransport object was
returned by createAssociatedTransport().
enum RTCIceComponent {
"RTP",
"RTCP"
};
| Enumeration description | |
|---|---|
RTP |
The RTP component ID, defined (as '1') in [[!RFC5245]] Section 4.1.1.1. Protocols multiplexed with RTP (e.g. SCTP data channel) share its component ID. |
RTCP |
The RTCP component ID, defined (as '2') in [[!RFC5245]] Section 4.1.1.1. |
RTCIceRole contains the current role of the ICE
transport.
enum RTCIceRole {
"controlling",
"controlled"
};
| Enumeration description | |
|---|---|
controlling |
controlling state |
controlled |
controlled state |
RTCIceTransportState represents the current state of the
ICE transport.
enum RTCIceTransportState {
"new",
"checking",
"connected",
"completed",
"disconnected",
"failed",
"closed"
};
| Enumeration description | |
|---|---|
new |
The |
checking |
The |
connected |
The |
completed |
A local and remote |
disconnected |
Connectivity is currently lost for this |
failed |
A local and remote |
closed |
The |
Some example transitions might be:
newnew, remote candidates received): checkingchecking, found usable connection): connectedchecking, checks fail but gathering still in progress):
disconnectedchecking, gave up): faileddisconnected, new local candidates): checkingconnected, finished all checks): completedcompleted, lost connectivity): disconnectednewclosedThe icecandidatepairchange event of the
RTCIceTransport object uses the
RTCIceCandidatePairChangedEvent interface.
Firing an RTCIceCandidatePairChangedEvent event named
e with an RTCIceCandidatePair pair means
that an event with the name e, which does not bubble (except where
otherwise stated) and is not cancelable (except where otherwise stated), and which
uses the RTCIceCandidatePairChangedEvent interface with
pair set to the selected RTCIceCandidatePair,
MUST be created and dispatched at the given
target.
[ Constructor (DOMString type, RTCIceCandidatePairChangedEventInit eventInitDict)]
interface RTCIceCandidatePairChangedEvent : Event {
readonly attribute RTCIceCandidatePair pair;
};
RTCIceCandidatePairChangedEvent| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| type | DOMString |
✘ | ✘ | |
| eventInitDict |
RTCIceCandidatePairChangedEventInit |
✘ | ✘ |
pair of type RTCIceCandidatePair, readonlyThe pair attribute is the selected
RTCIceCandidatePair that caused the event.
dictionary RTCIceCandidatePairChangedEventInit : EventInit {
RTCIceCandidatePair pair;
};
pair of type RTCIceCandidatePairThe pair attribute is the selected
RTCIceCandidatePair that caused the event.
The RTCIceCandidatePair contains the currently selected
ICE candidate pair.
dictionary RTCIceCandidatePair {
RTCIceCandidate local;
RTCIceCandidate remote;
};
local of type RTCIceCandidateThe local ICE candidate.
remote of type RTCIceCandidateThe 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 = {
gatherPolicy: "relay",
iceServers: [
{ urls: "stun:stun1.example.net" },
{ urls: "turn:turn.example.org", username: "user", credential: "myPassword",
credentialType: "password" }
]
};
// Create ICE gatherer objects
var iceRtpGatherer = new RTCIceGatherer(gatherOptions);
var iceRtcpGatherer = iceRtpGatherer.createAssociatedGatherer();
// Prepare to signal local candidates
iceRtpGatherer.onlocalcandidate = function(event) {
mySendLocalCandidate(event.candidate, "RTP", "audio",
iceRtpGatherer.getLocalParameters());
};
iceRtcpGatherer.onlocalcandidate = function(event) {
mySendLocalCandidate(event.candidate, "RTCP", "audio",
iceRtpGatherer.getLocalParameters());
};
// Start gathering
iceRtpGatherer.gather();
iceRtcpGatherer.gather();
// Initialize the ICE transport arrays
var iceRtpTransports = [];
var iceRtcpTransports = [];
// Set up response function
mySignaller.onResponse = function(responseSignaller, response) {
// We may get N responses
// Create the ICE RTP and RTCP transports
var iceRtpTransport = new RTCIceTransport(iceRtpGatherer);
var iceRtcpTransport = iceRtpTransport.createAssociatedTransport();
// Start the RTP and RTCP ICE transports so that outgoing ICE connectivity checks can begin
// The RTP and RTCP ICE parameters are the same, so only the RTP parameters are used
iceRtpTransport.start(iceRtpGatherer, response.icertp, RTCIceRole.controlling);
iceRtcpTransport.start(iceRtcpGatherer, response.icertp, RTCIceRole.controlling);
iceRtpTransports.push(iceRtpTransport);
iceRtcpTransports.push(iceRtcpTransport);
// Prepare to add ICE candidates signalled by the remote peer
responseSignaller.onRemoteCandidate = function(remote) {
// Locate the ICE transport that the signaled candidate relates to by matching
// the userNameFragment.
var transports;
if (remote.component === "RTP") {
transports = iceRtpTransports;
} else {
transports = iceRtcpTransports;
}
for (var j = 0; j < iceTransport.length; j++) {
var transport = transports[j];
if (transport.getRemoteParameters().userNameFragment === remote.parameters.userNameFragment)
transport.addRemoteCandidate(remote.candidate);
}
}
};
};
mySignaller.send({
// The RTP and RTCP parameters are identical, so no need to send both
"icertp": iceRtpGatherer.getLocalParameters()
});
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.
typedef (octet[]) ArrayBuffer;
[ Constructor (RTCIceTransport transport, sequence<RTCCertificate> certificates)]
interface RTCDtlsTransport : RTCStatsProvider {
readonly attribute FrozenArray<RTCCertificate> certificates;
readonly attribute RTCIceTransport transport;
readonly attribute RTCDtlsTransportState state;
RTCDtlsParameters getLocalParameters ();
RTCDtlsParameters? getRemoteParameters ();
sequence<ArrayBuffer> getRemoteCertificates ();
void start (RTCDtlsParameters remoteParameters);
void stop ();
attribute EventHandler onstatechange;
attribute EventHandler onerror;
};
RTCDtlsTransport| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| transport | RTCIceTransport |
✘ | ✘ | |
| certificates |
sequence<RTCCertificate> |
✘ | ✘ |
certificates of type sequence<RTCCertificate>, readonlyThe certificates provided in the constructor.
transport of type RTCIceTransport, readonlyThe associated RTCIceTransport instance.
state of type RTCDtlsTransportState, readonlyThe current state of the DTLS transport.
onstatechange of type EventHandlerThis event handler, of event handler event type
statechange, MUST
be fired any time the RTCDtlsTransportState
changes.
onerror of type EventHandlerThis event handler, of event handler event type error,
MUST be fired on reception of a DTLS
error alert; an implementation SHOULD include DTLS error alert information in
error.message (defined in [[!HTML5]] Section 6.1.3.6.2).
getLocalParametersObtain 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.
RTCDtlsParameters
getRemoteParametersObtain the remote DTLS parameters passed in the start()
method. Prior to calling start(), null is returned.
RTCDtlsParameters, nullable
getRemoteCertificatesReturns 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.
sequence<ArrayBuffer>
startStart 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.
| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| remoteParameters | RTCDtlsParameters |
✘ | ✘ |
void
stopStops and closes the RTCDtlsTransport object.
Calling stop() when state is closed
has no effect.
void
The RTCDtlsParameters object includes information
relating to DTLS configuration.
dictionary RTCDtlsParameters {
RTCDtlsRole role = "auto";
sequence<RTCDtlsFingerprint> fingerprints;
};
role of type RTCDtlsRole, defaulting to
"auto"The DTLS role, with a default of auto.
fingerprints of type sequence<RTCDtlsFingerprint>Sequence of fingerprints, one fingerprint for each certificate.
The RTCDtlsFingerprint object includes the hash function
algorithm and certificate fingerprint as described in [[!RFC4572]].
dictionary RTCDtlsFingerprint {
DOMString algorithm;
DOMString value;
};
algorithm of type DOMStringOne of the the hash function algorithms defined in the 'Hash function Textual Names' registry, initially specified in [[!RFC4572]] Section 8. As noted in [[!JSEP]] Section 5.2.1, the digest algorithm used for the fingerprint matches that used in the certificate signature.
value of type DOMStringThe 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.
enum RTCDtlsRole {
"auto",
"client",
"server"
};
| Enumeration description | |
|---|---|
auto |
The DTLS role is determined based on the resolved ICE role: the
|
client |
The DTLS client role. A transition to |
server |
The DTLS server role. If |
RTCDtlsTransportState indicates the state of the DTLS
transport.
enum RTCDtlsTransportState {
"new",
"connecting",
"connected",
"closed",
"failed"
};
| Enumeration description | |
|---|---|
new |
The |
connecting |
DTLS is in the process of negotiating a secure connection and
verifying the remote fingerprint. Once a secure connection is negotiated
(but prior to verification of the remote fingerprint, enabled by calling
|
connected |
DTLS has completed negotiation of a secure connection and verified the remote fingerprint. Outgoing data and media can now flow through. |
closed |
The DTLS connection has been closed intentionally via a call to
|
failed |
The DTLS connection has been closed as the result of an error (such as receipt of an error alert or a failure to validate the remote fingerprint). |
// This is an example of how to offer ICE and DTLS parameters and
// ICE candidates and get back ICE and DTLS parameters and ICE candidates,
// and start both ICE and DTLS, when RTP and RTCP are multiplexed.
// Assume that we have a way to signal (mySignaller).
// Include some helper functions
import {trace, errorHandler, mySendLocalCandidate, myIceGathererStateChange,
myIceTransportStateChange, myDtlsTransportStateChange} from 'helper';
function initiate(mySignaller) {
// Prepare the ICE gatherer
var gatherOptions = {
gatherPolicy: "all",
iceServers: [
{ urls: "stun:stun1.example.net" },
{ urls: "turn:turn.example.org", username: "user", credential: "myPassword",
credentialType: "password" }
]
};
var iceGatherer = new RTCIceGatherer(gatherOptions);
iceGatherer.onlocalcandidate = function(event) {
mySignaller.mySendLocalCandidate(event.candidate);
};
// Start gathering
iceGatherer.gather();
// Initialize the ICE and DTLS transport arrays
var iceTransports = [];
var dtlsTransports = [];
// Create the DTLS certificate and parameters
var certs;
var dtlsParameters = {};
var keygenAlgorithm = { name: "ECDSA", namedCurve: "P-256" };
RTCCertificate.generateCertificate(keygenAlgorithm).then(function(certificate){
certs[0] = certificate;
// Obtain the fingerprint of the created certificate
dtlsParameters.fingerprints[0] = certificate.fingerprint;
}, function(){
trace('Certificate could not be created');
});
// Prepare to handle remote ICE candidates
mySignaller.onRemoteCandidate = function(remote) {
// Figure out which 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 8.
mySignaller.mySendInitiate({
"ice": iceGatherer.getLocalParameters(),
"dtls": dtlsParameters,
// ... marshall RtpSender/RtpReceiver capabilities as illustrated in Section 6.5 Example 8.
}, 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 8.
});
}
// This is an example of how to answer with ICE and DTLS
// and DTLS parameters and ICE candidates and start both ICE and DTLS,
// assuming that RTP and RTCP are multiplexed.
// Include some helper functions
import {trace, errorHandler, mySendLocalCandidate, myIceGathererStateChange,
myIceTransportStateChange, myDtlsTransportStateChange} from 'helper';
// Assume that remote info is signalled to us.
function accept(mySignaller, remote) {
// Prepare the ICE gatherer
var gatherOptions = {
gatherPolicy: "all",
iceServers: [
{ urls: "stun:stun1.example.net" },
{ urls: "turn:turn.example.org", username: "user", credential: "myPassword",
credentialType: "password" }
]
};
var iceGatherer = new RTCIceGatherer(gatherOptions);
iceGatherer.onlocalcandidate = function(event) {
mySignaller.mySendLocalCandidate(event.candidate);
};
// Start gathering
iceGatherer.gather();
// Create the DTLS certificate
var certs;
var keygenAlgorithm = { name: "ECDSA", namedCurve: "P-256" };
RTCCertificate.generateCertificate(keygenAlgorithm).then(function(certificate){
certs[0] = certificate;
}, function(){
trace('Certificate could not be created');
});
// Create ICE and DTLS transports
var ice = new RTCIceTransport(iceGatherer);
var dtls = new RTCDtlsTransport(ice, certs);
// Prepare to handle remote candidates
mySignaller.onRemoteCandidate = function(remote) {
ice.addRemoteCandidate(remote.candidate);
};
// ... create RtpSender/RtpReceiver objects as illustrated in Section 6.5 Example 8.
mySignaller.mySendAccept({
"ice": iceGatherer.getLocalParameters(),
"dtls": dtls.getLocalParameters()
// ... marshall RtpSender/RtpReceiver capabilities as illustrated in Section 6.5 Example 8.
});
// 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 8.
}
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.
[ Constructor (MediaStreamTrack track, RTCDtlsTransport transport, optional RTCDtlsTransport rtcpTransport)]
interface RTCRtpSender : RTCStatsProvider {
readonly attribute MediaStreamTrack track;
readonly attribute RTCDtlsTransport transport;
readonly attribute RTCDtlsTransport? rtcpTransport;
readonly attribute DOMString kind;
void setTransport (RTCDtlsTransport transport, optional RTCDtlsTransport rtcpTransport);
Promise<void> setTrack (MediaStreamTrack track);
static RTCRtpCapabilities getCapabilities (DOMString kind);
Promise<void> send (RTCRtpParameters parameters);
void stop ();
attribute EventHandler onssrcconflict;
};
RTCRtpSender| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| track | MediaStreamTrack |
✘ | ✘ | |
| transport | RTCDtlsTransport |
✘ | ✘ | |
| rtcpTransport | RTCDtlsTransport |
✘ | ✔ |
track of type MediaStreamTrack, readonlyThe associated MediaStreamTrack instance.
If track is ended, or if
track.muted is set to true,
the RTCRtpSender sends silence (audio) or a black
frame (video). If track is set to null then
the RTCRtpSender does not send RTP.
transport of type RTCDtlsTransport, readonlyThe 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.
rtcpTransport of type RTCDtlsTransport, readonly , nullableThe associated RTCP RTCDtlsTransport instance if one
was provided in the constructor. When RTCP mux is used,
rtcpTransport will be null, and both RTP and RTCP traffic will
flow over the RTCDtlsTransport
transport.
kind of type DOMString, readonlyThe value of track.kind passed in the constructor.
onssrcconflict of type EventHandlerThe onssrcconflict event handler, of event
handler type RTCSsrcConflictEvent, is fired if an SSRC
conflict is detected within the RTP session or an SSRC misconfiguration is
detected after send() or receive()
returns or when setTransport() is called. In this
situation, the RTCRtpSender automatically sends an RTCP
BYE on the conflicted SSRC, if RTP packets were sent using that SSRC.
setTransportAttempts to replace the the RTP RTCDtlsTransport
transport (and if used) RTCP RTCDtlsTransport
rtcpTransport with the transport(s) provided.
When the setTransport() method is invoked, the user
agent MUST run the following steps:
Let sender be the RTCRtpSender object
on which setTransport() is invoked.
If sender.stop() has been called, throw an
InvalidStateError exception.
Let withTransport and withRtcpTransport be the arguments to this method.
If setTransport() is called with no arguments,
or if withTransport is unset, throw an
InvalidParameters exception.
If withTransport.transport.component is
RTCP, throw an InvalidParameters
exception.
If withRtcpTransport is set and
withRtcpTransport.transport.component is
RTP, throw an InvalidParameters
exception.
If withTransport is set and
withTransport.state is
closed, throw an InvalidStateError
exception.
If withRtcpTransport is set and
withRtcpTransport.state is
closed, throw an InvalidStateError
exception.
Replace transport with withTransport and
rtcpTransport (if set) with withRtcpTransport
and seamlessly send over the new transport(s).
| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| transport | RTCDtlsTransport |
✘ | ✘ | |
| rtcpTransport | RTCDtlsTransport |
✘ | ✔ |
void
setTrackAttempts to replace the track being sent with another track provided (or with a null track).
When the setTrack() method is invoked, the user
agent MUST run the following steps:
Let p be a new promise.
Let sender be the RTCRtpSender object
on which setTrack() is invoked.
If sender.stop() has been called,
reject p with InvalidStateError.
Let withTrack be the argument to this method.
If withTrack is non-null and
withTrack.kind differs from
sender.kind,
reject p with TypeError.
Run the following steps:
Set the track attribute to
withTrack. If withTrack is null,
the sender stops sending. Otherwise, have the sender
seamlessly switch to transmitting
withTrack in place of what it is sending.
Resolve p with undefined.
| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| track | MediaStreamTrack |
✔ | ✘ |
Promise<void>
getCapabilities, staticObtain the sender capabilities, based on kind. Capabilities
that can apply to multiple values of kind (such as
retransmission [[!RFC4588]], redundancy [[RFC2198]] and Forward Error
Correction) have
RTCRtpCapabilities.RTCRtpCodecCapability[i].kind set to the
value of the kind argument.
| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| kind | DOMString |
✘ | ✘ |
RTCRtpCapabilities
sendAttempts to set the parameters controlling the sending of media.
When the send() method is invoked, the user agent MUST run
the following steps:
Let sender be the RTCRtpSender object
on which send() is invoked.
Let p be a new promise.
If sender.stop() has been called,
reject p with InvalidStateError.
Let withParameters be the argument to this method.
If withParameters is invalid due to SSRC misusage or
other reasons, reject p with InvalidParameters.
If rtcpTransport is not set and
withParameters.rtcp.mux is set to false,
reject p with InvalidParameters.
For each value of i from 0 to the number of codecs, check
that each value of withParameters.codecs[i].payloadType is
set. If any value is unset, reject p with
InvalidParameters.
For each value of i from 0 to the number of encodings,
check whether
withParameters.encodings[i].codecPayloadType
(if set) corresponds to a value of
withParameters.codecs[j].payloadType where
j goes from 0 to the number of codecs. If there is no
correspondence, or if
withParameters.codecs[j].name is equal to
"red", "cn", "telephone-event", "rtx" or a forward error correction
codec ("ulpfec" [[RFC5109]] or "flexfec" [[FLEXFEC]]), reject p with
InvalidParameters.
For each value of i from 0 to the number of codecs, check
that each value of
withParameters.codecs[i].name not equal to
"red", "rtx" or a forward error correction codec ("ulpfec" [[RFC5109]]
or "flexfec" [[FLEXFEC]]), is included in
getCapabilities(track.kind).codecs[j].name,
where j goes from 0 to the number of codecs. If a match is
not found for any value of i, reject p with
InvalidParameters.
Run the following steps:
| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| parameters | RTCRtpParameters |
✘ | ✘ |
Promise<void>
stopStops sending the track on the wire, and sends an RTCP BYE. Stop is
final as in MediaStreamTrack.stop().
void
The ssrcconflict event of the
RTCRtpSender object uses the
RTCSsrcConflictEvent interface.
Firing an RTCSsrcConflictEvent event named e with
an ssrc means that an event with the name e, which does not
bubble (except where otherwise stated) and is not cancelable (except where
otherwise stated), and which uses the RTCSsrcConflictEvent
interface with the ssrc attribute set to the conflicting SSRC
MUST be created and dispatched at the given
target.
[ Constructor (DOMString type, RTCSsrcConflictEventInit eventInitDict)]
interface RTCSsrcConflictEvent : Event {
readonly attribute unsigned long ssrc;
};
RTCSsrcConflictEvent| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| type | DOMString |
✘ | ✘ | |
| eventInitDict | RTCSsrcConflictEventInit |
✘ | ✘ |
ssrc of type unsigned long, readonlyThe ssrc attribute represents the conflicting SSRC that
caused the event.
dictionary RTCSsrcConflictEventInit : EventInit {
unsigned long ssrc;
};
ssrc of type unsigned longThe ssrc attribute represents the conflicting SSRC that
caused the event.
The RTCRtpReceiver includes information relating to the
RTP receiver.
An RTCRtpReceiver instance produces an associated receiving
MediaStreamTrack and provides RTC related methods to it.
A RTCRtpReceiver instance is constructed from a value of
kind and an RTCDtlsTransport object. If an attempt
is made to construct an RTCRtpReceiver object with
transport.state or rtcpTransport.state with a value of
closed, throw an InvalidStateError exception. Upon
construction, track is set, and the value of track.kind
is determined based on the value of kind passed in the constructor.
An RTCRtpReceiver object can be garbage-collected once
stop() is called and it is no longer referenced.
[ Constructor (DOMString kind, RTCDtlsTransport transport, optional RTCDtlsTransport rtcpTransport)]
interface RTCRtpReceiver : RTCStatsProvider {
readonly attribute MediaStreamTrack track;
readonly attribute RTCDtlsTransport transport;
readonly attribute RTCDtlsTransport? rtcpTransport;
void setTransport (RTCDtlsTransport transport, optional RTCDtlsTransport rtcpTransport);
static RTCRtpCapabilities getCapabilities (DOMString kind);
Promise<void> receive (RTCRtpParameters parameters);
sequence<RTCRtpContributingSource> getContributingSources ();
void stop ();
};
RTCRtpReceiver| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| kind | DOMString |
✘ | ✘ | |
| transport | RTCDtlsTransport |
✘ | ✘ | |
| rtcpTransport | RTCDtlsTransport |
✘ | ✔ |
track of type MediaStreamTrack, readonlyThe associated MediaStreamTrack instance. Upon
construction, track is set. The value of
track.kind is set to the value of kind passed in
the constructor.
RTCDtlsTransport transport, and (if set)
rtcpTransport, track MUST NOT emit media for rendering.
transport of type RTCDtlsTransport, readonlyThe associated RTP RTCDtlsTransport instance.
rtcpTransport of type RTCDtlsTransport, readonly , nullableThe RTCDtlsTransport instance over which RTCP is
sent and received. When BUNDLE is used, multiple
RTCRtpReceiver objects will share one
rtcpTransport and will send and receive RTCP over the same
RTCDtlsTransport. When RTCP mux is used,
rtcpTransport will be null, and both RTP and RTCP traffic will
flow over the RTCDtlsTransport
transport.
setTransportAttempts to replace the the RTP RTCDtlsTransport
transport (and if used) RTCP RTCDtlsTransport
rtcpTransport with the transport(s) provided.
When the setTransport() method is invoked, the user
agent MUST run the following steps:
Let receiver be the RTCRtpReceiver object
on which setTransport() is invoked.
If receiver.stop() has been called, throw an
InvalidStateError exception.
Let withTransport and withRtcpTransport be the arguments to this method.
If setTransport() is called with no arguments,
or if withTransport is unset, throw an
InvalidParameters exception.
If withTransport.transport.component is
RTCP, throw an InvalidParameters
exception.
If withRtcpTransport is set and
withRtcpTransport.transport.component is
RTP, throw an InvalidParameters exception.
If withTransport is set and
withTransport.state is
closed, throw an InvalidStateError
exception.
If withRtcpTransport is set and
withRtcpTransport.state is
closed, throw an InvalidStateError
exception.
Replace transport with withTransport and
rtcpTransport (if set) with withRtcpTransport and
seamlessly receive over the new transport(s).
| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| transport | RTCDtlsTransport |
✘ | ✘ | |
| rtcpTransport | RTCDtlsTransport |
✘ | ✔ |
void
getCapabilities, staticObtain the receiver capabilities, based on kind.
Capabilities that can apply to multiple values of kind (such
as retransmission [[!RFC4588]], redundancy [[RFC2198]] and Forward Error
Correction) have
RTCRtpCapabilities.RTCRtpCodecCapability[i].kind
set to the value of the kind argument.
| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| kind | DOMString |
✘ | ✘ |
RTCRtpCapabilities
receiveAttempts to set the parameters controlling the receiving of media.
When the receive() method is invoked, the user agent MUST
run the following steps:
Let receiver be the RTCRtpReceiver
object on which receive() is invoked.
Let p be a new promise.
If receiver.stop() has been called,
reject p with InvalidStateError.
Let withParameters be the argument to this method.
If withParameters is invalid due to SSRC misusage,
ssrc_table, muxId_table or
pt_table conflicts described in Section 8.3 or other
reasons, reject p with InvalidParameters.
If rtcpTransport is not set and
withParameters.rtcp.mux is set to false,
reject p with InvalidParameters.
For each value of i from 0 to the number of codecs, check
that each value of
withParameters.codecs[i].payloadType
is set. If any value is unset, reject p with
InvalidParameters.
For each value of i from 0 to the number of encodings,
check whether
withParameters.encodings[i].codecPayloadType
corresponds to a value of
withParameters.codecs[j].payloadType where j goes
from 0 to the number of codecs. If there is no correspondence, or if
withParameters.codecs[j].name is equal to "red", "cn",
"telephone-event", "rtx" or a forward error correction codec ("ulpfec"
[[RFC5109]] or "flexfec" [[FLEXFEC]]), reject p with
InvalidParameters.
For each value of i from 0 to the number of codecs, check
that each value of
withParameters.codecs[i].name not equal to
"red", "rtx" or a forward error correction codec is included in
getCapabilities(kind).codecs[j].name, where j
goes from 0 to the number of codecs, and kind takes the
value passed in the RTCRtpReceiver constructor. If
no match is found for any value of i,
reject p with InvalidParameters.
Run the following steps:
| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| parameters | RTCRtpParameters |
✘ | ✘ |
Promise<void>
getContributingSourcesReturns 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. If no contributing sources are available, an empty list is
returned.
sequence<RTCRtpContributingSource>
stopStops the RTCRtpReceiver
receiver. receiver.stop()
is final like receiver.track.stop().
receiver.track.stop() does
not affect track clones and also does not stop receiver
so that Receiver Reports continue to be sent. Calling
receiver.stop() does not cause
the "onended" event to fire for track.
void
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.
dictionary RTCRtpContributingSource {
DOMHighResTimeStamp timestamp;
unsigned long source;
byte audioLevel;
boolean voiceActivityFlag;
};
timestamp of type DOMHighResTimeStampThe 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.
source of type unsigned longThe CSRC or SSRC value of the contributing source.
audioLevel of type byteThe 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.
voiceActivityFlag of type booleanWhether 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("audio", transport);
var videoReceiver = new RTCRtpReceiver("video", transport);
// Retrieve the audio and video receiver capabilities
var recvAudioCaps = RTCRtpReceiver.getCapabilities("audio");
var recvVideoCaps = RTCRtpReceiver.getCapabilities("video");
// Retrieve the audio and video sender capabilities
var sendAudioCaps = RTCRtpSender.getCapabilities("audio");
var sendVideoCaps = RTCRtpSender.getCapabilities("video");
mySignaller.myOfferTracks({
// The initiator offers its receiver and sender capabilities.
"recvAudioCaps": recvAudioCaps,
"recvVideoCaps": recvVideoCaps,
"sendAudioCaps": sendAudioCaps,
"sendVideoCaps": sendVideoCaps
}, function(answer) {
// The responder answers with its receiver capabilities
// Derive the send and receive parameters
var audioSendParams = myCapsToSendParams(sendAudioCaps, answer.recvAudioCaps);
var videoSendParams = myCapsToSendParams(sendVideoCaps, answer.recvVideoCaps);
var audioRecvParams = myCapsToRecvParams(recvAudioCaps, answer.sendAudioCaps);
var videoRecvParams = myCapsToRecvParams(recvVideoCaps, answer.sendVideoCaps);
audioSender.send(audioSendParams).then(function() {
trace("Set audio sender parameters");
}, function() {
trace("Could not set audio sender parameters");
}
);
videoSender.send(videoSendParams).then(function() {
trace("Set video sender parameters");
}, function() {
trace("Could not set video sender parameters");
}
);
audioReceiver.receive(audioRecvParams).then(function() {
trace("Set audio receiver parameters");
}, function() {
trace("Could not set audio receiver parameters");
}
);
videoReceiver.receive(videoRecvParams).then(function() {
trace("Set video receiver parameters");
}, function() {
trace("Could not set video receiver parameters");
}
);
// Now we can render/play
// audioReceiver.track and videoReceiver.track.
});
}
// Assume we already have a way to signal, a transport (RTCDtlsTransport)
// and audio and video tracks. This is an example of how to answer an
// offer with audio and video tracks, and begin sending and receiving them.
// The example assumes that RTP and RTCP are multiplexed.
function myAccept(mySignaller, remote, transport, audioTrack, videoTrack) {
var audioSender = new RTCRtpSender(audioTrack, transport);
var videoSender = new RTCRtpSender(videoTrack, transport);
var audioReceiver = new RTCRtpReceiver("audio", transport);
var videoReceiver = new RTCRtpReceiver("video", transport);
// Retrieve the send and receive capabilities
var recvAudioCaps = RTCRtpReceiver.getCapabilities("audio");
var recvVideoCaps = RTCRtpReceiver.getCapabilities("video");
var sendAudioCaps = RTCRtpSender.getCapabilities("audio");
var sendVideoCaps = RTCRtpSender.getCapabilities("video");
mySignaller.myAnswerTracks({
"recvAudioCaps": recvAudioCaps,
"recvVideoCaps": recvVideoCaps,
"sendAudioCaps": sendAudioCaps,
"sendVideoCaps": sendVideoCaps
});
// Derive the send and receive parameters using Javascript functions 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).then(function() {
trace("Set audio sender parameters");
}, function() {
trace("Could not set audio sender parameters");
}
);
videoSender.send(videoSendParams).then(function() {
trace("Set video sender parameters");
}, function() {
trace("Could not set video sender parameters");
}
);
audioReceiver.receive(audioRecvParams).then(function() {
trace("Set audio receiver parameters");
}, function() {
trace("Could not set audio receiver parameters");
}
);
videoReceiver.receive(videoRecvParams).then(function() {
trace("Set video receiver parameters");
}, function() {
trace("Could not set video receiver parameters");
}
);
// Now we can render/play
// audioReceiver.track and videoReceiver.track.
}
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.
[Constructor()]
interface RTCIceTransportController {
void addTransport (RTCIceTransport transport, optional unsigned long index);
sequence<RTCIceTransport> getTransports ();
};
addTransportAdds transport to the
RTCIceTransportController object for the purposes of
managing ICE freezing and sharing bandwidth estimation. Since
addTransport() manages ICE freezing, candidate pairs
that are not in the frozen state maintain their state when
addTransport(transport) is called.
RTCIceTransport objects will be unfrozen according to
their index. transport is inserted at
index, or at the end if index is not specified. If
index is greater than the current number of
RTCIceTransports with a component of
RTP, throw an InvalidParameters 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.
| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| transport | RTCIceTransport |
✘ | ✘ | |
| index | unsigned long |
✘ | ✔ |
void
getTransportsReturns the RTCIceTransport objects with a
component of RTP. If
addTransport() has not been called, an empty list is
returned.
sequence<RTCIceTransport>
// This is an example of how to utilize distinct ICE transports for Audio and Video
// as well as for RTP and RTCP. If both sides can multiplex audio/video
// and RTP/RTCP then the multiplexing will occur.
//
// Assume we have an audioTrack and a videoTrack to send.
//
// Include some helper functions
import {trace, errorHandler, mySendLocalCandidate, myIceGathererStateChange,
myIceTransportStateChange, myDtlsTransportStateChange} from 'helper';
// Create the ICE gather options
var gatherOptions = {
gatherPolicy: "all",
iceServers: [
{ urls: "stun:stun1.example.net" },
{ urls: "turn:turn.example.org", username: "user", credential: "myPassword",
credentialType: "password" }
]
};
// Create the RTP and RTCP ICE gatherers for audio and video
var audioRtpIceGatherer = new RTCIceGatherer(gatherOptions);
var audioRtcpIceGatherer = audioRtpIceGatherer.createAssociatedGatherer();
var videoRtpIceGatherer = new RTCIceGatherer(gatherOptions);
var videoRtcpIceGatherer = videoRtpIceGatherer.createAssociatedGatherer();
// Set up the ICE gatherer error handlers
audioRtpIceGatherer.onerror = errorHandler;
audioRtcpIceGatherer.onerror = errorHandler;
videoRtpIceGatherer.onerror = errorHandler;
videoRtcpIceGatherer.onerror = errorHandler;
// Create the RTP and RTCP ICE transports for audio and video
var audioRtpIceTransport = new RTCIceTransport(audioRtpIceGatherer);
var audioRtcpIceTransport = audioRtpIceTransport.createAssociatedTransport();
var videoRtpIceTransport = new RTCIceTransport(videoRtpIceGatherer);
var videoRtcpIceTransport = videoRtpIceTransport.createAssociatedTransport();
// Enable local ICE candidates to be signaled to the remote peer.
audioRtpIceGatherer.onlocalcandidate = function(event) {
mySendLocalCandidate(event.candidate, "RTP", "audio");
};
audioRtcpIceGatherer.onlocalcandidate = function(event) {
mySendLocalCandidate(event.candidate, "RTCP", "audio");
};
videoRtpIceGatherer.onlocalcandidate = function(event) {
mySendLocalCandidate(event.candidate, "RTP", "video");
};
videoRtcpIceGatherer.onlocalcandidate = function(event) {
mySendLocalCandidate(event.candidate, "RTCP", "video");
};
// Start gathering
audioRtpIceGatherer.gather();
audioRtcpIceGatherer.gather();
videoRtpIceGatherer.gather();
videoRtcpIceGatherer.gather();
// Set up the ICE state change event handlers
audioRtpIceTransport.onstatechange = function(event) {
myIceTransportStateChange("audioRtpIceTransport", event.state);
};
audioRtcpIceTransport.onstatechange = function(event) {
myIceTransportStateChange("audioRtcpIceTransport", event.state);
};
videoRtpIceTransport.onstatechange = function(event) {
myIceTransportStateChange("videoRtpIceTransport", event.state);
};
videoRtcpIceTransport.onstatechange = function(event) {
myIceTransportStateChange("videoRtcpIceTransport", event.state);
};
// Prepare to add ICE candidates signaled by the remote peer on any of the ICE transports
mySignaller.onRemoteCandidate = function(remote) {
switch (remote.kind) {
case "audio":
if (remote.component === "RTP") {
audioRtpIceTransport.addRemoteCandidate(remote.candidate);
} else {
audioRtcpIceTransport.addRemoteCandidate(remote.candidate);
}
break;
case "video":
if (remote.component === "RTP") {
videoRtpIceTransport.addRemoteCandidate(remote.candidate);
} else {
videoRtcpIceTransport.addRemoteCandidate(remote.candidate);
}
break;
default:
trace("Invalid media type received: " + remote.kind);
}
};
// Create the DTLS certificate
var certs;
var keygenAlgorithm = { name: "ECDSA", namedCurve: "P-256" };
RTCCertificate.generateCertificate(keygenAlgorithm).then(function(certificate){
certs[0] = certificate;
}, function(){
trace('Certificate could not be created');
});
// Create the DTLS transports (using the same certificate)
var audioRtpDtlsTransport = new RTCDtlsTransport(audioRtpIceTransport, certs);
var audioRtcpDtlsTransport = new RTCDtlsTransport(audioRtcpIceTransport, certs);
var videoRtpDtlsTransport = new RTCDtlsTransport(videoRtpIceTransport, certs);
var videoRtcpDtlsTransport = new RTCDtlsTransport(videoRtcpIceTransport, certs);
// Create the sender and receiver objects
var audioSender = new RTCRtpSender(audioTrack, audioRtpDtlsTransport, audioRtcpDtlsTransport);
var videoSender = new RTCRtpSender(videoTrack, videoRtpDtlsTransport, videoRtcpDtlsTransport);
var audioReceiver = new RTCRtpReceiver("audio", audioRtpDtlsTransport, audioRtcpDtlsTransport);
var videoReceiver = new RTCRtpReceiver("video", videoRtpDtlsTransport, videoRtcpDtlsTransport);
// Retrieve the receiver and sender capabilities
var recvAudioCaps = RTCRtpReceiver.getCapabilities("audio");
var recvVideoCaps = RTCRtpReceiver.getCapabilities("video");
var sendAudioCaps = RTCRtpSender.getCapabilities("audio");
var sendVideoCaps = RTCRtpSender.getCapabilities("video");
// Exchange ICE/DTLS parameters and Send/Receive capabilities
mySignaller.myOfferTracks({
// Indicate that the initiator would prefer to multiplex both A/V and RTP/RTCP
"bundle": true,
// Indicate that the initiator is willing to multiplex RTP/RTCP without A/V mux
"rtcpMux": true,
// Offer the ICE parameters
"audioRtpIce": audioRtpIceGatherer.getLocalParameters(),
"audioRtcpIce": audioRtcpIceGatherer.getLocalParameters(),
"videoRtpIce": videoRtpIceGatherer.getLocalParameters(),
"videoRtcpIce": videoRtcpIceGatherer.getLocalParameters(),
// Offer the DTLS parameters
"audioRtpDtls": audioRtpDtlsTransport.getLocalParameters(),
"audioRtcpDtls": audioRtcpDtlsTransport.getLocalParameters(),
"videoRtpDtls": videoRtpDtlsTransport.getLocalParameters(),
"videoRtcpDtls": videoRtcpDtlsTransport.getLocalParameters(),
// Offer the receiver and sender audio and video capabilities.
"recvAudioCaps": recvAudioCaps,
"recvVideoCaps": recvVideoCaps,
"sendAudioCaps": sendAudioCaps,
"sendVideoCaps": sendVideoCaps
}, function(answer) {
// The responder answers with its preferences, parameters and capabilities
// Since we didn"t create transport arrays, we are assuming that there
// is no forking (only one response)
//
// Derive the send and receive parameters, assuming that RTP/RTCP mux will be enabled.
var audioSendParams = myCapsToSendParams(sendAudioCaps, answer.recvAudioCaps);
var videoSendParams = myCapsToSendParams(sendVideoCaps, answer.recvVideoCaps);
var audioRecvParams = myCapsToRecvParams(recvAudioCaps, answer.sendAudioCaps);
var videoRecvParams = myCapsToRecvParams(recvVideoCaps, answer.sendVideoCaps);
//
// If the responder wishes to enable bundle, we will enable it
if (answer.bundle) {
// Since bundle implies RTP/RTCP multiplexing, we only need a single
// ICE transport and DTLS transport. No need for the ICE transport controller.
audioRtpIceTransport.start(audioRtpIceGatherer, answer.audioRtpIce, RTCIceRole.controlling);
audioRtpDtlsTransport.start(remote.audioRtpDtls);
//
// Replace the transport on the Sender and Receiver objects
//
audioSender.setTransport(audioRtpDtlsTransport);
videoSender.setTransport(audioRtpDtlsTransport);
audioReceiver.setTransport(audioRtpDtlsTransport);
videoReceiver.setTransport(audioRtpDtlsTransport);
// If BUNDLE was requested, then also assume RTP/RTCP mux
answer.rtcpMux = true;
} else {
var controller = new RTCIceTransportController();
if (answer.rtcpMux) {
// The peer doesn"t want BUNDLE, but it does want to multiplex RTP/RTCP
// Now we need audio and video ICE transports
// as well as an ICE Transport Controller object
controller.addTransport(audioRtpIceTransport);
controller.addTransport(videoRtpIceTransport);
// Start the audio and video ICE transports
audioRtpIceTransport.start(audioRtpIceGatherer, answer.audioRtpIce, RTCIceRole.controlling);
videoRtpIceTransport.start(videoRtpIceGatherer, answer.videoRtpIce, RTCIceRole.controlling);
// Start the audio and video DTLS transports
audioRtpDtlsTransport.onerror = errorHandler;
audioRtpDtlsTransport.start(answer.audioRtpDtls);
videoRtpDtlsTransport.onerror = errorHandler;
videoRtpDtlsTransport.start(answer.videoRtpDtls);
// Replace the transport on the Sender and Receiver objects
//
audioSender.setTransport(audioRtpDtlsTransport);
videoSender.setTransport(videoRtpDtlsTransport);
audioReceiver.setTransport(audioRtpDtlsTransport);
videoReceiver.setTransport(videoRtpDtlsTransport);
} else {
// We arrive here if the responder does not want BUNDLE
// or RTP/RTCP multiplexing
//
// Now we need all the audio and video RTP and RTCP ICE transports
// as well as an ICE Transport Controller object
controller.addTransport(audioRtpIceTransport);
controller.addTransport(videoRtpIceTransport);
// Start the ICE transports
audioRtpIceTransport.start(audioRtpIceGatherer, answer.audioRtpIce, RTCIceRole.controlling);
audioRtcpIceTransport.start(audioRtcpIceGatherer, answer.audioRtcpIce,
RTCIceRole.controlling);
videoRtpIceTransport.start(videoRtpIceGatherer, answer.videoRtpIce, RTCIceRole.controlling);
videoRtcpIceTransport.start(videoRtcpIceGatherer, answer.videoRtcpIce,
RTCIceRole.controlling);
// Start the DTLS transports that are needed
audioRtpDtlsTransport.start(answer.audioRtpDtls);
audioRtcpDtlsTransport.start(answer.audioRtcpDtls);
videoRtpDtlsTransport.start(answer.videoRtpDtls);
videoRtcpDtlsTransport.start(answer.videoRtcpDtls);
// Disable RTP/RTCP multiplexing
audioSendParams.rtcp.mux = false;
videoSendParams.rtcp.mux = false;
audioRecvParams.rtcp.mux = false;
videoRecvParams.rtcp.mux = false;
}
}
// Set the audio and video send and receive parameters.
audioSender.send(audioSendParams).then(function() {
trace("Set audio sender parameters");
}, function() {
trace("Could not set audio sender parameters");
}
);
videoSender.send(videoSendParams).then(function() {
trace("Set video sender parameters");
}, function() {
trace("Could not set video sender parameters");
}
);
audioReceiver.receive(audioRecvParams).then(function() {
trace("Set audio receiver parameters");
}, function() {
trace("Could not set audio receiver parameters");
}
);
videoReceiver.receive(videoRecvParams).then(function() {
trace("Set video receiver parameters");
}, function() {
trace("Could not set video receiver parameters");
}
);
// Now we can render/play audioReceiver.track and videoReceiver.track
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.
An 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 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.
[ Constructor (RTCDtlsTransport transport)]
interface RTCRtpListener {
readonly attribute RTCDtlsTransport transport;
attribute EventHandler onunhandledrtp;
};
RTCRtpListener| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| transport | RTCDtlsTransport |
✘ | ✘ |
transport of type RTCDtlsTransport, readonlyThe RTP RTCDtlsTransport instance.
onunhandledrtp of type EventHandlerThe 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.
[ Constructor (DOMString type, RTCRtpUnhandledEventInit eventInitDict)]
interface RTCRtpUnhandledEvent : Event {
readonly attribute DOMString muxId;
readonly attribute DOMString rid;
readonly attribute payloadtype payloadType;
readonly attribute unsigned long ssrc;
};
RTCRtpUnhandledEvent| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| type | DOMString |
✘ | ✘ | |
| eventInitDict | RTCRtpUnhandledEventInit |
✘ | ✘ |
muxId of type DOMString, readonlyThe value of the MID RTP header extension [[!BUNDLE]] in the RTP
stream triggering the unhandledrtp event. If
receive() has not been called, the MID header
extension cannot be decoded, so that muxId will be unset.
rid of type DOMString, readonlyThe value of the RID RTP header extension [[!RID]] in the RTP
stream triggering the unhandledrtp event. If
receive() has not been called, the RID header
extension cannot be decoded, so that rid will be unset.
payloadType of type payloadtype, readonlyThe Payload Type value in the RTP stream triggering the
unhandledrtp event.
ssrc of type unsigned long, readonlyThe SSRC in the RTP stream triggering the
unhandledrtp event.
dictionary RTCRtpUnhandledEventInit : EventInit {
DOMString muxId;
DOMString rid;
payloadtype payloadType;
unsigned long ssrc;
};
muxId of type DOMStringIf present, the value of the MID RTP header extension [[!BUNDLE]]
in the RTP stream triggering the unhandledrtp
event.
rid of type DOMStringIf present, the value of the RID RTP header extension [[!RID]] in
the RTP stream triggering the unhandledrtp event.
payloadType of type payloadtypeThe Payload Type value in the RTP stream triggering the
unhandledrtp event.
ssrc of type unsigned longThe 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.
dictionary RTCRtpCapabilities {
sequence<RTCRtpCodecCapability> codecs;
sequence<RTCRtpHeaderExtension> headerExtensions;
sequence<DOMString> fecMechanisms;
};
codecs of type sequence<RTCRtpCodecCapability>Supported codecs.
headerExtensions of type sequence<RTCRtpHeaderExtension>Supported RTP header extensions.
fecMechanisms of type sequence<DOMString>Supported Forward Error Correction (FEC) mechanisms. Values include "red" [[!RFC2198]], "red+ulpfec" [[RFC5109]] and "flexfec" [[FLEXFEC]]. [[FEC]] summarizes requirements relating to FEC mechanisms.
RTCRtcpFeedback provides information on RTCP feedback messages.
dictionary RTCRtcpFeedback {
DOMString type;
DOMString parameter;
};
type of type DOMStringValid values for type are the "RTCP Feedback" Attribute
Values enumerated in [[!IANA-SDP-14]] ("ack", "ccm", "nack", etc.), as well
as "goog-remb" [[REMB]] and "transport-cc" [[TRANSPORT-CC]].
parameter of type DOMStringFor a type value of "ack" or "nack", valid values for
parameter are the "ack" and "nack" Attribute Values enumerated
in [[!IANA-SDP-15]] ("sli", "rpsi", etc.). For the Generic NACK feedback
message defined in [[!RFC4585]] Section 6.2.1, the type
attribute is set to "nack" and the parameter attribute is
unset. For a type value of "ccm", valid values for
parameter are the "Codec Control Messages" enumerated in
[[!IANA-SDP-19]] ("fir", "tmmbr" (includes "tmmbn"), etc.).
RTCRtpCodecCapability provides information on the
capabilities of a codec.
typedef object Dictionary;
typedef octet payloadtype;
dictionary RTCRtpCodecCapability {
DOMString name;
DOMString mimeType;
DOMString kind;
unsigned long clockRate;
payloadtype preferredPayloadType;
unsigned long maxptime;
unsigned long ptime;
unsigned long numChannels;
sequence<RTCRtcpFeedback> rtcpFeedback;
Dictionary parameters;
Dictionary options;
unsigned short maxTemporalLayers = 0;
unsigned short maxSpatialLayers = 0;
boolean svcMultiStreamSupport;
};
name of type DOMStringThe MIME media subtype. Valid subtypes are listed in [[!IANA-RTP-2]].
mimeType of type DOMStringThe codec MIME media type/subtype. Valid media types and subtypes are listed in [[IANA-RTP-2]].
kind of type DOMStringThe media supported by the codec: "audio", "video", etc.
clockRate of type unsigned longCodec clock rate expressed in Hertz. If unset, the codec is applicable to any clock rate.
preferredPayloadType of type payloadtypeThe preferred RTP payload type for the codec denoted by
RTCRtpCodecCapability.name. This attribute was added to make
it possible for the sender and receiver to pick a matching payload type
when creating sender and receiver parameters. When returned by
RTCRtpSender.getCapabilities(),
RTCRtpCapabilities.codecs.preferredPayloadtype represents the
preferred RTP payload type for sending. When returned by
RTCRtpReceiver.getCapabilities(),
RTCRtpCapabilities.codecs.preferredPayloadtype represents the
preferred RTP payload type for receiving. To avoid payload type conflicts,
each value of preferredPayloadType MUST be unique.
maxptime of type unsigned longThe maximum packetization time supported by the
RTCRtpReceiver.
ptime of type unsigned longThe preferred duration of media represented by a packet in milliseconds
for the RTCRtpSender or
RTCRtpReceiver.
numChannels of type unsigned longThe number of channels supported (e.g. two for stereo). For video, this attribute is unset.
rtcpFeedback of type sequence<RTCRtcpFeedback>Transport layer and codec-specific feedback messages for this codec.
parameters of type DictionaryCodec-specific parameters that must be signaled to the remote party.
options of type DictionaryCodec-specific parameters that may be optionally signalled and are available as additional supported information or settings about the codec.
maxTemporalLayers of type unsigned short, defaulting to
0Maximum number of temporal layer extensions supported by this codec (e.g. a value of 1 indicates support for up to 2 temporal layers). A value of 0 indicates no support for temporal scalability.
maxSpatialLayers of type unsigned short, defaulting to
0Maximum number of spatial layer extensions supported by this codec (e.g. a value of 1 indicates support for up to 2 spatial layers). A value of 0 indicates no support for spatial scalability.
svcMultiStreamSupport of type booleanWhether the implementation can send/receive SVC layers utilizing distinct SSRCs. Unset for audio codecs. For video codecs, only set if the codec supports scalable video coding with MRST.
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 [[RFC7741]] 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 [[!RFC7742]] Section 6.2.
| Property Name | Values | Receiver/Sender | Notes |
|---|---|---|---|
profileLevelId |
DOMString |
Receiver/Sender | This parameter is encoded as a string representation of 6
upper case hexadecimal digits, representing the profile-level-id
parameter described in [[RFC6184]] Section 8.1. It represents
the maximum capability of the decoder (for an
RTCRtpReceiver) or the encoder (for an
RTCRtpSender). It MUST be supported, as noted
in [[!RFC7742]] Section 6.2. |
packetizationMode |
sequence<unsigned short> |
Receiver/Sender | A sequence of unsigned shorts, each ranging from 0 to 2, indicating supported packetizationMode values. As noted in [[!RFC7742]] Section 6.2, support for packetization-mode 1 is mandatory. |
| maxMbps, maxSmbps, maxFs, maxCpb, maxDpb, maxBr | unsigned long long |
Receiver | As noted in [[!RFC7742]] Section 6.2, these optional parameters allow the implementation to specify that the decoder can support certain features of H.264 at higher rates and values than those signalled with profile-level-id. |
The following capability is defined for "rtx", as noted in [[!RFC4588]] Section 8.6:
| Property Name | Values | Receiver/Sender | Notes |
|---|---|---|---|
apt |
payloadType |
Receiver/Sender | As defined in [[!RFC4588]], the associated payload type of the
original stream being retransmitted. There will be an "rtx" entry in
RTCRtpCapabilities.codecs[] for each media codec that can be
retransmitted, each with their own apt parameter. |
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. |
As defined in [[!RFC2198]] Section 5, "red" has no codec-specific capability parameters.
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.
dictionary RTCRtpParameters {
DOMString muxId = "";
required sequence<RTCRtpCodecParameters> codecs;
sequence<RTCRtpHeaderExtensionParameters> headerExtensions;
sequence<RTCRtpEncodingParameters> encodings;
RTCRtcpParameters rtcp;
RTCDegradationPreference degradationPreference = "balanced";
};
muxId of type DOMString, defaulting to ""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. Since
muxId is included in RTCRtpParameters but
not in RTCRtpEncodingParameters, if it is desired to
send simulcast streams with different muxId values for each
stream, then multiple RTCRtpSender objects are
needed.
codecs of type sequence<RTCRtpCodecParameters>,
requiredThe codecs to send or receive (could include "red" [[RFC2198]], "rtx"
[[!RFC4588]] and "cn" [[RFC3389]]). codecs MUST be set for an
RTCRtpParameters object to be a valid argument passed
to send() or receive().
headerExtensions of type sequence<RTCRtpHeaderExtensionParameters>Configured header extensions. If unset, no header extensions are configured.
encodings of type sequence<RTCRtpEncodingParameters>The "encodings" or "layers" to be used for things like simulcast,
Scalable Video Coding, RTX, FEC, etc. When unset in a call to
send(), the browser behaves as though a single
encodings[0] entry was provided, with
encodings[0].ssrc set to a browser-determined value,
encodings[0].active set to true,
encodings[0].codecPayloadType set to
codecs[j].payloadType where j is the
index of the first codec that is not "cn", "telephone-event", "red", "rtx"
or a forward error correction codec ("ulpfec" [[RFC5109]] or "flexfec"
[[FLEXFEC]]), and all the other parameters.encodings[0]
attributes (e.g. fec, rtx, priority,
maxBitrate, resolutionScale, etc.) unset. When
unset in a call to receive(), the behavior is described in
Section 8.3.
rtcp of type RTCRtcpParametersParameters to configure RTCP. If unset, the default values described in Section 9.6.1 are assumed.
degradationPreference of type RTCDegradationPreference, defaulting to
"balanced"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.
enum RTCDegradationPreference {
"maintain-framerate",
"maintain-resolution",
"balanced"
};
| Enumeration description | |
|---|---|
maintain-framerate |
Degrade resolution in order to maintain framerate. |
maintain-resolution |
Degrade framerate in order to maintain resolution. |
balanced |
Degrade a balance of framerate and resolution. |
RTCRtcpParameters provides information on RTCP
settings.
dictionary RTCRtcpParameters {
unsigned long ssrc;
DOMString cname;
boolean reducedSize = false;
boolean mux = true;
};
ssrc of type unsigned longThe SSRC to be used in the "SSRC of packet sender" field defined in
[[!RFC3550]] Section 6.4.2 (Receiver Report) and [[!RFC4585]] Section 6.1
(Feedback Messages), as well as the "SSRC" field defined in [[!RFC3611]]
Section 2 (Extended Reports). It can only be set for an
RTCRtpReceiver. Other than for debugging, or situations
where receive() is called before send() on the
same RTCDtlsTransport it is best to leave it unset, in
which case ssrc is chosen by the browser, though the chosen
value is not reflected in RTCRtcpParameters.ssrc. If the
browser chooses the ssrc it may change it in event of a
collision, as described in [[!RFC3550]]. Where
send(parameters) is called before
receive() on the same RTCDtlsTransport,
the browser can choose one of the SSRCs allocated to an
RTCRtpSender of the same kind. Where
receive() is called first, a random SSRC value can be
chosen.
cname of type DOMStringThe Canonical Name (CNAME) used by RTCP (e.g. in SDES messages).
Guidelines for CNAME generation are provided in [[!RTP-USAGE]] Section 4.9
and [[!RFC7022]]. By default, ORTC implementations SHOULD set the CNAME to be the same within all
RTCRtcpParameter objects created within the same Javascript
sandbox. For backward compatibility with WebRTC 1.0, applications MAY set
the CNAME only for an RTCRtpReceiver; if unset, the
CNAME is chosen by the browser.
reducedSize of type boolean, defaulting to falseWhether reduced size RTCP [[!RFC5506]] is configured (if
true) or compound RTCP as specified in [[!RFC3550]] (if
false). The default is false.
mux of type boolean, defaulting to trueWhether 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.
dictionary RTCRtpCodecParameters {
required DOMString name;
DOMString mimeType;
required payloadtype payloadType;
unsigned long clockRate;
unsigned long maxptime;
unsigned long ptime;
unsigned long numChannels;
sequence<RTCRtcpFeedback> rtcpFeedback;
Dictionary parameters;
};
name of type DOMString, requiredThe codec MIME subtype. Valid subtypes are listed in [[!IANA-RTP-2]].
mimeType of type DOMStringThe codec MIME media type/subtype. Valid media types and subtypes are listed in [[IANA-RTP-2]].
payloadType of type payloadtype, requiredThe value that goes in the RTP Payload Type Field [[!RFC3550]]. The
payloadType MUST always be provided, and MUST be unique.
clockRate of type unsigned longCodec clock rate expressed in Hertz. If unset, the implementation default is assumed.
maxptime of type unsigned longThe maximum packetization time set on the
RTCRtpSender. Not specified if unset. If
ptime is also set, maxptime is ignored.
ptime of type unsigned longThe duration of media represented by a packet in milliseconds for the
RTCRtpSender. If unset, the
RTCRtpSender may select any value up to
maxptime.
numChannels of type unsigned longThe number of channels supported (e.g. two for stereo). If unset for audio, use the codec default. For video, this can be left unset.
rtcpFeedback of type sequence<RTCRtcpFeedback>Transport layer and codec-specific feedback messages for this codec.
parameters of type DictionaryCodec-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 | DOMString |
Sender | This parameter, encoded as a string of 6 upper case hexadecimal digits, indicates the configuration of the stream to be sent, as described in [[RFC6184]] Section 8.2.2. It MUST be supported, as noted in [[!RFC7742]] Section 6.2. |
| 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 [[!RFC7742]] Section 6.2. |
The following settings are defined for "rtx", as noted in [[!RFC4588]] Section 8.6:
| Property Name | Values | Receiver/Sender | Notes |
|---|---|---|---|
| apt | payloadType |
Receiver/Sender | As defined in [[!RFC4588]], the associated payload type of the
original stream being retransmitted. There will be an "rtx" entry in
RTCRtpParameters.codecs[] for each media codec that can be
retransmitted, each with their own apt parameter. |
| 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, each of which
MUST be unique. If payloadTypes is unset, this means that
any codec other than "red" or "rtx" can be encapsulsated in RED. |
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.
dictionary RTCRtpEncodingParameters {
unsigned long ssrc;
payloadtype codecPayloadType;
RTCRtpFecParameters fec;
RTCRtpRtxParameters rtx;
RTCPriorityType priority;
unsigned long maxBitrate;
double resolutionScale;
double framerateScale;
unsigned long maxFramerate;
boolean active = true;
DOMString encodingId;
sequence<DOMString> dependencyEncodingIds;
};
ssrc of type unsigned longThe SSRC for this layering/encoding. Multiple
RTCRtpEncodingParameters objects can share the same
ssrc value (useful, for example, to indicate that different
RTX payload types associated to different codecs are carried over the same
stream). If ssrc is unset in a
RTCRtpEncodingParameters object passed to the
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
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 an RTCRtpEncodingParameters
object passed to the send() method and an SSRC conflict is
detected within the RTP session, then an
RTCSsrcConflictEvent is fired (see Section 5.4).
codecPayloadType of type payloadtypeFor per-encoding codec specifications, give the codec payload type here.
If unset, the browser will choose the first codec in
parameters.codecs[] of the appropriate kind.
fec of type RTCRtpFecParametersSpecifies the FEC mechanism if set.
rtx of type RTCRtpRtxParametersSpecifies the RTX [[!RFC4588]] parameters if set.
priority of type RTCPriorityTypeIndicates 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.
maxBitrate of type unsigned longRamp 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.
resolutionScale of type doubleIf sender.track.kind is "video",
the encoder will scale down the resolution of
sender.track in each dimension before
sending. For example, if the value is 2.0, the video will be
scaled down by a factor of at least 2 in each dimension,
resulting in sending a video no greater than one quarter size.
If the value is 1.0 or unset, the sender
will attempt to encode with the resolution of track. For
scalable video coding, resolutionScale refers to the aggregate
scale down of this layer when combined with all dependent layers.
resolutionScale is less than 1.0, reject the
promise with RangeError when send()
or receive() is called. If
sender.track.kind is "audio", the value is
ignored.
framerateScale of type doubleInverse of the input framerate fraction to be encoded. Example: 1.0 =
full framerate, 2.0 = one half of the full framerate. For scalable video
coding, framerateScale refers to the inverse of the aggregate
fraction of input framerate achieved by this layer when combined with all
dependent layers.
maxFramerate of type unsigned longThe maximum framerate to use for this encoding. This setting is not used
for scalable video coding. If framerateScale is set,
then maxFramerate is ignored.
active of type boolean, defaulting to trueFor 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.
encodingId of type DOMStringAn 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]].
dependencyEncodingIds of type sequence<DOMString>The encodingIds on which this layer depends. Within
this specification encodingIds 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.
Usage of the attributes is defined in the table below:
| Attribute | Type | Receiver/Sender |
|---|---|---|
ssrc |
unsigned long |
Receiver/Sender |
codecPayloadType |
payloadType |
Receiver/Sender |
fec |
RTCRtpFecParameters |
Receiver/Sender |
rtx |
RTCRtpRtxParameters |
Receiver/Sender |
priority |
RTCPriorityType |
Sender |
maxBitrate |
unsigned long |
Sender |
resolutionScale |
double |
Sender |
framerateScale |
double |
Sender |
maxFramerate |
unsigned long |
Sender |
active |
boolean |
Receiver/Sender |
encodingId |
DOMString |
Receiver/Sender |
dependencyEncodingIds |
sequence<DOMString> |
Receiver/Sender |
// Send a thumbnail along with regular size, prioritizing the thumbnail (ssrc: 2)
var encodings = [{ ssrc: 1, priority: 1.0 }];
var encodings = [{ ssrc: 2, priority: 10.0 }];
// Sign Language (prefer framerate)
var encodings = [{ degradationPreference: "maintain-framerate" }];
// Screencast (prefer resolution)
var encodings = [{ degradationPreference: "maintain-resolution" }];
// Remote Desktop (High framerate, must not downscale)
var encodings = [{ degradationPreference: "maintain-framerate" }];
// Audio more important than video
var audioEncodings = [{ priority: 10.0 }];
var videoEncodings = [{ priority: 0.1 }];
// Video more important than audio
var audioEncodings = [{ priority: 0.1 }];
var videoEncodings = [{ priority: 10.0 }];
// Crank up the quality
var encodings = [{ maxBitrate: 10000000 }];
// Keep the bandwidth low
var encodings = [{ maxBitrate: 100000 }];
// 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
}, {
// High 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 high 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 yielding half resolution when combined with the base layer
encodingId: "1",
dependencyEncodingIds: ["0"],
resolutionScale: 2.0
}, {
// Additional spatial enhancement layer yielding full 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.
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.
enum RTCPriorityType {
"very-low",
"low",
"medium",
"high"
};
| Enumeration description | |
|---|---|
very-low |
See [[RTCWEB-TRANSPORT]], Section 4. |
low |
See [[RTCWEB-TRANSPORT]], Section 4. |
medium |
See [[RTCWEB-TRANSPORT]], Section 4. |
high |
See [[RTCWEB-TRANSPORT]], Section 4. |
dictionary RTCRtpFecParameters {
unsigned long ssrc;
DOMString mechanism;
};
ssrc of type unsigned longThe SSRC to use for FEC. If unset in an RTCRtpSender
object, the browser will choose.
mechanism of type DOMStringThe Forward Error Correction (FEC) mechanism to use: "red", "red+ulpfec" or "flexfec".
dictionary RTCRtpRtxParameters {
unsigned long ssrc;
};
ssrc of type unsigned longThe SSRC to use for retransmission, as specified in [[!RFC4588]]. If
unset when passed to RTCRtpSender.send(), the browser will
choose.
Below is an example of how to configure an RTCRtpReceiver
to receive video encoded in VP8 or VP9, along with retransmission and forward
error correction. In the example, forward error correction is encapsulated in
RED, and it is possible to retransmit RED packets. The configuration enables VP8
or VP9 to be received either with or without RED encapsulation. The configuration
of an RTCRtpSender would be more prescriptive, at a given
time indicating a single encoding: that VP8 or VP9 video should be sent
encapsulated within RED or without RED encapsulation.
// Example of RTX and RED + ulpfec
//
// SDP from createOffer() in WebRTC 1.0
//
// m=video 62125 UDP/TLS/RTP/SAVPF 100 101 116 117 96
// a=sendonly
// a=rtpmap:100 VP8/90000
// a=rtpmap:101 VP9/90000
// a=rtpmap:116 red/90000
// a=rtpmap:117 ulpfec/90000
// a=rtpmap:96 rtx/90000
// a=fmtp:96 apt=100
// a=rtpmap:97 rtx/90000
// a=fmtp:97 apt=101
// a=rtpmap:98 rtx/90000
// a=fmtp:98 apt=116
// a=ssrc-group:FID 2224031971 3254585230
// a=ssrc:2224031971 cname:oC/i06PA+Lda+t1P
// a=ssrc:3254585230 cname:oC/i06PA+Lda+t1P
//
// Define RTCRtpCodecParameters
//
var codecs = [
// Define VP9 codec parameters
{
name: "vp9",
payloadType: 101,
clockRate: 90000
},
// Define VP8 codec parameters
{
name: "vp8",
payloadType: 100,
clockRate: 90000
},
// Define retransmission of VP9
{
name: "rtx",
payloadType: 97,
clockrate: 90000,
parameters: {
apt: 101
}
},
// Define retransmission of VP8
{
name: "rtx",
payloadType: 96,
clockrate: 90000,
parameters: {
apt: 100
}
},
// Define RED codec parameters
{
name: "red",
payloadType: 116,
clockRate: 90000,
parameters: {
payloadTypes: []
}
},
// Define ulpfec codec parameters
{
name: "ulpfec",
payloadType: 117,
clockRate: 90000
},
// Define RTX codec parameters
{
name: "rtx",
payloadType: 98,
clockrate: 90000,
parameters: {
apt: 116
}
}
];
//
// Define rtx parameters
var rtxParams = {
ssrc: 3254585230
};
// Define FEC parameters for "red+ulpfec"
var redulpfec = {
ssrc: 3254585230,
mechanism: "red+ulpfec"
};
// Define RTCRtpEncodingParameters
//
var encodings = [
// Define VP8 encoding parameters (without RED)
{
ssrc: 2224031971,
codecPayloadType: 100,
rtx: rtxParams
},
// Define VP8 encoding parameters with RED
{
ssrc: 2224031971,
codecPayloadType: 100,
fec: redulpfec,
rtx: rtxParams
},
// Define VP9 encoding parameters (without RED)
{
ssrc: 2224031971,
codecPayloadType: 101,
rtx: rtxParams
},
// Define VP9 encoding parameters with RED
{
ssrc: 2224031971,
codecPayloadType: 101,
fec: redulplfec,
rtx: rtxParams
}
];
The RTCRtpHeaderExtension dictionary enables a header
extension to be configured for use within an RTCRtpSender or
RTCRtpReceiver. In order to provide the equivalent of the
"direction" parameter defined in [[!RFC5285]] Section 5, an application can do the
following:
send(parameters).receive(parameters).send(parameters) and
receive(parameters).send(parameters) or
receive(parameters).dictionary RTCRtpHeaderExtension {
DOMString kind;
DOMString uri;
unsigned short preferredId;
boolean preferredEncrypt = false;
};
kind of type DOMStringThe media supported by the header extension: "audio" for an audio codec, "video" for a video codec, etc.
uri of type DOMStringThe URI of the RTP header extension, as defined in [[!RFC5285]].
preferredId of type unsigned shortThe preferred ID value that goes in the packet.
preferredEncrypt of type boolean, defaulting to falseIf true, it is preferred that the value in the header be
encrypted as per [[!RFC6904]]. Default is to prefer unencrypted.
dictionary RTCRtpHeaderExtensionParameters {
required DOMString uri;
required unsigned short id;
boolean encrypt = false;
Dictionary parameters;
};
uri of type DOMString, requiredThe URI of the RTP header extension, as defined in [[!RFC5285]].
id of type unsigned short, requiredThe value that goes in the packet.
encrypt of type boolean, defaulting to falseIf true, the value in the header is encrypted as per
[[!RFC6904]]. Default is unencrypted.
parameters of type DictionaryConfiguration parameters for the header extension. An example is the "vad" extension attribute in the client-to-mixer header extension, described in [[!RFC6464]] Section 4.
parameters dictionary. Most header
extensions do not require configuration parameters, and
the ORTC Lib implementation assumes that the "V" bit from
[[!RFC6464]] is always enabled so that a vad
parameter is unnecessary.
Registered RTP header extensions are listed in [[!IANA-RTP-10]]. Header extensions mentioned in [[!RTP-USAGE]] and [[!RID]] include:
| Header Extension | Reference | Attributes | Notes |
|---|---|---|---|
| Transmission Time Offset | [[RFC5450]] | None | This extension indicates the transmission time offset. |
| Rapid Synchronization | [[RFC6051]] | None | This extension enables carriage of an NTP-format timestamp, as defined in [[!RFC6051]] Section 3.3. |
| Client-to-Mixer Audio Level | [[!RFC6464]] | boolean vad | This extension indicates the audio level of the audio sample carried in
an RTP packet. For an RTCRtpSender, the vad
attribute indicates whether the V bit is in use (true) or not
(false). For an RTCRtpReceiver, the
vad attribute indicates whether the V bit is provided to the
application (true) in
RTCRtpContributingSource.voiceActivityFlag or is unset
(false). |
| Mixer-to-Client Audio Level | [[RFC6465]] | None | This extension indicates the audio level of individual conference participants. |
| Absolute Send Time | [[ABS-SEND-TIME]] | None | This extension indicates the absolute send time. |
| CVO | [[!TS26.114]] Section 7.4.5 | None | The Coordination of Video Orientation (CVO) extension indicates whether the receiver needs to change the orientation in which it renders the stream. |
| MID | [[!BUNDLE]] | None | This extension defines a track identifier which can be used to identify the track corresponding to an RTP stream. |
| RID | [[!RID]] | None | This extension defines an identifier used to carry the
encodingId. |
An RTCDtmfSender instance allows sending DTMF tones
to/from the remote peer, as per [[!RFC4733]].
An RTCDtmfSender object is constructed from an
RTCRtpSender sender. If
sender.track.kind is not "audio", throw an
InvalidParameters exception.
[ Constructor (RTCRtpSender sender)]
interface RTCDtmfSender {
readonly attribute boolean canInsertDTMF;
void insertDTMF (DOMString tones, optional unsigned long duration = 100, optional unsigned long interToneGap = 70);
readonly attribute RTCRtpSender sender;
attribute EventHandler ontonechange;
readonly attribute DOMString toneBuffer;
};
RTCDtmfSender| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| sender | RTCRtpSender |
✘ | ✘ |
canInsertDTMF of type boolean, readonlyWhether the RTCDtmfSender is capable of sending DTMF.
sender of type RTCRtpSender, readonlyThe RTCRtpSender instance
ontonechange of type EventHandlerThe ontonechange event handler uses the RTCDTMFToneChangeEvent interface to return the character for each tone as it is played out.
toneBuffer of type DOMString, readonlyThe toneBuffer attribute returns a list of the tones remaining to be played out.
insertDTMFThe 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 with
parameters.codecs[] not including the "telephone-event" 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 MUST be normalized to uppercase on entry and are equivalent to A to D. As noted in [[!RFC7874]] Section 3, support for the characters 0 through 9, A through D, #, and * are required. The character ',' MUST be supported, and indicates a delay of 2 seconds before processing the next character in the tones parameter. All other characters (and only those other characters) MUST be considered unrecognized.
The duration parameter indicates the duration in ms to use for each character passed in the tones parameters. The duration cannot be more than 6000 ms or less than 40 ms. The default duration is 100 ms for each tone.
The interToneGap parameter indicates the gap between tones. 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()
RTCRtpSender
used to send DTMF.
InvalidStateError exception.
InvalidCharacterError
exception and abort these steps.
toneBuffer attribute to
tones.duration parameter
is less than 40, set it to 40. If, on the other hand, the
value is greater than 6000, set it to 6000.interToneGap parameter
is less than 30, set it to 30.toneBuffer is an empty string,
abort these steps.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.
| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| tones | DOMString |
✘ | ✘ | |
| duration | unsigned long = 100 |
✘ | ✔ | |
| interToneGap | unsigned long = 70 |
✘ | ✔ |
void
The tonechange event uses the RTCDTMFToneChangeEvent interface.
Firing a tonechange event named e with a DOMString tone
means that an event with the name e, which does not bubble (except where
otherwise stated) and is not cancelable (except where otherwise stated), and which
uses the RTCDTMFToneChangeEvent interface with the tone
attribute set to tone, MUST be created and dispatched at the given
target.
[ Constructor (DOMString type, RTCDTMFToneChangeEventInit eventInitDict)]
interface RTCDTMFToneChangeEvent : Event {
readonly attribute DOMString tone;
};
RTCDTMFToneChangeEvent| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| type | DOMString |
✘ | ✘ | |
| eventInitDict |
RTCDTMFToneChangeEventInit |
✘ | ✘ |
tone of type DOMString, readonlyThe 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 toneBuffer is an empty string
and that the previous tones have completed playback.
dictionary RTCDTMFToneChangeEventInit : EventInit {
required DOMString tone;
};
tone of type DOMString, defaulting to ""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 toneBuffer is an empty string
and that the previous tones have completed playback.
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. If
transport.state is closed, throw an
InvalidState 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.
[ Constructor (RTCDataTransport transport, RTCDataChannelParameters parameters)]
interface RTCDataChannel : EventTarget {
readonly attribute RTCDataTransport transport;
readonly attribute RTCDataChannelState readyState;
readonly attribute unsigned long bufferedAmount;
attribute unsigned long bufferedAmountLowThreshold;
attribute DOMString binaryType;
RTCDataChannelParameters getParameters ();
void close ();
attribute EventHandler onopen;
attribute EventHandler onbufferedamountlow;
attribute EventHandler onerror;
attribute EventHandler onclose;
attribute EventHandler onmessage;
void send (USVString data);
void send (Blob data);
void send (ArrayBuffer data);
void send (ArrayBufferView data);
};
RTCDataChannel| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| transport | RTCDataTransport |
✘ | ✘ | |
| parameters | RTCDataChannelParameters |
✘ | ✘ |
transport of type RTCDataTransport, readonlyThe readonly attribute referring to the related transport object.
readyState of type RTCDataChannelState, readonlyThe 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).
bufferedAmount of type unsigned
long, readonlyThe bufferedAmount
attribute MUST return the number of
bytes of application data (UTF-8 text and binary data) that have been
queued using send() but that, as of the last time the event loop started
executing a task, had not yet been transmitted to the network. This
includes any text sent during the execution of the current task, regardless
of whether the user agent is able to transmit text asynchronously with
script execution. This does not include framing overhead incurred by the
protocol, or buffering done by the operating system or network hardware. If
the channel is closed, this attribute's value will only increase with each
call to the send() method (the attribute does not reset to zero once the
channel closes).
bufferedAmountLowThreshold of type unsigned longThe bufferedAmountLowThreshold
attribute sets the threshold at which the bufferedAmount is considered
to be low. When the bufferedAmount decreases from
above this threshold to equal or below it, the bufferedamountlow event
fires. The bufferedAmountLowThreshold
is initially zero on each new RTCDataChannel, but the
application may change its value at any time.
binaryType of type DOMStringThe binaryType
attribute MUST, on getting, return
the value to which it was last set. On setting, the user agent MUST set the IDL attribute to the new value.
When an RTCDataChannel object is constructed, the
binaryType attribute MUST be initialized to the string 'blob'. This attribute
controls how binary data is exposed to scripts. See the [[WEBSOCKETS-API]]
for more information.
onopen of type EventHandlerThis event handler, of event handler type open, MUST be supported by all objects implementing
the RTCDataChannel interface.
onbufferedamountlow of type EventHandlerThe event type of this event handler is bufferedamountlow.
onerror of type EventHandlerThis 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.
onclose of type EventHandlerThis event handler, of event handler type close, MUST be supported by all objects implementing
the RTCDataChannel interface.
onmessage of type EventHandlerThis 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. |
getParametersReturns the parameters applying to this data channel.
RTCDataChannelParameters
closeCloses 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.
void
sendRun the steps described by the send() algorithm with
argument type string object.
| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| data | USVString |
✘ | ✘ |
void
sendRun the steps described by the send() algorithm with
argument type Blob object.
| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| data | Blob |
✘ | ✘ |
void
sendRun the steps described by the send() algorithm with
argument type ArrayBuffer object.
| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| data | ArrayBuffer |
✘ | ✘ |
void
sendRun the steps described by the send() algorithm with
argument type ArrayBufferView object.
| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| data | ArrayBufferView |
✘ | ✘ |
void
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 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.
interface RTCDataTransport : RTCStatsProvider {
};
enum RTCDataChannelState {
"connecting",
"open",
"closing",
"closed"
};
| Enumeration description | |
|---|---|
connecting |
The user agent is attempting to establish the underlying data
transport. This is the initial state of an
|
open |
The underlying data transport is established and communication is
possible. This is the initial state of an
|
closing |
The procedure to close down the underlying data transport has started. |
closed |
The underlying data transport has been closed or could not be established. |
An RTCDataChannel can be configured to operate in different
reliability modes. A reliable channel ensures that the data is delivered at the
other peer through retransmissions. An unreliable channel is configured to either
limit the number of retransmissions (maxRetransmits ) or set a time during which
transmissions (including retransmissions) are allowed (maxPacketLifeTime). These
properties can not be used simultaneously and an attempt to do so will result in an
error. Not setting any of these properties results in a reliable channel.
dictionary RTCDataChannelParameters {
USVString label = "";
boolean ordered = true;
unsigned long maxPacketLifetime;
unsigned long maxRetransmits;
USVString protocol = "";
boolean negotiated = false;
unsigned short id;
};
label of type USVString, defaulting to ""The label attribute represents a label that can
be used to distinguish this RTCDataChannel object from
other RTCDataChannel objects. 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.
ordered of type boolean, defaulting to trueThe 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.
maxPacketLifetime of type unsigned longThe maxPacketLifetime
attribute represents the length of the time window (in milliseconds) during
which retransmissions may occur in unreliable mode. The attribute
MUST return the value to which it was
set when the RTCDataChannel was constructed.
maxRetransmits of type unsigned longThe maxRetransmits
attribute returns the maximum number of retransmissions that are attempted
in unreliable mode. The attribute MUST be initialized to null by default and MUST return the value to which it was set when the
RTCDataChannel was constructed.
protocol of type USVString, defaulting to ""The name of the sub-protocol used with this
RTCDataChannelif 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.
negotiated of type boolean, defaulting to falseThe 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.
id of type unsigned shortThe id attribute returns the id for this
RTCDataChannel. The id was either assigned by the user
agent at channel creation time or was selected by the script. For SCTP, the
id represents a stream identifier, as discussed in [[!DATA]] Section 6.5.
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.
[ Constructor (RTCDtlsTransport transport, optional unsigned short port)]
interface RTCSctpTransport : RTCDataTransport {
readonly attribute RTCDtlsTransport transport;
readonly attribute RTCSctpTransportState state;
readonly attribute unsigned short port;
static RTCSctpCapabilities getCapabilities ();
void start (RTCSctpCapabilities remoteCaps);
void stop ();
attribute EventHandler ondatachannel;
attribute EventHandler onstatechange;
};
RTCSctpTransport| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| transport | RTCDtlsTransport |
✘ | ✘ | |
| port | unsigned short |
✘ | ✔ |
transport of type RTCDtlsTransport, readonlyThe RTCDtlsTransport instance the RTCSctpTransport object is sending over.
state of type RTCSctpTransportState, readonlyThe current state of the SCTP transport.
port of type unsigned short, readonlyThe SCTP port number used by the data channel.
ondatachannel of type EventHandlerThe 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.
onstatechange of type EventHandlerThis event handler, of event handler event type
statechange, MUST
be fired any time the RTCSctpTransportState
changes.
getCapabilities, staticRetrieves the RTCSctpCapabilities of the RTCSctpTransport instance.
RTCSctpCapabilities
start| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| remoteCaps | RTCSctpCapabilities |
✘ | ✘ |
void
stopStops the RTCSctpTransport instance.
void
RTCSctpTransportState indicates the state of the SCTP
transport.
enum RTCSctpTransportState {
"new",
"connecting",
"connected",
"closed"
};
| Enumeration description | |
|---|---|
new |
The |
connecting |
SCTP is in the process of negotiating an association. |
connected |
SCTP has completed negotiation of an association. |
closed |
The SCTP association has been closed intentionally via a call to
|
dictionary RTCSctpCapabilities {
unsigned short maxMessageSize;
};
maxMessageSize of type unsigned shortMaximum 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.
[ Constructor (DOMString type, RTCDataChannelEventInit eventInitDict)]
interface RTCDataChannelEvent : Event {
readonly attribute RTCDataChannel channel;
};
RTCDataChannelEvent| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| type | DOMString |
✘ | ✘ | |
| eventInitDict | RTCDataChannelEventInit |
✘ | ✘ |
channel of type RTCDataChannel, readonlyThe channel
attribute represents the RTCDataChannel object
associated with the event.
dictionary RTCDataChannelEventInit : EventInit {
RTCDataChannel channel;
};
channel of type RTCDataChannelThe RTCDataChannel object associated with the
event.
function initiate(signaller) {
// Prepare the ICE gatherer
var gatherOptions = {
gatherPolicy: "all",
iceServers: [
{ urls: "stun:stun1.example.net" },
{ urls: "turn:turn.example.org", username: "user", credential: "myPassword",
credentialType: "password" }
]
};
var iceGatherer = new RTCIceGatherer(gatherOptions);
iceGatherer.onlocalcandidate = function(event) {
mySignaller.mySendLocalCandidate(event.candidate);
};
// Start gathering
iceGatherer.gather();
// Create the DTLS certificate
var certs;
var keygenAlgorithm = { name: "ECDSA", namedCurve: "P-256" };
RTCCertificate.generateCertificate(keygenAlgorithm).then(function(certificate){
certs[0] = certificate;
}, function(){
trace('Certificate could not be created');
});
// Create ICE and DTLS transports
var ice = new RTCIceTransport(iceGatherer);
var dtls = new RTCDtlsTransport(ice, certs);
// Prepare to handle remote ICE candidates
mySignaller.onRemoteCandidate = function(remote) {
ice.addRemoteCandidate(remote.candidate);
};
var sctp = new RTCSctpTransport(dtls);
// Construct RTCDataChannelParameters dictionary
var parameters = {
label: "channel1",
ordered: true,
protocol: "ship",
negotiated: false
};
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 = {
gatherPolicy: "all",
iceServers: [
{ urls: "stun:stun1.example.net" },
{ urls: "turn:turn.example.org", username: "user", credential: "myPassword",
credentialType: "password" }
]
};
var iceGatherer = new RTCIceGatherer(gatherOptions);
iceGatherer.onlocalcandidate = function(event) {
mySignaller.mySendLocalCandidate(event.candidate);
};
// Start gathering
iceGatherer.gather();
// Create the DTLS certificate
var certs;
var keygenAlgorithm = { name: "ECDSA", namedCurve: "P-256" };
RTCCertificate.generateCertificate(keygenAlgorithm).then(function(certificate){
certs[0] = certificate;
}, function(){
trace('Certificate could not be created');
});
// Create ICE and DTLS transports
var ice = new RTCIceTransport(iceGatherer);
var dtls = new RTCDtlsTransport(ice, certs);
// Prepare to handle remote candidates
mySignaller.onRemoteCandidate = function(remote) {
ice.addRemoteCandidate(remote.candidate);
};
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]].
interface RTCStatsProvider {
Promise<RTCStatsReport> getStats ();
};
getStatsGathers 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.
Promise<RTCStatsReport>
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).
interface RTCStatsReport {
getter RTCStats (DOMString id);
};
RTCStatsGetter to retrieve the RTCStats objects that this
stats report is composed of.
The set of supported property names [[!WEBIDL]] is defined as the ids of
all the RTCStats objects that has been generated for
this stats report. The order of the property names is left to the user
agent.
| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| id | DOMString |
✘ | ✘ |
getter
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.
dictionary RTCStats {
DOMHighResTimeStamp timestamp;
RTCStatsType type;
DOMString id;
};
timestamp of type DOMHighResTimeStampThe timestamp, of type
DOMHighResTimeStamp [[!HIGHRES-TIME]], associated with this
object. The time is relative to the UNIX epoch (Jan 1, 1970, UTC). The
timestamp for local measurements corresponds to the local clock and for
remote measurements corresponds to the timestamp indicated in the incoming
RTCP Sender Report (SR), Receiver Report (RR) or Extended Report (XR).
type of type RTCStatsTypeThe type of this object.
The type attribute
MUST be initialized to the name of
the most specific type this RTCStats dictionary
represents.
id of type DOMStringA 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.
getIdentityAssertion() sets the identity provider to be
used for a given RTCIdentity object, and initiates the process of
obtaining an identity 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.
An 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.
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]].
As defined in [[!WEBRTC10]] Section 10.4, the peerIdentity
parameter to getUserMedia() enables media to be sent to a specifically
identified peer, without the contents of mediastreams being accessible to
applications. If a MediaStreamTrack with a peerIdentity
constraint applied is attached to an RTCRtpSender, media is not
sent unless the attached RTCDtlsTransport has validated the
same peerIdentity as the MediaStreamTrack 's constraint.
The Identity API is described below.
[ Constructor (RTCDtlsTransport transport)]
interface RTCIdentity {
readonly attribute RTCIdentityAssertion? peerIdentity;
readonly attribute RTCDtlsTransport transport;
Promise<DOMString> getIdentityAssertion (DOMString provider, optional DOMString protocol = "default", optional DOMString username);
Promise<RTCIdentityAssertion> setIdentityAssertion (DOMString assertion);
};
RTCIdentity| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| transport | RTCDtlsTransport |
✘ | ✘ |
peerIdentity of type RTCIdentityAssertion, readonly , nullablepeerIdentity 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.
transport of type RTCDtlsTransport, readonlyThe RTCDtlsTransport to be authenticated.
getIdentityAssertionSets 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).
| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| provider | DOMString |
✘ | ✘ | |
| protocol | DOMString = "default" |
✘ | ✔ | |
| username | DOMString |
✘ | ✔ |
Promise<DOMString>
setIdentityAssertionValidates 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).
| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| assertion | DOMString |
✘ | ✘ |
Promise<RTCIdentityAssertion>
dictionary RTCIdentityError {
DOMString idp;
DOMString? loginUrl;
DOMString protocol;
};
idp of type DOMStringThe domain name of the identity provider that is providing the error response.
loginUrl of type DOMString, nullableAn 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.
protocol of type DOMStringThe IdP protocol that is in use.
dictionary RTCIdentityAssertion {
DOMString idp;
DOMString name;
};
The identity system is designed so that applications need not take any special action in order for users to generate and verify identity assertions; if a user has configured an IdP into their browser, then the browser will automatically request/generate assertions and the other side will automatically verify them and display the results. However, applications may wish to exercise tighter control over the identity system as shown by the following examples.
This example shows how to configure the identity provider and protocol, and consume identity assertions.
// Set ICE gather options and construct the RTCIceGatherer object, assuming that
// we are using RTP/RTCP mux and A/V mux so that only one RTCIceTransport is needed.
// Include some helper functions
import {trace, errorHandler, mySendLocalCandidate, myIceGathererStateChange,
myIceTransportStateChange, myDtlsTransportStateChange} from 'helper';
var gatherOptions = {
gatherPolicy: "all",
iceServers: [
{ urls: "stun:stun1.example.net" },
{ urls: "turn:turn.example.org", username: "user", credential: "myPassword",
credentialType: "password" }
]
};
var iceGatherer = new RTCIceGatherer(gatherOptions);
iceGatherer.onlocalcandidate = function(event) {
mySendLocalCandidate(event.candidate);
};
// Start gathering
iceGatherer.gather();
// Construct the ICE transport
var ice = new RTCIceTransport(iceGatherer);
// Create the DTLS certificate
var certs;
var keygenAlgorithm = { name: "ECDSA", namedCurve: "P-256" };
RTCCertificate.generateCertificate(keygenAlgorithm).then(function(certificate){
certs[0] = certificate;
}, function(){
trace('Certificate could not be created');
});
// Create the RTCDtlsTransport object.
var dtls = new RTCDtlsTransport(ice, certs);
var identity = new RTCIdentity(dtls);
identity
.getIdentityAssertion("example.com", "default", "alice@example.com")
.then(signalAssertion(assertion), function(e) {
trace("Could not obtain an Identity Assertion. idp: " + e.idp + " Protocol: "
+ e.protocol + " loginUrl: " + e.loginUrl);
});
function signalAssertion(assertion) {
mySignalInitiate({
"myAssertion": assertion,
"ice": iceGatherer.getLocalParameters(),
"dtls": dtls.getLocalParameters()
}, function(response) {
ice.start(iceGatherer, response.ice, RTCIceRole.controlling);
// Call dtls.start() before setIdentityAssertion so the peer assertion can be validated.
dtls.start(response.dtls);
identity.setIdentityAssertion(response.myAssertion).then(function(peerAssertion) {
trace("Peer identity assertion validated. idp: " + peerAssertion.idp + " name: "
+ peerAssertion.name);
}, function(e) {
trace("Could not validate peer assertion. idp: " + e.idp + " Protocol: " + e.protocol);
});
});
}
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.
interface RTCCertificate {
readonly attribute DOMTimeStamp expires;
readonly attribute RTCDtlsFingerprint fingerprint;
AlgorithmIdentifier getAlgorithm ();
static Promise<RTCCertificate> generateCertificate (AlgorithmIdentifier keygenAlgorithm);
};
expires of type DOMTimeStamp, readonlyThe 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.
fingerprint of type RTCDtlsFingerprint, readonlyThe 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.
getAlgorithmReturns the value of keygenAlgorithm passed in the call to
generateCertificate().
AlgorithmIdentifier
generateCertificate, staticThe 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.
| Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| keygenAlgorithm | AlgorithmIdentifier |
✘ | ✘ |
Promise<RTCCertificate>
The following events fire on RTCDtlsTransport objects:
| Event name | Interface | Fired when... |
|---|---|---|
error |
ErrorEvent |
The RTCDtlsTransport object has received a DTLS
Alert. |
statechange |
Event |
The RTCDtlsTransportState changed. |
The following events fire on RTCIceTransport objects:
| Event name | Interface | Fired when... |
|---|---|---|
statechange |
Event |
The RTCIceTransportState changed. |
icecandidatepairchange |
RTCIceCandidatePairChangedEvent |
The selected RTCIceCandidatePair changed. |
The following events fire on RTCIceGatherer objects:
| Event name | Interface | Fired when... |
|---|---|---|
icecandidateerror |
RTCIceGathererIceErrorEvent |
The RTCIceGatherer object has experienced an ICE
gathering failure (such as an authentication failure with TURN
credentials). |
statechange |
Event |
The RTCIceGathererState changed. |
icecandidate |
RTCIceGatherer |
A new RTCIceGatherCandidate is made available to the
script. |
The following events fire on RTCRtpSender objects:
| Event name | Interface | Fired when... |
|---|---|---|
ssrcconflict |
RTCSsrcConflictEvent |
An SSRC conflict has been detected within the RTP session. |
The following events fire on RTCRtpListener objects:
| Event name | Interface | Fired when... |
|---|---|---|
unhandledrtp |
RTCRtpUnhandledEvent |
The RTCRtpListener object has received an RTP packet
that it cannot deliver to an RTCRtpReceiver object. |
The following events fire on RTCDTMFSender objects:
| Event name | Interface | Fired when... |
|---|---|---|
tonechange |
Event |
The RTCDTMFSender object has either just begun playout
of a tone (returned as the tone attribute) or just ended playout
of a tone (returned as an empty value in the tone attribute). |
The following events fire on RTCDataChannel objects:
| Event name | Interface | Fired when... |
|---|---|---|
open |
Event |
The RTCDataChannel object's underlying data
transport has been established (or re-established).
|
message |
MessageEvent
[[!webmessaging]] |
A message was successfully received. |
bufferedamountlow |
Event |
The RTCDataChannel object's bufferedAmount decreases from
above its bufferedAmountLowThreshold
to less than or equal to its bufferedAmountLowThreshold. |
error |
ErrorEvent |
An error has been detected within the RTCDataChannel
object. This is not used for programmatic exceptions. |
close |
Event |
The RTCDataChannel object's underlying data
transport has been closed.
|
The following events fire on RTCSctpTransport objects:
| Event name | Interface | Fired when... |
|---|---|---|
datachannel |
RTCDataChannelEvent |
A new RTCDataChannel is dispatched to the script in
response to the other peer creating a channel. |
statechange |
Event |
The RTCSctpTransportState changed. |
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 [[!RFC7874]] 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.
Where RTP and RTCP are not multiplexed, distinct
RTCIceTransport, RTCDtlsTransport and
RTCIdentity objects can be constructed for RTP and RTCP. While
it is possible for getIdentityAssertion() to be called with different
values of provider, protocol and username
for the RTP and RTCP RTCIdentity objects, application
developers desiring backward compatibility with WebRTC 1.0 are strongly discouraged
from doing so, since this is likely to result in an error.
Also, where RTP and RTCP are not multiplexed, it is possible that the assertions for both the RTP and RTCP will be validated, but that the identities will not be equivalent. Applications requiring backward compatibility with WebRTC 1.0 are advised to consider this an error. However, if backward compatibility with WebRTC 1.0 is not required the application can consider an alternative, such as ignoring the RTCP identity assertion.
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.
resolutionScale, as noted in:
Issue 362
disconnected state, as noted in:
Issue 565
profileLevelId to a DOMString, as noted in:
Issue 587
setTrack() to replace a track that is "ended", as noted in:
Issue 589
setTransport(), as noted in:
Issue 591
RTCRtpReceiver.stop(), as noted in:
Issue 596
RTCRtpSender.track.stop(), as noted in:
Issue 597
RTCIceGatherer, as noted in:
Issue 606
RTCIceTransport.start(), as noted in:
Issue 607
RTCIceCandidate, as noted in:
Issue 608
setTrack(null), as noted in:
Issue 615
sender.track set to null, as noted in:
Issue 616
MRST SVC
codecs, as noted in: Issue
175
RTCRtpCodecCapability.options, as noted in:
Issue 412
RTCDtmfSender, as noted in: Issue 446
rtcp.ssrc advice for implementations, as noted in:
Issue 462
RTCRtpReceiver.track.stop(), as noted in:
Issue 498
muxId usage, as noted in: Issue 528
name, as noted in: Issue 529
RTCRtpCodecCapability and
RTCRtpCodecParameters, as noted in: Issue 539
codecPayloadType can be unset, as noted in:
Issue 545
gather() method, as noted in: Issue 165
RTCIceGatherPolicy, as noted in:
Issue 224
minQuality attribute, as noted in: Issue 351
send() and receive() asynchronous, as noted
in: Issue 399,
Issue 463, Issue 468 and Issue 469
state attribute to RTCSctpTransport,
as noted in: Issue 403
payloadType uniqueness, as noted in: Issue 405
RTCRtpReceiver
constructor, as noted in:
Issue 411
send() restrictions on kind, as noted in:
Issue 414
getAlgorithm() method, as noted in: Issue 427
RTCDataChannel protocol and
label to USVString, as noted in: Issue 429
RTCRtpEncodingParameters attributes,
as noted in: Issue 445
onssrcconflict event, as noted in:
Issue 448
RTCRtpSender, as
noted in: Issue 450
send() and receive() with
unset RTCRtpEncodingParameters, as noted in: Issue 461
RTCRtpEncodingParameters, as noted in:
Issue 470
RTCIceGatherer closed
state, as noted in: Issue
476
RTCIceTransport object, as noted
in: Issue 477
relatedPort, as noted in: Issue 484
RTCIceParameters, as noted in:
Issue 485
RTCDataChannel construction, as
noted in: Issue 492
error.message, as noted in: Issue 495
RTCRtpReceiver description, as noted in:
Issue 496
clockRate attribute, as noted in:
Issue 500
RTCSctpTransport constructor, as noted in:
Issue 504
getCapabilities(), as noted in: Issue 509
RTCDataChannelParameters, as noted
in: Issue 519
unhandledrtp event contents prior to calling
receive(), as noted in: Issue 243
ptime, as noted in: Issue 160
send() when encodings is unset,
as noted in: Issue 187
RTCRtpContributingSource, as
noted in: Issue 263
maxBitrate, as noted in: Issue 267
audioLevel, as noted in: Issue 377
datachannel.send(), as noted in: PR 387
RTCRtpContributingSource from an interface to a
dictionary, as noted in: Issue 289
maxFramerate encoding parameter, as noted in:
Issue 412
getRemoteCertificates(), as noted in:
Issue 378
RTCDtlsTransportState definition, as noted in:
Issue 294
iceServers, as noted in: Issue 302
RTCIceGatherPolicy, as noted in:
Issue 305
component attribute, as noted in:
Issue 314
credentialType attribute to Examples, as noted in:
Issue 323
RTCDtlsTransportState, as
noted in: Issue 327
RTCIceTransportState transitions, as noted
in: Issue 332
rtcpTransport for BUNDLE and RTP/RTCP mux
use, as noted in: Issue
349
RTCRtpReceiver, as noted in: Issue 355
RTCDataChannel event table, as noted in:
Issue 358
encodingId syntax, as noted in: Issue 375
url to RTCIceGathererEvent, as noted in:
Issue 376
RangeError for resolutionScale <1.0, as
noted in: Issue 379
payloadType attribute to
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
failed state to
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
maxPacketLifetime and maxRetransmits from
unsigned short to unsigned long, as noted in: Issue 231
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
failed state to
RTCIceTransportState, as noted in: Issue 199
complete attribute to the
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
component attribute and
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
maxptime, as noted in: Issue 160
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
muxId for receiverId as noted in:
Issue 138 and
Issue 140
track.kind as described in: Issue 141
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
payloadtype, as described in Issue 118
onerror from the RTCIceTransport
object to the RTCIceListener object as described in Issue 121
maxTemporalLayers and
maxSpatialLayers, as noted in Issue 130
getRemoteCertificates(), as described in
Issue 67
filterParameters() and createParameters()
methods, as described in Issue 80
RTCRtpListener object added and figure in Section 1
updated, as described in Issue 32
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