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 current WebRTC 1.0 APIs, ORTC does not mandate a media signaling protocol or format. As a result, ORTC does not utilize Session Description Protocol (SDP) within its APIs, nor does it mandate support for the Offer/Answer state machine. Instead, ORTC focuses on "connections" and "tracks" being carried over those connections.
Object RealTime Communications (ORTC) provides a powerful API for the development of WebRTC based applications. ORTC does not mandate a media signaling protocol or format (as the current WebRTC 1.0 does by mandating SDP Offer/Answer). Instead, ORTC focuses on "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" and "data channels" are sent over the transports, between senders and receivers.
This specification defines several objects: RTCDtlsTransport (Section 2), RTCIceTransport (Section 3), RTCIceListener (Section 4), RTCRtpSender (Section 5), RTCRtpReceiver (Section 6), RTCRtpListener (Section 7), RTCDtmfSender (Section 9), RTCDataChannel (Section 10), and RTCSctpTransport (Section 11). RTP dictionaries are described in Section 8, and the Statistics API is described in Section 12.
In a Javascript application utilizing the ORTC API, the relationship between the application and the objects, as well as between the objects themselves is shown below. Horizontal or slanted arrows denote the flow of media or data, whereas vertical arrows denote interactions via methods and events.
The EventHandler
interface represents a callback used for event handlers as defined in
[[!HTML5]].
The concepts queue a task and fires a simple event are defined in [[!HTML5]].
The terms event, event handlers and event handler event types are defined in [[!HTML5]].
The terms MediaStream, MediaStreamTrack, Constraints, and Consumer are defined in [[!GETUSERMEDIA]].
The terms single-session transmission (SST) and multi-session transmission (MST) are defined in [[!RFC6190]]. While this specification supports SST but not MST, multiple streams may be utilized within a single RTP session.
The RTCDtlsTransport includes information relating to Datagram Transport Layer Security (DTLS) transport.
An RTCDtlsTransport instance is associated to an RTCRtpSender or an RTCRtpReceiver.
A RTCDtlsTransport instance is optionally constructed from an RTCIceTransport object or an RTCDtlsTransport is automatically constructed.
The associated RTCIceTransport instance.
The current state of the DTLS transport.
Obtain the DTLS parameters of the local RTCDtlsTransport.
Obtain the current DTLS parameters of the remote RTCDtlsTransport.
Obtain the certificates used by the remote peer.
Start DTLS transport negotiation with the parameters of the remote DTLS transport.
Stops and closes the DTLS transport object.
This event handler, of type trust
, with the name statechanged
,
uses the RTCDtlsStateChangedEvent
interface.
It MUST be supported by
all objects implementing the RTCDtlsTransport
interface.
This event is fired when the RTCDtlsTransportState changes, and provides the new
RTCDtlsTransportState that caused the event.
This event handler, of type error
,
MUST be supported by all objects implementing the RTCDtlsTransport
interface.
The RTCDtlsParameters object includes information relating to DTLS configuration.
The DTLS role, with a default of auto.
Sequence of fingerprints.
The RTCDtlsFingerprint object includes the hash function algorithm and certificate fingerprint as described in [[!RFC4572]].
One of the the hash function algorithms defined in the 'Hash function Textual Names' registry, initially specified in [[!RFC4572]] Section 8.
The value of the certificate fingerprint in lowercase hex string as expressed utilizing the syntax of 'fingerprint' in [[!RFC4572]] Section 5.
The DTLS role is be determined based on the resolved ICE role: the 'Controlled' role acts as the DTLS client, the 'Controlling' role acts as the DTLS server.
The DTLS client role.
The DTLS server role.
RTCDtlsTransportState provides information about the state of the DTLS transport.
DTLS connection object has been created and has not started negotiating yet.
DTLS is in the process of negotiating a secure connection.
DTLS has completed negotiation of a secure connection (including DTLS/SRTP).
closed state
The statechanged
event of the RTCDtlsTransport
object uses
the RTCDtlsTransportStateChangedEvent
interface.
Firing an
RTCDtlsTransportStateChangedEvent
event named
e with an RTCDtlsTransportState
state means that an event with the name e,
which does not bubble (except where otherwise stated) and is not
cancelable (except where otherwise stated), and which uses the
RTCDtlsTransportStateChangedEvent
interface with the
state
attribute set to the new RTCDtlsTransportState,
MUST be
created and dispatched at the given target.
The state
attribute is the new
RTCDtlsTransportState
that caused the event.
The state
attribute is the new
RTCDtlsTransportState
that caused the event.
The RTCIceTransport includes information relating to Interactive Connectivity Establishment (ICE).
An RTCIceTransport
instance is associated to a transport object (such as RTCDtlsTransport
),
and provides RTC related methods to it. To do an ICE restart, construct a new RTCIceTransport
object
(or alternatively, a new RTCIceListener
object).
An RTCIceTransport instance is constructed from either an RTCIceListener or an RTCIceOptions object. If an RTCIceListener was not passed into the constructor, an RTCIceListener object is automatically created.
The RTCIceListener specified in the RTCIceTransport constructor. If none was specified, the system will create an RTCIceListener automatically using the RTCIceOptions specified.
RTCIceRole contains the current role of the ICE transport.
The current state of the ICE transport.
The current state of ICE candidate gathering.
Retrieve the sequence of valid candidates associated with the local
RTCIceTransport
.
This retrieves all candidates currently known, even if an onlocalcandidate
event hasn't been processed yet.
Retrieve the sequence of candidates associated with the remote
RTCIceTransport
.
Start gathering RTCIceCandidate
objects, based on the gather policy
(set on the local system, not negotiated).
Starts candidate connectivity checks and attempts to connect to the remote
RTCIceTransport
.
Stops and closes the current object.
Obtain the ICE parameters of the local RTCIceTransport.
Obtain the current ICE parameters of the remote RTCIceTransport
.
Add remote candidate associated with remote RTCIceTransport.
Set the sequence of candidates associated with the remote RTCIceTransport.
This event handler, of event handler event type icecandidate
,
MUST be supported by all objects implementing the
RTCIceTransport
interface.
It receives events when a new local ICE candidate is available.
This event handler, of type trust
, with the name statechanged
,
uses the RTCIceTransportStateChangedEvent
interface.
It MUST be supported by
all objects implementing the RTCIceTransport
interface.
This event is fired when the RTCIceTransportState changes, and provides the new
RTCIceTransportState that caused the event.
This event handler, of type trust
, with the name gatherstatechanged
,
uses the RTCIceGatheringStateChangedEvent
interface.
It MUST be supported by
all objects implementing the RTCIceTransport
interface.
This event is fired when the RTCIceGatheringState changes, and provides the new
RTCIceGatheringState that caused the event.
This event handler, of type error
,
MUST be supported by all objects implementing the RTCIceTransport
interface.
No networking has occurred yet.
The ICE engine is in the process of gathering candidates.
The ICE engine has completed gathering and is currently idle. Events such as adding a new interface or a new TURN server will cause the state to go back to gathering.
The gatherstatechanged
event of the RTCIceTransport
object uses
the RTCIceGatheringStateChangedEvent
interface.
Firing an
RTCIceGatheringStateChangedEvent
event named
e with an RTCIceGatheringState
state means that an event with the name e,
which does not bubble (except where otherwise stated) and is not
cancelable (except where otherwise stated), and which uses the
RTCIceGatheringStateChangedEvent
interface with the
state
attribute set to the new RTCIceGatheringState,
MUST be
created and dispatched at the given target.
The state
attribute is the new
RTCIceGatheringState
that caused the event.
The state
attribute is the new
RTCIceGatheringState
that caused the event.
The RTCIceParameters object includes the ICE username and password.
ICE username.
ICE password.
controlling state
controlled state
Gather all ICE candidate types.
Gather all ICE candidate types except for host candidates.
Only gather media relay candidates such as candidates passing through a TURN server. This can be used to reduce leakage of IP addresses in certain use cases.
new state
checking state
connected state
completed state
disconnected state
closed state
The non-normative ICE state transitions are:
The statechanged
event of the RTCIceTransport
object uses
the RTCIceTransportStateChangedEvent
interface.
Firing an
RTCIceTransportStateChangedEvent
event named
e with an RTCIceTransportState
state means that an event with the name e,
which does not bubble (except where otherwise stated) and is not
cancelable (except where otherwise stated), and which uses the
RTCIceTransportStateChangedEvent
interface with the
state
attribute set to the new RTCIceTransportState,
MUST be
created and dispatched at the given target.
The state
attribute is the new
RTCIceTransportState
that caused the event.
The state
attribute is the new
RTCIceTransportState
that caused the event.
The RTCIceOptions object includes information relating to ICE configuration.
An array containing STUN and TURN servers available to be used by ICE.
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"} ]
STUN or TURN URI(s) as defined in [[!RFC7064]] and [[!RFC7065]]
If this RTCIceServer object represents a TURN server, then this attribute specifies the username to use with that TURN server.
If the uri element is a TURN URI, then this is the credential to use with that TURN server.
The RTCIceCandidate object includes information relating to an ICE candidate.
{
foundation: "abcd1234",
priority: 1694498815,
ip: "192.0.2.33",
protocol: "udp",
port: 10000,
type: "host"
};
A unique identifier that allows ICE to correlate candidates that appear on multiple RTCIceTransports.
The assigned priority of the candidate. This is automatically populated by the browser.
The IP address of the candidate.
The protocol of the candidate (UDP/TCP).
The port for the candidate.
The type of candidate.
The type of TCP candidate.
For candidates that are derived from others, such as relay or reflexive candidates, the relatedAddress refers to the host candidate that these are derived from. For host candidates, the relatedAddress is set to the empty string.
For candidates that are derived from others, such as relay or reflexive candidates, the relatedPort refers to the host candidate that these are derived from. For host candidates, the relatedPort is null.
The RTCIceProtocol includes the protocol of the ICE candidate.
A UDP candidate, as described in [[!RFC5245]].
A TCP candidate, as described in [[!RFC6544]].
The RTCIceTcpCandidateType includes the type of the ICE TCP candidate, as described in [[!RFC6544]].
An active TCP candidate is one for which the agent will attempt to open an outbound connection but will not receive incoming connection requests.
A passive TCP candidate is one for which the agent will receive incoming connection attempts but not attempt a connection.
An so candidate is one for which the agent will attempt to open a connection simultaneously with its peer.
The RTCIceCandidateType includes the type of the ICE candidate.
A host candidate.
A server reflexive candidate.
A peer reflexive candidate.
A relay candidate.
The icecandidate
event of the RTCIceTransport uses
the RTCIceTransportEvent
interface.
Firing an
RTCIceTransportEvent
event named
e with an RTCIceCandidate
candidate 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
RTCIceTransportEvent
interface with the
candidate
attribute set to the new ICE candidate,
MUST be
created and dispatched at the given target.
The candidate
attribute is the
RTCIceCandidate
object with the new ICE
candidate that caused the event.
If candidate
is null,
there are no additional candidates for now.
The ICE candidate that caused the event.
// Assume we already have a way to signal. 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.
function initiate(signaller) {
var iceOptions = ...;
var ice = new RTCIceTransport(iceOptions);
var dtls = new RTCDtlsTransport(ice);
// ... get tracks and RTP objects from other example
signaller.sendInitiate({
"ice": ice.getLocalParameters(),
"dtls": dtls.getLocalParameters(),
// ... include RTP info from other example
}, function(remote) {
ice.start(remote.ice,RTCIceRole.controlling);
dtls.start(remote.dtls);
// ... start RTP senders and receivers from other example
});
ice.onlocalcandidate = function(candidate) {
signaller.sendLocalCandidate(candidate);
}
signaller.onRemoteCandidate = function(candidate) {
ice.addRemoteCandidate(candidate);
}
}
// Assume we already have a way to signal and remote info is
// signalled to us. This is an example of how to answer with ICE and DTLS
// and DTLS parameters and ICE candidates and start both ICE and DTLS.
//
function accept(signaller, remote) {
var iceOptions = ...;
var ice = new RTCIceTransport(iceOptions);
var dtls = new RTCDtlsTransport(ice);
// ... get tracks and RTP objects from other example
ice.onlocalcandidate = function(candidate) {
signaller.sendLocalCandidate(candidate);
}
signaller.onRemoteCandidate = function(candidate) {
ice.addRemoteCandidate(candidate);
}
signaller.sendAccept({
"ice": ice.getLocalParameters(),
"dtls": dtls.getLocalParameters()
// ... include RTP info from other example
});
ice.start(remote.ice,RTCIceRole.controlled);
dtls.start(remote.dtls);
// ... start RTP senders and receivers from other example
}
The RTCIceListener enables an endpoint to construct multiple RTCIceTransport
objects from a set of local ICE parameters,
enabling usage scenarios such as parallel forking.
An RTCIceListener
instance is associated to an RTCIceTransport
.
An RTCIceListener
instance is optionally constructed from an RTCIceOptions
object,
or an RTCIceListener
is automatically constructed.
The RTCIceOptions instance.
var iceOptions = ...;
var iceListener = new RTCIceListener(iceOptions);
var iceBase = new RTCIceTransport(iceListener);
sendInitiate(iceBase.getLocalParameters(), function(response) {
// We may get N responses
var ice = new RTCIceTransport(iceListener);
ice.start(response.iceParameters, RTCIceRole.controlling);
// ... setup DTLS, RTP, SCTP, etc.
});
iceBase.onlocalcandidate = sendLocalCandidate;
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
.
The associated MediaStreamTrack instance.
The associated RTCDtlsTransport
instance.
Obtain the sender capabilities, based on kind. If kind is omitted, then all capabilities are returned.
Create parameters based on the MediaStreamTrack and the remote capabilities specified in RTCRtpCapabilities.
Filter parameters based on the remote RTCRtpCapabilities.
Calling RTCRtpSender
.filterParameters
(RTCRtpSender
.createParameters
(track), remoteCapabilities)
returns the same result as calling RTCRtpSender
.createParameters
(track, remoteCapabilities).
Media is controlled by the given "parameters". The sender starts sending when send() is called and stops sending when stop() is called.
Stops sending the track on the wire. Stop is final like MediaStreamTrack
The RTCRtpReceiver includes information relating to the RTP receiver.
An RTCRtpReceiver
instance is associated to a receiving
MediaStreamTrack and provides RTC related methods to it.
A RTCRtpReceiver
instance is constructed from an RTCDtlsTransport
object.
The associated MediaStreamTrack instance.
The associated RTCDtlsTransport
instance.
Obtain the receiver capabilities, based on kind. If kind is omitted, then all capabilities are returned.
Filter parameters based on the remote RTCRtpCapabilities. Calling RTCRtpReceiver
.filterParameters
(RTCRtpReceiver
.createParameters
(kind), remoteCapabilities)
returns the same result as calling RTCRtpReceiver
.createParameters
(kind, remoteCapabilities).
Media is controlled by the given "parameters". The receiver starts receiving when the receive() is called and stopped when the stop() is called.
Stops receiving the track on the wire. Stop is final like MediaStreamTrack
// 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.
function initiate(signaller, transport, audioTrack, videoTrack) {
var audioSender = new RTCRtpSender(audioTrack, transport);
var videoSender = new RTCRtpSender(videoTrack, transport);
var audioReceiver = new RTCRtpReceiver(transport);
var videoReceiver = new RTCRtpReceiver(transport);
var sendAudioParams = RTCRtpSender.createParameters(audioTrack);
var sendVideoParams = RTCRtpSender.createParameters(videoTrack);
signaller.offerTracks({
// The initiator offers parameters it wants to send with,
// and the capabilities it has for receiving.
"rtpAudioCaps": RTCRtpReceiver.getCapabilities("audio"),
"rtpVideoCaps": RTCRtpReceiver.getCapabilities("video"),
"audio": sendAudioParams,
"video": sendVideoParams
}, function(answer) {
// The responder answers with parameters it wants to send with
// and the capabilities it has for receiving.
var audioSendParams = RTCRtpSender.filterParameters(
sendAudioParams, answer.rtpAudioCaps);
var videoSendParams = RTCRtpSender.filterParameters(
sendVideoParams, answer.rtpVideoCaps);
var audioRecvParams = RTCRtpReceiver.filterParameters(
answer.audio);
var videoRecvParams = RTCRtpReceiver.filterParameters(
answer.video);
audioSender.send(audioSendParams);
videoSender.send(videoSendParams)
audioReceiver.receive(audioRecvParams);
videoReceiver.receive(videoRecvParams);
// Now we can render/play
// audioReceiver.track and videoReceiver.track.
});
}
// Assume we already have a way to signal, a transport
// (RTCDtlsTransport), and audio and video tracks. This is an example
// of how to answer an offer with audio and video tracks, and begin
// sending and receiving them.
function accept(
signaller, remote, transport, audioTrack, videoTrack) {
var audioSender = new RTCRtpSender(audioTrack, transport);
var videoSender = new RTCRtpSender(videoTrack, transport);
var audioReceiver = new RTCRtpReceiver(transport);
var videoReceiver = new RTCRtpReceiver(transport);
var audioSendParams = RTCRtpSender.createParameters(
audioTrack, remote.rtpAudioCaps);
var videoSendParams = RTCRtpSender.createParameters(
videoTrack, remote.rtpVideoCaps);
var audioRecvParams = RTCRtpReceiver.filterParameters(
remote.audio);
var videoRecvParams = RTCRtpReceiver.filterParameters(
remote.video);
audioSender.send(audioSendParams);
videoSender.send(videoSendParams)
audioReceiver.receive(audioRecvParams);
videoReceiver.receive(videoRecvParams);
signaller.answerTracks({
"rtpAudioCaps": RTCRtpReceiver.getCapabilities("audio"),
"rtpVideoCaps": RTCRtpReceiver.getCapabilities("video"),
"audio": audioSendParams,
"video": videoSendParams
});
// Now we can render/play
// audioReceiver.track and videoReceiver.track.
}
The RTCRtpListener listens to RTP packets received from the DTLS transport.
An RTCRtpListener
instance is associated to an RTCDtlsTransport
.
An RTCRtpListener instance is constructed from an RTCDtlsTransport object.
The RTCDtlsTransport instance.
The event handler which handles the RTCRtpUnhandledRtpEvent.
An unhandledrtp
event is fired if the RTCRtpListener
detects an RTP stream that is not configured to be processed by an
existing RTCRtpReceiver
object. The amount of buffering to be provided for unhandled
RTP streams is recommended to be strictly limited to protect against denial of service attacks.
To determine whether an RTP stream is configured to be processed by an existing RTCRtpReceiver object,
the RTCRtpListener attempts to match the values of an incoming RTP packet's
Payload Type and SSRC fields as well as the value of its receiverId RTP extension (if present) against the
RTCRtpReceiver.RTCRtpParameters.RTCRtpCodecParameters.payLoadType
,
RTCRtpReceiver.RTCRtpParameters.RTCRtpEncodingParameters.ssrc
,
and RTCRtpReceiver.RTCRtpParameters.receiverId
attributes of configured RTCRtpReceiver objects.
TODO: provide details of matching behavior, along with examples.
The unhandledrtp
event of the RTCRtpListener uses
the RTCRtpUnhandledEvent
interface.
Firing an
unhandledrtp
event named
e with an RTCRtpUnhandled
stream means that an event with the name e,
which does not bubble (except where otherwise stated) and is not
cancelable (except where otherwise stated), and which uses the
RTCRtpUnhandledEvent
interface with the
stream
attribute set to an RTCRtpUnhandled
object,
MUST be
created and dispatched at the given target.
The stream
attribute is the
RTCRtpUnhandled
object with the characteristics of the RTP stream
that caused the event.
The characteristics of the RTP stream that caused the event.
The SSRC in the RTP stream triggering the unhandledrtp event.
The Payload Type value in the RTP stream triggering the unhandledrtp event.
The value of the AppId header extension in the RTP stream triggering the unhandledrtp event, if present.
Supported audio codecs.
Supported video codecs.
URIs of supported RTP header extensions.
Features supported by the RTP engine.
Supported RTCP capabilities, such as "nack" from [[!RFC4585]].
The MIME media type, if set, empty string otherwise.
Codec clock rate expressed in Hertz, null if unset.
Added to make it possible for the sender and receiver to pick a matching payload type when creating sender and receiver parameters.
The number of channels supported (e.g. stereo); one by default. For video, this will be null.
Codec-specific capabilities available for signaling.
The receiverId assigned to the RTP stream, if any, empty string if unset.
In an RTCRtpReceiver object, this corresponds to
recv-appId defined in [[!APPID]]. In an RTCRtpSender
object, it corresponds to the appId.
This is a stable identifier that can be defined and assign to any RTP stream rather than relying on an SSRC.
An SSRC is randomly generated and can change arbitrarily due to conflicts with other SSRCs, whereas
the receiverId has a value
whose meaning can be defined in advance between RTP
sender and receiver, assisting in RTP demultiplexing.
The codecs to send or receive (could include RTX and CN as well).
The RTP header extensions to send or receive.
The "encodings" or "layers" to be used for things like simulcast, Scalable Video Coding, RTX, FEC, etc.
The SSRC used by RTCP (e.g. in Receiver Reports)t. If unset, the SSRC is chosen by the browser. Note that the browser may change the SSRC in event of a collision, as described in [[!RFC3550]].
The value that goes in the RTP Payload Type Field [[!RFC3550]]. The payloadType must always be provided both within RTCRtpSender and RTCRtpReceiver objects.
The codec to be used for sending or receiving.
Codec settings that control what is sent or received. For example, with Opus [[!RFC6716]], stereo=1.
RTCP feedback settings, separated out because they are so different.
The SSRC for this layering/encoding, null if unset. If an SSRC is not present in a receive object, any SSRC will match. If an SSRC is not present in a sender object, the browser will choose.
For per-encoding codec specifications, give the codec name here. If the empty string, the browser will choose.
Specifies the FEC mechanism if used, null if unset.
Specifies the RTX mechanism if used, null if unset.
The higher the value, the more the bits will be given to each as available bandwidth goes up. Default is 1.0. This parameter is ignored in scalable video coding.
Ramp up resolution/quality/framerate until this bitrate, null if unset. Summed when using dependent layers.
This parameter is ignored in scalable video coding, or in an RTCRtpReceiver
object.
Never send less than this quality. 1.0 = maximum attainable quality.
This parameter is ignored in scalable video encoding, or in an RTCRtpReceiver
object.
What to give more bits to, if available, null if unset. 0.0 = strongly favor resolution or 1.0 = strongly favor
framerate. 0.5 = neither (default). This parameter is ignored in a scalable video encoding,
or in an RTCRtpReceiver
object.
Do this scale of the input resolution, or die trying. 1.0 = full resolution. Default is unconstrained (null). For scalable video coding, scale refers to the aggregate scale achieved by this layer when combined with all dependent layers.
Fraction of the framerate to be encoded. 1.0 = full framerate. Default is unconstrained (null). For scalable video coding, framerate refers to the aggregate framerate achieved by this layer when combined with all dependent layers.
Fraction of the quality to be encoded. 1.0 = full quality. Default is unconstrained (null). For scalable video coding, quality refers to the aggregate quality achieved by this layer when combined with all dependent layers.
Whether the sender or receiver is active. If false, don't send any media right now. Disable is different than omitting the encoding; it can keep resources available to re-enable more quickly than re-adding. Plus, it still sends RTCP. Default is active.
An identifier for the encoding object. This identifier should be unique within the scope of the localized sequence of RTCRtpEncodingParameters for any given RTCRtpParameters object. If encodings contained within sequences of other RTCRtpParameters objects are dependent upon this encoding identifier, the identifier should be globally unique (unless two or more encodings are intentionally referencing the same dependency RTCRtpEncodingParameters such as described in [[!RFC5583]] Section 6.5a).
Just the IDs. Within this specification it resolves to encodingIds within the same sequence only. In the future if MST were to be supported, then if searching the same sequence did not produce a match, then a global search would be carried out.
//Send a thumbnail along with regular size
var encodings1 = [{ ssrc: 1, priority: 1.0 }]
// Control the resolution and framerate with a different track and RtpSender.
var encodings2 = [{ ssrc: 2,
// Prioritize the thumbnail over the main video.
priority: 10.0 }];
// Sign Language (need high framerate, but don't get too bad quality)
var encodings = [{ minQuality: 0.2, framerateBias: 1.0 }];
// Screencast (High quality, framerate can be low)
var encodings = [{ framerateBias: 0.0 }];
//Remote Desktop (High framerate, must not downscale)
var encodings = [{ framerateBias: 1.0 }];
// 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 spatial scalability encoding
var encodings =[{
layerId: "0",
scale: 0.25
}, {
layerId: "1",
layerDependencies: ["0"]
scale: 0.5
}, {
layerId: "2",
layerDependencies: ["0", "1"]
scale: 1.0
}]
Example of 3-layer spatial scalability with all but bottom layer disabled
var encodings1 =[{
layerId: "0",
scale: 0.25
}, {
layerId: "1",
layerDependencies: ["0"],
scale: 0.5,
active: false
}, {
layerId: "2",
layerDependencies: ["0", "1"],
scale: 1.0,
active: false
}];
Example of 3-layer spatial simulcast
var encodings =[{
layerId: "0",
scale: 0.25
}, {
layerId: "1",
scale: 0.5
}, {
layerId: "2",
scale: 1.0
}]
Example of 3-layer spatial simulcast with all but bottom layer disabled
var encodings1 =[{
layerId: "0",
scale: 0.25
}, {
layerId: "1",
scale: 0.5,
active: false
}, {
layerId: "2",
scale: 1.0,
active: false
}];
Example of 2-layer spatial simulcast combined with 2-layer temporal scalability
var encodings =[{
layerId: "halfScaleBase",
scale: 0.5,
framerate: 0.5
}, {
layerId: "fullScaleBase",
scale: 1.0,
framerate: 0.5
}, {
layerId: "temporalEnhancemenToHalfScaleBase",
layerDependencies: ["halfScaleBase"],
scale: 0.5,
framerate: 1.0
}, {
layerId: "temporalEnhancementToFullScaleBase",
layerDependencies: ["fullScaleBase"],
scale: 1.0,
framerate:1.0
}]
The SSRC to use for FEC, null if unset.
If null in an RTCRtpSender
object, the browser will choose.
The Forward Error Correction (FEC) mechanism to use.
The SSRC to use for RTX, null if unset.
If null in an RTCRtpSender
object, the browser will choose.
The URI of the RTP header extension, as defined in [[!RFC5285]].
The value that goes in the packet.
If true, the value in the header is encrypted as per [[!RFC6904]]. Default is unencrypted.
The maximum legal value of this property.
The minimum legal value of this property.
The maximum legal value of this property.
The minimum legal value of this property.
Capabilities are a dictionary containing one or more key-value pairs,
where each key MUST be a property defined in the registry, and each value
MUST be a subset of the set of values defined for that property in the registry.
The exact syntax of the value expression depends on the type of the property but
is of type ConstraintValues
. The Capabilities dictionary specifies the subset
of the properties and values from the registry that the UA supports.
Note that a UA may support only a subset of the properties that are defined in
the registry, and may support a subset of the set values for those properties
that it does support. Note that Capabilities are returned from the UA to the
application, and cannot be specified by the application. However, the application
can set the Parameters.
An example of a Capabilities dictionary is shown below. This example is not
very realistic in that a browser would actually be required to support more
settings that just these.
A Settings is a dictionary containing one or more key-value pairs.
It MUST contain each key returned in Capabilities.
There MUST be
a single value for each key and the value MUST be a member of the set
defined for that property by Capabilities. The exact syntax of the
value expression depends on the type of the property. It will be a
DOMString[] for properties of type MultiPropertyValueSet
. It will
be a DOMString[] for properties of type PropertyValueSet
, it will be a long
for properties of type PropertyValueLongRange
, it will be a double
for properties of type PropertyValueDoubleRange
. Thus the Settings
dictionary contains the actual values that the UA has chosen for the
object's Capabilities.
An example of a Settings dictionary is shown below. This example is not
very realistic in that a browser would actually be required to support
more settings that just these.
An RTCDtmfSender instance allows sending DTMF tones to/from the remote peer, as per [[!RFC4733]].
An RTCDtmfSender object is constructed from an RTCRtpSender object.
Whether the RTCDtmfSender is capable of sending DTMF.
The RTCRtpSender instance
The ontonechange event handler uses the RTCDTMFToneChangeEvent interface to return the character for each tone as it is played out.
The toneBuffer attribute returns a list of the tones remaining to be played out.
The duration attribute returns the current tone duration
value in milliseconds. This value will be the value last set via the
insertDTMF()
method, or the default value of 70 ms if
insertDTMF()
was called without specifying the duration.
The interToneGap attribute returns the current value of
the between-tone gap. This value will be the value last set via the
insertDTMF()
method, or the default value of 70
ms if insertDTMF()
was called without specifying
the interToneGap.
The tonechange event uses the RTCDTMFToneChangeEvent interface.
Firing an tonechange event named e with a DOMString tone means that an event with the name e, which does not bubble (except where otherwise stated) and is not cancelable (except where otherwise stated), and which uses the RTCDTMFToneChangeEvent interface with the tone attribute set to tone, MUST be created and dispatched at the given target.
The tone
attribute contains the character for the tone that has just begun
playout (see insertDTMF()
). If the value is the
empty string, it indicates that the previous tone has completed
playback.
The tone parameter is treated as a series of characters. The characters 0 through 9, A through D, #, and * generate the associated DTMF tones. The characters a to d are equivalent to A to D. The character ',' indicates a delay of 2 seconds before processing the next character in the tones parameter. Unrecognized characters are ignored.
Examples assume that sendObject is an RTCRtpSender
object.
Sending the DTMF signal "1234" with 500 ms duration per tone:
var sender = new RTCDtmfSender(sendObject); if (sender.canInsertDTMF) { var duration = 500; sender.insertDTMF("1234", duration); } else log("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 an RTCDataTransport
object and
an RTCDataChannelParameters
object.
The RTCDataChannel
interface represents a bi-directional data channel between
two peers.
There are two ways to establish a connection with RTCDataChannel
.
The first way is to construct an RTCDataChannel
at one of the peers with the
RTCDataChannelParameters
.negotiated attribute unset or set to its default value false.
This will announce the new channel in-band and trigger an ondatachannel event with the
corresponding RTCDataChannel
object at the other peer.
The second way is to let the application negotiate the RTCDataChannel
.
To do this, create an RTCDataChannel
object with the RTCDataChannelParameters
.negotiated
dictionary member set to true, and signal out-of-band (e.g. via a web server) to the other
side that it should create a corresponding RTCDataChannel
with the
RTCDataChannelParameters
.negotiated dictionary member set to true and the same id.
This will connect the two separately created RTCDataChannel
objects.
The second way makes it possible to create channels with asymmetric properties and to
create channels in a declarative way by specifying matching ids.
Each RTCDataChannel
has an associated underlying data transport that is used
to transport actual data to the other peer.
The transport properties of the underlying data transport, such as in order delivery
settings and reliability mode, are configured by the peer as the channel is created.
The properties of a channel cannot change after the channel has been created.
The readonly attribute referring to the related transport object.
The parameters applying to this data channel.
The readyState
attribute represents the state of the RTCDataChannel object.
It MUST return the value to which the user agent last set it (as defined by the processing model algorithms).
The bufferedAmount
attribute
MUST return the number of bytes of application data
(UTF-8 text and binary data) that have been queued using send() but that, as of the last time
the event loop started executing a task, had not yet been transmitted to the network.
This includes any text sent during the execution of the current task, regardless of whether the
user agent is able to transmit text asynchronously with script execution.
This does not include framing overhead incurred by the protocol, or buffering done by the
operating system or network hardware.
If the channel is closed, this attribute's value will only increase with each call to the
send() method (the attribute does not reset to zero once the channel closes).
The binaryType
attribute
MUST, on getting, return the value to which it was last set.
On setting, the user agent MUST set the IDL attribute to the new value.
When an RTCDataChannel object is constructed, the binaryType
attribute
MUST be initialized to the string 'blob'.
This attribute controls how binary data is exposed to scripts.
See the [[!WEBSOCKETS-API]] for more information.
Closes the RTCDataChannel.
It may be called regardless of whether the RTCDataChannel object was created by this peer or the remote peer.
When the close()
method is called, the user agent
MUST run the following steps:
1. Let channel be the RTCDataChannel object which is about to be closed.
2. If channel's readyState
is closing or closed, then abort these steps.
3. Set channel's readyState
attribute to closing.
4. If the closing procedure has not started yet, start it.
This event handler, of type open
,
MUST be supported by all objects implementing the RTCDataChannel interface.
This event handler, of type error
,
MUST be supported by all objects implementing the RTCDataChannel interface.
This event handler, of type close
,
MUST be supported by all objects implementing the RTCDataChannel interface.
This event handler, of event handler event type message
,
MUST be fired to
allow a developer's JavaScript to receive data from a remote peer.
Event Argument | Description |
Object data | The received remote data. |
Run the steps described by the send()
algorithm with argument type string
object.
Run the steps described by the send()
algorithm with argument type Blob
object.
Run the steps described by the send()
algorithm with argument type ArrayBuffer
object.
Run the steps described by the send()
algorithm with argument type ArrayBufferView
object.
The user agent is attempting to establish the underlying data transport. This is the initial state of an RTCDataChannel object.
The underlying data transport is established and communication is possible. This is the initial state of an RTCDataChannel object dispatched as a part of an RTCDataChannelEvent.
The procedure to close down the underlying data transport has started.
The underlying data transport has been closed or could not be established.
An RTCDataChannel can be configured to operate in different reliability modes. A reliable channel ensures that the data is delivered at the other peer through retransmissions. An unreliable channel is configured to either limit the number of retransmissions (maxRetransmits ) or set a time during which transmissions (including retransmissions) are allowed (maxPacketLifeTime). These properties can not be used simultaneously and an attempt to do so will result in an error. Not setting any of these properties results in a reliable channel.
The label attribute represents a label that can be used to distinguish this RTCDataChannel object from other RTCDataChannel objects. The attribute MUST return the value to which it was set when the RTCDataChannel object was constructed. For an SCTP data channel, the label is carried in the DATA_CHANNEL_OPEN message defined in [[!DATA-PROT]] Section 5.1.
The ordered
attribute returns true if the RTCDataChannel is ordered, and
false if out of order delivery is allowed. Default is true.
The attribute MUST return the value to which it was set when the
RTCDataChannel was constructed.
The maxPacketLifetime
attribute represents the length of the time window (in milliseconds) during which
retransmissions may occur in unreliable mode, or null if unset.
The attribute MUST return the value to which it was set when the
RTCDataChannel was constructed.
The maxRetransmits
attribute returns the maximum number of
retransmissions that are attempted in unreliable mode, or null if unset.
The attribute MUST be initialized to null by default and
MUST return the
value to which it was set when the RTCDataChannel was constructed.
The name of the sub-protocol used with this RTCDataChannel if any, or the empty string otherwise (in which case the protocol is unspecified). The attribute MUST return the value to which it was set when the RTCDataChannel was constucted. Sub-protocols are registered in the 'Websocket Subprotocol Name Registry' created in [[!RFC6455]] Section 11.5.
The negotiated
attribute returns true if this RTCDataChannel
was negotiated by the application, or false otherwise. The attribute MUST
be initialized to false
by default and MUST return the value to which it
was set when the RTCDataChannel was constructed.
If set to true, the application developer MUST signal to the remote peer to
construct an RTCDataChannel object with the same id for the data channel
to be open.
If set to false, the remote party will receive an ondatachannel event with
a system constructed RTCDataChannel object.
The id attribute returns the id for this RTCDataChannel, or null if unset. The id was either assigned by the user agent at channel creation time or was selected by the script. For SCTP, the id represents a stream identifier, as discussed in [[!DATA]] Section 6.5. The attribute MUST return the value to which it was set when the RTCDataChannel was constructed.
The RTCSctpTransport includes information relating to Stream Control Transmission Protocol (SCTP) transport.
An RTCSctpTransport inherits from an RTCDataTransport object, which is associated to an RTCDataChannel object.
An RTCSctpTransport is constructed from an RTCDtlsTransport object.
The RTCDtlsTransport instance the RTCSctpTransport object is sending over.
Retrieves the RTCSctpCapabilities of the RTCSctpTransport instance.
Stops the RTCSctpTransport instance.
The ondatachannel event handler, of type datachannel
, MUST be
supported by all objects implementing the
RTCSctpTransport
interface.
If the remote peers sets RTCDataChannelParameters
.negotiated
to false,
then the event will fire indicating a new RTCDataChannel
object has been
constructed to connect with the RTCDataChannel
constructed by the remote peer.
Maximum message size or null if unset.
The datachannel
event
uses the RTCDataChannelEvent
interface.
Firing a datachannel event named
e with a RTCDataChannel
channel means that an event with the name e, which
does not bubble (except where otherwise stated) and is not cancelable
(except where otherwise stated), and which uses the
RTCDataChannelEvent
interface with the channel
attribute set to
channel, MUST be created and dispatched at the given
target.
The channel
attribute
represents the RTCDataChannel
object associated
with the event.
TODO
function initiate(signaller) {
var dtls = ...; // See ICE/DTLS example.
var sctp = new RTCSctpTransport(dtls);
var parameters = ...; // Construct RTCDataChannelParameters object
signaller.sendInitiate({
// ... include ICE/DTLS info from other example.
"sctpCapabilities": RTCSctpTransport.getCapabilities()
}, function(remote) {
sctp.start(remote.sctpCapabilities);
});
var channel = new RTCDataChannel (sctp, parameters);
channel.send("foo");
}
function accept(signaller, remote) {
var dtls = ...; // See ICE/DTLS example.
signaller.sendAccept({
// ... include ICE/DTLS info from other example.
"sctpCapabilities": RTCSctpTransport.getCapabilities()
});
var sctp = new RTCSctpTransport(dtls);
sctp.start(remote.sctpCapabilties);
// Assume in-band signalling. We could also easily add
// RTCDataChannelParameters into the out-of-band signalling
// And construct the data channel with 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
, RTCIceTransport
and
RTCSctpTransport
objects.
Gathers stats for the given object and reports the result asynchronously. TODO: Rework this as a Promise.
When the getStats() method is invoked, the user agent MUST queue a task to run the following steps:
If the object's
RTCRtpEncodingParameters
.active
state is false
, throw an
InvalidStateError
exception.
Return, but continue the following steps in the background.
Start gathering the stats.
When the relevant stats have been gathered, queue a task to
invoke the success callback (the method's second argument) with a
new RTCStatsReport
object, representing the
gathered stats, as its argument.
A RTCStatsReport
representing the gathered
stats.
An error object encapsulating information about what went wrong.
The getStats()
method delivers a successful result in the form of a
RTCStatsReport
object. A
RTCStatsReport
object represents a map between
strings, identifying the inspected objects (RTCStats.id), and their corresponding
RTCStats
objects.
An RTCStatsReport
may be composed of several
RTCStats
objects, each reporting stats for one
underlying object.
One achieves the total for the object by summing over all stats of a
certain type; for instance, if an RTCRtpSender object is sending
RTP streams involving multiple SSRCs over the network, the
RTCStatsReport
may contain one RTCStats
object per SSRC (which can be distinguished by the value of the "ssrc"
stats attribute).
Getter to retrieve the RTCStats
objects that
this stats report is composed of.
The set of supported property names [[!WEBIDL]] is defined as the
ids of all the RTCStats
objects that has been
generated for this stats report. The order of the property names is
left to the user agent.
An RTCStats
dictionary represents the stats
gathered by inspecting a specific object.
The RTCStats
dictionary is a base type that specifies as set of default attributes,
such as timestamp and type. Specific stats are added by extending the
RTCStats
dictionary.
Note that while stats names are standardized, any given implementation may be using experimental values or values not yet known to the Web application. Thus, applications MUST be prepared to deal with unknown stats.
Statistics need to be synchronized with each other in order to yield
reasonable values in computation; for instance, if "bytesSent" and
"packetsSent" are both reported, they both need to be reported over the
same interval, so that "average packet size" can be computed as "bytes /
packets" - if the intervals are different, this will yield errors. Thus
implementations MUST return synchronized values for all stats in a
RTCStats
object.
The timestamp
,
of type DOMHiResTimeStamp
[[!HIGHRES-TIME]], associated
with this object. The time is relative to the UNIX epoch (Jan 1,
1970, UTC).
The type of this object.
The type
attribute
MUST be initialized to the name of the most specific type this
RTCStats
dictionary represents.
A unique id
that is
associated with the object that was inspected to produce this
RTCStats
object. Two RTCStats
objects, extracted from two different
RTCStatsReport
objects, MUST have the same id if
they were produced by inspecting the same underlying object. User
agents are free to pick any format for the id as long as it meets the
requirements above.
Inbound RTP. Relevant to RTCRtpReceiver
objects.
Outbound RTP. Relevant to RTCRtpSender
objects.
Transport statistics. Relevant to RTCDtlsTransport
objects.
ICE candidate pair statistics. Relevant to RTCIceTransport
objects.
ICE local candidate statistics. Relevant to RTCIceTransport
objects.
ICE remote candidate statistics. Relevant to RTCIceTransport
objects.
...
The remoteId
can be used to look up the corresponding
RTCStats
object that represents stats reported by
the other peer.
Count of FIR packets, defined in [[!RFC5104]] Section 4.3.1.
Count of PLI packets, defined in [[!RFC4585]] Section 6.3.1.
Count of NACK packets, defined in [[!RFC4585]] Section 6.2.1.
Count of SLI packets, defined in [[!RFC4585]] Section 6.3.2.
RTCInboundRTPStreamStats are relevant to RTCRtpReceiver
objects.
Packets received.
Bytes received.
Packets lost.
Jitter, as calculated in [[!RFC3550]] Section 6.4.1, but given in seconds.
Present bitrate target of this SSRC, in bits per second.
RTCOutboundRTPStreamStats are relevant to RTCRtpSender
objects.
Packets sent.
Bytes sent.
Estimated round trip time (seconds) based on the RTCP timestamp, as described in [[!RFC3550]] Section 6.4.1.
Consider the case where the user is experiencing bad sound and the application wants to
determine if the cause of it is packet loss. Assume that receiver is an
RTCRtpReceiver
object. The following example code might be used:
var baselineReport, currentReport; getStats(receiver, function (report) { baselineReport = report; }); // ... wait a bit setTimeout(function () { getStats(receiver, function (report) { currentReport = report; processStats(); }); }, aBit); function processStats() { // compare the elements from the current report with the baseline for each (var now in currentReport) { if (now.type != "outbound-rtp") continue; // get the corresponding stats from the baseline report base = baselineReport[now.id]; if (base) { remoteNow = currentReport[now.remoteId]; remoteBase = baselineReport[base.remoteId]; 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; } } }
This specification requires that RTCP packets must be multiplexed with the RTP packets as defined by [[!RFC5761]].
The following events fire on RTCDtlsTransport
objects:
Event name | Interface | Fired when... |
---|---|---|
error |
Event
|
The RTCDtlsTransport object has
received a DTLS Alert. |
statechanged |
RTCDtlsTransportStateChangedEvent
|
The RTCDtlsTransportState changes. |
The following events fire on RTCIceTransport
objects:
Event name | Interface | Fired when... |
---|---|---|
statechanged |
RTCIceTransportStateChangedEvent
|
The RTCIceTransportState changes. |
gatherstatechanged |
RTCIceGatheringStateChangedEvent
|
The RTCIceGatheringState changes. |
icecandidate |
RTCIceTransport
|
A new RTCIceCandidate is made available to the script. |
error |
Event
|
The RTCIceTransport object has
experienced an ICE gathering failure (such as an authentication failure with TURN credentials). |
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).
|
MessageEvent
|
Event
|
A message was successfully received. TODO: Ref where MessageEvent is defined? |
error
|
Event
|
TODO. |
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.
|
This example code provides a basic audio and video session between two browsers.
This section will be removed before publication.