- From: Anant Narayanan via cvs-syncmail <cvsmail@w3.org>
- Date: Thu, 15 Nov 2012 19:30:33 +0000
- To: public-dap-commits@w3.org
Update of /sources/public/2011/webrtc/editor
In directory hutz:/tmp/cvs-serv25740
Modified Files:
getusermedia.html webrtc.html
Log Message:
Publish new ED for 2012-11-15
Index: webrtc.html
===================================================================
RCS file: /sources/public/2011/webrtc/editor/webrtc.html,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- webrtc.html 19 Oct 2012 21:19:37 -0000 1.28
+++ webrtc.html 15 Nov 2012 19:30:31 -0000 1.29
@@ -6,7 +6,8 @@
"HTML Tidy for HTML5 (experimental) for Mac OS X https://github.com/w3c/tidy-html5/tree/c63cc39">
<title>WebRTC 1.0: Real-time Communication Between Browsers</title>
- <meta content="text/html; charset=utf-8" http-equiv="Content-Type"><!--
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
+ <!--
After making changes to this document in the github repo, run:
./publish.sh webrtc.html
to publish a new editor's draft to the W3C CVS. This assumes your
@@ -49,8 +50,7 @@
<li>Privacy issues that arise when exposing local capabilities and local
streams.</li>
- <li>Technical discussions within the group, on the data channel in
- particular.</li>
+ <li>Technical discussions within the group.</li>
<li>Experience gained through early experimentations.</li>
@@ -65,10 +65,6 @@
this specification:</p>
<ul>
- <li>Representing a multimedia stream (video, audio, or both) from local
- devices (video cameras, microphones, Web cams) or from prerecorded files
- provided by the user.</li>
-
<li>Connecting to remote peers using NAT-traversal technologies such as
ICE, STUN, and TURN.</li>
@@ -159,7 +155,7 @@
[[!TURN-URI]].</p>
</dd>
- <dt>nullable DOMString credential</dt>
+ <dt>DOMString? credential</dt>
<dd>
<p>If the url element of the internal array is a TURN URI, then
@@ -233,6 +229,11 @@
</li>
<li>
+ <p>Initialize an internal variable to represent a queue of
+ <code>operations</code> with an empty set.</p>
+ </li>
+
+ <li>
<p>Let <var>connection</var>'s <code title=
"dom-RTCPeerConnection-localStreams"><a href=
"#widl-RTCPeerConnection-localStreams">localStreams</a></code>
@@ -259,8 +260,42 @@
</li>
</ol>
- <p>During the lifetime of the RTCPeerConnection object, the following
- procedures are followed:</p>
+ <p>Once the RTCPeerConnection object has been initialized, for every
+ call to <code>createOffer</code>, <code>setLocalDescription</code>,
+ <code>createAnswer</code> and <code>setRemoteDescription</code>;
+ execute the following steps:</p>
+
+ <ol>
+ <li>
+ <p>Append an object representing the current call being handled
+ (i.e. function name and corresponding arguments) to the
+ <code>operations</code> array.</p>
+ </li>
+
+ <li>
+ <p>If the length of the <code>operations</code> array is exactly 1,
+ execute the function from the front of the queue asynchronously.</p>
+ </li>
+
+ <li>
+ <p>When the ascynchronous operation completes (either successfully
+ or with an error), remove the corresponding object from the
+ <code>operations</code> array. After removal, if the array is
+ non-empty, execute the first object queued asynchronously and
+ repeat this step on completion.</p>
+ </li>
+ </ol>
+
+ <p>The general idea is to have only one among <code>createOffer</code>,
+ <code>setLocalDescription</code>, <code>createAnswer</code> and
+ <code>setRemoteDescription</code> executing at any given time. If
+ subsequent calls are made while one of them is still executing, they
+ are added to a queue and processed when the previous operation is fully
+ completed. It is valid, and expected, for normal error handling
+ procedures to be applied.</p>
+
+ <p>Additionally, during the lifetime of the RTCPeerConnection object,
+ the following procedures are followed when an ICE event occurs:</p>
<ol>
<li>
@@ -278,13 +313,8 @@
<li>
<p>When the ICE Agent finishes checking all candidate pairs, if at
least one connection has been found for each MediaStreamTrack, the
- <var>iceState</var> is changed to "completed"; if no connection has
- been found for any MediaStreamTrack, the iceState is changed to
- "failed".</p>
-
- <p class="issue">ISSUE: Note that this means that if I was able to
- negotiate audio but not video via ICE, then <var>iceState</var> ==
- "completed". Is this really what is desired?</p>
+ <var>iceState</var> is changed to "completed"; else the iceState is
+ changed to "failed".</p>
</li>
<li>
@@ -308,11 +338,7 @@
user agents renegotiate for a resolution that matches the rendered
display size.</p>
- <p class="note">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 its <code>video</code> element
- accordingly, there will be no need for a renegotiation once the stream
- is flowing.</p><!--
+ <!--
<p>All SDP media descriptions for RTP flows represented by <code>
<a>MediaStreamTrack</a>
</code> objects MUST include a label attribute ("<code
@@ -326,7 +352,7 @@
generate any candidates for media streams whose media descriptions do
not have a label attribute ("<code>a=label:</code>"). [[!ICE]] [[!SDP]]
[[!SDPLABEL]] (Note: CJ - I have no idea why this is here) </p>
- -->
+ -->
<p>The word "components" in this context refers to an RTP media flow
and does not have anything to do with how [[ICE]] uses the term
@@ -357,8 +383,7 @@
<ol>
<li>
<p>Create a <code><a>MediaStreamTrack</a></code> object
- <var>track</var> to represent the component. [[EDITORIAL: Can
- we just reference 3.2.1.2 here?]]</p>
+ <var>track</var> to represent the component.</p>
</li>
<li>
@@ -399,7 +424,7 @@
<li>
<p>If the <var>connection</var>'s <a href=
"#rtcpeerconnection-readiness-state"><code>RTCPeerConnection</code>
- readiness state</a> is <code>closed</code> (3), abort these
+ readiness state</a> is <code>closed</code>, abort these
steps.</p>
</li><!-- close() was probably called just before this
task ran -->
@@ -461,7 +486,7 @@
<li>
<p>If the <var>connection</var>'s <a href=
"#rtcpeerconnection-readiness-state"><code>RTCPeerConnection</code>
- readiness state</a> is <code>closed</code> (3), abort these
+ readiness state</a> is <code>closed</code>, abort these
steps.</p>
</li><!-- close() was probably called just before this
task ran -->
@@ -540,7 +565,7 @@
-->
<dt>void createOffer (RTCSessionDescriptionCallback successCallback,
- optional RTCPeerConnectionErrorCallback failureCallback,
+ RTCPeerConnectionErrorCallback failureCallback, optional
MediaConstraints constraints)</dt>
<dd>
@@ -550,8 +575,9 @@
attached to this <code>RTCPeerConnection</code>, 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.</p>
+ be supplied to provide additional control over the offer generated.
+ More information about constraints can be found in
+ [[!RTCWEB-CONSTRAINTS]].</p>
<p>As an offer, the generated SDP will contain the full set of
capabilities supported by the session (as opposed to an answer,
@@ -583,11 +609,24 @@
Identity assertions, then the session description SHALL contain an
appropriate assertion.</p>
- <p>The failureCallback will be called if the system cannot generate
- an appropriate offer given the state of the RTCPeerConnection.</p>
+ <p>If this <code>RTCPeerConnection</code> object is closed before
+ the SDP generation process completes, the USER agent MUST suppress
+ the result and not call any of the result callbacks.</p>
- <p>A TBD exception is thrown if the constraints parameter is
- malformed.</p>
+ <p>If the SDP generation process completed successfully, the user
+ agent MUST queue a task to invoke <var>successCallback</var> with a
+ newly created <code><a>RTCSessionDescription</a></code> object,
+ representing the generated offer, as its argument.</p>
+
+ <p>If the SDP generation process failed for any reason, the user
+ agent MUST queue a task to invoke <var>errorCallback</var> with an
+ <code>RTCError</code> object of type TBD as its argument.</p>
+
+ <p>An exception with an <code>RTCError</code> object of type
+ <code>INVALID_CONSTRAINTS_TYPE</code> is thrown if the constraints
+ parameter is malformed, and an <code>RTCError</code> object of type
+ <code>INCOMPATIBLE_CONSTRAINTS</code> is provided to the failure
+ callback if the constraints could not be successfully applied.</p>
<p>To Do: Discuss privacy aspects of this from a fingerprinting
point of view - it's probably around as bad as access to a canvas
@@ -595,8 +634,8 @@
</dd>
<dt>void createAnswer (RTCSessionDescriptionCallback successCallback,
- optional RTCPeerConnectionErrorCallback? failureCallback = null,
- MediaConstraints constraints = null)</dt>
+ RTCPeerConnectionErrorCallback failureCallback, optional
+ MediaConstraints? constraints = null)</dt>
<dd>
<p>The createAnswer method generates an [[!SDP]] answer with the
@@ -634,16 +673,29 @@
Identity assertions, then the session description SHALL contain an
appropriate assertion.</p>
- <p>The failureCallback will be called if the system cannot generate
- an appropriate answer given the offer.</p>
+ <p>If this <code>RTCPeerConnection</code> object is closed before
+ the SDP generation process completes, the USER agent MUST suppress
+ the result and not call any of the result callbacks.</p>
- <p>A TBD exception is thrown if the constraints parameter is
- malformed.</p>
+ <p>If the SDP generation process completed successfully, the user
+ agent MUST queue a task to invoke <var>successCallback</var> with a
+ newly created <code><a>RTCSessionDescription</a></code> object,
+ representing the generated answer, as its argument.</p>
+
+ <p>If the SDP generation process failed for any reason, the user
+ agent MUST queue a task to invoke <var>errorCallback</var> with an
+ <code>RTCError</code> object of type TBD as its argument.</p>
+
+ <p>An exception with an <code>RTCError</code> object of type
+ <code>INVALID_CONSTRAINTS_TYPE</code> is thrown if the constraints
+ parameter is malformed, and an <code>RTCError</code> object of type
+ <code>INCOMPATIBLE_CONSTRAINTS</code> is provided to the failure
+ callback if the constraints could not be successfully applied.</p>
</dd>
<dt>void setLocalDescription (RTCSessionDescription description,
- optional RTCVoidCallback successCallback,
- RTCPeerConnectionErrorCallback failureCallback)</dt>
+ RTCVoidCallback successCallback, RTCPeerConnectionErrorCallback
+ failureCallback)</dt>
<dd>
<p>The <dfn id=
@@ -680,7 +732,9 @@
back as necessary if the new description was partially applied when
the failure occurred.</p>
- <p>A TBD exception is thrown if the SDP content is invalid.</p>
+ <p>An <code>RTCError</code> object of type
+ <code>INVALID_SESSION_DESCRIPTION</code> is provided to the failure
+ callback if the SDP content is invalid.</p>
</dd>
<dt>readonly attribute RTCSessionDescription localDescription</dt>
@@ -699,8 +753,8 @@
</dd>
<dt>void setRemoteDescription (RTCSessionDescription description,
- optional RTCVoidCallback successCallback,
- RTCPeerConnectionErrorCallback failureCallback)</dt>
+ RTCVoidCallback successCallback, RTCPeerConnectionErrorCallback
+ failureCallback)</dt>
<dd>
<p>The <dfn id=
@@ -725,7 +779,9 @@
back as necessary if the new description was partially applied when
the failure occurred.</p>
- <p>A TBD exception is thrown if the SDP content is invalid.</p>
+ <p>An <code>RTCError</code> object of type
+ <code>INVALID_SESSION_DESCRIPTION</code> is provided to the failure
+ callback if the SDP content is invalid.</p>
</dd>
<dt>readonly attribute RTCSessionDescription remoteDescription</dt>
@@ -775,8 +831,11 @@
document the new procedure in the correct place.
</div>
- <p>A TBD exception will be thrown if the constraints parameter is
- malformed.</p>
+ <p>An exception with an <code>RTCError</code> object of type
+ <code>INVALID_CONSTRAINTS_TYPE</code> is thrown if the constraints
+ parameter is malformed, and an <code>RTCError</code> object of type
+ <code>INCOMPATIBLE_CONSTRAINTS</code> is provided to the failure
+ callback if the constraints could not be successfully applied.</p>
</dd>
<dt>void addIceCandidate (RTCIceCandidate candidate)</dt>
@@ -792,8 +851,9 @@
state if it results in different connectivity being
established.</p>
- <p>A TBD exception will be thrown if candidate parameter is
- malformed.</p>
+ <p>An exception with an <code>RTCError</code> object of type
+ <code>INVALID_CANDIDATE_TYPE</code> is thrown if candidate
+ parameter is malformed.</p>
</dd>
<dt>readonly attribute RTCGatheringState iceGatheringState</dt>
@@ -858,8 +918,8 @@
<p>If the <code><a>RTCPeerConnection</a></code> object’s
<a href=
"#rtcpeerconnection-readiness-state"><code>RTCPeerConnection</code>
- readiness state</a> is <code>closed</code> (3), throw an
- <code>INVALID_STATE_ERR</code> exception.</p>
+ readiness state</a> is <code>closed</code>, throw an
+ <code>INVALID_STATE</code> exception.</p>
</li>
<li>
@@ -936,7 +996,7 @@
<a href="#rtcpeerconnection-readiness-state"><code>RTCPeerConnection</code> readiness
state</a> is <code><a href=
"#widl-RTCPeerConnection-CLOSED">CLOSED</a></code> (3), throw an
- <code>INVALID_STATE_ERR</code> exception.</p>
+ <code>INVALID_STATE</code> exception.</p>
</li>
<li>
@@ -986,8 +1046,9 @@
<p>If the <code><a>RTCPeerConnection</a></code> object's
<a href=
"#rtcpeerconnection-readiness-state"><code>RTCPeerConnection</code>
- readiness state</a> is <code>closed</code> (3), throw an
- <code>INVALID_STATE_ERR</code> exception.</p>
+ readiness state</a> is <code>closed</code>, abort these steps,
+ and throw an exception with an <code>RTCError</code> object of
+ type <code>INVALID_STATE</code>.</p>
</li>
<li>
@@ -1008,8 +1069,11 @@
<li>
<p>Parse the <var>constraints</var> provided by the application
- and apply them to the MediaStream, if possible. NOTE - need to
- deal with throwing an exception here.</p>
+ and apply them to the MediaStream, if possible. If the
+ constraints could not be successfully applied, provide an
+ <code>RTCError</code> object of type
+ <code>INCOMPATIBLE_CONSTRAINTS</code> to the failure
+ callback.</p>
</li>
<li>
@@ -1042,8 +1106,8 @@
<p>If the <code><a>RTCPeerConnection</a></code> object's
<a href=
"#rtcpeerconnection-readiness-state"><code>RTCPeerConnection</code>
- readiness state</a> is <code>closed</code> (3), throw an
- <code>INVALID_STATE_ERR</code> exception.</p>
+ readiness state</a> is <code>closed</code>, throw an
+ <code>INVALID_STATE</code> exception.</p>
</li>
<li>
@@ -1051,8 +1115,7 @@
<code><a>RTCPeerConnection</a></code> object's <code title=
"dom-RTCPeerConnection-localStreams"><a href=
"#widl-RTCPeerConnection-localStreams">localStreams</a></code>
- object, then abort these steps. TODO: Do we need an exception
- here?</p>
+ object, then abort these steps.</p>
</li>
<li>
@@ -1104,9 +1167,9 @@
<li>
<p>If the <var>connection</var>'s <a href=
"#peerconnection-readiness-state"><code>RTCPeerConnection</code>
- readiness state</a> is <code><a href=
- "#widl-RTCPeerConnection-CLOSED">CLOSED</a></code> (3),
- abort these steps.</p>
+ readiness state</a> is <code>closed</code>, abort these
+ steps, and throw an exception with an <code>RTCError</code>
+ object of type <code>INVALID_STATE</code>.</p>
</li>
<li>
@@ -1141,9 +1204,8 @@
<li>
<p>If the <var>connection</var>'s <a href=
"#peerconnection-readiness-state"><code>RTCPeerConnection</code>
- readiness state</a> is <code><a href=
- "#widl-RTCPeerConnection-CLOSED">CLOSED</a></code> (3), abort
- these steps.</p>
+ readiness state</a> is <code>closed</code>, abort these
+ steps.</p>
</li><!-- close() was probably called just before this
task ran -->
@@ -1162,8 +1224,7 @@
</dd>
<dt>void getStats(MediaStreamTrack? selector, RTCStatsCallback
- successCallback, optional RTCPeerConnectionErrorCallback
- failureCallback)</dt>
+ successCallback, RTCPeerConnectionErrorCallback failureCallback)</dt>
<dd>
<p>When the <dfn id="dom-peerconnection-getStats"><code title=
@@ -1175,8 +1236,8 @@
<p>If the <code><a>RTCPeerConnection</a></code> object's
<a href=
"#rtcpeerconnection-readiness-state"><code>RTCPeerConnection</code>
- readiness state</a> is <code>closed</code> (3), throw an
- <code>INVALID_STATE_ERR</code> exception.</p>
+ readiness state</a> is <code>closed</code>, throw an
+ <code>INVALID_STATE</code> exception.</p>
</li>
<li>
@@ -1225,8 +1286,8 @@
<p>If the <code><a>RTCPeerConnection</a></code> object's
<a href=
"#rtcpeerconnection-readiness-state"><code>RTCPeerConnection</code>
- readiness state</a> is <code>closed</code> (3), throw an
- <code>INVALID_STATE_ERR</code> exception.</p>
+ readiness state</a> is <code>closed</code>, throw an
+ <code>INVALID_STATE</code> exception.</p>
</li>
<li>
@@ -1240,12 +1301,12 @@
<li>
<p>Set the object's <a href=
"#rtcpeerconnection-readiness-state"><code>RTCPeerConnection</code>
- readiness state</a> to <code>closed</code> (3).</p>
+ readiness state</a> to <code>closed</code>.</p>
</li>
</ol>
</dd>
- <dt>attribute EventHandler onnegotationneeded</dt>
+ <dt>attribute EventHandler onnegotiationneeded</dt>
<dd>This event handler, of event handler event type <code><a href=
"#event-negotiation-needed">negotiationneeded</a></code> , MUST be
@@ -1560,15 +1621,145 @@
<h4>RTCPeerConnectionErrorCallback</h4>
<dl title='callback RTCPeerConnectionErrorCallback = void' class='idl'>
- <dt>DOMString errorInformation</dt>
+ <dt>RTCError error</dt>
- <dd>
- Information about what went wrong.
+ <dd>An error object encapsulating information about what went
+ wrong.</dd>
+ </dl>
+ </section>
+ </section>
- <p class="issue">ISSUE: Should this be an enum?</p>
+ <section>
+ <h3>Error Handling</h3>
+
+ <section>
+ <h4>General Principles</h4>
+
+ <p>Errors are indicated in two ways: exceptions and objects passed to
+ error callbacks. Both forms of error reporting MUST provide an object
+ of type <code>RTCError</code>. An exception MUST be thrown in the
+ following cases:</p>
+
+ <ul>
+ <li>The type of any argument passed to a function did not match what
+ was expected. An appropriate string from the
+ <code>RTCExceptionName</code> enum MUST be used as the error
+ name.</li>
+
+ <li>A function call was made when the RTCPeerConnection is in an
+ invalid state, or a state in which that particular function is not
+ allowed to be executed. In this case, the string
+ <code>INVALID_STATE</code> MUST be used as the error name.</li>
+ </ul>
+
+ <p>In all other cases, an error object MUST be provided to the failure
+ callback. The error name in the object provided MUST be picked from
+ either the <code>RTCExceptionName</code> or <code>RTCErrorName</code>
+ enums.</p>
+ </section>
+
+ <section>
+ <h4>RTCError</h4>
+
+ <dl class='idl' title='interface RTCError'>
+ <dt>readonly attribute DOMString name</dt>
+
+ <dd>A string representing the type of error. This string must be one
+ of those defined by the <code>RTCExceptionName</code> or
+ <code>RTCErrorName</code> enums for the error object to be
+ valid.</dd>
+
+ <dt>readonly attribute DOMString? message</dt>
+
+ <dd>A human readable description of the error. This string may vary
+ between different user agents.</dd>
+ </dl>
+ </section>
+
+ <section>
+ <h4>RTCSdpError</h4>
+
+ <dl class='idl' title='interface RTCSdpError : RTCError'>
+ <dt>readonly attribute long sdpLineNumber</dt>
+
+ <dd>
+ The line number of an <a>RTCSessionDescription</a> at which the
+ error was encountered.
</dd>
</dl>
</section>
+
+ <section>
+ <h4>RTCExceptionName</h4>
+
+ <dl class='idl' title='enum RTCExceptionName'>
+ <dt>INVALID_SUCCESS_CALLBACK</dt>
+
+ <dd>The provided successCallback is not a function.</dd>
+
+ <dt>INVALID_FAILURE_CALLBACK</dt>
+
+ <dd>The provided failureCallback is not a function.</dd>
+
+ <dt>INVALID_CONSTRAINTS_TYPE</dt>
+
+ <dd>The provided constraints object is not a dictionary with either
+ the <code>mandatory</code> or <code>optional</code> keys.</dd>
+
+ <dt>INVALID_SESSION_DESCRIPTION_TYPE</dt>
+
+ <dd>The provided session description is not an object of type
+ <code>RTCSessionDescription</code>.</dd>
+
+ <dt>INVALID_CONFIGURATION_TYPE</dt>
+
+ <dd>The provided configuration is not an object of type
+ <code>RTCConfiguration</code>.</dd>
+
+ <dt>INVALID_CANDIDATE_TYPE</dt>
+
+ <dd>The provided candidate is not an object of type
+ <code>RTCIceCandidate</code>.</dd>
+
+ <dt>INVALID_MEDIASTREAM</dt>
+
+ <dd>The provided media stream is not an object of type
+ <code>MediaStream</code>.</dd>
+
+ <dt>INVALID_MEDIASTREAM_TRACK</dt>
+
+ <dd>The provided track is not an object of type
+ <code>MediaStreamTrack</code>.</dd>
+
+ <dt>INVALID_STATE</dt>
+
+ <dd>The function was called on a <code>RTCPeerConnection</code> that
+ is an invalid state, or a state in which the function is not allowed
+ to be executed.</dd>
+ </dl>
+ </section>
+
+ <section>
+ <h4>RTCErrorName</h4>
+
+ <dl class='idl' title='enum RTCErrorName'>
+ <dt>INVALID_SESSION_DESCRIPTION</dt>
+
+ <dd>The provided <code>RTCSessionDescription</code> either contained
+ invalid SDP, or SDP that could not be correctly applied to the
+ <code>RTCPeerConnection</code> due to its current state. User agents
+ SHOULD provide as much additional information in the error message as
+ possible, including the <code>sdpLineNumber</code>, if
+ appropriate.</dd>
+
+ <dt>INCOMPATIBLE_CONSTRAINTS</dt>
+
+ <dd>The provided <code>MediaConstraints</code> could not be correctly
+ applied to the <code>RTCPeerConnection</code> due to its current
+ state. User agents SHOULD provide as much additional information in
+ the error message as possible.</dd>
+ </dl>
+ </section>
</section>
<section>
@@ -1797,8 +1988,7 @@
<p>If the associated <code><a>RTCPeerConnection</a></code> object's
<a href=
"#rtcpeerconnection-readiness-state"><code>RTCPeerConnection</code>
- readiness state</a> is <code>closed</code> (3), abort these
- steps.</p>
+ readiness state</a> is <code>closed</code>, abort these steps.</p>
</li>
<li>
@@ -1827,8 +2017,7 @@
<p>If the associated <code><a>RTCPeerConnection</a></code> object's
<a href=
"#rtcpeerconnection-readiness-state"><code>RTCPeerConnection</code>
- readiness state</a> is <code>closed</code> (3), abort these
- steps.</p>
+ readiness state</a> is <code>closed</code>, abort these steps.</p>
</li>
<li>
@@ -1931,7 +2120,7 @@
<li>
<p>Set <var>channel</var>'s <code><a href=
"#dom-datachannel-readystate">readyState</a></code> attribute to
- <code>closed</code> (3).</p>
+ <code>closed</code>.</p>
</li>
<li>
@@ -2727,9 +2916,8 @@
<p>A track in a <code><a>MediaStream</a></code>, received with an
<code><a>RTCPeerConnection</a></code>, MUST have its
- <code>readyState</code> attribute [[!GETUSERMEDIA]] set to <code><a href=
- "#event-mediastreamtrack-muted">muted</a></code> (1) until media data
- arrives.</p>
+ <code>readyState</code> attribute [[!GETUSERMEDIA]] set to
+ <code>muted</code> until media data arrives.</p>
<p>In addition, a <code>MediaStreamTrack</code> has its
<code>readyState</code> set to <code>muted</code> on the remote peer if
@@ -2863,51 +3051,63 @@
mechanism they used to establish that they were going to communicate in
the first place.</p>
<pre class="example sh_javascript">
-var signalingChannel = createSignalingChannel();
+
+var signalingChannel = new SignalingChannel();
+var configuration = { "iceServers": [{ "url": "stun:stun.example.org" }] };
var pc;
-var configuration = ...;
-// run start(true) to initiate a call
-function start(isCaller) {
+// call start() to initiate
+function start() {
pc = new RTCPeerConnection(configuration);
// send any ice candidates to the other peer
pc.onicecandidate = function (evt) {
- signalingChannel.send(JSON.stringify({ "candidate": evt.candidate }));
+ if (evt.candidate)
+ signalingChannel.send(JSON.stringify({ "candidate": evt.candidate }));
};
+ // let the "negotiationneeded" event trigger offer generation
+ pc.onnegotiationneeded = function () {
+ pc.createOffer(localDescCreated, logError);
+ }
+
// 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
+ // get a local stream, show it in a self-view and add it to be sent
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 }));
- }
});
}
+function localDescCreated(desc) {
+ pc.setLocalDescription(desc, function () {
+ signalingChannel.send(JSON.stringify({ "sdp": pc.localDescription }));
+ }, logError);
+}
+
signalingChannel.onmessage = function (evt) {
if (!pc)
- start(false);
+ start();
- var signal = JSON.parse(evt.data);
- if (signal.sdp)
- pc.setRemoteDescription(new RTCSessionDescription(signal.sdp));
+ var message = JSON.parse(evt.data);
+ if (message.sdp)
+ pc.setRemoteDescription(new RTCSessionDescription(message.sdp), function () {
+ // if we received an offer, we need to answer
+ if (pc.remoteDescription.type == "offer")
+ pc.createAnswer(localDescCreated, logError);
+ }, logError);
else
- pc.addIceCandidate(new RTCIceCandidate(signal.candidate));
+ pc.addIceCandidate(new RTCIceCandidate(message.candidate));
};
+
+function logError(error) {
+ log(error.name + ": " + error.message);
+}
+
</pre>
</div>
@@ -2946,23 +3146,24 @@
<code>negotiationneeded</code> event will not do so during an ongoing
offer/answer dialog.</p>
<pre class="example sh_javascript">
-var signalingChannel = createSignalingChannel();
+var signalingChannel = new SignalingChannel();
+var configuration = { "iceServers": [{ "url": "stun:stun.example.org" }] };
var pc;
-var configuration = "...";
var channel;
// call start(true) to initiate
function start(isInitiator) {
- pc = new PeerConnection(configuration);
+ pc = new RTCPeerConnection(configuration);
// send any ice candidates to the other peer
pc.onicecandidate = function (evt) {
- signalingChannel.send(JSON.stringify({ "candidate": evt.candidate }));
+ if (evt.candidate)
+ signalingChannel.send(JSON.stringify({ "candidate": evt.candidate }));
};
- // let the "negotiationneeded" event trigger negotiation
+ // let the "negotiationneeded" event trigger offer generation
pc.onnegotiationneeded = function () {
- pc.createOffer(localDescCreated);
+ pc.createOffer(localDescCreated, logError);
}
if (isInitiator) {
@@ -2981,7 +3182,7 @@
function localDescCreated(desc) {
pc.setLocalDescription(desc, function () {
signalingChannel.send(JSON.stringify({ "sdp": pc.localDescription }));
- });
+ }, logError);
}
signalingChannel.onmessage = function (evt) {
@@ -2990,12 +3191,13 @@
var message = JSON.parse(evt.data);
if (message.sdp)
- pc.setRemoteDescription(new SessionDescription(message.sdp), function () {
+ pc.setRemoteDescription(new RTCSessionDescription(message.sdp), function () {
+ // if we received an offer, we need to answer
if (pc.remoteDescription.type == "offer")
- createAnswer(localDescCreated);
- });
+ pc.createAnswer(localDescCreated, logError);
+ }, logError);
else
- pc.addIceCandidate(new IceCandidate(message.candidate));
+ pc.addIceCandidate(new RTCIceCandidate(message.candidate));
};
function setupChat() {
@@ -3013,6 +3215,9 @@
channel.send(msg);
}
+function logError(error) {
+ log(error.name + ": " + error.message);
+}
</pre>
</div><!--div>
@@ -3039,16 +3244,15 @@
<p><img alt=
"A message sequence chart detailing a call flow between two browsers"
- src="images/ladder-2party-simple.svg" style="width:100%"></p>
-
+ src="images/ladder-2party-simple.svg" style="width:100%"></p><!--
<p>The following flow shows a more complete set of the callbacks and
events that happen.</p>
<p><img alt=
"A more complete message sequence chart detailing a call flow between two browsers"
src="images/ladder-2party-full.svg" style="width:100%"></p>
- </section>
-
+ -->
+ </section><!--
<section>
<h3>Call Flow Browser to MCU</h3>
@@ -3064,6 +3268,7 @@
"A message sequence chart detailing a call flow between a browser and a centralized conferencing server"
src="images/ladder-mcu-simple.svg" style="width:100%"></p>
</section>
+-->
</section>
<section class="informative">
@@ -3251,6 +3456,12 @@
</section>
<section>
+ <h2>Security Considerations</h2>
+
+ <p>TBD.</p>
+ </section>
+
+ <section>
<h2 id="sec-iana">IANA Registrations</h2>
<p>IANA is requested to register the constraints defined in <a href=
@@ -3360,18 +3571,44 @@
</section>
<section>
- <h2>Security Considerations</h2>
-
- <p>TBD.</p>
- </section>
-
- <section>
<h2>Change Log</h2>
<p>This section will be removed before publication.</p>
<!-- Why do the first two headings automatically convert to <h2>? -->
- <h3>Changes since Sept 23 , 2012</h3>
+ <h3>Changes since Nov 13, 2012</h3>
+
+ <ol>
+ <li>Made some clarifications as to how operation queuing works, and fixed
+ a few errors with the error handling description.</li>
+ </ol>
+
+ <h3>Changes since Nov 03, 2012</h3>
+
+ <ol>
+ <li>Added text describing the queuing mechanism for
+ RTCPeerConnection.</li>
+
+ <li>Updated simple P2P example to include all mandatory (error)
+ callbacks.</li>
+
+ <li>Updated P2P data example to include all mandatory (error) callbacks.
+ Also added some missing RTC prefixes.</li>
+ </ol>
+
+ <h3>Changes since Oct 19, 2012</h3>
+
+ <ol>
+ <li>Clarified how createOffer() and createAnswer() use their
+ callbacks.</li>
+
+ <li>Made all failure callbacks mandatory.</li>
+
+ <li>Added error object types, general error handling principles, and
+ rules for when errors should be thrown.</li>
+ </ol>
+
+ <h3>Changes since Sept 23, 2012</h3>
<ol>
<li>Restructured the document layout and created separate sections for
Index: getusermedia.html
===================================================================
RCS file: /sources/public/2011/webrtc/editor/getusermedia.html,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- getusermedia.html 25 Sep 2012 17:26:23 -0000 1.13
+++ getusermedia.html 15 Nov 2012 19:30:31 -0000 1.14
@@ -185,106 +185,77 @@
<h2>MediaStream</h2>
<p>The <dfn id="dom-mediastream"> <code>MediaStream()</code></dfn>
- constructor takes zero or one argument. If the argument,
- <var>trackContainers</var>, is supplied, it specifies a list of <code>
- <a>MediaStream</a></code>, <code><a>MediaStreamTrackList</a></code> and
- <code><a>MediaStreamTrack</a></code> objects. The list objects specifies
- existing tracks whose sources will be used to constuct the tracks in the
- new <code><a>MediaStream</a></code> object. A <code>
- <a>MediaStreamTrack</a></code> object specifies a track directly, while
- <code><a>MediaStream</a></code> and <code><a>MediaStreamTrackList</a>
- </code> objects specifiy all tracks contained within these objects. When
- the constructor is invoked, the UA must run the following steps:</p>
+ constructor takes zero or one argument. If the argument is supplied, it
+ MUST either be of type <code><a>MediaStream</a></code>, an array of
+ <code><a>MediaStreamTrack</a></code> objects or null. When the constructor
+ is invoked, the UA must run the following steps:</p>
<ol>
<li>
- <p>Let <var>trackContainers</var> be the constructor’s argument, if
- any, or null otherwise.</p>
- </li>
-
- <li>
<p>Let <var>stream</var> be a newly constructed <code>
<a>MediaStream</a></code> object.</p>
</li>
<li>
- <p>Set <var>stream’s</var> label attribute to a newly generated
+ <p>Initialize <var>stream’s</var> label attribute to a newly generated
value.</p>
</li>
<li>
- <p>If <var>trackContainers</var> is not null, then run the following
- sub steps for every element, <var>trackContainer</var>, in
- <var>trackContainers</var>:</p>
+ <p>If the constructor’s argument is present and not null, run the sub
+ steps that corresponds to the argument type.</p>
</li>
- <ol>
- <li>
- <p>If <var>trackContainer</var> is null, then abort these steps
- and continue with the next element.</p>
- </li>
-
+ <ul>
<li>
- <p>If <var>trackContainer</var> is of type <code>
- <a>MediaStreamTrack</a></code>, then run the following sub
- steps:</p>
- </li>
+ <p><code>Array</code> of <code><a>MediaStreamTrack</a></code>
+ objects:</p>
- <ol>
- <li>
- <p><em>Add track</em>: Let <var>track</var> be the <code>
- <a>MediaStreamTrack</a></code> about to be processed.</p>
- </li>
+ <p>Run the following sub steps for each <code>
+ <a>MediaStreamTrack</a></code> in the array:</p>
- <li>
- <p>If <var>track’s</var> kind attribute is not
- "<code>audio</code>" or "<code>video</code>", then throw a
- <code>SyntaxError</code> exception.</p>
- </li>
+ <ol>
+ <li>
+ <p><em>Add track</em>: Let <var>track</var> be the <code>
+ <a>MediaStreamTrack</a></code> about to be processed.</p>
+ </li>
- <li>
- <p>If <var>track</var> has <a>ended</a> or if there is already
- a <code><a>MediaStreamTrack</a></code> contained within
- <var>stream</var> that has the same underlying source as
- <var>track</var>, then abort these steps.
- </p>
- </li>
+ <li>
+ <p>If <var>track</var> has <a>ended</a> or if there is already
+ a <code><a>MediaStreamTrack</a></code> contained within
+ <var>stream</var> that has the same underlying source as
+ <var>track</var>, then abort these steps and continue with the
+ next track (if any).</p>
+ </li>
- <li>
- <p>Create a new <code><a>MediaStreamTrack</a></code> object
- and let it inherit <var>track’s</var> underlying source,
- <code><a href="#dom-mediastreamtrack-kind">kind</a></code> and
- <code><a href="#dom-mediastreamtrack-label">label</a></code>
- attributes. Append the new <code><a>MediaStreamTrack</a>
- </code> to the corresponding track list
- (<code><a href="#dom-mediastream-audiotracks">audioTracks</a>
- </code> or <code>
- <a href="#dom-mediastream-videotracks">videoTracks</a></code>)
- in <var>stream</var> according to kind.</p>
- </li>
- </ol>
+ <li>
+ <p>Create a new <code><a>MediaStreamTrack</a></code> object
+ and let it inherit <var>track’s</var> underlying source,
+ <code><a href="#dom-mediastreamtrack-kind">kind</a></code> and
+ <code><a href="#dom-mediastreamtrack-label">label</a></code>
+ attributes. Append the new <code><a>MediaStreamTrack</a>
+ </code> to the corresponding track list
+ (<code><a href="#dom-mediastream-audiotracks">audioTracks</a>
+ </code> or <code>
+ <a href="#dom-mediastream-videotracks">videoTracks</a></code>)
+ in <var>stream</var> according to kind.</p>
+ </li>
+ </ol>
- <li>
- <p>If <var>trackContainer</var> is of type <code>
- <a>MediaStreamTrackList</a></code>, then run the sub steps
- labeled <em>Add track</em> (above) for every <code>
- <a>MediaStreamTrack</a></code> in <var>trackContainer</var>.</p>
</li>
<li>
- <p>If <var>trackContainer</var> is of type <code>
- <a>MediaStream</a></code>, then run the sub steps labeled
- <em>Add track</em> (above) for every <code>
- <a>MediaStreamTrack</a></code> in <var>trackContainer’s</var>
- two track lists
+ <p><code><a>MediaStream</a></code>:</p>
+
+ <p>Run the sub steps labeled <em>Add track</em> (above) for every
+ <code><a>MediaStreamTrack</a></code> in the argument stream’s two
+ track lists
(<code><a href="#dom-mediastream-audiotracks">audioTracks</a>
</code> and <code>
<a href="#dom-mediastream-videotracks">videoTracks</a></code>).
</p>
</li>
-
- </li>
- </ol>
+ </ul>
<li>
<p>Return <var>stream</var>.</p>
@@ -355,13 +326,15 @@
interaction task source. Otherwise the task source for this <span title=
"concept-task">task</span> is the networking task source.</p>
- <p class="note">The union type we want to express here is not supported
- by ReSpec at the moment. Until it is supported, let
- <code>TracksUnionType</code> be defined as <code>(MediaStream? or
- MediaStreamTrackList or MediaStreamTrack)[]</code>.</p>
+ <!-- The "[]" in MediaStreamTrack[] breaks rendering if added directly to
+ the constructor declaration -->
+ <dl class="idl" title="typedef MediaStreamTrack[] MediaStreamTrackArray"></dl>
<dl class="idl"
- title="[Constructor (TracksUnionType? trackContainers)] interface MediaStream">
+ title="[Constructor (),
+ Constructor (MediaStream? stream),
+ Constructor (MediaStreamTrackArray tracks)]
+ interface MediaStream : EventTarget">
<dt>readonly attribute DOMString label</dt>
<dd>
@@ -443,8 +416,6 @@
objects implementing the <code><a>MediaStream</a></code>
interface.</dd>
</dl>
-
- <div class="idl" title="MediaStream implements EventTarget"></div>
</section>
<section>
@@ -594,10 +565,9 @@
<dd>
<p>The <dfn id=
"dom-mediastreamtrack-kind"><code>MediaStreamTrack.kind</code></dfn>
- attribute MUST return the string "<code>audio</code>" if the object’s
- corresponding track is or was an audio track, "<code>video</code>" if
- the corresponding track is or was a video track, and a user agent
- defined string otherwise.</p>
+ attribute MUST return the string "<code>audio</code>" if the object
+ represents an audio track or "<code>video</code>" if object represents
+ a video track.</p>
</dd>
<dt>readonly attribute DOMString label</dt>
@@ -1952,6 +1922,17 @@
<p>-</p>
-->
+ <h2>October 1 2012</h2>
+
+ <ol>
+ <li>Limited the track kind values to "audio" and "video" only (could
+ previously be user defined as well).</li>
+
+ <li>Made MediaStream extend EventTarget.</li>
+
+ <li>Simplified the MediaStream constructor.</li>
+ </ol>
+
<h2>June 23 2012</h2>
<ol>
Received on Thursday, 15 November 2012 19:30:36 UTC