RTCConfiguration
MembersRTCIceServer
MembersRTCPeerConnectionErrorCallback
ParametersRTCSessionDescriptionInit
MembersRTCSessionDescriptionCallback
ParametersRTCIceCandidateInit
MembersRTCPeerConnectionIceEventInit
MembersRTCDataChannelInit
MembersRTCDataChannelEventInit
MembersRTCStatsCallback
ParametersRTCStatsElement
MembersRTCIdentityAssertion
MembersMediaStreamEventInit
MembersThis section is non-normative.
There are a number of facets to video-conferencing in HTML covered by this specification:
This document defines the APIs used for these features. This specification is being developed in conjunction with a protocol specification developed by theIETF RTCWEB group and an API specification to get access to local media devices developed by the Media Capture Task Force.
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words must,must not, required,should, should not,recommended, may, andoptional in this specification are to be interpreted as described in [RFC2119].
This specification defines conformance criteria that apply to a single product: theuser agent that implements the interfaces that it contains.
Implementations that use ECMAScript to implement the APIs defined in this specification must implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [WEBIDL], as this specification uses that specification and terminology.
The EventHandler
interface represents a callback used for event handlers as defined in [HTML5].
The concepts queue a task andfires a simple event are defined in [HTML5].
The terms event handlers andevent handler event types are defined in [HTML5].
An
allows two users to communicate directly, browser to browser. Communications are coordinated via a signaling channel which is provided by unspecified means, but generally by a script in the page via the server, e.g. using RTCPeerConnection
XMLHttpRequest
.
dictionary RTCConfiguration {
RTCIceServer
[] iceServers;
};
RTCConfiguration
MembersiceServers
of type array ofRTCIceServer
An array containing STUN and TURN servers available to be used by ICE.
dictionary RTCIceServer {
DOMString url;
nullable DOMString credential;
};
RTCIceServer
Memberscredential
of typenullable DOMString
If the url element of the internal array is a TURN URI, then this is the credential to use with that TURN server.
url
of typeDOMString
A STUN or TURN URI as defined in [STUN-URI] and [TURN-URI].
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 array of RTCIceServer objects is:
[ { url:"stun:stun.example.net"] } , { url:"turn:[email protected]", credential:"myPassword"} ]
The general operation of the RTCPeerConnection is described in [RTCWEB-JSEP].
Calling new
creates anRTCPeerConnection
(configuration )
object.RTCPeerConnection
The configuration has the information to find and access the [STUN] and [TURN] servers. There may be multiple servers of each type and any TURN server also acts as a STUN server.
An
object has an associated ICE agent, [ICE] RTCPeerConnection readiness state, and ICE state. These are initialized when the object is created.RTCPeerConnection
When the RTCPeerConnection()
constructor is invoked, the user agentmust run the following steps. This algorithm has a synchronous section (which is triggered as part of the event loop algorithm).
Create an ICE Agent and let connection'sRTCPeerConnection
ICE Agent be that ICE Agent and provide it the STUN and TURN servers from the configuration array. The ICE Agent will proceed with gathering as soon as the IceTransports constraint is not set to "none". At this point the ICE Agent does not know how many ICE components it needs (and hence the number of candidates to gather), but it can make a reasonable assumption. As the RTCPeerConnection
object gets more information, the ICE Agent can adjust the number of components.
Set connection's RTCPeerConnection
readiness state tonew
.
Set connection's RTCPeerConnection
ice state tonew
.
Let connection's localStreams
attribute be an empty read-onlyMediaStream
array.
Let connection's remoteStreams
attribute be an empty read-onlyMediaStream
array.
Return connection, but continue these steps asynchronously.
Await a stable state. The synchronous section consists of the remaining steps of this algorithm.
During the lifetime of the RTCPeerConnection object, the following procedures are followed:
If iceState is "new" and the IceTransports constraint is not set to "none", itmust queue a task to start gathering ICE addresses and set theiceState to "gathering".
If the ICE Agent has found one or more candidate pairs for each MediaStreamTrack that forms a valid connection, the ICE state is changed to "connected".
When the ICE Agent finishes checking all candidate pairs, if at least one connection has been found for each MediaStreamTrack, the iceState is changed to "completed"; if no connection has been found for any MediaStreamTrack, the iceState is changed to "failed".
ISSUE: Note that this means that if I was able to negotiate audio but not video via ICE, theniceState == "completed". Is this really what is desired?
If the iceState is "connected" or "completed" and both the local and remote session descriptions are set, the RTCPeerConnection state is set to "active".
If the iceState is "failed", a task is queued to call the close method.
ISSUE:: CJ - this seems wrong to me.
User agents negotiate the codec resolution, bitrate, and other media parameters. It isrecommended that user agents initially negotiate for the maximum resolution of a video stream. For streams that are then rendered (using avideo
element), it isrecommended that user agents renegotiate for a resolution that matches the rendered display size.
Starting with the native resolution means that if the Web application notifies its peer of the native resolution as it starts sending data, and the peer prepares itsvideo
element accordingly, there will be no need for a renegotiation once the stream is flowing.
Add the newly created MediaStream
object to the end ofconnection'sremoteStreams
array.
Fire a stream event named addstream
with the newly createdMediaStream
object at the connection object.
When a user agent has negotiated media for a component that belongs to a media stream that is already represented by an existing MediaStream
object, the user agentmust associate the component with thatMediaStream
object.
When an
finds that a stream from the remote peer has been removed , the user agent must follow these steps:RTCPeerConnection
Let connection be the
associated with the stream being removed.RTCPeerConnection
Let stream be the MediaStream
object that represents the media stream being removed, if any. If there isn't one, then abort these steps.
By definition, stream is now finished.
A task is thus queued to update stream and fire an event.
Queue a task to run the following substeps:
If the connection's RTCPeerConnection
readiness state isclosed
(3), abort these steps.
Remove stream from connection's remoteStreams
array.
Fire a stream event named removestream
with stream at the connection object.
The task source for the tasks listed in this section is the networking task source.
If something in the browser changes that causes the
object to need to initiate a new session description negotiation, a RTCPeerConnection
negotiationneeded
event is fired at the
object.RTCPeerConnection
In particular, if an
object is consuming a RTCPeerConnection
MediaStream
and a track is added to one of the stream's MediaStreamTrackList
objects, by, e.g., the add()
method being invoked, the
object must fire the "negotiationneeded" event. Removal of media components must also trigger "negotiationneeded".RTCPeerConnection
To prevent network sniffing from allowing a fourth party to establish a connection to a peer using the information sent out-of-band to the other peer and thus spoofing the client, the configuration informationshould always be transmitted using an encrypted connection.
typedef MediaStream[] MediaStreamArray;
[Constructor (RTCConfiguration configuration, optional MediaConstraints constraints)]
interface RTCPeerConnection : EventTarget {
void createOffer (RTCSessionDescriptionCallback
successCallback, optional RTCPeerConnectionErrorCallback
failureCallback, optional MediaConstraints constraints);
void createAnswer (RTCSessionDescriptionCallback
successCallback, optional RTCPeerConnectionErrorCallback? failureCallback = null, optional MediaConstraints constraints = null);
void setLocalDescription (RTCSessionDescription
description, optional RTCVoidCallback
successCallback, optional RTCPeerConnectionErrorCallback
failureCallback);
readonly attribute RTCSessionDescription
localDescription;
void setRemoteDescription (RTCSessionDescription
description, optional RTCVoidCallback
successCallback, optional RTCPeerConnectionErrorCallback
failureCallback);
readonly attribute RTCSessionDescription
remoteDescription;
readonly attribute RTCPeerState
readyState;
void updateIce (optional RTCConfiguration? configuration = null, optional MediaConstraints? constraints = null);
void addIceCandidate (RTCIceCandidate
candidate);
readonly attribute RTCGatheringState
iceGatheringState;
readonly attribute RTCIceState
iceState;
readonly attribute MediaStreamArray
localStreams;
readonly attribute MediaStreamArray
remoteStreams;
RTCDataChannel
createDataChannel ([TreatNullAs=EmptyString] DOMString label, optional RTCDataChannelInit
dataChannelDict);
attribute EventHandler ondatachannel;
void addStream (MediaStream stream, optional MediaConstraints constraints);
void removeStream (MediaStream stream);
void setIdentityProvider (DOMString provider, optional DOMString protocol, optional DOMString username);
void getIdentityAssertion ();
readonly attribute RTCIdentityAssertion
? peerIdentity;
void getStats (MediaStreamTrack? selector, RTCStatsCallback
successCallback, optional RTCPeerConnectionErrorCallback
failureCallback);
void close ();
attribute EventHandler onnegotationneeded;
attribute EventHandler onicecandidate;
attribute EventHandler onopen;
attribute EventHandler onstatechange;
attribute EventHandler onaddstream;
attribute EventHandler onremovestream;
attribute EventHandler ongatheringchange;
attribute EventHandler onicechange;
attribute EventHandler onidentityresult;
};
iceGatheringState
of typeRTCGatheringState
, readonly
The iceGatheringState
attributemust return the gathering state of theRTCPeerConnection
ICE Agent connection state.
iceState
of typeRTCIceState
, readonly
The iceState
attribute must return the state of theRTCPeerConnection
ICE Agent ICE state.
localDescription
of typeRTCSessionDescription
, readonly
The localDescription
attributemust return the
that was most recently passed toRTCSessionDescription
setLocalDescription()
, plus any local candidates that have been generated by the ICE Agent since then.
A null object will be returned if the local description has not yet been set.
localStreams
of typeMediaStreamArray
, readonly
Returns a live array containing the local streams (those that were added withaddStream()
).
onaddstream
of typeEventHandler
addstream
,must be fired by all objects implementing theRTCPeerConnection
interface. It is called any time aMediaStream
is added by the remote peer. This will be fired only as a result of setRemoteDescription
. Onnaddstream happens as early as possible after thesetRemoteDescription
. This callback does not wait for a given media stream to be accepted or rejected via SDP negotiation. Later, when the SDP accepts something, you get the addTrack
callback. Later if SDP ended a media flow, that would result in thetrackEnded
callback being called.
ondatachannel
of typeEventHandler
datachannel
,must be supported by all objects implementing the RTCPeerConnection
interface.
ongatheringchange
of typeEventHandler
icechange
,must be fired by all objects implementing theRTCPeerConnection
interface. It is called any time theiceGatheringState changes. NOTE: Is this really of type icechange??
onicecandidate
of typeEventHandler
icecandidate
,must be supported by all objects implementing theRTCPeerConnection
interface. It is called any time there is a new ICE candidate added to a previous offer or answer.
onicechange
of typeEventHandler
icechange
,must be fired by all objects implementing theRTCPeerConnection
interface. It is called any time theiceState changes.
onidentityresult
of typeEventHandler
identityresult
,must be fired by all objects implementing theRTCPeerConnection
interface. It is called any time an identity verification succeeds or fails.
onnegotationneeded
of typeEventHandler
negotiationneeded
,must be supported by all objects implementing the RTCPeerConnection
interface.
onopen
of typeEventHandler
open
,must be supported by all objects implementing theRTCPeerConnection
interface.
Open issue if the "onopen" is needed or not.
onremovestream
of typeEventHandler
removestream
,must be fired by all objects implementing the RTCPeerConnection
interface. It is called any time aMediaStream
is removed by the remote peer. This will be fired only as a result of setRemoteDescription
.
onstatechange
of typeEventHandler
statechange
,must be supported by all objects implementing theRTCPeerConnection
interface. It is called any time thereadyState
changes, i.e., from a call tosetLocalDescription
, a call to setRemoteDescription
, or code. It does not fire for the initial state change intonew
.
peerIdentity
of typeRTCIdentityAssertion
, readonly, nullable
Contains the peer identity assertion information if an identity assertion was provided and verified.
readyState
of typeRTCPeerState
, readonly
The readyState
attributemust return the
object'sRTCPeerConnection
RTCPeerConnection
readiness state.
remoteDescription
of typeRTCSessionDescription
, readonly
The remoteDescription
attributemust return the
that was most recently passed toRTCSessionDescription
setRemoteDescription()
, plus any remote candidates that have been supplied via addIceCandidate()
since then.
A null object will be returned if the remote description has not yet been set.
remoteStreams
of typeMediaStreamArray
, readonly
Returns a live array containing the remote streams (those that were added by the remote side).
This array is updated when addstream
and removestream
events are fired.
addIceCandidate
The addIceCandidate()
method provides a remote candidate to the ICE Agent. In addition to being added to the remote description, connectivity checks will be sent to the new candidates as long as the "IceTransports" constraint is not set to "none". This call will result in a change to the state of the ICE Agent, and may result in a change to media state if it results in different connectivity being established.
A TBD exception will be thrown if candidate parameter is malformed.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
candidate |
|
✘ | ✘ |
void
addStream
Adds a new stream to the RTCPeerConnection.
When the addStream()
method is invoked, the user agentmust run the following steps:
If the
object's RTCPeerConnection
RTCPeerConnection
readiness state isclosed
(3), throw an INVALID_STATE_ERR
exception.
If stream is already in the
object'sRTCPeerConnection
localStreams
object, then abort these steps.
Add stream to the end of the
object'sRTCPeerConnection
localStreams
object.
Parse the constraints provided by the application and apply them to the MediaStream, if possible. NOTE - need to deal with throwing an exception here.
Fire a negotiationneeded event.
ISSUE: Should this fire if the RTCPeerConnection is in "new"?
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
stream | MediaStream |
✘ | ✘ | |
constraints | MediaConstraints |
✘ | ✔ |
void
close
When the close()
method is invoked, the user agentmust run the following steps:
If the
object's RTCPeerConnection
RTCPeerConnection
readiness state isclosed
(3), throw an INVALID_STATE_ERR
exception.
Destroy the RTCPeerConnection
ICE Agent, abruptly ending any active ICE processing and any active streaming, and releasing any relevant resources (e.g. TURN permissions).
Set the object's RTCPeerConnection
readiness state toclosed
(3).
void
createAnswer
The createAnswer method generates an [SDP] answer with the supported configuration for the session that is compatible with the parameters in the remote configuration. Like createOffer, the returned blob contains descriptions of the local MediaStreams attached to this RTCPeerConnection, the codec/RTP/RTCP options negotiated for this session, and any candidates that have been gathered by the ICE Agent. The constraints parameter may be supplied to provide additional control over the generated answer.
As an answer, the generated SDP will contain a specific configuration that, along with the corresponding offer, specifies how the media plane should be established. The generation of the SDP must follow the appropriate process for generating an answer.
Session descriptions generated by createAnswer must be immediately usable by setLocalDescription without generating an error if setLocalDescription is called from the successCallback function. Like createOffer, the returned description should reflect the current state of the system. The session descriptionsmust remain usable by setLocalDescription without causing an error until at least the end of the successCallback function. Calling this method is needed to get the ICE user name fragment and password.
An answer can be marked as provisional, as described in [RTCWEB-JSEP], by setting thetype
to "pranswer"
.
If the RTCPeerConnection
is configured to generate Identity assertions, then the session descriptionshall contain an appropriate assertion.
The failureCallback will be called if the system cannot generate an appropriate answer given the offer.
A TBD exception is thrown if the constraints parameter is malformed.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
successCallback |
|
✘ | ✘ | |
null | RTCPeerConnectionErrorCallback? failureCallback = |
✘ | ✔ | |
null | MediaConstraints constraints = |
✘ | ✔ |
void
createDataChannel
Creates a new
object with the given label. TheRTCDataChannel
dictionary can be used to configure properties of the underlying channel such as data reliability. A corresponding RTCDataChannelInit
object is dispatched at the other peer if the channel setup was successful.RTCDataChannel
When the createDataChannel()
method is invoked, the user agentmust run the following steps.
If the
object’s RTCPeerConnection
RTCPeerConnection
readiness state isclosed
(3), throw an INVALID_STATE_ERR
exception.
Let channel be a newly created
object.RTCDataChannel
Initialize channel's label
attribute to the value of the first argument.
Initialize channel's reliable
attribute to true.
If the second argument is present and it contains a reliable
dictionary member, then setchannel'sreliable
attribute to the dictionary member value.
Return channel and continue these steps in the background.
Create channel's associated underlying data transport.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
label | DOMString |
✘ | ✘ | |
dataChannelDict |
|
✘ | ✔ |
RTCDataChannel
createOffer
The createOffer method generates a blob of SDP that contains an RFC 3264 offer with the supported configurations for the session, including descriptions of the localMediaStream
s attached to thisRTCPeerConnection
, the codec/RTP/RTCP options supported by this implementation, and any candidates that have been gathered by the ICE Agent. The constraints parameter may be supplied to provide additional control over the offer generated.
As an offer, the generated SDP will contain the full set of capabilities supported by the session (as opposed to an answer, which will include only a specific negotiated subset to use); for each SDP line, the generation of the SDP must follow the appropriate process for generating an offer. In the event createOffer is called after the session is established, createOffer will generate an offer that is compatible with the current session, incorporating any changes that have been made to the session since the last complete offer-answer exchange, such as addition or removal of streams. If no changes have been made, the offer will include the capabilities of the current local description as well as any additional capabilities that could be negotiated in an updated offer.
Session descriptions generated by createOffer must be immediately usable by setLocalDescription without causing an error as long as setLocalDiscription is called within the successCallback function. If a system has limited resources (e.g. a finite number of decoders), createOffer needs to return an offer that reflects the current state of the system, so that setLocalDescription will succeed when it attempts to acquire those resources. The session descriptionsmust remain usable by setLocalDescription without causing an error until at least end of the successCallback function. Calling this method is needed to get the ICE user name fragment and password.
If the RTCPeerConnection
is configured to generate Identity assertions, then the session descriptionshall contain an appropriate assertion.
The failureCallback will be called if the system cannot generate an appropriate offer given the state of the RTCPeerConnection.
A TBD exception is thrown if the constraints parameter is malformed.
To Do: Discuss privacy aspects of this from a fingerprinting point of view - it's probably around as bad as access to a canvas :-)
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
successCallback |
|
✘ | ✘ | |
failureCallback |
|
✘ | ✔ | |
constraints | MediaConstraints |
✘ | ✔ |
void
getIdentityAssertion
Initiates the process of obtaining an identity assertion. Applications need not make this call. It is merely intended to allow them to start the process of obtaining identity assertions before a call is initiated. If an identity is needed, either because the browser has been configured with a default identity provider or because thesetIdentityProvider()
method was called, then an identity will be automatically requested when an offer or answer is created.
Queue a task to run the following substeps.
If the connection's RTCPeerConnection
readiness state isCLOSED
(3), abort these steps.
Instantiate a new IdP proxy and request an identity assertion.
void
getStats
When the getStats()
method is invoked, the user agentmust queue a task to run the following substeps:
If the
object's RTCPeerConnection
RTCPeerConnection
readiness state isclosed
(3), throw an INVALID_STATE_ERR
exception.
Gather the stats indicated by the selector. If the selector is invalid, call the failureCallback.
Call the successCallback, supplying the relevant statistics object.
The "selector" may be a MediaStreamTrack
that is a member of aMediaStream
on the incoming or outgoing streams. The callback reports on all relevant statistics for that selector. If the selector is blank or missing, stats for the whole RTCPeerConnection
are reported. TODO: Evaluate the need for other selectors than MediaStreamTrack.
The returned structure contains a list of RTCStatsElement
s, each reporting stats for one object that the implementation thinks is relevant for the selector. One achieves the total for the selector by summing over all the elements; for instance, if aMediaStreamTrack
is carried by multiple SSRCs over the network, the getStats()
function may return one RTCStatsElement
per SSRC (which can be distinguished by the value of the “ssrc” stats attribute).
An RTCPeerConnection
must return consistent stats for each element in the array, adding new elements to the end as needed; this is needed so that an application can simply correlate a value read at one moment to a value read at a later moment.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
selector | MediaStreamTrack |
✔ | ✘ | |
successCallback |
|
✘ | ✘ | |
failureCallback |
|
✘ | ✔ |
void
removeStream
Removes the given stream from the localStream array in the RTCPeerConnection and fires thenegotiationneeded event.
When the other peer stops sending a stream in this manner, a removestream
event is fired at the
object.RTCPeerConnection
When the removeStream()
method is invoked, the user agent must run the following steps:
If the
object's RTCPeerConnection
RTCPeerConnection
readiness state isclosed
(3), throw an INVALID_STATE_ERR
exception.
If stream is not in the
object'sRTCPeerConnection
localStreams
object, then abort these steps. TODO: Do we need an exception here?
Remove stream from the
object'sRTCPeerConnection
localStreams
object.
Fire a negotiationneeded event.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
stream | MediaStream |
✘ | ✘ |
void
setIdentityProvider
Sets the identity provider to be used for a given PeerConnection
object. Applications need not make this call; if the browser is already configured for an IdP, then that configured IdP will be used to get an assertion.
When the setIdentityProvider()
method is invoked, the user agentmust run the following steps:
Set the current identity values to the triplet (provider
,protocol
, username
).
If the
object's RTCPeerConnection
RTCPeerConnection
readiness state isactive
, and any of the identity settings have changed, queue a task to run the following substeps:
If the connection's RTCPeerConnection
readiness state isCLOSED
(3), abort these steps.
Instantiate a new IdP proxy and request an identity assertion.
If/when the assertion is obtained, fire a negotiationneeded event.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
provider | DOMString |
✘ | ✘ | |
protocol | DOMString |
✘ | ✔ | |
username | DOMString |
✘ | ✔ |
void
setLocalDescription
The setLocalDescription()
method instructs the
to apply the suppliedRTCPeerConnection
as the local description.RTCSessionDescription
This API changes the local media state. In order to successfully handle scenarios where the application wants to offer to change from one media format to a different, incompatible format, the
must be able to simultaneously support use of both the old and new local descriptions (e.g. support codecs that exist in both descriptions) until a final answer is received, at which point the RTCPeerConnection
can fully adopt the new local description, or roll back to the old description if the remote side denied the change.RTCPeerConnection
ISSUE: how to indicate to roll back?
To Do: specify what parts of the SDP can be changed between the createOffer and setLocalDescription
Changes to the state of media transmission will occur when a final answer is successfully applied. localDescription
must return the previous description until the new description is successfully applied.
The failureCallback
will be called if the
is a valid description but cannot be applied at the media layer, e.g., if there are insufficient resources to apply the SDP. The user agentmust roll back as necessary if the new description was partially applied when the failure occurred.RTCSessionDescription
A TBD exception is thrown if the SDP content is invalid.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
description |
|
✘ | ✘ | |
successCallback |
|
✘ | ✔ | |
failureCallback |
|
✘ | ✔ |
void
setRemoteDescription
The setRemoteDescription()
method instructs the
to apply the suppliedRTCPeerConnection
as the remote offer or answer. This API changes the local media state.RTCSessionDescription
If a=identity
attributes are present, the browser verifies the identity following the procedures in [XREF sec.identity-proxy-assertion-request].
Changes to the state of media transmission will occur when a final answer is successfully applied. remoteDescription
must return the previous description until the new description is successfully applied.
The failureCallback
will be called if the
is a valid description but cannot be applied at the media layer, e.g., if there are insufficient resources to apply the SDP. The user agentmust roll back as necessary if the new description was partially applied when the failure occurred.RTCSessionDescription
A TBD exception is thrown if the SDP content is invalid.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
description |
|
✘ | ✘ | |
successCallback |
|
✘ | ✔ | |
failureCallback |
|
✘ | ✔ |
void
updateIce
The updateIce method updates the ICE Agent process of gathering local candidates and pinging remote candidates. If there is a mandatory constraint called "IceTransports" it will control how the ICE engine can act. This can be used to limit the use to TURN candidates by a callee to avoid leaking location information prior to the call being accepted.
This call may result in a change to the state of the ICE Agent, and may result in a change to media state if it results in connectivity being established.
A TBD exception will be thrown if the constraints parameter is malformed.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
null | RTCConfiguration? configuration = |
✘ | ✔ | |
null | MediaConstraints? constraints = |
✘ | ✔ |
void
A Window
objecthas a strong reference to any
objects created from the constructor whose global object is thatRTCPeerConnection
Window
object.
enum RTCPeerState {
"new",
"have-local-offer",
"have-local-pranswer",
"have-remote-pranswer",
"active (also could be called "open", "stable")",
"closed"
};
Enumeration description | |
---|---|
new |
The object was just created, and no networking has yet occurred. |
have-local-offer |
A local description, of type "offer", has been supplied. |
have-local-pranswer |
A remote description of type "offer" has been supplied and a local description of type "pranswer" has been supplied. |
have-remote-pranswer |
A local description of type "offer" has been supplied and a remote description of type "pranswer" has been supplied. |
active (also could be called "open", "stable") |
Both local and remote descriptions have been supplied, and the offer-answer exchange is complete. |
closed |
The connection is closed. |
The non-normative peer state transitions are:
An example set of transitions might be:
Caller transition:
Callee transition:
enum RTCGatheringState {
"new",
"gathering",
"complete"
};
Enumeration description | |
---|---|
new |
The object was just created, and no networking has occurred yet. |
gathering |
The ICE engine is in the process of gathering candidates for this RTCPeerConnection. |
complete |
The ICE engine has completed gathering. Events such as adding a new interface or new TURN server could cause the state to go back to gathering. |
There is active discussion around changing these states.
enum RTCIceState {
"starting",
"checking",
"connected",
"completed",
"failed",
"disconnected",
"closed"
};
Enumeration description | |
---|---|
starting |
The ICE Agent is gathering addresses and/or waiting for remote candidates to be supplied. |
checking |
The ICE Agent has received remote candidates on at least one component, and is checking candidate pairs but has not yet found a connection. In addition to checking, it may also still be gathering. |
connected |
The ICE Agent has found a usable connection for all components but is still checking other candidate pairs to see if there is a better connection. It may also still be gathering. |
completed |
The ICE Agent has finished gathering and checking and found a connection for all components. |
failed |
The ICE Agent is finished checking all candidate pairs and failed to find a connection for at least one component. |
disconnected |
Liveness checks have failed for one or more components. This is more aggressive thanfailed , and may trigger intermittently (and resolve itself without action) on a flaky network. |
closed |
The ICE Agent has shut down and is no longer responding to STUN requests. |
States take either the value of any component or all components, as outlined below:
checking
occurs if ANY component has received a candidate and can start checkingconnected
occurs if ALL components have established a working connectioncompleted
occurs if ALL components have finalized the running of their ICE processesfailed
occurs if ANY component has given up trying to connectdisconnected
occurs if ANY component has failed liveness checksclosed
occurs only if PeerConnection.close()
has been called.If a component is discarded as a result of signaling (e.g. RTCP mux or BUNDLE), the state may advance directly fromchecking
tocompleted
.
An example transition might look like:
The non-normative ICE state transitions are:
callback RTCVoidCallback = void ();
callback RTCPeerConnectionErrorCallback = void (DOMString errorInformation);
RTCPeerConnectionErrorCallback
ParameterserrorInformation
of typeDOMString
ISSUE: Should this be an enum?
The RTCSdpType enum describes the type of an
instance.RTCSessionDescription
enum RTCSdpType {
"offer",
"pranswer",
"answer"
};
Enumeration description | |
---|---|
offer |
An RTCSdpType of "offer" indicates that a description should be treated as an [SDP] offer. |
pranswer |
An RTCSdpType of "pranswer" indicates that a description should be treated as an [SDP] answer, but not a final answer. A description used as an SDP "pranswer" may be applied as a response to a SDP offer, or an update to a previously sent SDP "pranswer". |
answer |
An RTCSdpType of "answer" indicates that a description should be treated as an [SDP] final answer, and the offer-answer exchange should be considered complete. A description used as an SDP answer may be applied as a response to an SDP offer or as an update to a previously sent SDP "pranswer". |
The RTCSessionDescription()
constructor takes an optional dictionary argument, descriptionInitDict, whose content is used to initialize the new
object. If a dictionary key is not present in descriptionInitDict, the corresponding attribute will be initialized to null. If the constructor is run without the dictionary argument, all attributes will be initialized to null. This class is a future extensible carrier for the data contained in it and does not perform any substantive processing.RTCSessionDescription
Objects implementing the
interfacemust serialize with the serialization pattern "RTCSessionDescription
{ attribute }
".
[Constructor (optional RTCSessionDescriptionInit descriptionInitDict)]
interface RTCSessionDescription {
attribute RTCSdpType
? type;
attribute DOMString? sdp;
};
dictionary RTCSessionDescriptionInit {
RTCSdpType
type;
DOMString sdp;
};
sdp
of typeDOMString, nullable
type
of typeRTCSdpType
, nullable
RTCSessionDescriptionInit
Memberssdp
of typeDOMString
type
of typeRTCSdpType
callback RTCSessionDescriptionCallback = void (RTCSessionDescription
sdp);
RTCSessionDescriptionCallback
Parameterssdp
of typeRTCSessionDescription
The RTCIceCandidate()
constructor takes an optional dictionary argument, candidateInitDict, whose content is used to initialize the new
object. If a dictionary key is not present incandidateInitDict, the corresponding attribute will be initialized to null. If the constructor is run without the dictionary argument, all attributes will be initialized to null. This class is a future extensible carrier for the data contained in it and does not perform any substantive processing.RTCIceCandidate
Objects implementing the
interfacemust serialize with the serialization pattern "RTCIceCandidate
{ attribute }
".
[Constructor (optional RTCIceCandidateInit candidateInitDict)]
interface RTCIceCandidate {
attribute DOMString? candidate;
attribute DOMString? sdpMid;
attribute unsigned short? sdpMLineIndex;
};
dictionary RTCIceCandidateInit {
DOMString candidate;
DOMString sdpMid;
unsigned short sdpMLineIndex;
};
candidate
of typeDOMString, nullable
sdpMLineIndex
of typeunsigned short, nullable
sdpMid
of typeDOMString, nullable
RTCIceCandidateInit
Memberscandidate
of typeDOMString
sdpMLineIndex
of typeunsigned short
sdpMid
of typeDOMString
The icecandidate
event of the RTCPeerConnection uses the
interface.RTCPeerConnectionIceEvent
Firing an
event named e with an RTCPeerConnectionIceEvent
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 RTCIceCandidate
RTCPeerConnectionIceEvent
interface with the candidate
attribute set to the new ICE candidate,must be created and dispatched at the given target.
[Constructor(DOMString type, RTCPeerConnectionIceEventInit eventInitDict)]
interface RTCPeerConnectionIceEvent : Event {
readonly attribute RTCIceCandidate
candidate;
};
dictionary RTCPeerConnectionIceEventInit : EventInit {
RTCIceCandidate
candidate;
};
candidate
of typeRTCIceCandidate
, readonly
The candidate
attribute is the
object with the new ICE candidate that caused the event.RTCIceCandidate
RTCPeerConnectionIceEventInit
Memberscandidate
of typeRTCIceCandidate
The Peer-to-peer Data API lets a web application send and receive generic application data peer-to-peer.
The
interface represents a bi-directional data channel between two peers. A RTCDataChannel
is created via a factory method on an RTCDataChannel
object. The corresponding RTCPeerConnection
object is then dispatched at the other peer if the channel setup was successful.RTCDataChannel
Each
has an associated underlying data transport that is used to transport actual data to the other peer. The transport properties of theunderlying data transport, such as reliability mode, are configured by the peer taking the initiative to create the channel. The other peer cannot change any transport properties of an offered data channel. The actual wire protocol between the peers is out of the scope for this specification.RTCDataChannel
A
created withRTCDataChannel
createDataChannel()
must initially be in theconnecting
state. If the
object’sunderlying data transport is successfully set up, the user agentmustannounce theRTCDataChannel
RTCDataChannel
as open.
When the user agent is to announce aRTCDataChannel
as open, the user agentmust queue a task to run the following steps:
If the associated
object's RTCPeerConnection
RTCPeerConnection
readiness state isclosed
(3), abort these steps.
Let channel be the
object to be announced.RTCDataChannel
Set channel's readyState
attribute to open
.
Fire a simple event namedopen
atchannel.
When an underlying data transport has been established, the user agent of the peer that did not initiate the creation processmust queue a task to run the following steps:
If the associated
object's RTCPeerConnection
RTCPeerConnection
readiness state isclosed
(3), abort these steps.
Let configuration be an information bundle with key-value pairs, received from the other peer as a part of the process to establish theunderlying data channel.
Let channel be a newly created
object.RTCDataChannel
Initialize channel's label
attribute to value that corresponds to the "label
" key in configuration.
Initialize channel's reliable
attribute to true.
If configuration contains a key named "reliable
", setchannel'sreliable
attribute to the corresponding value.
The basic statistics model is that the browser maintains a set of statistics indexed byselector
. The "selector" may be a MediaStreamTrack
that is a member of a MediaStream
on the incoming or outgoing streams. The calling Web application provides the selector to thegetStats()
method and the browser returns (in the JavaScript) a set of statistics that it believes is relevant to the selector.
The statistics returned are designed in such a way that repeated queries yield the same statistics in the same place in the structure. Thus, a Web application can make measurements over a given time period by requesting measurements at the beginning and end of that period.
callback RTCStatsCallback = void (RTCStatsElement
[] statsElements, MediaStreamTrack? selector);
RTCStatsCallback
ParametersstatsElements
of type array ofRTCStatsElement
The objects containing the stats result.
selector
of typeMediaStreamTrack, nullable
The selector object that the statistics were gathered for. Currently onlyMediaStreamTrack
is supported as a selector object.
Each RTCStatsElement
object consists of two RTCStatsReport
objects, one corresponding to local statistics and one to remote statistics.
dictionary RTCStatsElement {
RTCStatsReport
local;
RTCStatsReport
remote;
};
RTCStatsElement
Memberslocal
of typeRTCStatsReport
The statistics corresponding to local properties.
remote
of typeRTCStatsReport
The statistics corresponding to remote properties.
Each RTCStatsReport
has a timestamp. Individual statistics are accessed by passing string names to thegetValue()
method. Note that while stats names are standardized [[OPEN ISSUE: Need to define an IANA registry for this and populate with pointers to existing things such as the RTCP statistics. ]], any given implementation may be using experimental values or values not yet known to the Web application. Thus, applicationsmust 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 implementationsmust return synchronized values for all stats in a RTCStatsReport
.
interface RTCStatsReport {
readonly attribute long timestamp;
any getValue (DOMString statName);
};
timestamp
of typelong, readonly
The timestamp in milliseconds since the UNIX epoch (Jan 1, 1970, UTC).
getValue
The getValue()
method returns the value for the statistic that corresponds to statName.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
statName | DOMString |
✘ | ✘ |
any
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 sound track is audio track 0 of remote stream 0 of pc1. The following example code might be used:
var baseline, now;
var selector = pc.remoteStreams[0].audioTracks[0];
pc.getStats(selector, function (stats) {
baseline = stats;
});
// ... wait a bit
setTimeout(function () {
pc.getStats(selector, function (stats) {
now = stats;
processStats();
});
}, aBit);
function processStats() {
// Real code would:
// - Check that timestamp of “local stats” and “remote stats”
// are reasonably consistent.
// - Sum up over all the elements rather than just accessing
// element zero.
var packetsSent = now[0].remote.getValue("packetsSent") -
baseline[0].remote.getValue("packetsSent");
var packetsReceived = now[0].local.getValue("packetsReceived") -
baseline[0].local.getValue("packetsReceived");
// if fractionLost is > 0.3, we have probably found the culprit
var fractionLost = (packetsSent - packetsReceived) / packetsSent;
}
WebRTC offers and answers (and hence the channels established by RTCPeerConnection
objects) can be authenticated by using web-based Identity Providers. The idea is that the entity sending the offer/answer acts as the Authenticating Party (AP) and obtains an identity assertion from the IdP which it attaches to the offer/answer. The consumer of the offer/answer (i.e., the RTCPeerConnection
on which setRemoteDescription()
is called acts as the Relying Party (RP) and verifies the assertion.
The interaction with the IdP is designed to decouple the browser from any particular identity provider; the browser need only know how to load the IdP's JavaScript -- 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 browser was written. The generic protocol details are described in [RTCWEB-SECURITY-ARCH]. This document specifies the procedures required to instantiate the IdP proxy, request identity assertions, and consume the results.
In order to communicate with the IdP, the browser must instantiate an isolated interpreted context [TODO: What's the technical term?], such as an invisible IFRAME. The initial contents of the context are loaded from a URI derived from the IdP's domain name. [RTCWEB-SECURITY-ARCH; Section XXX].
For purposes of generating assertions, the IdP shall be chosen as follows:
setIdentityProvider()
method has been called, the IdP provided shall be used.setIdentityProvider()
method has not been called, then the browser shall use an IdP configured into the browser. If more than one such IdP is configured, the browser should provide the user with a chooser interface.In order to verify assertions, the IdP domain name and protocol shall be equal to the "domain" and "protocol" fields of the identity assertion.
The context must have aMessageChannel
named window.TBD
which is "entangled" to the RTCPeerConnection
and is unique to that subcontext. This channel is used for messaging between the RTCPeerConnection
and the IdP. All messages sent via this channel are strings, specifically the JSONified versions of JavaScript structs.
All messages sent from the RTCPeerConnection
to the IdP contextmust have anorigin
of rtcweb://peerconnection/
. The fact that ordinary Web pages cannot set their origin values arbitrarily is an essential security feature, as it stops attackers from requesting WebRTC-compatible identity assertions from IdPs. For this reason, the origin must be included in the identity assertion and verified by the consuming RTCPeerConnection
.
The identity assertion request process involves the following steps.
RTCPeerConnection
instantiates an IdP context as described in the previous section.RTCPeerConnection
desires to be bound to the user's identity.RTCPeerConnection
over the message channel.RTCPeerConnection
stores the assertion for use with future offers or answers. If the identity request was triggered by acreateOffer()
or createAnswer()
, then the assertion is inserted in the offer/answer.The identity assertion request process involves the following steps.
RTCPeerConnection
instantiates an IdP context as described in the previous section.PostMessage
calls.RTCPeerConnection
over the message channel.RTCPeerConnection
displays the assertion information in the browser UI and stores the assertion in the peerIdentity
attribute for availability to the JavaScript application. The assertion information to be displayed shall contain the domain name of the IdP and the identity returned by the IdP and must be displayed via some mechanism which cannot be spoofed by content. [[OPEN ISSUE: The identity information should also be available in the inspector interface defined in [RTCWEB-SECURITY-ARCH; Section 5.5].dictionary RTCIdentityAssertion {
DOMString idp;
DOMString name;
};
RTCIdentityAssertion
Membersidp
of typeDOMString
A domain name representing the identity provider.
name
of typeDOMString
An RFC822-conformant [TODO: REF] representation of the verified peer identity. This identity will have been verified via the procedures described in [RTCWEB-SECURITY-ARCH].
The identity system is designed so that applications need not take any special action in order for users to generate and verify identity assertions; if a user has configured an IdP into their browser, then the browser will automatically request/generate assertions and the other side will automatically verify them and display the results. However, applications may wish to exercise tighter control over the identity system as shown by the following examples.
This example shows how to configure the identity provider and protocol.
pc.setIdentityProvider("example.com", "default", "[email protected]");
This example shows how to consume identity assertions inside a Web application.
pc.onidentityresult = function(result) {
console.log("IdP= " + pc.peerIdentity.idp +
" identity=" + pc.peerIdentity.name);
};
The MediaStream
interface, as defined in the [GETUSERMEDIA] specification, typically represents a stream of data of audio and/or video. A MediaStream
may be extended to represent a stream that either comes from or is sent to a remote node (and not just the local camera, for instance). The extensions required to enable this capability on the MediaStream
object will be described in this document.
A MediaStream
as defined in [GETUSERMEDIA] may contain zero or moreMediaStreamTrack
objects. A MediaStreamTrack
sent to another peer will appear as one and only oneMediaStreamTrack
to the recipient. A peer is defined as a user agent that supports this specification.
Channels are the smallest unit considered in the MediaStream
specification. Channels are intended to be encoded together for transmission as, for instance, an RTP payload type. All of the channels that a codec needs to encode jointlymust be in the sameMediaStreamTrack
and the codecsshould be able to encode, or discard, all the channels in the track.
The concepts of an input and output to a given MediaStream
apply in the case ofMediaStream
objects transmitted over the network as well. A MediaStream
created by an
object (described later in this document) will take as input the data received from a remote peer. Similarly, a RTCPeerConnection
MediaStream
from a local source, for instance a camera via [GETUSERMEDIA], will have an output that represents what is transmitted to a remote peer if the object is used with an
object.RTCPeerConnection
The concept of duplicating MediaStream
objects as described in [GETUSERMEDIA] is also applicable here. This feature can be used, for instance, in a video-conferencing scenario to display the local video from the user’s camera and microphone in a local monitor, while only transmitting the audio to the remote peer (e.g. in response to the user using a "video mute" feature). Combining tracks from different MediaStream
objects into a new MediaStream
is useful in certain situations.
In this document, we only specify aspects of the following objects that are relevant when used along with an
. Please refer to the original definitions of the objects in the [GETUSERMEDIA] document for general information on usingRTCPeerConnection
MediaStream
and MediaStreamTrack
.
The label
attribute specified in MediaStream
returns a label that is unique to this stream, so that streams can be recognized after they are sent through the RTCPeerConnection
API.
When a MediaStream
is created to represent a stream obtained from a remote peer, the label
attribute is initialized from information provided by the remote source.
The label of a MediaStream
object is unique to the source of the stream, but that does not mean it is not possible to end up with duplicates. For example, a locally generated stream could be sent from one user agent to a remote peer using
and then sent back to the original user agent in the same manner, in which case the original user agent will have multiple streams with the same label (the locally-generated one and the one received from the remote peer).RTCPeerConnection
A new media track may be associated with an existing MediaStream
. For example, if a remote peer adds a newMediaStreamTrack
object to one of the track lists of aMediaStream
that is being sent over an
, this is observed on the local user agent. If this happens for the reason exemplified, or for any other reason than theRTCPeerConnection
add()
[GETUSERMEDIA] method being invoked locally on aMediaStreamTrackList
or tracks being added as the stream is created (i.e. the stream is initialized with tracks), the user agentmust run the following steps:
Create a MediaStreamTrack
object track to represent the new media component.
If track's kind
attribute equals "audio
", add it to the MediaStream
object’saudioTracks
MediaStreamTrackList
object.
If track's kind
attribute equals "video
", add it to the MediaStream
object’svideoTracks
MediaStreamTrackList
object.
Fire a track event named addtrack
with the newly createdtrack at the MediaStreamTrackList
object.
An existing media track may also be disassociated from a MediaStream
. If this happens for any other reason than theremove()
[GETUSERMEDIA] method being invoked locally on aMediaStreamTrackList
or the stream being destroyed, the user agentmust run the following steps:
Let track be the MediaStreamTrack
object representing the media component about to be removed.
Remove track from the MediaStreamTrackList
object.
Fire a track event named removetrack
withtrack at the MediaStreamTrackList
object.
The event source for the onended
event in the networked case is the
object.RTCPeerConnection
A MediaStreamTrack
object’s reference to its MediaStream
in the non-local media source case (an RTP source, as is the case for aMediaStream
received over an
) is always strong.RTCPeerConnection
When a track belongs to a MediaStream
that comes from a remote peer and the remote peer has permanently stopped sending data theended
event must be fired on the track, as specified in [GETUSERMEDIA].
ISSUE: How do you know when it has stopped? This seems like an SDP question, not a media-level question.
A track in a MediaStream
, received with an
,must have its RTCPeerConnection
readyState
attribute [GETUSERMEDIA] set tomuted
(1) until media data arrives.
In addition, a MediaStreamTrack
has its readyState
set tomuted
on the remote peer if the local user agent disables the corresponding MediaStreamTrack
in the MediaStream
that is being sent. When the addstream event triggers on an
, all RTCPeerConnection
MediaStreamTrack
objects in the resulting MediaStream
are muted until media data can be read from the RTP source.
ISSUE: How do you know when it has been disabled? This seems like an SDP question, not a media-level question.
The DTMF API is undergoing significant list discussion and will probably change.
The
is a specialization of a normalAudioMediaStreamTrack
MediaStreamTrack
that only carries audio and is extended to have the capability to send and/or receive DTMF codes.
interface AudioMediaStreamTrack : MediaStreamTrack {
readonly attribute boolean canInsertDTMF;
void insertDTMF (DOMString tones, optional long duration);
};
canInsertDTMF
of typeboolean, readonly
The canInsertDTMF
attributemust indicate if the
is capable of sending DTMF.AudioMediaStreamTrack
insertDTMF
When an
object’s AudioMediaStreamTrack
insertDTMF()
method is invoked, the user agentmust queue a task that sends the DTMF tones.
The tone parameters 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.
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 or less than 70. The default duration is 100 ms for each tone. The gap between tones must be at least 50 ms but should be as short as possible.
ISSUE: How are invalid values handled?
If insertDTMF is called on the same object while an existing task for this object to generate DTMF is still running, the previous task is canceled. Calling insertDTMF with an empty tones parameter can be used to cancel any tones currently being sent.
Editor Note: We need to add a callback to insertDTMF that is called after the tones are sent. This is needed to allow the application to know when it can send new tones without canceling the tones that are currently being sent.
Editor Note: It seems we would want a callback or event for incoming tones. The proposal sent to the list had them played as audio to the speaker but I don’t see how that is useful.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
tones | DOMString |
✘ | ✘ | |
duration | long |
✘ | ✔ |
void
The addstream
andremovestream
events use the
interface.MediaStreamEvent
Firing a stream event namede with a MediaStream
stream means that an event with the namee, which does not bubble (except where otherwise stated) and is not cancelable (except where otherwise stated), and which uses the
interface with the MediaStreamEvent
stream
attribute set tostream,must be created and dispatched at the given target.
[Constructor(DOMString type, MediaStreamEventInit eventInitDict)]
interface MediaStreamEvent : Event {
readonly attribute MediaStream? stream;
};
dictionary MediaStreamEventInit : EventInit {
MediaStream stream;
};
stream
of typeMediaStream, readonly, nullable
The stream
attribute represents theMediaStream
object associated with the event.
MediaStreamEventInit
Membersstream
of typeMediaStream
This section is non-normative.
This section is non-normative.
When two peers decide they are going to set up a connection to each other, they both go through these steps. The STUN/TURN server configuration describes a server they can use to get things like their public IP address or to set up NAT traversal. They also have to send data for the signaling channel to each other using the same out-of-band mechanism they used to establish that they were going to communicate in the first place.
var signalingChannel = createSignalingChannel();
var pc;
var configuration = ...;
// run start(true) to initiate a call
function start(isCaller) {
pc = new RTCPeerConnection(configuration);
// send any ice candidates to the other peer
pc.onicecandidate = function (evt) {
signalingChannel.send(JSON.stringify({
"candidate": evt.candidate }));
};
// once remote stream arrives, show it in the remote video element
pc.onaddstream = function (evt) {
remoteView.src = URL.createObjectURL(evt.stream);
};
// get the local stream, show it in the local video element and send it
navigator.getUserMedia({
"audio": true, "video": true }, function (stream) {
selfView.src = URL.createObjectURL(stream);
pc.addStream(stream);
if (isCaller)
pc.createOffer(gotDescription);
else
pc.createAnswer(gotDescription);
function gotDescription(desc) {
pc.setLocalDescription(desc);
signalingChannel.send(JSON.stringify({
"sdp": desc }));
}
});
}
signalingChannel.onmessage = function (evt) {
if (!pc)
start(false);
var signal = JSON.parse(evt.data);
if (signal.sdp)
pc.setRemoteDescription(new RTCSessionDescription(signal.sdp));
else
pc.addIceCandidate(new RTCIceCandidate(signal.candidate));
};
This example shows the more complete functionality.
TODO
This example shows how to create a
object and perform the offer/answer exchange required to connect the channel to the other peer. The RTCDataChannel
is used in the context of a simple chat application and listeners are attached to monitor when the channel is ready, messages are received and when the channel is closed.RTCDataChannel
This example uses the negotiationneeded
event to initiate the offer/answer dialog. The exact behavior surrounding thenegotiationneeded
event is not specified in detail at the moment. This example can hopefully help to drive that discussion. An assumption made in this example is that the event only triggeres when a new negotiation should be started. This means that an action (such as addStream()) that normally would have fired the negotiationneeded
event will not do so during an ongoing offer/answer dialog.
var signalingChannel = createSignalingChannel();
var pc;
var configuration = "...";
var channel;
// call start(true) to initiate
function start(isInitiator) {
pc = new PeerConnection(configuration);
// send any ice candidates to the other peer
pc.onicecandidate = function (evt) {
signalingChannel.send(JSON.stringify({
"candidate": evt.candidate }));
};
// let the "negotiationneeded" event trigger negotiation
pc.onnegotiationneeded = function () {
pc.createOffer(localDescCreated);
}
if (isInitiator) {
// create data channel and setup chat
channel = pc.createDataChannel("chat");
setupChat();
} else {
// setup chat on incoming data channel
pc.ondatachannel = function (evt) {
channel = evt.channel;
setupChat();
};
}
}
function localDescCreated(desc) {
pc.setLocalDescription(desc, function () {
signalingChannel.send(JSON.stringify({
"sdp": pc.localDescription }));
});
}
signalingChannel.onmessage = function (evt) {
if (!pc)
start(false);
var message = JSON.parse(evt.data);
if (message.sdp)
pc.setRemoteDescription(new SessionDescription(message.sdp), function () {
if (pc.remoteDescription.type == "offer")
createAnswer(localDescCreated);
});
else
pc.addIceCandidate(new IceCandidate(message.candidate));
};
function setupChat() {
channel.onopen = function () {
// e.g. enable send button
enableChat(channel);
};
channel.onmessage = function (evt) {
showChatMessage(evt.data);
};
}
function sendChatMessage(msg) {
channel.send(msg);
}
This section is non-normative.
The following events fire on
objects:RTCDataChannel
Event name | Interface | Fired when... |
---|---|---|
open |
Event |
The object'sunderlying 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 object'sunderlying data transport has bee closed. |
The following events fire on
objects:RTCPeerConnection