You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2686 lines
156 KiB
2686 lines
156 KiB
<?xml version='1.0' encoding='UTF-8'?>
|
|
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
|
|
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
|
|
<head>
|
|
<meta name="generator" content="HTML Tidy for Linux/x86 (vers 11 February 2007), see www.w3.org" />
|
|
<title>WebRTC 1.0: Real-time Communication Between Browsers</title>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<style type="text/css">
|
|
/*****************************************************************
|
|
* Styles specific to WebRTC spec
|
|
*****************************************************************/
|
|
pre { white-space: pre-wrap; }
|
|
table { border-collapse: collapse; border-style: hidden hidden none hidden; }
|
|
table thead, table tbody { border-bottom: solid #90B8DE; }
|
|
table tbody th { text-align: left; }
|
|
table tbody th:first-child { border-left: solid #90B8DE; }
|
|
table td, table th { border-left: solid #90B8DE; border-right: solid #90B8DE; border-bottom: solid thin #90B8DE; vertical-align: top; padding: 0.2em; }
|
|
.note { color: green; }
|
|
.example { display: block; color: #222222; background: #FCFCFC; border-left: double; margin-left: 2em; padding-left: 1em; }
|
|
|
|
|
|
/*****************************************************************
|
|
* ReSpec CSS
|
|
* Robin Berjon (robin at berjon dot com)
|
|
* v0.05 - 2009-07-31
|
|
*****************************************************************/
|
|
|
|
|
|
/* --- INLINES --- */
|
|
em.rfc2119 {
|
|
text-transform: lowercase;
|
|
font-variant: small-caps;
|
|
font-style: normal;
|
|
color: #900;
|
|
}
|
|
|
|
h1 acronym, h2 acronym, h3 acronym, h4 acronym, h5 acronym, h6 acronym, a acronym,
|
|
h1 abbr, h2 abbr, h3 abbr, h4 abbr, h5 abbr, h6 abbr, a abbr {
|
|
border: none;
|
|
}
|
|
|
|
dfn {
|
|
font-weight: bold;
|
|
}
|
|
|
|
a.internalDFN {
|
|
color: inherit;
|
|
border-bottom: 1px solid #99c;
|
|
text-decoration: none;
|
|
}
|
|
|
|
a.externalDFN {
|
|
color: inherit;
|
|
border-bottom: 1px dotted #ccc;
|
|
text-decoration: none;
|
|
}
|
|
|
|
a.bibref {
|
|
text-decoration: none;
|
|
}
|
|
|
|
code {
|
|
color: #ff4500;
|
|
}
|
|
|
|
|
|
/* --- WEB IDL --- */
|
|
pre.idl {
|
|
border-top: 1px solid #90b8de;
|
|
border-bottom: 1px solid #90b8de;
|
|
padding: 1em;
|
|
line-height: 120%;
|
|
}
|
|
|
|
pre.idl::before {
|
|
content: "WebIDL";
|
|
display: block;
|
|
width: 150px;
|
|
background: #90b8de;
|
|
color: #fff;
|
|
font-family: initial;
|
|
padding: 3px;
|
|
font-weight: bold;
|
|
margin: -1em 0 1em -1em;
|
|
}
|
|
|
|
.idlType {
|
|
color: #ff4500;
|
|
font-weight: bold;
|
|
text-decoration: none;
|
|
}
|
|
|
|
/*.idlModule*/
|
|
/*.idlModuleID*/
|
|
/*.idlInterface*/
|
|
.idlInterfaceID, .idlDictionaryID {
|
|
font-weight: bold;
|
|
color: #005a9c;
|
|
}
|
|
|
|
.idlSuperclass {
|
|
font-style: italic;
|
|
color: #005a9c;
|
|
}
|
|
|
|
/*.idlAttribute*/
|
|
.idlAttrType, .idlFieldType, .idlMemberType {
|
|
color: #005a9c;
|
|
}
|
|
.idlAttrName, .idlFieldName, .idlMemberName {
|
|
color: #ff4500;
|
|
}
|
|
.idlAttrName a, .idlFieldName a, .idlMemberName a {
|
|
color: #ff4500;
|
|
border-bottom: 1px dotted #ff4500;
|
|
text-decoration: none;
|
|
}
|
|
|
|
/*.idlMethod*/
|
|
.idlMethType {
|
|
color: #005a9c;
|
|
}
|
|
.idlMethName {
|
|
color: #ff4500;
|
|
}
|
|
.idlMethName a {
|
|
color: #ff4500;
|
|
border-bottom: 1px dotted #ff4500;
|
|
text-decoration: none;
|
|
}
|
|
|
|
/*.idlParam*/
|
|
.idlParamType {
|
|
color: #005a9c;
|
|
}
|
|
.idlParamName {
|
|
font-style: italic;
|
|
}
|
|
|
|
.extAttr {
|
|
color: #666;
|
|
}
|
|
|
|
/*.idlConst*/
|
|
.idlConstType {
|
|
color: #005a9c;
|
|
}
|
|
.idlConstName {
|
|
color: #ff4500;
|
|
}
|
|
.idlConstName a {
|
|
color: #ff4500;
|
|
border-bottom: 1px dotted #ff4500;
|
|
text-decoration: none;
|
|
}
|
|
|
|
/*.idlException*/
|
|
.idlExceptionID {
|
|
font-weight: bold;
|
|
color: #c00;
|
|
}
|
|
|
|
.idlTypedefID, .idlTypedefType {
|
|
color: #005a9c;
|
|
}
|
|
|
|
.idlRaises, .idlRaises a.idlType, .idlRaises a.idlType code, .excName a, .excName a code {
|
|
color: #c00;
|
|
font-weight: normal;
|
|
}
|
|
|
|
.excName a {
|
|
font-family: monospace;
|
|
}
|
|
|
|
.idlRaises a.idlType, .excName a.idlType {
|
|
border-bottom: 1px dotted #c00;
|
|
}
|
|
|
|
.excGetSetTrue, .excGetSetFalse, .prmNullTrue, .prmNullFalse, .prmOptTrue, .prmOptFalse {
|
|
width: 45px;
|
|
text-align: center;
|
|
}
|
|
.excGetSetTrue, .prmNullTrue, .prmOptTrue { color: #0c0; }
|
|
.excGetSetFalse, .prmNullFalse, .prmOptFalse { color: #c00; }
|
|
|
|
.idlImplements a {
|
|
font-weight: bold;
|
|
}
|
|
|
|
dl.attributes, dl.methods, dl.constants, dl.fields, dl.dictionary-members {
|
|
margin-left: 2em;
|
|
}
|
|
|
|
.attributes dt, .methods dt, .constants dt, .fields dt, .dictionary-members dt {
|
|
font-weight: normal;
|
|
}
|
|
|
|
.attributes dt code, .methods dt code, .constants dt code, .fields dt code, .dictionary-members dt code {
|
|
font-weight: bold;
|
|
color: #000;
|
|
font-family: monospace;
|
|
}
|
|
|
|
.attributes dt code, .fields dt code, .dictionary-members dt code {
|
|
background: #ffffd2;
|
|
}
|
|
|
|
.attributes dt .idlAttrType code, .fields dt .idlFieldType code, .dictionary-members dt .idlMemberType code {
|
|
color: #005a9c;
|
|
background: transparent;
|
|
font-family: inherit;
|
|
font-weight: normal;
|
|
font-style: italic;
|
|
}
|
|
|
|
.methods dt code {
|
|
background: #d9e6f8;
|
|
}
|
|
|
|
.constants dt code {
|
|
background: #ddffd2;
|
|
}
|
|
|
|
.attributes dd, .methods dd, .constants dd, .fields dd, .dictionary-members dd {
|
|
margin-bottom: 1em;
|
|
}
|
|
|
|
table.parameters, table.exceptions {
|
|
border-spacing: 0;
|
|
border-collapse: collapse;
|
|
margin: 0.5em 0;
|
|
width: 100%;
|
|
}
|
|
table.parameters { border-bottom: 1px solid #90b8de; }
|
|
table.exceptions { border-bottom: 1px solid #deb890; }
|
|
|
|
.parameters th, .exceptions th {
|
|
color: #fff;
|
|
padding: 3px 5px;
|
|
text-align: left;
|
|
font-family: initial;
|
|
font-weight: normal;
|
|
text-shadow: #666 1px 1px 0;
|
|
}
|
|
.parameters th { background: #90b8de; }
|
|
.exceptions th { background: #deb890; }
|
|
|
|
.parameters td, .exceptions td {
|
|
padding: 3px 10px;
|
|
border-top: 1px solid #ddd;
|
|
vertical-align: top;
|
|
}
|
|
|
|
.parameters tr:first-child td, .exceptions tr:first-child td {
|
|
border-top: none;
|
|
}
|
|
|
|
.parameters td.prmName, .exceptions td.excName, .exceptions td.excCodeName {
|
|
width: 100px;
|
|
}
|
|
|
|
.parameters td.prmType {
|
|
width: 120px;
|
|
}
|
|
|
|
table.exceptions table {
|
|
border-spacing: 0;
|
|
border-collapse: collapse;
|
|
width: 100%;
|
|
}
|
|
|
|
/* --- TOC --- */
|
|
.toc a {
|
|
text-decoration: none;
|
|
}
|
|
|
|
a .secno {
|
|
color: #000;
|
|
}
|
|
|
|
/* --- TABLE --- */
|
|
table.simple {
|
|
border-spacing: 0;
|
|
border-collapse: collapse;
|
|
border-bottom: 3px solid #005a9c;
|
|
}
|
|
|
|
.simple th {
|
|
background: #005a9c;
|
|
color: #fff;
|
|
padding: 3px 5px;
|
|
text-align: left;
|
|
}
|
|
|
|
.simple th[scope="row"] {
|
|
background: inherit;
|
|
color: inherit;
|
|
border-top: 1px solid #ddd;
|
|
}
|
|
|
|
.simple td {
|
|
padding: 3px 10px;
|
|
border-top: 1px solid #ddd;
|
|
}
|
|
|
|
.simple tr:nth-child(even) {
|
|
background: #f0f6ff;
|
|
}
|
|
|
|
/* --- DL --- */
|
|
.section dd > p:first-child {
|
|
margin-top: 0;
|
|
}
|
|
|
|
.section dd > p:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.section dd {
|
|
margin-bottom: 1em;
|
|
}
|
|
|
|
.section dl.attrs dd, .section dl.eldef dd {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
/* --- EXAMPLES --- */
|
|
pre.example {
|
|
border-top: 1px solid #ff4500;
|
|
border-bottom: 1px solid #ff4500;
|
|
padding: 1em;
|
|
margin-top: 1em;
|
|
}
|
|
|
|
pre.example::before {
|
|
content: "Example";
|
|
display: block;
|
|
width: 150px;
|
|
background: #ff4500;
|
|
color: #fff;
|
|
font-family: initial;
|
|
padding: 3px;
|
|
font-weight: bold;
|
|
margin: -1em 0 1em -1em;
|
|
}
|
|
|
|
/* --- EDITORIAL NOTES --- */
|
|
.issue {
|
|
padding: 1em;
|
|
margin: 1em 0em 0em;
|
|
border: 1px solid #f00;
|
|
background: #ffc;
|
|
}
|
|
|
|
.issue::before {
|
|
content: "Issue";
|
|
display: block;
|
|
width: 150px;
|
|
margin: -1.5em 0 0.5em 0;
|
|
font-weight: bold;
|
|
border: 1px solid #f00;
|
|
background: #fff;
|
|
padding: 3px 1em;
|
|
}
|
|
|
|
.note {
|
|
margin: 1em 0em 0em;
|
|
padding: 1em;
|
|
border: 2px solid #cff6d9;
|
|
background: #e2fff0;
|
|
}
|
|
|
|
.note::before {
|
|
content: "Note";
|
|
display: block;
|
|
width: 150px;
|
|
margin: -1.5em 0 0.5em 0;
|
|
font-weight: bold;
|
|
border: 1px solid #cff6d9;
|
|
background: #fff;
|
|
padding: 3px 1em;
|
|
}
|
|
|
|
/* --- Best Practices --- */
|
|
div.practice {
|
|
border: solid #bebebe 1px;
|
|
margin: 2em 1em 1em 2em;
|
|
}
|
|
|
|
span.practicelab {
|
|
margin: 1.5em 0.5em 1em 1em;
|
|
font-weight: bold;
|
|
font-style: italic;
|
|
}
|
|
|
|
span.practicelab { background: #dfffff; }
|
|
|
|
span.practicelab {
|
|
position: relative;
|
|
padding: 0 0.5em;
|
|
top: -1.5em;
|
|
}
|
|
|
|
p.practicedesc {
|
|
margin: 1.5em 0.5em 1em 1em;
|
|
}
|
|
|
|
@media screen {
|
|
p.practicedesc {
|
|
position: relative;
|
|
top: -2em;
|
|
padding: 0;
|
|
margin: 1.5em 0.5em -1em 1em;
|
|
}
|
|
}
|
|
|
|
/* --- SYNTAX HIGHLIGHTING --- */
|
|
pre.sh_sourceCode {
|
|
background-color: white;
|
|
color: black;
|
|
font-style: normal;
|
|
font-weight: normal;
|
|
}
|
|
|
|
pre.sh_sourceCode .sh_keyword { color: #005a9c; font-weight: bold; } /* language keywords */
|
|
pre.sh_sourceCode .sh_type { color: #666; } /* basic types */
|
|
pre.sh_sourceCode .sh_usertype { color: teal; } /* user defined types */
|
|
pre.sh_sourceCode .sh_string { color: red; font-family: monospace; } /* strings and chars */
|
|
pre.sh_sourceCode .sh_regexp { color: orange; font-family: monospace; } /* regular expressions */
|
|
pre.sh_sourceCode .sh_specialchar { color: #ffc0cb; font-family: monospace; } /* e.g., \n, \t, \\ */
|
|
pre.sh_sourceCode .sh_comment { color: #A52A2A; font-style: italic; } /* comments */
|
|
pre.sh_sourceCode .sh_number { color: purple; } /* literal numbers */
|
|
pre.sh_sourceCode .sh_preproc { color: #00008B; font-weight: bold; } /* e.g., #include, import */
|
|
pre.sh_sourceCode .sh_symbol { color: blue; } /* e.g., *, + */
|
|
pre.sh_sourceCode .sh_function { color: black; font-weight: bold; } /* function calls and declarations */
|
|
pre.sh_sourceCode .sh_cbracket { color: red; } /* block brackets (e.g., {, }) */
|
|
pre.sh_sourceCode .sh_todo { font-weight: bold; background-color: #00FFFF; } /* TODO and FIXME */
|
|
|
|
/* Predefined variables and functions (for instance glsl) */
|
|
pre.sh_sourceCode .sh_predef_var { color: #00008B; }
|
|
pre.sh_sourceCode .sh_predef_func { color: #00008B; font-weight: bold; }
|
|
|
|
/* for OOP */
|
|
pre.sh_sourceCode .sh_classname { color: teal; }
|
|
|
|
/* line numbers (not yet implemented) */
|
|
pre.sh_sourceCode .sh_linenum { display: none; }
|
|
|
|
/* Internet related */
|
|
pre.sh_sourceCode .sh_url { color: blue; text-decoration: underline; font-family: monospace; }
|
|
|
|
/* for ChangeLog and Log files */
|
|
pre.sh_sourceCode .sh_date { color: blue; font-weight: bold; }
|
|
pre.sh_sourceCode .sh_time, pre.sh_sourceCode .sh_file { color: #00008B; font-weight: bold; }
|
|
pre.sh_sourceCode .sh_ip, pre.sh_sourceCode .sh_name { color: #006400; }
|
|
|
|
/* for Prolog, Perl... */
|
|
pre.sh_sourceCode .sh_variable { color: #006400; }
|
|
|
|
/* for LaTeX */
|
|
pre.sh_sourceCode .sh_italics { color: #006400; font-style: italic; }
|
|
pre.sh_sourceCode .sh_bold { color: #006400; font-weight: bold; }
|
|
pre.sh_sourceCode .sh_underline { color: #006400; text-decoration: underline; }
|
|
pre.sh_sourceCode .sh_fixed { color: green; font-family: monospace; }
|
|
pre.sh_sourceCode .sh_argument { color: #006400; }
|
|
pre.sh_sourceCode .sh_optionalargument { color: purple; }
|
|
pre.sh_sourceCode .sh_math { color: orange; }
|
|
pre.sh_sourceCode .sh_bibtex { color: blue; }
|
|
|
|
/* for diffs */
|
|
pre.sh_sourceCode .sh_oldfile { color: orange; }
|
|
pre.sh_sourceCode .sh_newfile { color: #006400; }
|
|
pre.sh_sourceCode .sh_difflines { color: blue; }
|
|
|
|
/* for css */
|
|
pre.sh_sourceCode .sh_selector { color: purple; }
|
|
pre.sh_sourceCode .sh_property { color: blue; }
|
|
pre.sh_sourceCode .sh_value { color: #006400; font-style: italic; }
|
|
|
|
/* other */
|
|
pre.sh_sourceCode .sh_section { color: black; font-weight: bold; }
|
|
pre.sh_sourceCode .sh_paren { color: red; }
|
|
pre.sh_sourceCode .sh_attribute { color: #006400; }
|
|
|
|
</style><link href="http://www.w3.org/StyleSheets/TR/W3C-WD" rel="stylesheet" type="text/css" charset="utf-8" /></head>
|
|
|
|
<body style="display: inherit; "><div class="head"><p><a href="http://www.w3.org/"><img width="72" height="48" src="http://www.w3.org/Icons/w3c_home" alt="W3C" /></a></p><h1 class="title" id="title">WebRTC 1.0: Real-time Communication Between Browsers</h1><h2 id="w3c-working-draft-27-october-2011">W3C Working Draft 27 October 2011</h2><dl><dt>This version:</dt><dd><a href="http://www.w3.org/TR/2011/WD-webrtc-20111027/">http://www.w3.org/TR/2011/WD-webrtc-20111027/</a></dd><dt>Latest published version:</dt><dd><a href="http://www.w3.org/TR/webrtc/">http://www.w3.org/TR/webrtc/</a></dd><dt>Latest editor's draft:</dt><dd><a href="http://dev.w3.org/2011/webrtc/editor/webrtc.html">http://dev.w3.org/2011/webrtc/editor/webrtc.html</a></dd><dt>Previous version:</dt><dd>none</dd><dt>Editors:</dt><dd><span>Adam Bergkvist</span>, Ericsson</dd>
|
|
<dd><span>Daniel C. Burnett</span>, Voxeo</dd>
|
|
<dd><span>Cullen Jennings</span>, Cisco</dd>
|
|
<dd><span>Anant Narayanan</span>, Mozilla</dd>
|
|
</dl><p class="copyright">Initial Author of this Specification was Ian Hickson, Google Inc., with the following copyright statement:<br /> © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and Opera Software ASA. You are granted a license to use, reproduce and create derivative works of this document.</p> <p class="copyright">All subsequent changes since 26 July 2011 done by the W3C WebRTC Working Group are under the following <a href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a>:<br />© 2011 <a href="http://www.w3.org/"><acronym title="World Wide Web Consortium">W3C</acronym></a><sup>®</sup> (<a href="http://www.csail.mit.edu/"><acronym title="Massachusetts Institute of Technology">MIT</acronym></a>, <a href="http://www.ercim.eu/"><acronym title="European Research Consortium for Informatics and Mathematics">ERCIM</acronym></a>, <a href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved. <a href="http://www.w3.org/Consortium/Legal/copyright-documents">Document use</a> rules apply.</p> <p class="copyright">For the entire publication on the W3C site the <a href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a> and <a href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a> rules apply.</p><hr /></div>
|
|
<div id="abstract" class="introductory section"><h2>Abstract</h2>
|
|
<p>This document defines a set of APIs that allow local media, including audio and video, to be requested from a platform, media to be sent over the network to another browser or device implementing the appropriate set of real-time protocols, and media received from another browser or device to be processed and displayed locally. This specification is being developed in conjunction with a protocol specification developed by the IETF RTCWEB group.</p>
|
|
</div><div id="sotd" class="introductory section"><h2>Status of This Document</h2><p><em>This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the <a href="http://www.w3.org/TR/">W3C technical reports index</a> at http://www.w3.org/TR/.</em></p>
|
|
<p>This document is a First Public Working Draft and is not complete.
|
|
It is subject to major changes and, while early experimentations are
|
|
encouraged, it is therefore not intended for implementation. The API
|
|
is based on preliminary work done in the WHATWG. The Web Real-Time
|
|
Communications Working Group expects this specification to evolve
|
|
significantly based on:</p>
|
|
<ul>
|
|
<li>The outcomes of ongoing exchanges in the companion RTCWEB group
|
|
at IETF to define the set of protocols that, together with this
|
|
document, will enable real-time communications in Web browsers.</li>
|
|
<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>Experience gained through early experimentations.</li>
|
|
<li>Feedback received from other groups and individuals.</li>
|
|
</ul>
|
|
<p>As the specification matures, the group hopes to strike the right
|
|
balance between a low-level API that would enable interested parties
|
|
to tweak potentially complex system parameters, and a more high-level
|
|
API that Web developers can use without <em>a priori</em> technical
|
|
knowledge about real-time communications.</p>
|
|
<p>This document was published by the <a href="http://www.w3.org/2011/04/webrtc/">Web Real-Time Communications Working Group</a> as a Working Draft. This document is intended to become a W3C Recommendation. If you wish to make comments regarding this document, please send them to <a href="mailto:public-webrtc@w3.org">public-webrtc@w3.org</a> (<a href="mailto:public-webrtc-request@w3.org?subject=subscribe">subscribe</a>, <a href="http://lists.w3.org/Archives/Public/public-webrtc/">archives</a>). All feedback is welcome.</p><p>Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.</p><p>This document was produced by a group operating under the <a href="http://www.w3.org/Consortium/Patent-Policy-20040205/">5 February 2004 W3C Patent Policy</a>. W3C maintains a <a href="http://www.w3.org/2004/01/pp-impl/47318/status" rel="disclosure">public list of any patent disclosures</a> made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains <a href="http://www.w3.org/Consortium/Patent-Policy-20040205/#def-essential">Essential Claim(s)</a> must disclose the information in accordance with <a href="http://www.w3.org/Consortium/Patent-Policy-20040205/#sec-Disclosure">section 6 of the W3C Patent Policy</a>.</p></div><div id="toc" class="section"><h2 class="introductory">Table of Contents</h2><ul class="toc"><li class="tocline"><a href="#intro" class="tocxref"><span class="secno">1. </span>Introduction</a></li><li class="tocline"><a href="#local-content" class="tocxref"><span class="secno">2. </span>Obtaining local multimedia content</a><ul class="toc"><li class="tocline"><a href="#local-content-definition" class="tocxref"><span class="secno">2.1 </span>Definition</a><ul class="toc"><li class="tocline"><a href="#navigatorusermedia" class="tocxref"><span class="secno">2.1.1 </span>NavigatorUserMedia</a><ul class="toc"><li class="tocline"><a href="#methods" class="tocxref"><span class="secno">2.1.1.1 </span>Methods</a></li></ul></li><li class="tocline"><a href="#mediastreamoptions" class="tocxref"><span class="secno">2.1.2 </span>MediaStreamOptions</a><ul class="toc"><li class="tocline"><a href="#attributes" class="tocxref"><span class="secno">2.1.2.1 </span>Attributes</a></li></ul></li><li class="tocline"><a href="#navigatorusermediasuccesscallback" class="tocxref"><span class="secno">2.1.3 </span>NavigatorUserMediaSuccessCallback</a><ul class="toc"><li class="tocline"><a href="#methods-1" class="tocxref"><span class="secno">2.1.3.1 </span>Methods</a></li></ul></li><li class="tocline"><a href="#navigatorusermediaerror-and-navigatorusermediaerrorcallback" class="tocxref"><span class="secno">2.1.4 </span>NavigatorUserMediaError and NavigatorUserMediaErrorCallback</a><ul class="toc"><li class="tocline"><a href="#attributes-1" class="tocxref"><span class="secno">2.1.4.1 </span>Attributes</a></li><li class="tocline"><a href="#constants" class="tocxref"><span class="secno">2.1.4.2 </span>Constants</a></li><li class="tocline"><a href="#methods-2" class="tocxref"><span class="secno">2.1.4.3 </span>Methods</a></li></ul></li></ul></li><li class="tocline"><a href="#examples" class="tocxref"><span class="secno">2.2 </span>Examples</a></li></ul></li><li class="tocline"><a href="#stream-api" class="tocxref"><span class="secno">3. </span>Stream API</a><ul class="toc"><li class="tocline"><a href="#introduction" class="tocxref"><span class="secno">3.1 </span>Introduction</a></li><li class="tocline"><a href="#interface-definitions" class="tocxref"><span class="secno">3.2 </span>Interface definitions</a><ul class="toc"><li class="tocline"><a href="#mediastream" class="tocxref"><span class="secno">3.2.1 </span>MediaStream</a><ul class="toc"><li class="tocline"><a href="#attributes-2" class="tocxref"><span class="secno">3.2.1.1 </span>Attributes</a></li><li class="tocline"><a href="#methods-3" class="tocxref"><span class="secno">3.2.1.2 </span>Methods</a></li><li class="tocline"><a href="#constants-1" class="tocxref"><span class="secno">3.2.1.3 </span>Constants</a></li></ul></li><li class="tocline"><a href="#localmediastream" class="tocxref"><span class="secno">3.2.2 </span>LocalMediaStream</a><ul class="toc"><li class="tocline"><a href="#methods-4" class="tocxref"><span class="secno">3.2.2.1 </span>Methods</a></li></ul></li><li class="tocline"><a href="#mediastreamtrack" class="tocxref"><span class="secno">3.2.3 </span>MediaStreamTrack</a><ul class="toc"><li class="tocline"><a href="#attributes-3" class="tocxref"><span class="secno">3.2.3.1 </span>Attributes</a></li></ul></li><li class="tocline"><a href="#mediastreamrecorder" class="tocxref"><span class="secno">3.2.4 </span>MediaStreamRecorder</a><ul class="toc"><li class="tocline"><a href="#methods-5" class="tocxref"><span class="secno">3.2.4.1 </span>Methods</a></li></ul></li><li class="tocline"><a href="#blobcallback" class="tocxref"><span class="secno">3.2.5 </span>BlobCallback</a><ul class="toc"><li class="tocline"><a href="#methods-6" class="tocxref"><span class="secno">3.2.5.1 </span>Methods</a></li></ul></li><li class="tocline"><a href="#url" class="tocxref"><span class="secno">3.2.6 </span>URL</a><ul class="toc"><li class="tocline"><a href="#methods-7" class="tocxref"><span class="secno">3.2.6.1 </span>Methods</a></li></ul></li></ul></li><li class="tocline"><a href="#examples-1" class="tocxref"><span class="secno">3.3 </span>Examples</a></li></ul></li><li class="tocline"><a href="#peer-to-peer-connections" class="tocxref"><span class="secno">4. </span>Peer-to-peer connections</a><ul class="toc"><li class="tocline"><a href="#peerconnection" class="tocxref"><span class="secno">4.1 </span>PeerConnection</a><ul class="toc"><li class="tocline"><a href="#attributes-4" class="tocxref"><span class="secno">4.1.1 </span>Attributes</a></li><li class="tocline"><a href="#methods-8" class="tocxref"><span class="secno">4.1.2 </span>Methods</a></li><li class="tocline"><a href="#constants-2" class="tocxref"><span class="secno">4.1.3 </span>Constants</a></li></ul></li><li class="tocline"><a href="#signalingcallback" class="tocxref"><span class="secno">4.2 </span>SignalingCallback</a><ul class="toc"><li class="tocline"><a href="#methods-9" class="tocxref"><span class="secno">4.2.1 </span>Methods</a></li></ul></li><li class="tocline"><a href="#examples-2" class="tocxref"><span class="secno">4.3 </span>Examples</a></li></ul></li><li class="tocline"><a href="#the-data-stream" class="tocxref"><span class="secno">5. </span>The data stream</a></li><li class="tocline"><a href="#garbage-collection" class="tocxref"><span class="secno">6. </span>Garbage collection</a></li><li class="tocline"><a href="#event-definitions" class="tocxref"><span class="secno">7. </span>Event definitions</a><ul class="toc"><li class="tocline"><a href="#mediastreamevent" class="tocxref"><span class="secno">7.1 </span>MediaStreamEvent</a><ul class="toc"><li class="tocline"><a href="#attributes-5" class="tocxref"><span class="secno">7.1.1 </span>Attributes</a></li><li class="tocline"><a href="#methods-10" class="tocxref"><span class="secno">7.1.2 </span>Methods</a></li></ul></li></ul></li><li class="tocline"><a href="#event-summary" class="tocxref"><span class="secno">8. </span>Event summary</a></li><li class="tocline"><a href="#application-html-peer-connection-data" class="tocxref"><span class="secno">9. </span>application/html-peer-connection-data</a></li><li class="tocline"><a href="#acknowledgements" class="tocxref"><span class="secno">A. </span>Acknowledgements</a></li><li class="tocline"><a href="#references" class="tocxref"><span class="secno">B. </span>References</a><ul class="toc"><li class="tocline"><a href="#normative-references" class="tocxref"><span class="secno">B.1 </span>Normative references</a></li><li class="tocline"><a href="#informative-references" class="tocxref"><span class="secno">B.2 </span>Informative references</a></li></ul></li></ul></div>
|
|
|
|
|
|
|
|
<div id="intro" class="informative section">
|
|
|
|
<!-- OddPage -->
|
|
<h2><span class="secno">1. </span>Introduction</h2><p><em>This section is non-normative.</em></p>
|
|
|
|
<p>There are a number of facets to video-conferencing in HTML:</p>
|
|
|
|
<ul>
|
|
<li>Getting 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>Recording such streams locally.</li>
|
|
|
|
<li>Connecting to remote peers using NAT-traversal technologies such as ICE, STUN,
|
|
and TURN.</li>
|
|
|
|
<li>Sending the locally-produced streams to remote peers and receiving streams from
|
|
remote peers.</li>
|
|
|
|
<li>Displaying such streams (both the locally-produced ones and the remotely-obtained
|
|
ones) locally using the <code>video</code> or <code>audio</code> elements.</li>
|
|
|
|
<li>Sending arbitrary data to remote peers.</li>
|
|
</ul>
|
|
|
|
<p>This document defines the APIs used for these features. This specification is being developed in conjunction with a protocol specification developed by the <a href="http://datatracker.ietf.org/wg/rtcweb/">IETF RTCWEB group</a>.</p>
|
|
</div>
|
|
|
|
<div id="local-content" class="section">
|
|
|
|
<!-- OddPage -->
|
|
<h2><span class="secno">2. </span>Obtaining local multimedia content</h2>
|
|
|
|
<div id="local-content-definition" class="section">
|
|
<h3><span class="secno">2.1 </span>Definition</h3>
|
|
|
|
<div id="navigatorusermedia" class="section">
|
|
<h4><span class="secno">2.1.1 </span>NavigatorUserMedia</h4>
|
|
|
|
<pre class="idl"><span class="idlInterface" id="idl-def-NavigatorUserMedia">[<span class="extAttr">NoInterfaceObject</span>]
|
|
interface <span class="idlInterfaceID">NavigatorUserMedia</span> {
|
|
<span class="idlMethod"> <span class="idlMethType"><a>void</a></span> <span class="idlMethName"><a href="#widl-NavigatorUserMedia-getUserMedia-void-MediaStreamOptions-options-NavigatorUserMediaSuccessCallback-successCallback-NavigatorUserMediaErrorCallback-errorCallback">getUserMedia</a></span> (<span class="idlParam"><span class="idlParamType"><a href="#idl-def-MediaStreamOptions" class="idlType"><code>MediaStreamOptions</code></a>?</span> <span class="idlParamName">options</span></span>, <span class="idlParam"><span class="idlParamType"><a href="#idl-def-NavigatorUserMediaSuccessCallback" class="idlType"><code>NavigatorUserMediaSuccessCallback</code></a>?</span> <span class="idlParamName">successCallback</span></span>, <span class="idlParam">optional <span class="idlParamType"><a href="#idl-def-NavigatorUserMediaErrorCallback" class="idlType"><code>NavigatorUserMediaErrorCallback</code></a>?</span> <span class="idlParamName">errorCallback</span></span>);</span>
|
|
};</span>
|
|
</pre><div id="methods" class="section"><h5><span class="secno">2.1.1.1 </span>Methods</h5><dl class="methods"><dt id="widl-NavigatorUserMedia-getUserMedia-void-MediaStreamOptions-options-NavigatorUserMediaSuccessCallback-successCallback-NavigatorUserMediaErrorCallback-errorCallback"><code>getUserMedia</code></dt><dd>
|
|
<p>Prompts the user for permission to use their Web cam or other video or audio
|
|
input.</p>
|
|
|
|
<p>The <var title="">options</var> argument is an object of type
|
|
<code title="">MediaStreamOptions</code>. The object can contain
|
|
the following boolean properties:
|
|
</p>
|
|
|
|
<dl>
|
|
<dt>"<code title="">audio</code>"</dt>
|
|
<dd>The provided media needs to include audio data.</dd>
|
|
|
|
<dt>"<code title="">video</code>"</dt>
|
|
<dd>The provided media needs to include video data.</dd>
|
|
</dl>
|
|
|
|
<p>If the user accepts, the <var title="">successCallback</var> is invoked, with a
|
|
suitable <code><a href="#localmediastream">LocalMediaStream</a></code> object as
|
|
its argument.</p>
|
|
|
|
<p>If the user declines, the <var title="">errorCallback</var> (if any) is
|
|
invoked.</p>
|
|
|
|
<p>When the <a href="#widl-NavigatorUserMedia-getUserMedia-void-MediaStreamOptions-options-NavigatorUserMediaSuccessCallback-successCallback-NavigatorUserMediaErrorCallback-errorCallback">
|
|
<code>getUserMedia()</code></a> method is called, the user agent must run the
|
|
following steps:</p>
|
|
|
|
<ol>
|
|
<li>
|
|
<p>Let <var title="">options</var> be the method's first argument.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Let <var title="">successCallback</var> be the callback indicated by the
|
|
method's second argument.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Let <var title="">errorCallback</var> be the callback indicated by the
|
|
method's third argument, if any, or null otherwise.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>If <var title="">successCallback</var> is null, abort these steps.</p>
|
|
</li>
|
|
<!-- we could throw an exception instead (that's
|
|
why the method doesn't return until later: so that we can add an
|
|
exception here, or for /options/ below, without changing the
|
|
algorithm) -->
|
|
|
|
|
|
<li>
|
|
<p>Let <var title="">audio</var> be true.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Let <var title="">video</var> be true.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>If the <var title="">audio</var> property in <var title="">options</var>
|
|
is present and set to false, let <var title="">audio</var> be false.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>If the <var title="">video</var> property in <var title="">options</var>
|
|
is present and set to false, let <var title="">video</var> be false.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>If both <var title="">audio</var> and <var title="">video</var> are still
|
|
false, then throw a <code>NOT_SUPPORTED_ERR</code> exception and abort these
|
|
steps.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Return, and run the remaining steps asynchronously.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Optionally, e.g. based on a previously-established user preference, for
|
|
security reasons, or due to platform limitations, jump to the step labeled
|
|
<em>failure</em> below.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Prompt the user in a user-agent-specific manner for permission to provide
|
|
the entry script's origin with a <code><a href="#localmediastream">LocalMediaStream</a></code> object representing a media
|
|
stream.</p>
|
|
|
|
<p>If <var title="">audio</var> is true, then the provided media should include
|
|
an audio track. If <var title="">audio</var> is false, then the provided media
|
|
must not include an audio track.</p>
|
|
|
|
<p>If <var title="">video</var> is true, then the provided media should include
|
|
a video track. If <var title="">video</var> is false, then the provided media
|
|
must not include a video track.</p>
|
|
|
|
<p>User agents are encouraged to default to using the user's primary or system
|
|
default camera and/or microphone (as appropriate) to generate the media stream.
|
|
User agents may allow users to use any media source, including pre-recorded
|
|
media files.</p>
|
|
|
|
<p>User agents may wish to offer the user more control over the provided media.
|
|
For example, a user agent could offer to enable a camera light or flash, or to
|
|
change settings such as the frame rate or shutter speed.</p>
|
|
|
|
<p>If the user grants permission to use local recording devices, user agents
|
|
are encouraged to include a prominent indicator that the devices are "hot"
|
|
(i.e. an "on-air" or "recording" indicator).</p>
|
|
|
|
<p>If the user denies permission, jump to the step labeled <em>failure</em>
|
|
below. If the user never responds, this algorithm stalls on this step.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Let <var title="">stream</var> be the <code><a href="#localmediastream">LocalMediaStream</a></code> object for which the user
|
|
granted permission.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Queue a task to invoke <var title="">successCallback</var> with
|
|
<var title="">stream</var> as its argument.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Abort these steps.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p><em>Failure</em>: If <var title="">errorCallback</var> is null, abort these
|
|
steps.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Let <var title="">error</var> be a new <code><a href="#navigatorusermediaerror-and-navigatorusermediaerrorcallback">NavigatorUserMediaError</a></code> object whose
|
|
<code title="dom-NavigatorUserMediaError-code"><a href="#widl-NavigatorUserMediaError-code">code</a></code> attribute has the numeric
|
|
value 1 (<code title="dom-NavigatorUserMediaError-PERMISSION_DENIED"><a href="#widl-NavigatorUserMediaError-PERMISSION_DENIED">PERMISSION_DENIED</a></code>).</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Queue a task to invoke <var title="">errorCallback</var> with
|
|
<var title="">error</var> as its argument.</p>
|
|
</li>
|
|
</ol>
|
|
|
|
<p>The task source for these <span title="concept-task">tasks</span>
|
|
is the user interaction task source.</p>
|
|
<table class="parameters"><tr><th>Parameter</th><th>Type</th><th>Nullable</th><th>Optional</th><th>Description</th></tr><tr><td class="prmName">options</td><td class="prmType"><code><a href="#idl-def-MediaStreamOptions" class="idlType"><code>MediaStreamOptions</code></a></code></td><td class="prmNullTrue">✔</td><td class="prmOptFalse">✘</td><td class="prmDesc"></td></tr><tr><td class="prmName">successCallback</td><td class="prmType"><code><a href="#idl-def-NavigatorUserMediaSuccessCallback" class="idlType"><code>NavigatorUserMediaSuccessCallback</code></a></code></td><td class="prmNullTrue">✔</td><td class="prmOptFalse">✘</td><td class="prmDesc"></td></tr><tr><td class="prmName">errorCallback</td><td class="prmType"><code><a href="#idl-def-NavigatorUserMediaErrorCallback" class="idlType"><code>NavigatorUserMediaErrorCallback</code></a></code></td><td class="prmNullTrue">✔</td><td class="prmOptTrue">✔</td><td class="prmDesc"></td></tr></table><div><em>No exceptions.</em></div><div><em>Return type: </em><code><a>void</a></code></div></dd></dl></div>
|
|
|
|
<pre class="idl"><span class="idlImplements"><a>Navigator</a> implements <a href="#idl-def-NavigatorUserMedia" class="idlType"><code>NavigatorUserMedia</code></a>;</span></pre><div class="idlImplementsDesc"><p>All instances of the <code><a>Navigator</a></code> type are defined to also implement the <a href="#idl-def-NavigatorUserMedia" class="idlType"><code>NavigatorUserMedia</code></a> interface.</p></div>
|
|
</div>
|
|
|
|
<div id="mediastreamoptions" class="section">
|
|
<h4><span class="secno">2.1.2 </span>MediaStreamOptions</h4>
|
|
|
|
<pre class="idl"><span class="idlInterface" id="idl-def-MediaStreamOptions">[<span class="extAttr">NoInterfaceObject</span>]
|
|
interface <span class="idlInterfaceID">MediaStreamOptions</span> {
|
|
<span class="idlAttribute"> attribute <span class="idlAttrType"><a>boolean</a></span> <span class="idlAttrName"><a href="#widl-MediaStreamOptions-audio">audio</a></span>;</span>
|
|
<span class="idlAttribute"> attribute <span class="idlAttrType"><a>boolean</a></span> <span class="idlAttrName"><a href="#widl-MediaStreamOptions-video">video</a></span>;</span>
|
|
};</span>
|
|
</pre><div id="attributes" class="section"><h5><span class="secno">2.1.2.1 </span>Attributes</h5><dl class="attributes"><dt id="widl-MediaStreamOptions-audio"><code>audio</code> of type <span class="idlAttrType"><a>boolean</a></span></dt><dd>Set to false if an audio track is not required, default is true<div><em>No exceptions.</em></div></dd><dt id="widl-MediaStreamOptions-video"><code>video</code> of type <span class="idlAttrType"><a>boolean</a></span></dt><dd>Set to false if a video track is not required, default is true<div><em>No exceptions.</em></div></dd></dl></div>
|
|
</div>
|
|
|
|
<div id="navigatorusermediasuccesscallback" class="section">
|
|
<h4><span class="secno">2.1.3 </span>NavigatorUserMediaSuccessCallback</h4>
|
|
|
|
<pre class="idl"><span class="idlInterface" id="idl-def-NavigatorUserMediaSuccessCallback">[<span class="extAttr">Callback=FunctionOnly, NoInterfaceObject</span>]
|
|
interface <span class="idlInterfaceID">NavigatorUserMediaSuccessCallback</span> {
|
|
<span class="idlMethod"> <span class="idlMethType"><a>void</a></span> <span class="idlMethName"><a href="#widl-NavigatorUserMediaSuccessCallback-handleEvent-void-LocalMediaStream-stream">handleEvent</a></span> (<span class="idlParam"><span class="idlParamType"><a href="#idl-def-LocalMediaStream" class="idlType"><code>LocalMediaStream</code></a></span> <span class="idlParamName">stream</span></span>);</span>
|
|
};</span>
|
|
</pre><div id="methods-1" class="section"><h5><span class="secno">2.1.3.1 </span>Methods</h5><dl class="methods"><dt id="widl-NavigatorUserMediaSuccessCallback-handleEvent-void-LocalMediaStream-stream"><code>handleEvent</code></dt><dd>(Explanation of handleEvent TBD)<table class="parameters"><tr><th>Parameter</th><th>Type</th><th>Nullable</th><th>Optional</th><th>Description</th></tr><tr><td class="prmName">stream</td><td class="prmType"><code><a href="#idl-def-LocalMediaStream" class="idlType"><code>LocalMediaStream</code></a></code></td><td class="prmNullFalse">✘</td><td class="prmOptFalse">✘</td><td class="prmDesc"></td></tr></table><div><em>No exceptions.</em></div><div><em>Return type: </em><code><a>void</a></code></div></dd></dl></div>
|
|
</div>
|
|
|
|
<div id="navigatorusermediaerror-and-navigatorusermediaerrorcallback" class="section">
|
|
<h4><span class="secno">2.1.4 </span>NavigatorUserMediaError and NavigatorUserMediaErrorCallback</h4>
|
|
|
|
<pre class="idl"><span class="idlInterface" id="idl-def-NavigatorUserMediaError">[<span class="extAttr">NoInterfaceObject</span>]
|
|
interface <span class="idlInterfaceID">NavigatorUserMediaError</span> {
|
|
<span class="idlConst"> const <span class="idlConstType"><a>unsigned short</a></span> <span class="idlConstName"><a href="#widl-NavigatorUserMediaError-PERMISSION_DENIED">PERMISSION_DENIED</a></span> = <span class="idlConstValue">1</span>;</span>
|
|
<span class="idlAttribute"> readonly attribute <span class="idlAttrType"><a>unsigned short</a></span> <span class="idlAttrName"><a href="#widl-NavigatorUserMediaError-code">code</a></span>;</span>
|
|
};</span>
|
|
</pre><div id="attributes-1" class="section"><h5><span class="secno">2.1.4.1 </span>Attributes</h5><dl class="attributes"><dt id="widl-NavigatorUserMediaError-code"><code>code</code> of type <span class="idlAttrType"><a>unsigned short</a></span>, readonly</dt><dd>Returns the current error's error code. At this time, this will always be 1, for
|
|
which the constant <code title="dom-NavigatorUserMediaError-PERMISSION_DENIED"><a href="#widl-NavigatorUserMediaError-PERMISSION_DENIED">PERMISSION_DENIED</a></code> is
|
|
defined.<div><em>No exceptions.</em></div></dd></dl></div><div id="constants" class="section"><h5><span class="secno">2.1.4.2 </span>Constants</h5><dl class="constants"><dt id="widl-NavigatorUserMediaError-PERMISSION_DENIED"><code>PERMISSION_DENIED</code> of type <span class="idlConstType"><a>unsigned short</a></span></dt><dd>The user denied the page permission to use the user's media devices.</dd></dl></div>
|
|
|
|
<pre class="idl"><span class="idlInterface" id="idl-def-NavigatorUserMediaErrorCallback">[<span class="extAttr">Callback=FunctionOnly, NoInterfaceObject</span>]
|
|
interface <span class="idlInterfaceID">NavigatorUserMediaErrorCallback</span> {
|
|
<span class="idlMethod"> <span class="idlMethType"><a>void</a></span> <span class="idlMethName"><a href="#widl-NavigatorUserMediaErrorCallback-handleEvent-void-NavigatorUserMediaError-error">handleEvent</a></span> (<span class="idlParam"><span class="idlParamType"><a href="#idl-def-NavigatorUserMediaError" class="idlType"><code>NavigatorUserMediaError</code></a></span> <span class="idlParamName">error</span></span>);</span>
|
|
};</span>
|
|
</pre><div id="methods-2" class="section"><h5><span class="secno">2.1.4.3 </span>Methods</h5><dl class="methods"><dt id="widl-NavigatorUserMediaErrorCallback-handleEvent-void-NavigatorUserMediaError-error"><code>handleEvent</code></dt><dd>(Explanation of handleEvent TBD)<table class="parameters"><tr><th>Parameter</th><th>Type</th><th>Nullable</th><th>Optional</th><th>Description</th></tr><tr><td class="prmName">error</td><td class="prmType"><code><a href="#idl-def-NavigatorUserMediaError" class="idlType"><code>NavigatorUserMediaError</code></a></code></td><td class="prmNullFalse">✘</td><td class="prmOptFalse">✘</td><td class="prmDesc"></td></tr></table><div><em>No exceptions.</em></div><div><em>Return type: </em><code><a>void</a></code></div></dd></dl></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="examples" class="section">
|
|
<h3><span class="secno">2.2 </span>Examples</h3>
|
|
|
|
<div class="example">
|
|
<p>A voice chat feature in a game could attempt to get access to the user's
|
|
microphone by calling the API as follows:</p>
|
|
<pre><script>
|
|
navigator.getUserMedia('audio', gotAudio);
|
|
function gotAudio(stream) {
|
|
// ... use 'stream' ...
|
|
}
|
|
</script>
|
|
</pre>
|
|
</div>
|
|
|
|
<div class="example">
|
|
<p>A video-conferencing system would ask for both audio and video:</p>
|
|
<pre><script>
|
|
function beginCall() {
|
|
navigator.getUserMedia('audio,video user', gotStream);
|
|
}
|
|
function gotStream(stream) {
|
|
// ... use 'stream' ...
|
|
}
|
|
</script>
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="stream-api" class="section">
|
|
|
|
<!-- OddPage -->
|
|
<h2><span class="secno">3. </span>Stream API</h2>
|
|
|
|
<div id="introduction" class="section">
|
|
<h3><span class="secno">3.1 </span>Introduction</h3>
|
|
|
|
<p>The <code><a href="#mediastream">MediaStream</a></code> interface is used to
|
|
represent streams of media data, typically (but not necessarily) of audio and/or video
|
|
content, e.g. from a local camera or a remote site. The data from a <code><a href="#mediastream">MediaStream</a></code> object does not necessarily have a canonical
|
|
binary form; for example, it could just be "the video currently coming from the user's
|
|
video camera". This allows user agents to manipulate media streams in whatever fashion
|
|
is most suitable on the user's platform.</p>
|
|
|
|
<p>Each <code><a href="#mediastream">MediaStream</a></code> object can represent zero
|
|
or more tracks, in particular audio and video tracks. Tracks can contain multiple
|
|
channels of parallel data; for example a single audio track could have nine channels of
|
|
audio data to represent a 7.2 surround sound audio track.</p>
|
|
|
|
<p>Each track represented by a <code><a href="#mediastream">MediaStream</a></code>
|
|
object has a corresponding <code><a href="#mediastreamtrack">MediaStreamTrack</a></code> object.</p>
|
|
|
|
<p>A <code><a href="#mediastream">MediaStream</a></code> object has an input and an
|
|
output. The input depends on how the object was created: a <code><a href="#localmediastream">LocalMediaStream</a></code> object generated by a <code title="dom-navigator-getUserMedia"><a href="#widl-NavigatorUserMedia-getUserMedia-void-MediaStreamOptions-options-NavigatorUserMediaSuccessCallback-successCallback-NavigatorUserMediaErrorCallback-errorCallback">getUserMedia()</a></code> call, for instance, might take
|
|
its input from the user's local camera, while a <code><a href="#mediastream">MediaStream</a></code> created by a <code><a href="#peerconnection">PeerConnection</a></code> object will take as input the data received
|
|
from a remote peer. The output of the object controls how the object is used, e.g. what
|
|
is saved if the object is written to a file, what is displayed if the object is used in
|
|
a <code>video</code> element, or indeed what is transmitted to a remote peer if the
|
|
object is used with a <code><a href="#peerconnection">PeerConnection</a></code>
|
|
object.</p>
|
|
|
|
<p>Each track in a <code><a href="#mediastream">MediaStream</a></code> object can be
|
|
disabled, meaning that it is muted in the object's output. All tracks are initially
|
|
enabled.</p>
|
|
|
|
<p id="finishedMute">A <code><a href="#mediastream">MediaStream</a></code> can be
|
|
<a href="#concept-stream-finished" title="concept-stream-finished">finished</a>,
|
|
indicating that its inputs have forever stopped providing data. When a <code><a href="#mediastream">MediaStream</a></code> object is finished, all its tracks are muted
|
|
regardless of whether they are enabled or disabled.</p>
|
|
|
|
<p>The output of a <code><a href="#mediastream">MediaStream</a></code> object must
|
|
correspond to the tracks in its input. Muted audio tracks must be replaced with
|
|
silence. Muted video tracks must be replaced with blackness.</p>
|
|
|
|
<p>A new <code><a href="#mediastream">MediaStream</a></code> object can be created
|
|
from a list of <code><a href="#mediastreamtrack">MediaStreamTrack</a></code> objects
|
|
using the <code title="dom-MediaStream"><a href="#dom-mediastream">MediaStream()</a>
|
|
</code> constructor. The list of <code><a href="#mediastreamtrack">MediaStreamTrack</a>
|
|
</code> objects can be the track list of another stream, a subset of the track list of
|
|
a stream or a composition of <code><a href="#mediastreamtrack">MediaStreamTrack</a>
|
|
</code> objects from different <code><a href="#mediastream">MediaStream</a></code> objects.
|
|
|
|
</p><p><img alt="" src="images/media-stream-1.png" /></p>
|
|
<!-- no alt since
|
|
it's all described in the previous paragraphs: this is just a
|
|
summary -->
|
|
|
|
|
|
<!--
|
|
c.clearRect(0, 0, 640, 480);
|
|
c.save();
|
|
try {
|
|
with (c) {
|
|
save();
|
|
strokeStyle = '#AA0000';
|
|
lineWidth = 20;
|
|
beginPath();
|
|
moveTo(50,98);
|
|
lineTo(550, 98);
|
|
stroke();
|
|
}
|
|
mediaStream(c,50,10, true);
|
|
|
|
} finally {
|
|
c.restore();
|
|
}
|
|
|
|
function cameraIcon(c,x,y) {
|
|
with (c) { save(); try {
|
|
translate(x,y);
|
|
fillRect(-10,-10,20,20);
|
|
beginPath();
|
|
moveTo(7,0);
|
|
lineTo(20,-10);
|
|
lineTo(20,10);
|
|
fill();
|
|
font = '100 8px "Press Start 2P", sans-serif';
|
|
textAlign = 'center';
|
|
textBaseline = 'top';
|
|
fillText('Camera', 4, 15);
|
|
} finally { restore(); } }
|
|
}
|
|
|
|
function mediaStream(c,x,y,vid) {
|
|
with (c) {
|
|
save();
|
|
translate(x-10,y-97);
|
|
|
|
// cable
|
|
fillStyle = 'black';
|
|
font = '100 10px "Press Start 2P", sans-serif';
|
|
textAlign = 'right';
|
|
fillText('Input', 95, 170);
|
|
textAlign = 'left';
|
|
fillText('Output', 407, 170);
|
|
|
|
// media stream
|
|
fillStyle = '#EE8800';
|
|
strokeStyle = '#FFCC00';
|
|
lineWidth = 6;
|
|
fillRect(100,100,300,170);
|
|
strokeRect(100,100,300,170);
|
|
fillStyle = 'black';
|
|
font = '900 12px "Press Start 2P", sans-serif';
|
|
textAlign = 'left';
|
|
fillText('MediaStream', 110, 123);
|
|
|
|
// tracks
|
|
textAlign = 'left';
|
|
strokeStyle = '#CC3300';
|
|
fillStyle = '#FFFF00';
|
|
lineWidth = 4;
|
|
globalAlpha = vid ? 1 : 0.4;
|
|
fillRect(120,140,100,110);
|
|
strokeRect(120,140,100,110);
|
|
globalAlpha = 1;
|
|
fillRect(238,140,100,110);
|
|
strokeRect(238,140,100,110);
|
|
fillStyle = 'black';
|
|
font = '900 10px "Press Start 2P", sans-serif';
|
|
globalAlpha = vid ? 1 : 0.4;
|
|
fillText('Track', 123, 155);
|
|
fillText('(video)', 123, 170);
|
|
globalAlpha = 1;
|
|
fillText('Track', 241, 155);
|
|
fillText('(stereo', 241, 170);
|
|
fillText(' audio)', 241, 185);
|
|
|
|
// channels
|
|
strokeStyle = '#999999';
|
|
fillStyle = '#FFFFFF';
|
|
lineWidth = 2;
|
|
fillRect(245,191,86,23);
|
|
strokeRect(245,191,86,23);
|
|
fillRect(245,220,86,23);
|
|
strokeRect(245,220,86,23);
|
|
fillStyle = 'black';
|
|
font = '100 8px "Press Start 2P", sans-serif';
|
|
textAlign = 'left';
|
|
textBaseline = 'alphabetic';
|
|
fillText('left', 249, 202);
|
|
fillText('channel', 249, 211);
|
|
fillText('right', 249, 231);
|
|
fillText('channel', 249, 240);
|
|
|
|
// track check marks
|
|
fillStyle = 'black';
|
|
font = '900 35px "Lucida Grande", sans-serif';
|
|
textAlign = 'center';
|
|
textBaseline = 'middle';
|
|
fillText(vid ? '\u2713' : '\u2716', 220, 245);
|
|
fillText('\u2713', 338, 245);
|
|
|
|
restore();
|
|
}
|
|
}
|
|
-->
|
|
|
|
|
|
<p>The ability to duplicate a <code><a href="#mediastream">MediaStream</a></code>, i.e.
|
|
create a new <code><a href="#mediastream">MediaStream</a></code> object from the track
|
|
list of an existing stream, allows for greater control since separate <code>
|
|
<a href="#mediastream">MediaStream</a></code> instances can be manipulated and consumed
|
|
individually. This 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 <code><a href="#mediastream">MediaStream</a>
|
|
</code> objects into a new <code><a href="#mediastream">MediaStream</a></code> makes it
|
|
possible to, e.g., record selected tracks from a conversation involving several <code>
|
|
<a href="#mediastream">MediaStream</a></code> objects with a single <code>
|
|
<a href="#mediastreamrecorder">MediaStreamRecorder</a></code>.</p>
|
|
|
|
|
|
<!--
|
|
c.clearRect(0, 0, 640, 480);
|
|
c.save();
|
|
try {
|
|
with (c) {
|
|
save();
|
|
strokeStyle = '#AA0000';
|
|
lineWidth = 20;
|
|
beginPath();
|
|
moveTo(50,98);
|
|
lineTo(550, 98);
|
|
lineTo(550, 210);
|
|
lineTo(50, 210);
|
|
lineTo(50, 320);
|
|
lineTo(550, 320);
|
|
lineTo(550,420);
|
|
stroke();
|
|
beginPath();
|
|
moveTo(50,320);
|
|
lineTo(50,420);
|
|
stroke();
|
|
restore();
|
|
fillStyle = 'black';
|
|
font = '100 10px "Press Start 2P", sans-serif';
|
|
textAlign = 'center';
|
|
fillText('<video>', 50, 440);
|
|
fillText('PeerConnection', 550, 440);
|
|
font = '100 8px "Press Start 2P", sans-serif';
|
|
}
|
|
cameraIcon(c,25,98)
|
|
mediaStream(c,50,10, true);
|
|
mediaStream(c,50,233, false);
|
|
|
|
with (c) {
|
|
font = '100 8px "Press Start 2P", sans-serif';
|
|
textAlign = 'left';
|
|
textBaseline = 'middle';
|
|
fillStyle = 'gray';
|
|
|
|
fillText('from', 4, 130);
|
|
fillText('getUserMedia()', 4, 140);
|
|
|
|
fillText('via URL.getObjectURL()', 4, 450);
|
|
|
|
textAlign = 'center';
|
|
fillText('via addStream()', 550, 450);
|
|
}
|
|
} finally {
|
|
c.restore();
|
|
}
|
|
|
|
function cameraIcon(c,x,y) {
|
|
with (c) { save(); try {
|
|
translate(x,y);
|
|
fillRect(-10,-10,20,20);
|
|
beginPath();
|
|
moveTo(7,0);
|
|
lineTo(20,-10);
|
|
lineTo(20,10);
|
|
fill();
|
|
font = '100 8px "Press Start 2P", sans-serif';
|
|
textAlign = 'center';
|
|
textBaseline = 'top';
|
|
fillText('Camera', 4, 15);
|
|
} finally { restore(); } }
|
|
}
|
|
|
|
function mediaStream(c,x,y,vid) {
|
|
with (c) {
|
|
save();
|
|
translate(x-10,y-97);
|
|
|
|
// cable
|
|
fillStyle = 'black';
|
|
font = '100 10px "Press Start 2P", sans-serif';
|
|
textAlign = 'right';
|
|
fillText('Input', 95, 170);
|
|
textAlign = 'left';
|
|
fillText('Output', 407, 170);
|
|
|
|
// media stream
|
|
fillStyle = '#EE8800';
|
|
strokeStyle = '#FFCC00';
|
|
lineWidth = 6;
|
|
fillRect(100,100,300,170);
|
|
strokeRect(100,100,300,170);
|
|
fillStyle = 'black';
|
|
font = '900 12px "Press Start 2P", sans-serif';
|
|
textAlign = 'left';
|
|
fillText(!vid ? 'MediaStream' : 'LocalMediaStream', 110, 123);
|
|
|
|
// tracks
|
|
textAlign = 'left';
|
|
strokeStyle = '#CC3300';
|
|
fillStyle = '#FFFF00';
|
|
lineWidth = 4;
|
|
globalAlpha = vid ? 1 : 0.4;
|
|
fillRect(120,140,100,110);
|
|
strokeRect(120,140,100,110);
|
|
globalAlpha = 1;
|
|
fillRect(238,140,100,110);
|
|
strokeRect(238,140,100,110);
|
|
fillStyle = 'black';
|
|
font = '900 10px "Press Start 2P", sans-serif';
|
|
globalAlpha = vid ? 1 : 0.4;
|
|
fillText('Track', 123, 155);
|
|
fillText('(video)', 123, 170);
|
|
globalAlpha = 1;
|
|
fillText('Track', 241, 155);
|
|
fillText('(stereo', 241, 170);
|
|
fillText(' audio)', 241, 185);
|
|
|
|
// channels
|
|
strokeStyle = '#999999';
|
|
fillStyle = '#FFFFFF';
|
|
lineWidth = 2;
|
|
fillRect(245,191,86,23);
|
|
strokeRect(245,191,86,23);
|
|
fillRect(245,220,86,23);
|
|
strokeRect(245,220,86,23);
|
|
fillStyle = 'black';
|
|
font = '100 8px "Press Start 2P", sans-serif';
|
|
textAlign = 'left';
|
|
textBaseline = 'alphabetic';
|
|
fillText('left', 249, 202);
|
|
fillText('channel', 249, 211);
|
|
fillText('right', 249, 231);
|
|
fillText('channel', 249, 240);
|
|
|
|
// track check marks
|
|
fillStyle = 'black';
|
|
font = '900 35px "Lucida Grande", sans-serif';
|
|
textAlign = 'center';
|
|
textBaseline = 'middle';
|
|
fillText(vid ? '\u2713' : '\u2716', 220, 245);
|
|
fillText('\u2713', 338, 245);
|
|
|
|
restore();
|
|
}
|
|
}
|
|
-->
|
|
|
|
|
|
<p>The <code><a href="#localmediastream">LocalMediaStream</a></code> interface is used
|
|
when the user agent is generating the stream's data (e.g. from a camera or streaming it
|
|
from a local video file). It allows authors to control individual tracks during the
|
|
generation of the content, e.g. to allow the user to temporarily disable a local camera
|
|
during a video-conference chat.</p>
|
|
|
|
<p>When a <code><a href="#localmediastream">LocalMediaStream</a></code> object is being
|
|
generated from a local file (as opposed to a live audio/video source), the user agent
|
|
should stream the data from the file in real time, not all at once. This reduces the
|
|
ease with which pages can distinguish live video from pre-recorded video, which can
|
|
help protect the user's privacy.</p>
|
|
</div>
|
|
<div id="interface-definitions" class="section">
|
|
<h3><span class="secno">3.2 </span>Interface definitions</h3>
|
|
|
|
<div id="mediastream" class="section">
|
|
<h4><span class="secno">3.2.1 </span>MediaStream</h4>
|
|
|
|
<p>The <dfn id="dom-mediastream" title="dom-MediaStream"><code>MediaStream(<var title="">trackList</var>)</code></dfn> constructor must return a new <code><a href="#mediastream">MediaStream</a></code> object with a newly generated label.
|
|
A new <code><a href="#mediastreamtrack">MediaStreamTrack</a></code> object is created
|
|
for every unique underlying media source in <var title="">trackList</var> and appended
|
|
to the new <code><a href="#mediastream">MediaStream</a></code> object's track list
|
|
according to the track ordering constraints.
|
|
|
|
</p><p>A <code><a href="#mediastream">MediaStream</a></code> object is said to <em>end</em>
|
|
when the user agent learns that no more data will ever be forthcoming for this
|
|
stream.</p>
|
|
|
|
<p>When a <code><a href="#mediastream">MediaStream</a></code> object ends for any
|
|
reason (e.g. because the user rescinds the permission for the page to use the local
|
|
camera, or because the data comes from a finite file and the file's end has been
|
|
reached and the user has not requested that it be looped, or because the stream comes
|
|
from a remote peer and the remote peer has permanently stopped sending data, it is
|
|
said to be <dfn id="concept-stream-finished" title="concept-stream-finished">finished
|
|
</dfn>. When this happens for any reason other than the <code title="dom-MediaStream-stop">
|
|
<a href="#dom-mediastream-stop">stop()</a></code> method being invoked, the user agent must
|
|
queue a task that runs the following steps:</p>
|
|
|
|
<ol>
|
|
<li>
|
|
<p>If the object's <code title="dom-MediaStream-readyState"><a href="#dom-mediastream-readystate">readyState</a></code> attribute has the value
|
|
<code title="dom-MediaStream-ENDED"><a href="#widl-MediaStream-ENDED">ENDED</a></code> (2) already, then abort these steps. (The
|
|
<code title="dom-MediaStream-stop"><a href="#dom-mediastream-stop">stop()</a></code> method was probably called just before
|
|
the stream stopped for other reasons, e.g. the user clicked an in-page stop button
|
|
and then the user-agent-provided stop button.)</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Set the object's <code title="dom-MediaStream-readyState"><a href="#dom-mediastream-readystate">readyState</a></code> attribute to <code title="dom-MediaStream-ENDED"><a href="#widl-MediaStream-ENDED">ENDED</a></code> (2).</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Fire a simple event named <code title="event-MediaStream-ended"><a href="#event-mediastream-ended">ended</a></code> at
|
|
the object.</p>
|
|
</li>
|
|
</ol>
|
|
|
|
<p>As soon as a <code><a href="#mediastream">MediaStream</a></code> object is <a href="#concept-stream-finished" title="concept-stream-finished">finished</a>, the stream's
|
|
tracks start outputting only silence and/or blackness, as appropriate, <a href="#finishedMute">as defined earlier</a>.</p>
|
|
|
|
<p>If the end of the stream was reached due to a user request, the task
|
|
source for this <span title="concept-task">task</span> is the user
|
|
interaction task source. Otherwise the task source for this
|
|
<span title="concept-task">task</span> is the networking task source.</p>
|
|
|
|
<pre class="idl"><span class="idlInterface" id="idl-def-MediaStream">[<span class="extAttr">Constructor (in MediaStreamTrackList trackList)</span>]
|
|
interface <span class="idlInterfaceID">MediaStream</span> {
|
|
<span class="idlAttribute"> readonly attribute <span class="idlAttrType"><a>DOMString</a></span> <span class="idlAttrName"><a href="#widl-MediaStream-label">label</a></span>;</span>
|
|
<span class="idlAttribute"> readonly attribute <span class="idlAttrType"><a id="mediastreamtracklist">MediaStreamTrackList</a></span> <span class="idlAttrName"><a href="#widl-MediaStream-tracks">tracks</a></span>;</span>
|
|
<span class="idlMethod"> <span class="idlMethType"><a href="#idl-def-MediaStreamRecorder" class="idlType"><code>MediaStreamRecorder</code></a></span> <span class="idlMethName"><a href="#widl-MediaStream-record-MediaStreamRecorder">record</a></span> ();</span>
|
|
<span class="idlConst"> const <span class="idlConstType"><a>unsigned short</a></span> <span class="idlConstName"><a href="#widl-MediaStream-LIVE">LIVE</a></span> = <span class="idlConstValue">1</span>;</span>
|
|
<span class="idlConst"> const <span class="idlConstType"><a>unsigned short</a></span> <span class="idlConstName"><a href="#widl-MediaStream-ENDED">ENDED</a></span> = <span class="idlConstValue">2</span>;</span>
|
|
<span class="idlAttribute"> readonly attribute <span class="idlAttrType"><a>unsigned short</a></span> <span class="idlAttrName"><a href="#widl-MediaStream-readyState">readyState</a></span>;</span>
|
|
<span class="idlAttribute"> attribute <span class="idlAttrType"><a>Function</a>?</span> <span class="idlAttrName"><a href="#widl-MediaStream-onended">onended</a></span>;</span>
|
|
};</span>
|
|
</pre><div id="attributes-2" class="section"><h5><span class="secno">3.2.1.1 </span>Attributes</h5><dl class="attributes"><dt id="widl-MediaStream-label"><code>label</code> of type <span class="idlAttrType"><a>DOMString</a></span>, readonly</dt><dd>Returns a label that is unique to this stream, so that streams can be recognized
|
|
after they are sent through the <code><a href="#peerconnection">PeerConnection</a></code> API.<div><em>No exceptions.</em></div></dd><dt id="widl-MediaStream-onended"><code>onended</code> of type <span class="idlAttrType"><a>Function</a></span>, nullable</dt><dd>This event handler, of type <code title="event-MediaStream-ended"><a href="#event-mediastream-ended">ended</a></code>, must be supported by all objects
|
|
implementing the <code><a href="#mediastream">MediaStream</a></code> interface.<div><em>No exceptions.</em></div></dd><dt id="widl-MediaStream-readyState"><code>readyState</code> of type <span class="idlAttrType"><a>unsigned short</a></span>, readonly</dt><dd>
|
|
<p>The <dfn id="dom-mediastream-readystate" title="dom-MediaStream-readyState"><code>readyState</code></dfn> attribute represents the
|
|
state of the stream. It must return the value to which the user agent last set it
|
|
(as defined below). It can have the following values: <dfn id="dfn-live">LIVE</dfn> or
|
|
<dfn id="dfn-ended">ENDED</dfn>.</p>
|
|
|
|
<p>When a <code><a href="#mediastream">MediaStream</a></code> object is created,
|
|
its <code title="dom-MediaStream-readyState"><a href="#dom-mediastream-readystate">readyState</a></code> attribute must be set to
|
|
<code title="dom-MediaStream-LIVE"><a href="#widl-MediaStream-LIVE">LIVE</a></code>
|
|
(1), unless it is being created using the <code title="dom-MediaStream"><a href="#dom-mediastream">MediaStream()</a></code> constructor whose argument is a list of
|
|
<code><a href="#mediastreamtrack">MediaStreamTrack</a></code> objects whose underlying
|
|
media sources will never produce any more data, in which case the <code><a href="#mediastream">MediaStream</a></code> object must be created with its <code title="dom-MediaStream-readyState"><a href="#dom-mediastream-readystate">readyState</a></code> attribute set to <code title="dom-MediaStream-ENDED"><a href="#widl-MediaStream-ENDED">ENDED</a></code> (2).</p>
|
|
<div><em>No exceptions.</em></div></dd><dt id="widl-MediaStream-tracks"><code>tracks</code> of type <span class="idlAttrType"><a>MediaStreamTrackList</a></span>, readonly</dt><dd>
|
|
<p>Returns a <code><a href="#mediastreamtracklist">MediaStreamTrackList</a></code>
|
|
object representing the tracks that can be enabled and disabled.</p>
|
|
|
|
<p>A <code><a href="#mediastream">MediaStream</a></code> can have multiple audio
|
|
and video sources (e.g. because the user has multiple microphones, or because the
|
|
real source of the stream is a media resource with
|
|
many media tracks). The stream represented by a <code><a href="#mediastream">MediaStream</a></code> thus has zero or more tracks.</p>
|
|
|
|
<p>The <dfn id="dom-mediastream-tracks" title="dom-MediaStream-tracks"><code>tracks</code></dfn> attribute must return an
|
|
<span title="array host objects">array host object</span> for objects of type
|
|
<code><a href="#mediastreamtrack">MediaStreamTrack</a></code> that is <em>fixed
|
|
length</em> and <em>read only</em>. The same object must be returned each time the
|
|
attribute is accessed. [<cite><a class="bibref" rel="biblioentry" href="#bib-WEBIDL">WEBIDL</a></cite>]</p>
|
|
|
|
<p>The array must contain the <code><a href="#mediastreamtrack">MediaStreamTrack</a></code> objects that correspond to the the
|
|
tracks of the stream. The relative order of all tracks in a user agent must be
|
|
stable. All audio tracks must precede all video tracks. Tracks that come from a
|
|
media resource whose format defines an order must be
|
|
in the order defined by the format; tracks that come from a media resource whose format does not define an order must be
|
|
in the relative order in which the tracks are declared in that media resource. Within these constraints, the order is
|
|
user-agent defined.</p>
|
|
<div><em>No exceptions.</em></div></dd></dl></div><div id="methods-3" class="section"><h5><span class="secno">3.2.1.2 </span>Methods</h5><dl class="methods"><dt id="widl-MediaStream-record-MediaStreamRecorder"><code>record</code></dt><dd>
|
|
<p>Begins recording the stream. The returned <code><a href="#mediastreamrecorder">MediaStreamRecorder</a></code> object provides access to the
|
|
recorded data.</p>
|
|
|
|
<p>When the <dfn id="dom-mediastream-record" title="dom-MediaStream-record"><code>record()</code></dfn> method is invoked, the user
|
|
agent must return a new <code><a href="#mediastreamrecorder">MediaStreamRecorder</a></code> object associated with the
|
|
stream.</p>
|
|
<div><em>No parameters.</em></div><div><em>No exceptions.</em></div><div><em>Return type: </em><code><a href="#idl-def-MediaStreamRecorder" class="idlType"><code>MediaStreamRecorder</code></a></code></div></dd></dl></div><div id="constants-1" class="section"><h5><span class="secno">3.2.1.3 </span>Constants</h5><dl class="constants"><dt id="widl-MediaStream-ENDED"><code>ENDED</code> of type <span class="idlConstType"><a>unsigned short</a></span></dt><dd>The stream has finished (the user agent is no longer receiving or generating
|
|
data, and will never receive or generate more data for this stream).</dd><dt id="widl-MediaStream-LIVE"><code>LIVE</code> of type <span class="idlConstType"><a>unsigned short</a></span></dt><dd>The stream is active (the user agent is making a best-effort attempt to receive
|
|
or generate data in real time).</dd></dl></div>
|
|
|
|
<pre class="idl"><span class="idlImplements"><a href="#idl-def-MediaStream" class="idlType"><code>MediaStream</code></a> implements <a>EventTarget</a>;</span></pre><div class="idlImplementsDesc"><p>All instances of the <code><a href="#idl-def-MediaStream" class="idlType"><code>MediaStream</code></a></code> type are defined to also implement the <a>EventTarget</a> interface.</p></div>
|
|
</div>
|
|
|
|
<div id="localmediastream" class="section">
|
|
<h4><span class="secno">3.2.2 </span>LocalMediaStream</h4>
|
|
|
|
<pre class="idl"><span class="idlInterface" id="idl-def-LocalMediaStream">interface <span class="idlInterfaceID">LocalMediaStream</span> : <span class="idlSuperclass"><a href="#idl-def-MediaStream" class="idlType"><code>MediaStream</code></a></span> {
|
|
<span class="idlMethod"> <span class="idlMethType"><a>void</a></span> <span class="idlMethName"><a href="#widl-LocalMediaStream-stop-void">stop</a></span> ();</span>
|
|
};</span>
|
|
</pre><div id="methods-4" class="section"><h5><span class="secno">3.2.2.1 </span>Methods</h5><dl class="methods"><dt id="widl-LocalMediaStream-stop-void"><code>stop</code></dt><dd>
|
|
<p>When a <code><a href="#localmediastream">LocalMediaStream</a></code> object's
|
|
<dfn id="dom-mediastream-stop" title="dom-MediaStream-stop"><code>stop()</code></dfn> method is invoked, the user agent
|
|
must queue a task that runs the following steps:</p>
|
|
|
|
<ol>
|
|
<li>
|
|
<p>If the object's <code title="dom-MediaStream-readyState"><a href="#dom-mediastream-readystate">readyState</a></code> attribute is in the
|
|
<code title="dom-MediaStream-ENDED"><a href="#widl-MediaStream-ENDED">ENDED</a></code> (2) state, then abort these
|
|
steps.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Permanently stop the generation of data for the stream. If the data is being
|
|
generated from a live source (e.g. a microphone or camera), and no other stream
|
|
is being generated from a live source, then the user agent should remove any
|
|
active "on-air" indicator. If the data is being generated from a prerecorded
|
|
source (e.g. a video file), any remaining content in the file is ignored. The
|
|
stream is <a href="#concept-stream-finished" title="concept-stream-finished">finished</a>. The stream's tracks start outputting
|
|
only silence and/or blackness, as appropriate, <a href="#finishedMute">as
|
|
defined earlier</a>.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Set the object's <code title="dom-MediaStream-readyState"><a href="#dom-mediastream-readystate">readyState</a></code> attribute to <code title="dom-MediaStream-ENDED"><a href="#widl-MediaStream-ENDED">ENDED</a></code>
|
|
(2).</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Fire a simple event named <code title="event-MediaStream-ended"><a href="#event-mediastream-ended">ended</a></code>
|
|
at the object.</p>
|
|
</li>
|
|
</ol>
|
|
|
|
<p>The task source for the <span title="concept-task">tasks</span>
|
|
queued for the <code title="dom-MediaStream-stop"><a href="#dom-mediastream-stop">stop()</a></code> method is the DOM manipulation task
|
|
source.</p>
|
|
<div><em>No parameters.</em></div><div><em>No exceptions.</em></div><div><em>Return type: </em><code><a>void</a></code></div></dd></dl></div>
|
|
</div>
|
|
|
|
<div id="mediastreamtrack" class="section">
|
|
<h4><span class="secno">3.2.3 </span>MediaStreamTrack</h4>
|
|
|
|
<pre class="idl"><span class="idlTypedef" id="idl-def-MediaStreamTrackList">typedef <span class="idlTypedefType"><a href="#idl-def-MediaStreamTrack" class="idlType"><code>MediaStreamTrack</code></a></span>[] <span class="idlTypedefID">MediaStreamTrackList</span>;</span></pre><div class="idlTypedefDesc">Throughout this specification, the identifier <span class="idlTypedefID">MediaStreamTrackList</span> is used to refer to the array of <span class="idlTypedefType"><a href="#idl-def-MediaStreamTrack" class="idlType"><code>MediaStreamTrack</code></a></span> type.</div>
|
|
|
|
<pre class="idl"><span class="idlInterface" id="idl-def-MediaStreamTrack">interface <span class="idlInterfaceID">MediaStreamTrack</span> {
|
|
<span class="idlAttribute"> readonly attribute <span class="idlAttrType"><a>DOMString</a></span> <span class="idlAttrName"><a href="#widl-MediaStreamTrack-kind">kind</a></span>;</span>
|
|
<span class="idlAttribute"> readonly attribute <span class="idlAttrType"><a>DOMString</a></span> <span class="idlAttrName"><a href="#widl-MediaStreamTrack-label">label</a></span>;</span>
|
|
<span class="idlAttribute"> attribute <span class="idlAttrType"><a>boolean</a></span> <span class="idlAttrName"><a href="#widl-MediaStreamTrack-enabled">enabled</a></span>;</span>
|
|
};</span>
|
|
</pre><div id="attributes-3" class="section"><h5><span class="secno">3.2.3.1 </span>Attributes</h5><dl class="attributes"><dt id="widl-MediaStreamTrack-enabled"><code>enabled</code> of type <span class="idlAttrType"><a>boolean</a></span></dt><dd>
|
|
<p>The <dfn id="dom-mediastreamtrack-enabled" title="dom-MediaStreamTrack-enabled"><code>MediaStreamTrack.enabled</code></dfn>
|
|
attribute, on getting, must return the last value to which it was set. On setting,
|
|
it must be set to the new value, and then, if the <code><a href="#mediastreamtrack">MediaStreamTrack</a></code> object is still associated with a
|
|
track, must enable the track if the new value is true, and disable it
|
|
otherwise.</p>
|
|
|
|
<p class="note">Thus, after a <code><a href="#mediastreamtrack">MediaStreamTrack</a></code> is disassociated from its track,
|
|
its <code title="dom-MediaStreamTrack-enabled"><a href="#dom-mediastreamtrack-enabled">enabled</a></code> attribute still changes value
|
|
when set, it just doesn't do anything with that new value.</p>
|
|
<div><em>No exceptions.</em></div></dd><dt id="widl-MediaStreamTrack-kind"><code>kind</code> of type <span class="idlAttrType"><a>DOMString</a></span>, readonly</dt><dd>
|
|
<p>The <dfn id="dom-mediastreamtrack-kind" title="dom-MediaStreamTrack-kind"><code>MediaStreamTrack.kind</code></dfn> attribute must
|
|
return the string "<code title="""">audio</code>" if the object's corresponding
|
|
track is or was an audio track, "<code title="""">video</code>" if the
|
|
corresponding track is or was a video track, and a user-agent defined string
|
|
otherwise.</p>
|
|
<div><em>No exceptions.</em></div></dd><dt id="widl-MediaStreamTrack-label"><code>label</code> of type <span class="idlAttrType"><a>DOMString</a></span>, readonly</dt><dd>
|
|
<p>When a <code><a href="#localmediastream">LocalMediaStream</a></code> object is
|
|
created, the user agent must generate a globally unique identifier string, and must
|
|
initialize the object's <code title="dom-MediaStream-label"><a href="#dom-mediastream-label">label</a></code> attribute to that string. Such strings
|
|
must only use characters in the ranges U+0021, U+0023 to U+0027, U+002A to U+002B,
|
|
U+002D to U+002E, U+0030 to U+0039, U+0041 to U+005A, U+005E to U+007E, and must be
|
|
36 characters long.</p>
|
|
<!-- UUIDs have 36 characters
|
|
including hyphens; the ranges above comes from RFC4574 (the a=label:
|
|
thing in SDP) -->
|
|
|
|
|
|
<p>When a <code><a href="#mediastream">MediaStream</a></code> is created to
|
|
represent a stream obtained from a remote peer, the <code title="dom-MediaStream-label"><a href="#dom-mediastream-label">label</a></code> attribute
|
|
is initialized from information provided by the remote source.</p>
|
|
|
|
<!-- described below
|
|
-->
|
|
|
|
|
|
<p>When a <code><a href="#mediastream">MediaStream</a></code> is created from
|
|
another using the <code title="dom-MediaStream"><a href="#dom-mediastream">MediaStream()</a></code> constructor, the <code title="dom-MediaStream-label"><a href="#dom-mediastream-label">label</a></code> attribute
|
|
is initialized to a newly generated value.</p>
|
|
<!-- described above -->
|
|
|
|
|
|
<p>The <dfn id="dom-mediastream-label" title="dom-MediaStream-label"><code>label</code></dfn> attribute must return the value to
|
|
which it was initialized when the object was created.</p>
|
|
|
|
<p class="note">The label of a <code><a href="#mediastream">MediaStream</a></code>
|
|
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 to a remote peer using <code><a href="#peerconnection">PeerConnection</a></code>, and then sent back to the original
|
|
user in the same manner, in which case the original user will have multiple streams
|
|
with the same label (the locally-generated one and the one received from the remote
|
|
peer).</p>
|
|
|
|
<p>User agents may label audio and video sources (e.g. "Internal microphone" or
|
|
"External USB Webcam"). The <dfn id="dom-mediastreamtrack-label" title="dom-MediaStreamTrack-label"><code>MediaStreamTrack.label</code></dfn> attribute
|
|
must return the label of the object's corresponding track, if any. If the
|
|
corresponding track has or had no label, the attribute must instead return the
|
|
empty string.</p>
|
|
|
|
<p class="note">Thus the <code title="dom-MediaStreamTrack-kind"><a href="#dom-mediastreamtrack-kind">kind</a></code> and <code title="dom-MediaStreamTrack-label"><a href="#dom-mediastreamtrack-label">label</a></code>
|
|
attributes do not change value, even if the <code><a href="#mediastreamtrack">MediaStreamTrack</a></code> object is disassociated from its
|
|
corresponding track.</p>
|
|
<div><em>No exceptions.</em></div></dd></dl></div>
|
|
</div>
|
|
|
|
<div id="mediastreamrecorder" class="section">
|
|
<h4><span class="secno">3.2.4 </span>MediaStreamRecorder</h4>
|
|
|
|
<pre class="idl"><span class="idlInterface" id="idl-def-MediaStreamRecorder">interface <span class="idlInterfaceID">MediaStreamRecorder</span> {
|
|
<span class="idlMethod"> <span class="idlMethType"><a>voice</a></span> <span class="idlMethName"><a href="#widl-MediaStreamRecorder-getRecordedData-voice-BlobCallback-callback">getRecordedData</a></span> (<span class="idlParam"><span class="idlParamType"><a href="#idl-def-BlobCallback" class="idlType"><code>BlobCallback</code></a>?</span> <span class="idlParamName">callback</span></span>);</span>
|
|
};</span>
|
|
</pre><div id="methods-5" class="section"><h5><span class="secno">3.2.4.1 </span>Methods</h5><dl class="methods"><dt id="widl-MediaStreamRecorder-getRecordedData-voice-BlobCallback-callback"><code>getRecordedData</code></dt><dd>
|
|
<p>Creates a <code>Blob</code> of the recorded data, and invokes the provided
|
|
callback with that <code>Blob</code>.</p>
|
|
|
|
<p>When the <dfn id="dom-mediastreamrecorder-getrecordeddata" title="dom-MediaStreamRecorder-getRecordedData"><code>getRecordedData()</code></dfn>
|
|
method is called, the user agent must run the following steps:</p>
|
|
|
|
<ol>
|
|
<li>
|
|
<p>Let <var title="">callback</var> be the callback indicated by the method's
|
|
first argument.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>If <var title="">callback</var> is null, abort these steps.</p>
|
|
</li>
|
|
<!-- we could throw an exception instead (that's
|
|
why the method doesn't return until later: so that we can add an
|
|
exception here without changing the algorithm) -->
|
|
|
|
|
|
<li>
|
|
<p>Let <var title="">data</var> be the data that was streamed by the
|
|
<code><a href="#mediastream">MediaStream</a></code> object from which the
|
|
<code><a href="#mediastreamrecorder">MediaStreamRecorder</a></code> was created
|
|
since the creation of the <code><a href="#mediastreamrecorder">MediaStreamRecorder</a></code> object.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Return, and run the remaining steps asynchronously.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Generate a file that containing <var title="">data</var> in a format
|
|
supported by the user agent for use in <code>audio</code> and
|
|
<code>video</code> elements.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Let <var title="">blob</var> be a <code>Blob</code> object representing the
|
|
contents of the file generated in the previous step. [<cite><a class="bibref" rel="biblioentry" href="#bib-FILE-API">FILE-API</a></cite>]</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Queue a task to invoke <var title="">callback</var> with
|
|
<var title="">blob</var> as its argument.</p>
|
|
</li>
|
|
</ol>
|
|
|
|
<p class="note">The <code title="dom-MediaStreamRecorder-getRecordedData"><a href="#dom-mediastreamrecorder-getrecordeddata">getRecordedData()</a></code> method can
|
|
be called multiple times on one <code><a href="#mediastreamrecorder">MediaStreamRecorder</a></code> object; each time, it will
|
|
create a new file as if this was the first time the method was being called. In
|
|
particular, the method does not stop or reset the recording when the method is
|
|
called.</p>
|
|
<table class="parameters"><tr><th>Parameter</th><th>Type</th><th>Nullable</th><th>Optional</th><th>Description</th></tr><tr><td class="prmName">callback</td><td class="prmType"><code><a href="#idl-def-BlobCallback" class="idlType"><code>BlobCallback</code></a></code></td><td class="prmNullTrue">✔</td><td class="prmOptFalse">✘</td><td class="prmDesc"></td></tr></table><div><em>No exceptions.</em></div><div><em>Return type: </em><code><a>voice</a></code></div></dd></dl></div>
|
|
</div>
|
|
|
|
<div id="blobcallback" class="section">
|
|
<h4><span class="secno">3.2.5 </span>BlobCallback</h4>
|
|
|
|
<pre class="idl"><span class="idlInterface" id="idl-def-BlobCallback">[<span class="extAttr">Callback=FunctionOnly, NoInterfaceObject</span>]
|
|
interface <span class="idlInterfaceID">BlobCallback</span> {
|
|
<span class="idlMethod"> <span class="idlMethType"><a>void</a></span> <span class="idlMethName"><a href="#widl-BlobCallback-handleEvent-void-Blob-blob">handleEvent</a></span> (<span class="idlParam"><span class="idlParamType"><a>Blob</a></span> <span class="idlParamName">blob</span></span>);</span>
|
|
};</span>
|
|
</pre><div id="methods-6" class="section"><h5><span class="secno">3.2.5.1 </span>Methods</h5><dl class="methods"><dt id="widl-BlobCallback-handleEvent-void-Blob-blob"><code>handleEvent</code></dt><dd>Def TBD<table class="parameters"><tr><th>Parameter</th><th>Type</th><th>Nullable</th><th>Optional</th><th>Description</th></tr><tr><td class="prmName">blob</td><td class="prmType"><code><a>Blob</a></code></td><td class="prmNullFalse">✘</td><td class="prmOptFalse">✘</td><td class="prmDesc"></td></tr></table><div><em>No exceptions.</em></div><div><em>Return type: </em><code><a>void</a></code></div></dd></dl></div>
|
|
</div>
|
|
|
|
<div id="url" class="section">
|
|
<h4><span class="secno">3.2.6 </span>URL</h4>
|
|
|
|
<p><em>Note that the following is actually only a partial interface, but ReSpec does
|
|
not yet support that.</em></p>
|
|
|
|
<pre class="idl"><span class="idlInterface" id="idl-def-URL">interface <span class="idlInterfaceID">URL</span> {
|
|
<span class="idlMethod"> <span class="idlMethType"><a>static DOMString</a></span> <span class="idlMethName"><a href="#widl-URL-createObjectURL-static-DOMString-MediaStream-stream">createObjectURL</a></span> (<span class="idlParam"><span class="idlParamType"><a href="#idl-def-MediaStream" class="idlType"><code>MediaStream</code></a></span> <span class="idlParamName">stream</span></span>);</span>
|
|
};</span>
|
|
</pre><div id="methods-7" class="section"><h5><span class="secno">3.2.6.1 </span>Methods</h5><dl class="methods"><dt id="widl-URL-createObjectURL-static-DOMString-MediaStream-stream"><code>createObjectURL</code></dt><dd>
|
|
<p>Mints a <a href="#blob-url">Blob URL</a> to refer to the given <code><a href="#mediastream">MediaStream</a></code>.</p>
|
|
|
|
<p>When the <dfn id="dom-url-createobjecturl" title="dom-URL-createObjectURL"><code>createObjectURL()</code></dfn> method is called
|
|
with a <code><a href="#mediastream">MediaStream</a></code> argument, the user agent
|
|
must return a unique <a href="#blob-url">Blob URL</a> for the given <code><a href="#mediastream">MediaStream</a></code>. [<cite><a class="bibref" rel="biblioentry" href="#bib-FILE-API">FILE-API</a></cite>]</p>
|
|
|
|
<p>For audio and video streams, the data exposed on that stream must be in a format
|
|
supported by the user agent for use in <code>audio</code> and <code>video</code>
|
|
elements.</p>
|
|
|
|
<p class="bookkeeping">A <dfn id="blob-url">Blob URL</dfn> is the same as what the
|
|
File API specification calls a Blob URI, except that anything in the
|
|
definition of that feature that refers to <code>File</code> and <code>Blob</code>
|
|
objects is hereby extended to also apply to <code><a href="#mediastream">MediaStream</a></code> and <code><a href="#localmediastream">LocalMediaStream</a></code> objects.</p>
|
|
<table class="parameters"><tr><th>Parameter</th><th>Type</th><th>Nullable</th><th>Optional</th><th>Description</th></tr><tr><td class="prmName">stream</td><td class="prmType"><code><a href="#idl-def-MediaStream" class="idlType"><code>MediaStream</code></a></code></td><td class="prmNullFalse">✘</td><td class="prmOptFalse">✘</td><td class="prmDesc"></td></tr></table><div><em>No exceptions.</em></div><div><em>Return type: </em><code><a>static DOMString</a></code></div></dd></dl></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="examples-1" class="section">
|
|
<h3><span class="secno">3.3 </span>Examples</h3>
|
|
|
|
<div class="example">
|
|
<p>This sample code exposes a button. When clicked, the button is disabled and the
|
|
user is prompted to offer a stream. The user can cause the button to be re-enabled by
|
|
providing a stream (e.g. giving the page access to the local camera) and then
|
|
disabling the stream (e.g. revoking that access).</p>
|
|
<pre><input type="button" value="Start" onclick="start()" id="startBtn">
|
|
<script>
|
|
var startBtn = document.getElementById('startBtn');
|
|
function start() {
|
|
navigator.getUserMedia('audio,video', gotStream);
|
|
startBtn.disabled = true;
|
|
}
|
|
function gotStream(stream) {
|
|
stream.onended = function () {
|
|
startBtn.disabled = false;
|
|
}
|
|
}
|
|
</script>
|
|
</pre>
|
|
</div>
|
|
|
|
<div class="example">
|
|
<p>This example allows people to record a short audio message and upload it to the
|
|
server. This example even shows rudimentary error handling.</p>
|
|
<pre><input type="button" value="⚫" onclick="msgRecord()" id="recBtn">
|
|
<input type="button" value="◼" onclick="msgStop()" id="stopBtn" disabled>
|
|
<p id="status">To start recording, press the ⚫ button.</p>
|
|
<script>
|
|
var recBtn = document.getElementById('recBtn');
|
|
var stopBtn = document.getElementById('stopBtn');
|
|
function report(s) {
|
|
document.getElementById('status').textContent = s;
|
|
}
|
|
function msgRecord() {
|
|
report('Attempting to access microphone...');
|
|
navigator.getUserMedia('audio', gotStream, noStream);
|
|
recBtn.disabled = true;
|
|
}
|
|
var msgStream, msgStreamRecorder;
|
|
function gotStream(stream) {
|
|
report('Recording... To stop, press to ◼ button.');
|
|
msgStream = stream;
|
|
msgStreamRecorder = stream.record();
|
|
stopBtn.disabled = false;
|
|
stream.onended = function () {
|
|
msgStop();
|
|
}
|
|
}
|
|
function msgStop() {
|
|
report('Creating file...');
|
|
stopBtn.disabled = true;
|
|
msgStream.onended = null;
|
|
msgStream.stop();
|
|
msgStreamRecorder.getRecordedData(msgSave);
|
|
}
|
|
function msgSave(blob) {
|
|
report('Uploading file...');
|
|
var x = new XMLHttpRequest();
|
|
x.open('POST', 'uploadMessage');
|
|
x.send(blob);
|
|
x.onload = function () {
|
|
report('Done! To record a new message, press the ⚫ button.');
|
|
recBtn.disabled = false;
|
|
};
|
|
x.onerror = function () {
|
|
report('Failed to upload message. To try recording a message again, press the ⚫ button.');
|
|
recBtn.disabled = false;
|
|
};
|
|
}
|
|
function noStream() {
|
|
report('Could not obtain access to your microphone. To try again, press the ⚫ button.');
|
|
recBtn.disabled = false;
|
|
}
|
|
</script>
|
|
</pre>
|
|
</div>
|
|
|
|
<div class="example">
|
|
<p>This example allows people to take photos of themselves from the local video
|
|
camera.</p>
|
|
<pre><article>
|
|
<style scoped>
|
|
video { transform: scaleX(-1); }
|
|
p { text-align: center; }
|
|
</style>
|
|
<h1>Snapshot Kiosk</h1>
|
|
<section id="splash">
|
|
<p id="errorMessage">Loading...</p>
|
|
</section>
|
|
<section id="app" hidden>
|
|
<p><video id="monitor" autoplay></video> <canvas id="photo"></canvas>
|
|
<p><input type=button value="&#x1F4F7;" onclick="snapshot()">
|
|
</section>
|
|
<script>
|
|
navigator.getUserMedia('video user', gotStream, noStream);
|
|
var video = document.getElementById('monitor');
|
|
var canvas = document.getElementById('photo');
|
|
function gotStream(stream) {
|
|
video.src = URL.getObjectURL(stream);
|
|
video.onerror = function () {
|
|
stream.stop();
|
|
};
|
|
stream.onended = noStream;
|
|
video.onloadedmetadata = function () {
|
|
canvas.width = video.videoWidth;
|
|
canvas.height = video.videoHeight;
|
|
document.getElementById('splash').hidden = true;
|
|
document.getElementById('app').hidden = false;
|
|
};
|
|
}
|
|
function noStream() {
|
|
document.getElementById('errorMessage').textContent = 'No camera available.';
|
|
}
|
|
function snapshot() {
|
|
canvas.getContext('2d').drawImage(video, 0, 0);
|
|
}
|
|
</script>
|
|
</article>
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="peer-to-peer-connections" class="section">
|
|
|
|
<!-- OddPage -->
|
|
<h2><span class="secno">4. </span>Peer-to-peer connections</h2>
|
|
|
|
<p>A <code><a href="#peerconnection">PeerConnection</a></code> allows two users to
|
|
communicate directly, browser-to-browser. Communications are coordinated via a
|
|
signaling channel provided by script in the page via the server, e.g. using
|
|
<code>XMLHttpRequest</code>.</p>
|
|
|
|
<p>Calling "new <code title="dom-PeerConnection"><a href="#dom-peerconnection">PeerConnection</a></code>(<var title="">configuration</var>,
|
|
<var title="">signalingCallback</var>)" creates a <code><a href="#peerconnection">PeerConnection</a></code> object.</p>
|
|
|
|
<p>The <var title="">configuration</var> string gives the address of a STUN or TURN
|
|
server to use to establish the connection. [<cite><a class="bibref" rel="biblioentry" href="#bib-STUN">STUN</a></cite>] [<cite><a class="bibref" rel="biblioentry" href="#bib-TURN">TURN</a></cite>]</p>
|
|
|
|
<p>The allowed formats for this string are:</p>
|
|
|
|
<dl>
|
|
<dt>"<code title=""""><var title="">TYPE</var> 203.0.113.2:3478</code>"</dt>
|
|
|
|
<dd>
|
|
<p>Indicates a specific IP address and port for the server.</p>
|
|
</dd>
|
|
|
|
<dt>"<code title=""""><var title="">TYPE</var> relay.example.net:3478</code>""</dt>
|
|
|
|
<dd>
|
|
<p>Indicates a specific host and port for the server; the user agent will look up
|
|
the IP address in DNS.</p>
|
|
</dd>
|
|
|
|
<dt>"<code title=""""><var title="">TYPE</var> example.net</code>""</dt>
|
|
|
|
<dd>
|
|
<p>Indicates a specific domain for the server; the user agent will look up the IP
|
|
address and port in DNS.</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<p>The "<code title=""""><var title="">TYPE</var></code>" is one of:</p>
|
|
|
|
<dl>
|
|
<dt><code title="""">STUN</code></dt>
|
|
|
|
<dd>Indicates a STUN server</dd>
|
|
|
|
<dt><code title="""">STUNS</code></dt>
|
|
|
|
<dd>Indicates a STUN server that is to be contacted using a TLS session.</dd>
|
|
|
|
<dt><code title="""">TURN</code></dt>
|
|
|
|
<dd>Indicates a TURN server</dd>
|
|
|
|
<dt><code title="""">TURNS</code></dt>
|
|
|
|
<dd>Indicates a TURN server that is to be contacted using a TLS session.</dd>
|
|
</dl>
|
|
|
|
<p>The <var title="">signalingCallback</var> argument is a method that will be invoked
|
|
when the user agent needs to send a message to the other host over the signaling
|
|
channel. When the callback is invoked, convey its first argument (a string) to the
|
|
other peer using whatever method is being used by the Web application to relay
|
|
signaling messages. (Messages returned from the other peer are provided back to the
|
|
user agent using the <code title="dom-PeerConnection-processSignalingMessage"><a href="#dom-peerconnection-processsignalingmessage">processSignalingMessage()</a></code>
|
|
method.)</p>
|
|
|
|
<p>A <code><a href="#peerconnection">PeerConnection</a></code> object has an associated
|
|
<dfn id="peerconnection-signaling-callback"><code>PeerConnection</code> signaling
|
|
callback</dfn>, a <dfn id="peerconnection-ice-agent"><code>PeerConnection</code> ICE
|
|
Agent</dfn>,
|
|
|
|
a <dfn id="peerconnection-readiness-state"><code>PeerConnection</code>
|
|
readiness state</dfn> and an <dfn id="ice-started-flag">SDP Agent</dfn>. These
|
|
are initialized when the object is created.</p>
|
|
|
|
<p>When the <dfn id="dom-peerconnection" title="dom-PeerConnection"><code>PeerConnection()</code></dfn> constructor is invoked, the
|
|
user agent must run the following steps. This algorithm has a synchronous
|
|
section (which is triggered as part of the event loop algorithm).
|
|
Steps in the synchronous section are marked with ⌛.</p>
|
|
|
|
<ol>
|
|
<li>
|
|
<p>Let <var title="">serverConfiguration</var> be the constructor's first
|
|
argument.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Let <var title="">signalingCallback</var> be the constructor's second
|
|
argument.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Let <var title="">connection</var> be a newly created <code><a href="#peerconnection">PeerConnection</a></code> object.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Create an ICE Agent and let <var title="">connection</var>'s <a href="#peerconnection-ice-agent"><code>PeerConnection</code> ICE Agent</a> be that ICE
|
|
Agent. [<cite><a class="bibref" rel="biblioentry" href="#bib-ICE">ICE</a></cite>]</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>If <var title="">serverConfiguration</var> contains a U+000A LINE FEED (LF)
|
|
character or a U+000D CARRIAGE RETURN (CR) character (or both), remove all
|
|
characters from <var title="">serverConfiguration</var> after the first such
|
|
character.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p><span title="split a string on spaces">Split <var title="">serverConfiguration</var> on spaces</span> to obtain <var title="">configuration
|
|
components</var>.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>If <var title="">configuration components</var> has two or more components, and
|
|
the first component is a case-sensitive match for one of the following
|
|
strings:</p>
|
|
|
|
<ul class="breif">
|
|
<li>"<code title="">STUN</code>"</li>
|
|
|
|
<li>"<code title="">STUNS</code>"</li>
|
|
|
|
<li>"<code title="">TURN</code>"</li>
|
|
|
|
<li>"<code title="">TURNS</code>"</li>
|
|
</ul>
|
|
|
|
<p>...then run the following substeps:</p>
|
|
|
|
<ol>
|
|
<li>
|
|
<p>Let <var title="">server type</var> be STUN if the first component of
|
|
<var title="">configuration components</var> is '<code title="">STUN</code>' or
|
|
'<code title="">STUNS</code>', and TURN otherwise (the first component of
|
|
<var title="">configuration components</var> is "<code title="">TURN</code>" or
|
|
"<code title="">TURNS</code>").</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Let <var title="">secure</var> be true if the first component of <var title="">configuration components</var> is "<code title="">STUNS</code>" or
|
|
"<code title="">TURNS</code>", and false otherwise.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Let <var title="">host</var> be the contents of the second component of
|
|
<var title="">configuration components</var> up to the character before the
|
|
first U+003A COLON character (:), if any, or the entire string otherwise.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Let <var title="">port</var> be the contents of the second component of
|
|
<var title="">configuration components</var> from the character after the first
|
|
U+003A COLON character (:) up to the end, if any, or the empty string
|
|
otherwise.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Configure the <a href="#peerconnection-ice-agent"><code>PeerConnection</code> ICE Agent</a>'s STUN or
|
|
TURN server as follows:</p>
|
|
|
|
<ul>
|
|
<li>If <var title="">server type</var> is STUN, the server is a STUN server.
|
|
Otherwise, <var title="">server type</var> is TURN and the server is a TURN
|
|
server.</li>
|
|
|
|
<li>If <var title="">secure</var> is true, the server is to be contacted
|
|
using TLS-over-TCP, otherwise, it is to be contacted using UDP.</li>
|
|
|
|
<li>The IP address, host name, or domain name of the server is <var title="">host</var>.</li>
|
|
|
|
<li>The port to use is <var title="">port</var>. If this is the empty string,
|
|
then only a domain name is configured (and the ICE Agent will use DNS SRV
|
|
requests to determine the IP address and port).</li>
|
|
|
|
<li>The long-term username for the STUN or TURN server is the <span title="ASCII serialization of an origin">ASCII serialization</span> of the
|
|
entry script's origin; the long-term password is
|
|
the empty string.</li>
|
|
</ul>
|
|
|
|
<p>If the given IP address, host name, domain name, or port are invalid, then
|
|
the user agent must act as if no STUN or TURN server is configured.</p>
|
|
</li>
|
|
</ol>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Let the <var title="">connection</var>'s <a href="#peerconnection-signaling-callback"><code>PeerConnection</code> signaling
|
|
callback</a> be <var title="">signalingCallback</var>.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Set <var title="">connection</var>'s <a href="#peerconnection-readiness-state"><code>PeerConnection</code> readiness state</a>
|
|
to <code title="dom-PeerConnection-NEW"><a href="#widl-PeerConnection-NEW">NEW</a></code> (0).</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Set <var title="">connection</var>'s <a href="#peerconnection-readiness-state"><code>PeerConnection</code> ice state </a>
|
|
to <code title="dom-PeerConnection-NEW"><a href="#widl-PeerConnection-NEW">NEW</a></code> (0).</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Set <var title="">connection</var>'s <a href="#peerconnection-readiness-state"><code>PeerConnection</code> sdp state </a>
|
|
to <code title="dom-PeerConnection-NEW"><a href="#widl-PeerConnection-NEW">NEW</a></code> (0).</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Let <var title="">connection</var>'s <code title="dom-PeerConnection-localStreams"><a href="#widl-PeerConnection-localStreams">localStreams</a></code> attribute be an empty
|
|
read-only <code><a href="#mediastream">MediaStream</a></code> array.
|
|
[<cite><a class="bibref" rel="biblioentry" href="#bib-WEBIDL">WEBIDL</a></cite>]</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Let <var title="">connection</var>'s <code title="dom-PeerConnection-remoteStreams"><a href="#widl-PeerConnection-remoteStreams">remoteStreams</a></code> attribute be an empty
|
|
read-only <code><a href="#mediastream">MediaStream</a></code> array.
|
|
[<cite><a class="bibref" rel="biblioentry" href="#bib-WEBIDL">WEBIDL</a></cite>]</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Return <var title="">connection</var>, but continue these steps
|
|
asynchronously.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Await a stable state. The synchronous section consists
|
|
of the remaining steps of this algorithm. (Steps in <span title="synchronous section">synchronous sections</span> are marked with ⌛.)</p>
|
|
</li>
|
|
|
|
<li> <p>⌛ If the ice state is set to NEW, it must queue a task to start
|
|
gathering ICE address and set the ice state to ICEGATHERING.</p> </li>
|
|
|
|
<li> <p>⌛ Once the ICE address gathering is complete, if there are any streams in
|
|
localStreams, the SDP Agent will send the initial the SDP offer. The
|
|
initial SDP offer <em class="rfc2119" title="must">must</em> contain both the ICE candidate information
|
|
as well as the SDP to represent the media descriptions for all the
|
|
streams in localStreams. </p> </li>
|
|
|
|
</ol>
|
|
|
|
<p> During the lifetime of the peerConnection object, the following
|
|
procedures are followed: </p>
|
|
|
|
<ol>
|
|
<li> <p> If a local media stream has been added and an SDP offer needs to
|
|
be sent, and the ICE state is not NEW or ICEGATHERING, and the SDP Agent
|
|
state is NEW or SDPIDLE, then send and queue a task to send an SDP offer and
|
|
change the SPD state to SDP Waiting.</p> </li>
|
|
|
|
<li> <p> If an SDP offer has been received, and the SDP state is NEW or
|
|
SDPIDLE, pass the ICE candidates from the SDP offer to the ICE Agent and
|
|
change it state to ICECHECKING. Construct an appropriate SDP answer, update the
|
|
remote streams, queue a task to send the SDP offer, and set the SDPAgent
|
|
state to SDPIDLE. </p> </li>
|
|
|
|
<li> <p> At the point the sdpState changes from NEW to some other
|
|
state, the readyState changes to NEGOTIATING. </p> </li>
|
|
|
|
<li> <p> If the ICE Agent finds a candidates that froms a valid
|
|
connection, the ICE state is changed to ICECONNECTED </p> </li>
|
|
|
|
<li> <p> If the ICE Agent finishes checking all candidates, if a
|
|
connection has been found, the ice state is changed to ICECOMPLETED and if
|
|
not connection has been found it is changed to ICEFAILED. </p> </li>
|
|
|
|
<li> <p> If the iceState is ICECONNECTED or ICECOMPLETED and the
|
|
SDP stat is SDPIDLE, the readyState is set to ACTIVE. </p> </li>
|
|
|
|
<li> <p> If the iceState is ICEFAILED, a task is queued to calls the close method. </p> </li>
|
|
|
|
<li> <p> The close method will cause the system to wait until the sdpStat
|
|
is SDPIDLE then it will send an SDP offer terminating all media and change
|
|
the readyState to CLOSING as well as stop all ICE process and change the
|
|
iceState to ICE_CLOSED. Once an SDP anser to this offer is received, the
|
|
readyState will be changed to CLOSED. </p> </li>
|
|
|
|
</ol>
|
|
|
|
<p>User agents may negotiate any codec and any resolution, bitrate, or other quality
|
|
metric. User agents are encouraged to initially negotiate for the native resolution of
|
|
the stream. For streams that are then rendered (using a <code>video</code> element),
|
|
user agents are encouraged to 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 streams represented by <code><a href="#mediastream">MediaStream</a></code> objects must include a label attribute
|
|
("<code title="">a=label:</code>") whose value is the value of the <code><a href="#mediastream">MediaStream</a></code> object's <code title="dom-MediaStream-label"><a href="#dom-mediastream-label">label</a></code> attribute.
|
|
[<cite><a class="bibref" rel="biblioentry" href="#bib-SDP">SDP</a></cite>] [<cite><a class="bibref" rel="biblioentry" href="#bib-SDPLABEL">SDPLABEL</a></cite>]</p>
|
|
|
|
<p><a href="#peerconnection"><code>PeerConnection</code>s</a> must not generate any
|
|
candidates for media streams whose media descriptions do not have a label attribute
|
|
("<code title="">a=label:</code>"). [<cite><a class="bibref" rel="biblioentry" href="#bib-ICE">ICE</a></cite>] [<cite><a class="bibref" rel="biblioentry" href="#bib-SDP">SDP</a></cite>] [<cite><a class="bibref" rel="biblioentry" href="#bib-SDPLABEL">SDPLABEL</a></cite>]</p>
|
|
|
|
<p>When a user agent starts receiving media for a component and a candidate was
|
|
provided for that component by a <a href="#peerconnection"><code>PeerConnection</code></a>, the user agent must follow these
|
|
steps:</p>
|
|
|
|
<ol>
|
|
<li>
|
|
<p>Let <var title="">connection</var> be the <code><a href="#peerconnection">PeerConnection</a></code> expecting this media.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>If there is already a <code><a href="#mediastream">MediaStream</a></code> object
|
|
for the media stream to which this component belongs, then associate the component
|
|
with that media stream and abort these steps. (Some media streams have multiple
|
|
components; this API does not expose the role of these individual components in
|
|
ICE.)</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Create a <code><a href="#mediastream">MediaStream</a></code> object to represent
|
|
the media stream. Set its <code title="dom-MediaStream-label"><a href="#dom-mediastream-label">label</a></code> attribute to the value of the SDP Label
|
|
attribute for that component's media stream.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Queue a task to run the following substeps:</p>
|
|
|
|
<ol>
|
|
<li>
|
|
<p>If the <var title="">connection</var>'s <a href="#peerconnection-readiness-state"><code>PeerConnection</code> readiness
|
|
state</a> is <code title="dom-PeerConnection-CLOSED"><a href="#widl-PeerConnection-CLOSED">CLOSED</a></code> (3), abort these steps.</p>
|
|
</li>
|
|
<!-- close() was probably called just before this
|
|
task ran -->
|
|
|
|
|
|
<li>
|
|
<p>Add the newly created <code><a href="#mediastream">MediaStream</a></code>
|
|
object to the end of <var title="">connection</var>'s <code title="dom-PeerConnection-remoteStreams"><a href="#widl-PeerConnection-remoteStreams">remoteStreams</a></code> array.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p><a href="#fire-a-stream-event">Fire a stream event</a> named <code title="event-MediaStream-addstream"><a href="#event-mediastream-addstream">addstream</a></code> with the newly created
|
|
<code><a href="#mediastream">MediaStream</a></code> object at the <var title="">connection</var> object.</p>
|
|
</li>
|
|
</ol>
|
|
</li>
|
|
</ol>
|
|
|
|
<p>When a <a href="#peerconnection"><code>PeerConnection</code></a> finds that a stream
|
|
from the remote peer has been removed (its port has been set to zero in a media
|
|
description sent on the signaling channel), the user agent must follow these steps:</p>
|
|
|
|
<ol>
|
|
<li>
|
|
<p>Let <var title="">connection</var> be the <code><a href="#peerconnection">PeerConnection</a></code> associated with the stream being
|
|
removed.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Let <var title="">stream</var> be the <code><a href="#mediastream">MediaStream</a></code> object that represents the media stream being
|
|
removed, if any. If there isn't one, then abort these steps.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>By definition, <var title="">stream</var> is now <a href="#concept-stream-finished" title="concept-stream-finished">finished</a>.</p>
|
|
|
|
<p class="note">A <span title="concept-task">task</span> is thus <span title="queue a task">queued</span> to update <var title="">stream</var> and fire an
|
|
event.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Queue a task to run the following substeps:</p>
|
|
|
|
<ol>
|
|
<li>
|
|
<p>If the <var title="">connection</var>'s <a href="#peerconnection-readiness-state"><code>PeerConnection</code> readiness
|
|
state</a> is <code title="dom-PeerConnection-CLOSED"><a href="#widl-PeerConnection-NEW">CLOSED</a></code> (3), abort these steps.</p>
|
|
</li>
|
|
<!-- close() was probably called just before this
|
|
task ran -->
|
|
|
|
|
|
<li>
|
|
<p>Remove <var title="">stream</var> from <var title="">connection</var>'s
|
|
<code title="dom-PeerConnection-remoteStreams"><a href="#widl-PeerConnection-remoteStreams">remoteStreams</a></code> array.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p><a href="#fire-a-stream-event">Fire a stream event</a> named <code title="event-MediaStream-removestream"><a href="#event-mediastream-removestream">removestream</a></code> with <var title="">stream</var> at the <var title="">connection</var> object.</p>
|
|
</li>
|
|
</ol>
|
|
</li>
|
|
</ol>
|
|
|
|
<p>The task source for the <span title="concept-task">tasks</span> listed
|
|
in this section is the networking task source.</p>
|
|
|
|
<p class="warning">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 information should always be
|
|
transmitted using an encrypted connection.</p>
|
|
|
|
<div id="peerconnection" class="section">
|
|
<h3><span class="secno">4.1 </span>PeerConnection</h3>
|
|
|
|
<pre class="idl"><span class="idlInterface" id="idl-def-PeerConnection">[<span class="extAttr">Constructor (in DOMString configuration, in SignalingCallback signalingCallback)</span>]
|
|
interface <span class="idlInterfaceID">PeerConnection</span> {
|
|
<span class="idlMethod"> <span class="idlMethType"><a>void</a></span> <span class="idlMethName"><a href="#widl-PeerConnection-processSignalingMessage-void-DOMString-message">processSignalingMessage</a></span> (<span class="idlParam"><span class="idlParamType"><a>DOMString</a></span> <span class="idlParamName">message</span></span>);</span>
|
|
<span class="idlConst"> const <span class="idlConstType"><a>unsigned short</a></span> <span class="idlConstName"><a href="#widl-PeerConnection-NEW">NEW</a></span> = <span class="idlConstValue">0</span>;</span>
|
|
<span class="idlConst"> const <span class="idlConstType"><a>unsigned short</a></span> <span class="idlConstName"><a href="#widl-PeerConnection-NEGOTIATING">NEGOTIATING</a></span> = <span class="idlConstValue">1</span>;</span>
|
|
<span class="idlConst"> const <span class="idlConstType"><a>unsigned short</a></span> <span class="idlConstName"><a href="#widl-PeerConnection-ACTIVE">ACTIVE</a></span> = <span class="idlConstValue">2</span>;</span>
|
|
<span class="idlConst"> const <span class="idlConstType"><a>unsigned short</a></span> <span class="idlConstName"><a href="#widl-PeerConnection-CLOSING">CLOSING</a></span> = <span class="idlConstValue">4</span>;</span>
|
|
<span class="idlConst"> const <span class="idlConstType"><a>unsigned short</a></span> <span class="idlConstName"><a href="#widl-PeerConnection-CLOSED">CLOSED</a></span> = <span class="idlConstValue">3</span>;</span>
|
|
<span class="idlAttribute"> readonly attribute <span class="idlAttrType"><a>unsigned short</a></span> <span class="idlAttrName"><a href="#widl-PeerConnection-readyState">readyState</a></span>;</span>
|
|
<span class="idlConst"> const <span class="idlConstType"><a>unsigned short</a></span> <span class="idlConstName"><a href="#widl-PeerConnection-ICE_GATHERING">ICE_GATHERING</a></span> = <span class="idlConstValue">0x100</span>;</span>
|
|
<span class="idlConst"> const <span class="idlConstType"><a>unsigned short</a></span> <span class="idlConstName"><a href="#widl-PeerConnection-ICE_WAITING">ICE_WAITING</a></span> = <span class="idlConstValue">0x200</span>;</span>
|
|
<span class="idlConst"> const <span class="idlConstType"><a>unsigned short</a></span> <span class="idlConstName"><a href="#widl-PeerConnection-ICE_CHECKING">ICE_CHECKING</a></span> = <span class="idlConstValue">0x300</span>;</span>
|
|
<span class="idlConst"> const <span class="idlConstType"><a>unsigned short</a></span> <span class="idlConstName"><a href="#widl-PeerConnection-ICE_CONNECTED">ICE_CONNECTED</a></span> = <span class="idlConstValue">0x400</span>;</span>
|
|
<span class="idlConst"> const <span class="idlConstType"><a>unsigned short</a></span> <span class="idlConstName"><a href="#widl-PeerConnection-ICE_COMPLETED">ICE_COMPLETED</a></span> = <span class="idlConstValue">0x500</span>;</span>
|
|
<span class="idlConst"> const <span class="idlConstType"><a>unsigned short</a></span> <span class="idlConstName"><a href="#widl-PeerConnection-ICE_FAILED">ICE_FAILED</a></span> = <span class="idlConstValue">0x600</span>;</span>
|
|
<span class="idlConst"> const <span class="idlConstType"><a>unsigned short</a></span> <span class="idlConstName"><a href="#widl-PeerConnection-ICE_CLOSED">ICE_CLOSED</a></span> = <span class="idlConstValue">00x700</span>;</span>
|
|
<span class="idlAttribute"> readonly attribute <span class="idlAttrType"><a>unsigned short</a></span> <span class="idlAttrName"><a href="#widl-PeerConnection-iceState">iceState</a></span>;</span>
|
|
<span class="idlConst"> const <span class="idlConstType"><a>unsigned short</a></span> <span class="idlConstName"><a href="#widl-PeerConnection-SDP_IDLE">SDP_IDLE</a></span> = <span class="idlConstValue">0x1000</span>;</span>
|
|
<span class="idlConst"> const <span class="idlConstType"><a>unsigned short</a></span> <span class="idlConstName"><a href="#widl-PeerConnection-SDP_WAITING">SDP_WAITING</a></span> = <span class="idlConstValue">0x2000</span>;</span>
|
|
<span class="idlConst"> const <span class="idlConstType"><a>unsigned short</a></span> <span class="idlConstName"><a href="#widl-PeerConnection-SDP_GLARE">SDP_GLARE</a></span> = <span class="idlConstValue">0x3000</span>;</span>
|
|
<span class="idlAttribute"> readonly attribute <span class="idlAttrType"><a>unsigned short</a></span> <span class="idlAttrName"><a href="#widl-PeerConnection-sdpState">sdpState</a></span>;</span>
|
|
<span class="idlMethod"> <span class="idlMethType"><a>void</a></span> <span class="idlMethName"><a href="#widl-PeerConnection-addStream-void-MediaStream-stream-MediaStreamHints-hints">addStream</a></span> (<span class="idlParam"><span class="idlParamType"><a href="#idl-def-MediaStream" class="idlType"><code>MediaStream</code></a></span> <span class="idlParamName">stream</span></span>, <span class="idlParam"><span class="idlParamType"><a>MediaStreamHints</a></span> <span class="idlParamName">hints</span></span>);</span>
|
|
<span class="idlMethod"> <span class="idlMethType"><a>void</a></span> <span class="idlMethName"><a href="#widl-PeerConnection-removeStream-void-MediaStream-stream">removeStream</a></span> (<span class="idlParam"><span class="idlParamType"><a href="#idl-def-MediaStream" class="idlType"><code>MediaStream</code></a></span> <span class="idlParamName">stream</span></span>);</span>
|
|
<span class="idlAttribute"> readonly attribute <span class="idlAttrType"><a href="#idl-def-MediaStream" class="idlType"><code>MediaStream</code></a>[]</span> <span class="idlAttrName"><a href="#widl-PeerConnection-localStreams">localStreams</a></span>;</span>
|
|
<span class="idlAttribute"> readonly attribute <span class="idlAttrType"><a href="#idl-def-MediaStream" class="idlType"><code>MediaStream</code></a>[]</span> <span class="idlAttrName"><a href="#widl-PeerConnection-remoteStreams">remoteStreams</a></span>;</span>
|
|
<span class="idlMethod"> <span class="idlMethType"><a>void</a></span> <span class="idlMethName"><a href="#widl-PeerConnection-close-void">close</a></span> ();</span>
|
|
<span class="idlAttribute"> attribute <span class="idlAttrType"><a>Function</a>?</span> <span class="idlAttrName"><a href="#widl-PeerConnection-onconnecting">onconnecting</a></span>;</span>
|
|
<span class="idlAttribute"> attribute <span class="idlAttrType"><a>Function</a>?</span> <span class="idlAttrName"><a href="#widl-PeerConnection-onopen">onopen</a></span>;</span>
|
|
<span class="idlAttribute"> attribute <span class="idlAttrType"><a>Function</a>?</span> <span class="idlAttrName"><a href="#widl-PeerConnection-onstatechange">onstatechange</a></span>;</span>
|
|
<span class="idlAttribute"> attribute <span class="idlAttrType"><a>Function</a>?</span> <span class="idlAttrName"><a href="#widl-PeerConnection-onaddstream">onaddstream</a></span>;</span>
|
|
<span class="idlAttribute"> attribute <span class="idlAttrType"><a>Function</a>?</span> <span class="idlAttrName"><a href="#widl-PeerConnection-onremovestream">onremovestream</a></span>;</span>
|
|
};</span>
|
|
</pre><div id="attributes-4" class="section"><h4><span class="secno">4.1.1 </span>Attributes</h4><dl class="attributes"><dt id="widl-PeerConnection-iceState"><code>iceState</code> of type <span class="idlAttrType"><a>unsigned short</a></span>, readonly</dt><dd>
|
|
<p>The <dfn id="dom-peerconnection-icestate" title="dom-PeerConnection-iceState"><code title="">iceState</code></dfn> attribute
|
|
must return the state of the <code><a href="#peerconnection">PeerConnection</a></code> ICE Agent
|
|
<a href="#dom-peerconnection-icestate"><code>PeerConnection</code> ICE
|
|
state</a>, represented by a number from the following list:</p>
|
|
|
|
<dl>
|
|
<dt><code><a href="#peerconnection">PeerConnection</a></code> . <code title="dom-PeerConnection-NEW"><a href="#widl-PeerConnection-NEW">NEW</a></code>
|
|
(0)</dt>
|
|
|
|
<dd>The object was just created, and no networking has yet occurred.</dd>
|
|
|
|
<dt><code><a href="#peerconnection">PeerConnection</a></code> . <code title="dom-PeerConnection-GATHERING"><a href="#widl-PeerConnection-ICE_GATHERING">ICE_GATHERING</a></code> (0x100)</dt>
|
|
|
|
<dd>The ICE Agent is attempting to establish a gather addresses.</dd>
|
|
|
|
<dt><code><a href="#peerconnection">PeerConnection</a></code> . <code title="dom-PeerConnection-ICE_WAITING"><a href="#widl-PeerConnection-ICE_WAITING">ICE_WAITING</a></code> (0x200)</dt>
|
|
|
|
<dd>The ICE Agent is waiting for candidates from the other side before it
|
|
can start checking.</dd>
|
|
|
|
<dt><code><a href="#peerconnection">PeerConnection</a></code> . <code title="dom-PeerConnection-CHECKING"><a href="#widl-PeerConnection-ICE_CHECKING">ICE_CHECKING</a></code> (0x300)</dt>
|
|
<dd>The ICE Agent is checking candidates but has not yet found a connection.</dd>
|
|
|
|
<dt><code><a href="#peerconnection">PeerConnection</a></code> . <code title="dom-PeerConnection-CONNECTED"><a href="#widl-PeerConnection-ICE_CONNECTED">ICE_CONNECTED</a></code> (0x400)</dt>
|
|
<dd>The ICE Agent has found a connection but is still checking other
|
|
candidates to see if there is a better connection.</dd>
|
|
|
|
<dt><code><a href="#peerconnection">PeerConnection</a></code> . <code title="dom-PeerConnection-COMPLETED"><a href="#widl-PeerConnection-ICE_COMPLETED">ICE_COMPLETED</a></code> (0x500)</dt>
|
|
<dd>The ICE Agent has finished checking and found a connection.</dd>
|
|
|
|
<dt><code><a href="#peerconnection">PeerConnection</a></code> . <code title="dom-PeerConnection-ICE_FAILED"><a href="#widl-PeerConnection-ICE_FAILED">ICE_FAILED</a></code> (0x600)</dt>
|
|
<dd>The ICE Agent is finished checking all candidates and failed to find a connection.</dd>
|
|
|
|
<dt><code><a href="#peerconnection">PeerConnection</a></code> . <code title="dom-PeerConnection-CLOSED"><a href="#widl-PeerConnection-ICE_CLOSED">ICE_CLOSED</a></code> (0x700)</dt>
|
|
<dd>The ICE Agent has shut down and is no longer responding to STUN requests.</dd>
|
|
</dl>
|
|
<div><em>No exceptions.</em></div></dd><dt id="widl-PeerConnection-localStreams"><code>localStreams</code> of type array of <span class="idlAttrType"><a href="#idl-def-MediaStream" class="idlType"><code>MediaStream</code></a></span>, readonly</dt><dd>
|
|
<p>Returns a live array containing the streams that the user agent is currently
|
|
attempting to transmit to the remote peer (those that were added with <code title="dom-PeerConnection-addStream"><a href="#widl-PeerConnection-addStream-void-MediaStream-stream-MediaStreamHints-hints">addStream()</a></code>).</p>
|
|
|
|
<p>Specifically, it must return the read-only <code><a href="#mediastream">MediaStream</a></code> array that the attribute was set to when the
|
|
<code><a href="#peerconnection">PeerConnection</a></code>'s constructor ran.</p>
|
|
<div><em>No exceptions.</em></div></dd><dt id="widl-PeerConnection-onaddstream"><code>onaddstream</code> of type <span class="idlAttrType"><a>Function</a></span>, nullable</dt><dd>This event handler, of <span title="event handler event type">event handler event
|
|
type</span> <code title="event-MediaStream-addstream"><a href="#event-mediastream-addstream">addstream</a></code>, must be supported by all objects
|
|
implementing the <code><a href="#peerconnection">PeerConnection</a></code>
|
|
interface.<div><em>No exceptions.</em></div></dd><dt id="widl-PeerConnection-onconnecting"><code>onconnecting</code> of type <span class="idlAttrType"><a>Function</a></span>, nullable</dt><dd>This event handler, of <span title="event handler event type">event handler event
|
|
type</span> <code title="event-MediaStream-connecting"><a href="#event-mediastream-connecting">connecting</a></code>, must be supported by all
|
|
objects implementing the <code><a href="#peerconnection">PeerConnection</a></code>
|
|
interface.<div><em>No exceptions.</em></div></dd><dt id="widl-PeerConnection-onopen"><code>onopen</code> of type <span class="idlAttrType"><a>Function</a></span>, nullable</dt><dd>This event handler, of <span title="event handler event type">event handler event
|
|
type</span> <code title="event-MediaStream-open"><a href="#event-mediastream-open">open</a></code>, must be supported by all objects
|
|
implementing the <code><a href="#peerconnection">PeerConnection</a></code>
|
|
interface.<div><em>No exceptions.</em></div></dd><dt id="widl-PeerConnection-onremovestream"><code>onremovestream</code> of type <span class="idlAttrType"><a>Function</a></span>, nullable</dt><dd>This event handler, of <span title="event handler event type">event handler event
|
|
type</span> <code title="event-MediaStream-removestream"><a href="#event-mediastream-removestream">removestream</a></code>, must be supported by all
|
|
objects implementing the <code><a href="#peerconnection">PeerConnection</a></code>
|
|
interface.<div><em>No exceptions.</em></div></dd><dt id="widl-PeerConnection-onstatechange"><code>onstatechange</code> of type <span class="idlAttrType"><a>Function</a></span>, nullable</dt><dd>This event handler, of <span title="event handler event type">event handler event
|
|
type</span> <code title="event-MediaStream-open"><a href="#event-mediastream-open">open</a></code>, must be supported by all objects
|
|
implementing the <code><a href="#peerconnection">PeerConnection</a></code>
|
|
interface. It is called any time the readyState, iceState, or sdpState
|
|
changes. <div><em>No exceptions.</em></div></dd><dt id="widl-PeerConnection-readyState"><code>readyState</code> of type <span class="idlAttrType"><a>unsigned short</a></span>, readonly</dt><dd>
|
|
<p>The <dfn id="dom-peerconnection-readystate" title="dom-PeerConnection-readyState"><code title="">readyState</code></dfn> attribute
|
|
must return the <code><a href="#peerconnection">PeerConnection</a></code> object's
|
|
<a href="#peerconnection-readiness-state"><code>PeerConnection</code> readiness
|
|
state</a>, represented by a number from the following list:</p>
|
|
|
|
<dl>
|
|
<dt><code><a href="#peerconnection">PeerConnection</a></code> . <code title="dom-PeerConnection-NEW"><a href="#widl-PeerConnection-NEW">NEW</a></code>
|
|
(0)</dt>
|
|
|
|
<dd>The object was just created, and no networking has yet occurred.</dd>
|
|
|
|
<dt><code><a href="#peerconnection">PeerConnection</a></code> . <code title="dom-PeerConnection-NEGOTIATING"><a href="#widl-PeerConnection-NEGOTIATING">NEGOTIATING</a></code> (1)</dt>
|
|
|
|
<dd>The user agent is attempting to establish an connection with the ICE
|
|
Agent and to negotiate codecs with the SDP Agent.</dd>
|
|
|
|
<dt><code><a href="#peerconnection">PeerConnection</a></code> . <code title="dom-PeerConnection-ACTIVE"><a href="#widl-PeerConnection-ACTIVE">ACTIVE</a></code> (2)</dt>
|
|
|
|
<dd>The ICE Agent has found a connection the SDP Agent has performed a
|
|
round of codec negotiation. It is possible for whatever media was
|
|
negotiated to flow.</dd>
|
|
|
|
<dt><code><a href="#peerconnection">PeerConnection</a></code> . <code title="dom-PeerConnection-CLOSING"><a href="#widl-PeerConnection-CLOSING">CLOSING</a></code> (4)</dt>
|
|
|
|
<dd> The <code><a href="#peerconnection">PeerConnection</a></code>
|
|
object is terminating all media and is in the process of closing the
|
|
Ice Agent and SDP Agent. </dd>
|
|
|
|
<dt><code><a href="#peerconnection">PeerConnection</a></code> . <code title="dom-PeerConnection-CLOSED"><a href="#widl-PeerConnection-CLOSED">CLOSED</a></code> (3)</dt>
|
|
|
|
<dd>The connection is closed. </dd>
|
|
</dl>
|
|
<div><em>No exceptions.</em></div></dd><dt id="widl-PeerConnection-remoteStreams"><code>remoteStreams</code> of type array of <span class="idlAttrType"><a href="#idl-def-MediaStream" class="idlType"><code>MediaStream</code></a></span>, readonly</dt><dd>
|
|
<p>Returns a live array containing the streams that the user agent is currently
|
|
receiving from the remote peer.</p>
|
|
|
|
<p>Specifically, it must return the read-only <code><a href="#mediastream">MediaStream</a></code> array that the attribute was set to when the
|
|
<code><a href="#peerconnection">PeerConnection</a></code>'s constructor ran.</p>
|
|
|
|
<p>This array is updated when <code title="event-MediaStream-addstream"><a href="#event-mediastream-addstream">addstream</a></code> and <code title="event-MediaStream-removestream"><a href="#event-mediastream-removestream">removestream</a></code> events are fired.</p>
|
|
<div><em>No exceptions.</em></div></dd><dt id="widl-PeerConnection-sdpState"><code>sdpState</code> of type <span class="idlAttrType"><a>unsigned short</a></span>, readonly</dt><dd> <p>The <dfn id="dom-peerconnection-sdpstate" title="dom-PeerConnection-sdpState"><code title="">sdpState</code></dfn> attribute
|
|
must return the state of the <code><a href="#peerconnection">PeerConnection</a></code> SDP Agent , represented by
|
|
a number from the following list:</p>
|
|
|
|
<dl>
|
|
<dt><code><a href="#peerconnection">PeerConnection</a></code> . <code title="dom-PeerConnection-NEW"><a href="#widl-PeerConnection-NEW">NEW</a></code>
|
|
(0)</dt>
|
|
|
|
<dd>The object was just created, and no networking has yet occurred.</dd>
|
|
|
|
<dt><code><a href="#peerconnection">PeerConnection</a></code> . <code title="dom-PeerConnection-SDP_IDLE"><a href="#widl-PeerConnection-SDP_IDLE">SDP_IDLE</a></code> (0x1000)</dt>
|
|
|
|
<dd>At least one SDP offer or answer has been exchange and the SDP Agent
|
|
is ready to send an SDP offer or receive an SDP answer.</dd>
|
|
|
|
<dt><code><a href="#peerconnection">PeerConnection</a></code> . <code title="dom-PeerConnection-SDP_WAITING"><a href="#widl-PeerConnection-SDP_WAITING">SDP_WAITING</a></code> (0x2000)</dt>
|
|
|
|
<dd>The SDP Agent has sent and offer and is waiting for a answer.</dd>
|
|
|
|
<dt><code><a href="#peerconnection">PeerConnection</a></code> . <code title="dom-PeerConnection-SDP_GLARE"><a href="#widl-PeerConnection-SDP_GLARE">SDP_GLARE</a></code> (0x3000)</dt>
|
|
|
|
<dd>The SDP Agent received an offer while waiting for an answer and now
|
|
much wait a rondom amount of time before retrying to send the offer.</dd>
|
|
|
|
</dl>
|
|
<div><em>No exceptions.</em></div></dd></dl></div><div id="methods-8" class="section"><h4><span class="secno">4.1.2 </span>Methods</h4><dl class="methods"><dt id="widl-PeerConnection-addStream-void-MediaStream-stream-MediaStreamHints-hints"><code>addStream</code></dt><dd>
|
|
<p>Attempts to starting sending the given stream to the remote peer.
|
|
The format for the MediaStreamHints objects is currently undefined
|
|
by the specification.</p>
|
|
|
|
<p>When the other peer starts sending a stream in this manner, an <code title="event-MediaStream-addstream"><a href="#event-mediastream-addstream">addstream</a></code> event is fired at the
|
|
<code><a href="#peerconnection">PeerConnection</a></code> object.</p>
|
|
<!-- </ol> -->
|
|
|
|
|
|
<p>When the <dfn id="dom-peerconnection-addstream" title="dom-PeerConnection-addStream"><code title="">addStream()</code></dfn> method is
|
|
invoked, the user agent must run the following steps:</p>
|
|
|
|
<ol>
|
|
<li>
|
|
<p>Let <var title="">stream</var> be the method's first argument.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Let <var title="">hints</var> be the method's second argument.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>If the <code><a href="#peerconnection">PeerConnection</a></code> object's
|
|
<a href="#peerconnection-readiness-state"><code>PeerConnection</code> readiness
|
|
state</a> is <code title="dom-PeerConnection-CLOSED"><a href="#widl-PeerConnection-NEW">CLOSED</a></code> (3), throw an
|
|
<code>INVALID_STATE_ERR</code> exception.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>If <var title="">stream</var> is already in the <code><a href="#peerconnection">PeerConnection</a></code> object's <code title="dom-PeerConnection-localStreams"><a href="#widl-PeerConnection-localStreams">localStreams</a></code> object, then abort
|
|
these steps.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Add <var title="">stream</var> to the end of the <code><a href="#peerconnection">PeerConnection</a></code> object's <code title="dom-PeerConnection-localStreams"><a href="#widl-PeerConnection-localStreams">localStreams</a></code> object.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Return from the method.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Parse the <var title="">hints</var> provided by the application
|
|
and apply them to the MediaStream, if possible.
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>Have the <code><a href="#peerconnection">PeerConnection</a></code> add a
|
|
media stream for <var title="">stream</var> the next time the user agent
|
|
<span title="provide a stable state">provides a stable state</span>. Any other
|
|
pending stream additions and removals must be processed at the same time.</p>
|
|
</li>
|
|
</ol>
|
|
<table class="parameters"><tr><th>Parameter</th><th>Type</th><th>Nullable</th><th>Optional</th><th>Description</th></tr><tr><td class="prmName">stream</td><td class="prmType"><code><a href="#idl-def-MediaStream" class="idlType"><code>MediaStream</code></a></code></td><td class="prmNullFalse">✘</td><td class="prmOptFalse">✘</td><td class="prmDesc"></td></tr><tr><td class="prmName">hints</td><td class="prmType"><code><a>MediaStreamHints</a></code></td><td class="prmNullFalse">✘</td><td class="prmOptFalse">✘</td><td class="prmDesc"></td></tr></table><div><em>No exceptions.</em></div><div><em>Return type: </em><code><a>void</a></code></div></dd><dt id="widl-PeerConnection-close-void"><code>close</code></dt><dd>
|
|
<p>When the <dfn id="dom-peerconnection-close" title="dom-PeerConnection-close"><code title="">close()</code></dfn> method is invoked,
|
|
the user agent must run the following steps:</p>
|
|
|
|
<ol>
|
|
<li>
|
|
<p>If the <code><a href="#peerconnection">PeerConnection</a></code> object's
|
|
<a href="#peerconnection-readiness-state"><code>PeerConnection</code> readiness
|
|
state</a> is <code title="dom-PeerConnection-CLOSED"><a href="#widl-PeerConnection-CLOSED">CLOSED</a></code> (3), throw an
|
|
<code>INVALID_STATE_ERR</code> exception.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Destroy the <a href="#peerconnection-ice-agent"><code>PeerConnection</code>
|
|
ICE Agent</a>, abruptly ending any active ICE processing and any active
|
|
streaming, and releasing any relevant resources (e.g. TURN permissions).</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Set the object's <a href="#peerconnection-readiness-state"><code>PeerConnection</code> readiness
|
|
state</a> to <code title="dom-PeerConnection-CLOSED"><a href="#widl-PeerConnection-CLOSED">CLOSED</a></code> (3).</p>
|
|
</li>
|
|
<!--
|
|
<li><p>Queue a task to fire a simple
|
|
event named <code title="event-MediaStream-close">close</code> at the
|
|
<code>PeerConnection</code> object.</p></p></li>
|
|
-->
|
|
|
|
</ol>
|
|
|
|
<p class="note">The <code title="dom-PeerConnection-localStreams"><a href="#widl-PeerConnection-localStreams">localStreams</a></code> and <code title="dom-PeerConnection-remoteStreams"><a href="#widl-PeerConnection-remoteStreams">remoteStreams</a></code> objects remain in the
|
|
state they were in when the object was closed.</p>
|
|
<div><em>No parameters.</em></div><div><em>No exceptions.</em></div><div><em>Return type: </em><code><a>void</a></code></div></dd><dt id="widl-PeerConnection-processSignalingMessage-void-DOMString-message"><code>processSignalingMessage</code></dt><dd>
|
|
<p>When a message is relayed from the remote peer over the signaling channel is
|
|
received by the Web application, pass it to the user agent by calling the
|
|
<code title="dom-PeerConnection-processSignalingMessage"><a href="#dom-peerconnection-processsignalingmessage">processSignalingMessage()</a></code>
|
|
method.</p>
|
|
|
|
<p>The order of messages is important. Passing messages to the user agent in a
|
|
different order than they were generated by the remote peer's user agent can
|
|
prevent a successful connection from being established or degrade the connection's
|
|
quality if one is established.</p>
|
|
|
|
<p>When the <dfn id="dom-peerconnection-processsignalingmessage" title="dom-PeerConnection-processSignalingMessage"><code title="""">processSignalingMessage()</code></dfn> method is invoked, the user agent must
|
|
run the following steps:</p>
|
|
|
|
<ol>
|
|
<li>
|
|
<p>Let <var title="">message</var> be the method's argument.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Let <var title="">connection</var> be the <code><a href="#peerconnection">PeerConnection</a></code> object on which the method was
|
|
invoked.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>If <var title="">connection</var>'s <a href="#peerconnection-readiness-state"><code>PeerConnection</code> readiness
|
|
state</a> is <code title="dom-PeerConnection-CLOSED"><a href="#widl-PeerConnection-NEW">CLOSED</a></code> (3), throw an
|
|
<code>INVALID_STATE_ERR</code> exception.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>If the first four characters of <var title="">message</var> are not
|
|
"<code title="">SDP</code>" followed by a U+000A LINE FEED (LF) character, then
|
|
abort these steps. (This indicates an error in the signaling channel
|
|
implementation. User agents may report such errors to their developer consoles
|
|
to aid debugging.)</p>
|
|
|
|
<p class="note">Future extensions to the <code><a href="#peerconnection">PeerConnection</a></code> interface might use other prefix
|
|
values to implement additional features.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Let <var title="">sdp</var> be the string consisting of all but the first
|
|
four characters of <var title="">message</var>.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p> Pass the <var title="">sdp</var> to the <a href="#peerconnection-ice-agent"><code>PeerConnection</code> SDP Agent</a> as a
|
|
subsequent offer or answer, to be interpreted as appropriate given the current
|
|
state of the SDP Agent. [<cite><a class="bibref" rel="biblioentry" href="#bib-ICE">ICE</a></cite>]</p>
|
|
</li>
|
|
|
|
</ol>
|
|
|
|
<p>When a <a href="#peerconnection-ice-agent"><code>PeerConnection</code> ICE
|
|
Agent</a> forms a connection to the the far side and enters the state
|
|
ICECONNECTED, the user
|
|
agent must queue a task that sets the <code><a href="#peerconnection">PeerConnection</a></code> object's <a href="#peerconnection-readiness-state"><code>PeerConnection</code> readiness state</a>
|
|
to <code title="dom-PeerConnection-ACTIVE"><a href="#widl-PeerConnection-ACTIVE">ACTIVE</a></code> (2) and then <span title="fire a simple event">fires a simple event</span> named <code title="event-MediaStream-open"><a href="#event-mediastream-open">open</a></code> at the
|
|
<code><a href="#peerconnection">PeerConnection</a></code> object.</p>
|
|
|
|
<table class="parameters"><tr><th>Parameter</th><th>Type</th><th>Nullable</th><th>Optional</th><th>Description</th></tr><tr><td class="prmName">message</td><td class="prmType"><code><a>DOMString</a></code></td><td class="prmNullFalse">✘</td><td class="prmOptFalse">✘</td><td class="prmDesc"></td></tr></table><div><em>No exceptions.</em></div><div><em>Return type: </em><code><a>void</a></code></div></dd><dt id="widl-PeerConnection-removeStream-void-MediaStream-stream"><code>removeStream</code></dt><dd>
|
|
<p>Stops sending the given stream to the remote peer.</p>
|
|
|
|
<p>When the other peer stops sending a stream in this manner, a <code title="event-MediaStream-removestream"><a href="#event-mediastream-removestream">removestream</a></code> event is fired at the
|
|
<code><a href="#peerconnection">PeerConnection</a></code> object.</p>
|
|
|
|
<p>When the <dfn id="dom-peerconnection-removestream" title="dom-PeerConnection-removeStream"><code title="">removeStream()</code></dfn> method
|
|
is invoked, the user agent must run the following steps:</p>
|
|
|
|
<ol>
|
|
<li>
|
|
<p>Let <var title="">stream</var> be the method's argument.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>If the <code><a href="#peerconnection">PeerConnection</a></code> object's
|
|
<a href="#peerconnection-readiness-state"><code>PeerConnection</code> readiness
|
|
state</a> is <code title="dom-PeerConnection-CLOSED"><a href="#widl-PeerConnection-CLOSED">CLOSED</a></code> (3), throw an
|
|
<code>INVALID_STATE_ERR</code> exception.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>If <var title="">stream</var> is not in the <code><a href="#peerconnection">PeerConnection</a></code> object's <code title="dom-PeerConnection-localStreams"><a href="#widl-PeerConnection-localStreams">localStreams</a></code> object, then abort
|
|
these steps.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Remove <var title="">stream</var> from the <code><a href="#peerconnection">PeerConnection</a></code> object's <code title="dom-PeerConnection-localStreams"><a href="#widl-PeerConnection-localStreams">localStreams</a></code> object.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Return from the method.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Have the <code><a href="#peerconnection">PeerConnection</a></code>remove the
|
|
media stream for <var title="">stream</var> the next time the user agent
|
|
<span title="provide a stable state">provides a stable state</span>. Any other
|
|
pending stream additions and removals must be processed at the same time.</p>
|
|
</li>
|
|
<!-- section 9.1.1.2 -->
|
|
|
|
</ol>
|
|
<table class="parameters"><tr><th>Parameter</th><th>Type</th><th>Nullable</th><th>Optional</th><th>Description</th></tr><tr><td class="prmName">stream</td><td class="prmType"><code><a href="#idl-def-MediaStream" class="idlType"><code>MediaStream</code></a></code></td><td class="prmNullFalse">✘</td><td class="prmOptFalse">✘</td><td class="prmDesc"></td></tr></table><div><em>No exceptions.</em></div><div><em>Return type: </em><code><a>void</a></code></div></dd></dl></div><div id="constants-2" class="section"><h4><span class="secno">4.1.3 </span>Constants</h4><dl class="constants"><dt id="widl-PeerConnection-ACTIVE"><code>ACTIVE</code> of type <span class="idlConstType"><a>unsigned short</a></span></dt><dd> A connection has been formed and if any media streams were
|
|
successfully negotiated, any relevant media can be streaming.</dd><dt id="widl-PeerConnection-CLOSED"><code>CLOSED</code> of type <span class="idlConstType"><a>unsigned short</a></span></dt><dd>The <code title="dom-PeerConnection-close"><a href="#dom-peerconnection-close">close()</a></code> method has been invoked.</dd><dt id="widl-PeerConnection-CLOSING"><code>CLOSING</code> of type <span class="idlConstType"><a>unsigned short</a></span></dt><dd>The object is starting to shut down after the <code title="dom-PeerConnection-close"><a href="#dom-peerconnection-close">close()</a></code> method has been invoked.</dd><dt id="widl-PeerConnection-ICE_CHECKING"><code>ICE_CHECKING</code> of type <span class="idlConstType"><a>unsigned short</a></span></dt><dd>The ICE Agent is checking candidates but has not yet found a connection
|
|
that works.</dd><dt id="widl-PeerConnection-ICE_CLOSED"><code>ICE_CLOSED</code> of type <span class="idlConstType"><a>unsigned short</a></span></dt><dd>The ICE Agent is terminating and will no longer repined to STUN
|
|
connectivity checks.</dd><dt id="widl-PeerConnection-ICE_COMPLETED"><code>ICE_COMPLETED</code> of type <span class="idlConstType"><a>unsigned short</a></span></dt><dd>The ICE Agent has finished checking all candidates and a connection has
|
|
been formed.</dd><dt id="widl-PeerConnection-ICE_CONNECTED"><code>ICE_CONNECTED</code> of type <span class="idlConstType"><a>unsigned short</a></span></dt><dd>The ICE Agent has found at least one candidate that works but is still checking.</dd><dt id="widl-PeerConnection-ICE_FAILED"><code>ICE_FAILED</code> of type <span class="idlConstType"><a>unsigned short</a></span></dt><dd>The ICE Agent has finished checking all candidates and no connection
|
|
was worked.</dd><dt id="widl-PeerConnection-ICE_GATHERING"><code>ICE_GATHERING</code> of type <span class="idlConstType"><a>unsigned short</a></span></dt><dd>The ICE Agent is gather addresses that can be used.</dd><dt id="widl-PeerConnection-ICE_WAITING"><code>ICE_WAITING</code> of type <span class="idlConstType"><a>unsigned short</a></span></dt><dd>THE ICE Agent has complete gathering addresses and is waiting for candidates
|
|
to start checking. </dd><dt id="widl-PeerConnection-NEGOTIATING"><code>NEGOTIATING</code> of type <span class="idlConstType"><a>unsigned short</a></span></dt><dd>The peerConenction object is attempting to get to the point wehre media
|
|
can flow.</dd><dt id="widl-PeerConnection-NEW"><code>NEW</code> of type <span class="idlConstType"><a>unsigned short</a></span></dt><dd>The object was just created and its ICE and SDP Agent have not yet been started.</dd><dt id="widl-PeerConnection-SDP_GLARE"><code>SDP_GLARE</code> of type <span class="idlConstType"><a>unsigned short</a></span></dt><dd>Both side sent SDP offers at the same time and the SDP Agent is waiting to
|
|
be able to retransmit the SDP offer.</dd><dt id="widl-PeerConnection-SDP_IDLE"><code>SDP_IDLE</code> of type <span class="idlConstType"><a>unsigned short</a></span></dt><dd>A valid offer anser pair has been exchanged and the SDP Agent is waiting
|
|
for the next SDP transaction.</dd><dt id="widl-PeerConnection-SDP_WAITING"><code>SDP_WAITING</code> of type <span class="idlConstType"><a>unsigned short</a></span></dt><dd> The SDP Agent has sent an SDP offer and is waiting for a response.</dd></dl></div>
|
|
|
|
<pre class="idl"><span class="idlImplements"><a href="#idl-def-PeerConnection" class="idlType"><code>PeerConnection</code></a> implements <a>EventTarget</a>;</span></pre><div class="idlImplementsDesc"><p>All instances of the <code><a href="#idl-def-PeerConnection" class="idlType"><code>PeerConnection</code></a></code> type are defined to also implement the <a>EventTarget</a> interface.</p></div>
|
|
</div>
|
|
|
|
<div id="signalingcallback" class="section">
|
|
<h3><span class="secno">4.2 </span>SignalingCallback</h3>
|
|
|
|
<pre class="idl"><span class="idlInterface" id="idl-def-SignalingCallback">[<span class="extAttr">Callback=FunctionOnly, NoInterfaceObject</span>]
|
|
interface <span class="idlInterfaceID">SignalingCallback</span> {
|
|
<span class="idlMethod"> <span class="idlMethType"><a>void</a></span> <span class="idlMethName"><a href="#widl-SignalingCallback-handleEvent-void-DOMString-message-PeerConnection-source">handleEvent</a></span> (<span class="idlParam"><span class="idlParamType"><a>DOMString</a></span> <span class="idlParamName">message</span></span>, <span class="idlParam"><span class="idlParamType"><a href="#idl-def-PeerConnection" class="idlType"><code>PeerConnection</code></a></span> <span class="idlParamName">source</span></span>);</span>
|
|
};</span>
|
|
</pre><div id="methods-9" class="section"><h4><span class="secno">4.2.1 </span>Methods</h4><dl class="methods"><dt id="widl-SignalingCallback-handleEvent-void-DOMString-message-PeerConnection-source"><code>handleEvent</code></dt><dd>Def TBD<table class="parameters"><tr><th>Parameter</th><th>Type</th><th>Nullable</th><th>Optional</th><th>Description</th></tr><tr><td class="prmName">message</td><td class="prmType"><code><a>DOMString</a></code></td><td class="prmNullFalse">✘</td><td class="prmOptFalse">✘</td><td class="prmDesc"></td></tr><tr><td class="prmName">source</td><td class="prmType"><code><a href="#idl-def-PeerConnection" class="idlType"><code>PeerConnection</code></a></code></td><td class="prmNullFalse">✘</td><td class="prmOptFalse">✘</td><td class="prmDesc"></td></tr></table><div><em>No exceptions.</em></div><div><em>Return type: </em><code><a>void</a></code></div></dd></dl></div>
|
|
</div>
|
|
|
|
<div id="examples-2" class="section">
|
|
<h3><span class="secno">4.3 </span>Examples</h3>
|
|
|
|
<div class="example">
|
|
<p>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.</p>
|
|
<pre>// the first argument describes the STUN/TURN server configuration
|
|
var local = new PeerConnection('TURNS example.net', sendSignalingChannel);
|
|
local.signalingChannel(...); // if we have a message from the other side, pass it along here
|
|
|
|
// (aLocalStream is some LocalMediaStream object)
|
|
local.addStream(aLocalStream); // start sending video
|
|
|
|
function sendSignalingChannel(message) {
|
|
... // send message to the other side via the signaling channel
|
|
}
|
|
|
|
function receiveSignalingChannel (message) {
|
|
// call this whenever we get a message on the signaling channel
|
|
local.signalingChannel(message);
|
|
}
|
|
|
|
local.onaddstream = function (event) {
|
|
// (videoElement is some <video> element)
|
|
videoElement.src = URL.getObjectURL(event.stream);
|
|
};
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="the-data-stream" class="section">
|
|
|
|
<!-- OddPage -->
|
|
<h2><span class="secno">5. </span>The data stream</h2>
|
|
|
|
<p class="note">Although progress is being made, there is currently not enough
|
|
agreement on the data channel to write it up. This section will be filled in as rough
|
|
consensus is reached.</p>
|
|
</div>
|
|
|
|
<div id="garbage-collection" class="section">
|
|
|
|
<!-- OddPage -->
|
|
<h2><span class="secno">6. </span>Garbage collection</h2>
|
|
|
|
<p>A <code>Window</code> object <dfn id="concept-peerconnection-owner" title="concept-PeerConnection-owner">has a strong reference</dfn> to any <code><a href="#peerconnection">PeerConnection</a></code> objects created from the constructor whose
|
|
global object is that <code>Window</code> object.</p>
|
|
<!-- we
|
|
could be less strict here, e.g. dropping the reference when there's
|
|
no way for an event to be fired because there's no event handlers
|
|
registered and there's no way for the remote peer to notice anything
|
|
because no media is streaming; or e.g. dropping the reference when
|
|
the object reaches the CLOSED state. But as dropping the reference
|
|
in those cases is black-box indistinguishable from keeping the
|
|
reference, I haven't bothered to work out the exact rules. If you do
|
|
change this, see the /unloading document cleanup steps/. -->
|
|
|
|
</div>
|
|
|
|
<div id="event-definitions" class="section">
|
|
|
|
<!-- OddPage -->
|
|
<h2><span class="secno">7. </span>Event definitions</h2>
|
|
|
|
<p>The <code title="event-MediaStream-addstream"><a href="#event-mediastream-addstream">addstream</a></code> and <code title="event-MediaStream-removestream"><a href="#event-mediastream-removestream">removestream</a></code> events use the <code><a href="#mediastreamevent">MediaStreamEvent</a></code> interface:</p>
|
|
|
|
<div id="mediastreamevent" class="section">
|
|
<h3><span class="secno">7.1 </span>MediaStreamEvent</h3>
|
|
|
|
<p><dfn id="fire-a-stream-event" title="fire a stream event">Firing a stream event
|
|
named <var title="">e</var></dfn> with a <code><a href="#mediastream">MediaStream</a></code> <var title="">stream</var> means that an event
|
|
with the name <var title="">e</var>, which does not bubble (except where otherwise
|
|
stated) and is not cancelable (except where otherwise stated), and which uses the
|
|
<code><a href="#mediastreamevent">MediaStreamEvent</a></code> interface with the
|
|
<code title="dom-MediaStreamEvent-stream"><a href="#dom-mediastreamevent-stream">stream</a></code> attribute set to <var title="">stream</var>, must be created and dispatched at the given target.</p>
|
|
|
|
<pre class="idl"><span class="idlInterface" id="idl-def-MediaStreamEvent">interface <span class="idlInterfaceID">MediaStreamEvent</span> : <span class="idlSuperclass"><a>Event</a></span> {
|
|
<span class="idlAttribute"> readonly attribute <span class="idlAttrType"><a href="#idl-def-MediaStream" class="idlType"><code>MediaStream</code></a>?</span> <span class="idlAttrName"><a href="#widl-MediaStreamEvent-stream">stream</a></span>;</span>
|
|
<span class="idlMethod"> <span class="idlMethType"><a>void</a></span> <span class="idlMethName"><a href="#widl-MediaStreamEvent-initMediaStreamEvent-void-DOMString-typeArg-boolean-canBubbleArg-boolean-cancelableArg-MediaStream-streamArg">initMediaStreamEvent</a></span> (<span class="idlParam"><span class="idlParamType"><a>DOMString</a></span> <span class="idlParamName">typeArg</span></span>, <span class="idlParam"><span class="idlParamType"><a>boolean</a></span> <span class="idlParamName">canBubbleArg</span></span>, <span class="idlParam"><span class="idlParamType"><a>boolean</a></span> <span class="idlParamName">cancelableArg</span></span>, <span class="idlParam"><span class="idlParamType"><a href="#idl-def-MediaStream" class="idlType"><code>MediaStream</code></a>?</span> <span class="idlParamName">streamArg</span></span>);</span>
|
|
};</span>
|
|
</pre><div id="attributes-5" class="section"><h4><span class="secno">7.1.1 </span>Attributes</h4><dl class="attributes"><dt id="widl-MediaStreamEvent-stream"><code>stream</code> of type <span class="idlAttrType"><a href="#idl-def-MediaStream" class="idlType"><code>MediaStream</code></a></span>, readonly, nullable</dt><dd>
|
|
<p>The <dfn id="dom-mediastreamevent-stream" title="dom-MediaStreamEvent-stream"><code>stream</code></dfn> attribute represents the
|
|
<code><a href="#mediastream">MediaStream</a></code> object associated with the
|
|
event.</p>
|
|
<div><em>No exceptions.</em></div></dd></dl></div><div id="methods-10" class="section"><h4><span class="secno">7.1.2 </span>Methods</h4><dl class="methods"><dt id="widl-MediaStreamEvent-initMediaStreamEvent-void-DOMString-typeArg-boolean-canBubbleArg-boolean-cancelableArg-MediaStream-streamArg"><code>initMediaStreamEvent</code></dt><dd>
|
|
<p>The <dfn id="dom-mediastreamevent-initmediastreamevent" title="dom-MediaStreamEvent-initMediaStreamEvent"><code>initMediaStreamEvent()</code></dfn>
|
|
method must initialize the event in a manner analogous to the similarly-named
|
|
method in the DOM Events interfaces. [<cite><a class="bibref" rel="biblioentry" href="#bib-DOM-LEVEL-3-EVENTS">DOM-LEVEL-3-EVENTS</a></cite>]</p>
|
|
<table class="parameters"><tr><th>Parameter</th><th>Type</th><th>Nullable</th><th>Optional</th><th>Description</th></tr><tr><td class="prmName">typeArg</td><td class="prmType"><code><a>DOMString</a></code></td><td class="prmNullFalse">✘</td><td class="prmOptFalse">✘</td><td class="prmDesc"></td></tr><tr><td class="prmName">canBubbleArg</td><td class="prmType"><code><a>boolean</a></code></td><td class="prmNullFalse">✘</td><td class="prmOptFalse">✘</td><td class="prmDesc"></td></tr><tr><td class="prmName">cancelableArg</td><td class="prmType"><code><a>boolean</a></code></td><td class="prmNullFalse">✘</td><td class="prmOptFalse">✘</td><td class="prmDesc"></td></tr><tr><td class="prmName">streamArg</td><td class="prmType"><code><a href="#idl-def-MediaStream" class="idlType"><code>MediaStream</code></a></code></td><td class="prmNullTrue">✔</td><td class="prmOptFalse">✘</td><td class="prmDesc"></td></tr></table><div><em>No exceptions.</em></div><div><em>Return type: </em><code><a>void</a></code></div></dd></dl></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="informative section" id="event-summary">
|
|
|
|
<!-- OddPage -->
|
|
<h2><span class="secno">8. </span>Event summary</h2><p><em>This section is non-normative.</em></p>
|
|
|
|
<p>The following event fires on <code><a href="#mediastream">MediaStream</a></code>
|
|
objects:</p>
|
|
|
|
<table>
|
|
<tbody><tr>
|
|
<th>Event name</th>
|
|
|
|
<th>Interface</th>
|
|
|
|
<th>Fired when...</th>
|
|
</tr>
|
|
|
|
</tbody><tbody>
|
|
<tr>
|
|
<td><dfn id="event-mediastream-ended" title="event-MediaStream-ended"><code>ended</code></dfn></td>
|
|
|
|
<td><code>Event</code></td>
|
|
|
|
<td>The <code><a href="#mediastream">MediaStream</a></code> object will no longer
|
|
stream any data, either because the user revoked the permissions, or because the
|
|
source device has been ejected, or because the remote peer stopped sending data,
|
|
or because the <code title="dom-MediaStream-stop"><a href="#dom-mediastream-stop">stop()</a></code> method was invoked.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<p>The following events fire on <code><a href="#peerconnection">PeerConnection</a></code> objects:</p>
|
|
|
|
<table>
|
|
<tbody><tr>
|
|
<th>Event name</th>
|
|
|
|
<th>Interface</th>
|
|
|
|
<th>Fired when...</th>
|
|
</tr>
|
|
|
|
</tbody><tbody>
|
|
<tr>
|
|
<td><dfn id="event-mediastream-connecting" title="event-MediaStream-connecting"><code>connecting</code></dfn></td>
|
|
|
|
<td><code>Event</code></td>
|
|
|
|
<td>The ICE Agent has begun negotiating with the peer. This can happen multiple
|
|
times during the lifetime of the <code><a href="#peerconnection">PeerConnection</a></code> object.</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><dfn id="event-mediastream-open" title="event-MediaStream-open"><code>open</code></dfn></td>
|
|
|
|
<td><code>Event</code></td>
|
|
|
|
<td>The ICE Agent has finished negotiating with the peer.</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><dfn id="event-mediastream-message" title="event-MediaStream-message"><code>message</code></dfn></td>
|
|
|
|
<td><code>MessageEvent</code></td>
|
|
|
|
<td>A data UDP media stream message (to be defined) was
|
|
received.</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><dfn id="event-mediastream-addstream" title="event-MediaStream-addstream"><code>addstream</code></dfn></td>
|
|
|
|
<td><code><a href="#mediastreamevent">MediaStreamEvent</a></code></td>
|
|
|
|
<td>A new stream has been added to the <code title="dom-PeerConnection-remoteStreams"><a href="#widl-PeerConnection-remoteStreams">remoteStreams</a></code> array.</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><dfn id="event-mediastream-removestream" title="event-MediaStream-removestream"><code>removestream</code></dfn></td>
|
|
|
|
<td><code><a href="#mediastreamevent">MediaStreamEvent</a></code></td>
|
|
|
|
<td>A stream has been removed from the <code title="dom-PeerConnection-remoteStreams"><a href="#widl-PeerConnection-remoteStreams">remoteStreams</a></code> array.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div id="application-html-peer-connection-data" class="section">
|
|
|
|
<!-- OddPage -->
|
|
<h2><span class="secno">9. </span>application/html-peer-connection-data</h2>
|
|
|
|
<p>This registration is for community review and will be submitted to the IESG for
|
|
review, approval, and registration with IANA.</p>
|
|
<!--
|
|
To: ietf-types@iana.org
|
|
Subject: Registration of media type application/html-peer-connection-data
|
|
-->
|
|
|
|
|
|
<dl>
|
|
<dt>Type name:</dt>
|
|
|
|
<dd>application</dd>
|
|
|
|
<dt>Subtype name:</dt>
|
|
|
|
<dd>html-peer-connection-data</dd>
|
|
|
|
<dt>Required parameters:</dt>
|
|
|
|
<dd>No required parameters</dd>
|
|
|
|
<dt>Optional parameters:</dt>
|
|
|
|
<dd>No optional parameters</dd>
|
|
|
|
<dt>Encoding considerations:</dt>
|
|
|
|
<dd>This MIME type defines a binary protocol format which uses UTF-8 for text
|
|
encoding.</dd>
|
|
|
|
<dt>Security considerations:</dt>
|
|
|
|
<dd>
|
|
<p>This format is used for encoding UDP packets transmitted by potentially hostile
|
|
Web page content via a trusted user agent to a destination selected by a
|
|
potentially hostile remote server. To prevent this mechanism from being abused for
|
|
cross-protocol attacks, all the data in these packets is masked so as to appear to
|
|
be random noise. The intent of this masking is to reduce the potential attack
|
|
scenarios to those already possible previously.</p>
|
|
|
|
<p>However, this feature still allows random data to be sent to destinations that
|
|
might not normally have been able to receive them, such as to hosts within the
|
|
victim's intranet. If a service within such an intranet cannot handle receiving UDP
|
|
packets containing random noise, it might be vulnerable to attack from this
|
|
feature.</p>
|
|
</dd>
|
|
|
|
<dt>Interoperability considerations:</dt>
|
|
|
|
<dd>Rules for processing both conforming and non-conforming content are defined in
|
|
this specification.</dd>
|
|
|
|
<dt>Published specification:</dt>
|
|
|
|
<dd>This document is the relevant specification.</dd>
|
|
|
|
<dt>Applications that use this media type:</dt>
|
|
|
|
<dd>This type is only intended for use with SDP. [<cite><a class="bibref" rel="biblioentry" href="#bib-SDP">SDP</a></cite>]</dd>
|
|
|
|
<dt>Additional information:</dt>
|
|
|
|
<dd>
|
|
<dl>
|
|
<dt>Magic number(s):</dt>
|
|
|
|
<dd>No sequence of bytes can uniquely identify data in this format, as all data
|
|
in this format is intentionally masked to avoid cross-protocol attacks.</dd>
|
|
|
|
<dt>File extension(s):</dt>
|
|
|
|
<dd>This format is not for use with files.</dd>
|
|
|
|
<dt>Macintosh file type code(s):</dt>
|
|
|
|
<dd>This format is not for use with files.</dd>
|
|
</dl>
|
|
</dd>
|
|
|
|
<dt>Person & email address to contact for further information:</dt>
|
|
|
|
<dd>Daniel C. Burnett <dburnett@voxeo.com></dd>
|
|
|
|
<dt>Intended usage:</dt>
|
|
|
|
<dd>Common</dd>
|
|
|
|
<dt>Restrictions on usage:</dt>
|
|
|
|
<dd>No restrictions apply.</dd>
|
|
|
|
<dt>Author:</dt>
|
|
|
|
<dd>Daniel C. Burnett <dburnett@voxeo.com></dd>
|
|
|
|
<dt>Change controller:</dt>
|
|
|
|
<dd>W3C</dd>
|
|
</dl>
|
|
|
|
<p>Fragment identifiers cannot be used with <code><a href="#application-html-peer-connection-data">application/html-peer-connection-data</a></code>
|
|
as URLs cannot be used to identify streams that use this format.</p>
|
|
</div>
|
|
|
|
<div class="appendix section" id="acknowledgements">
|
|
|
|
<!-- OddPage -->
|
|
<h2><span class="secno">A. </span>Acknowledgements</h2>
|
|
|
|
<p>The editors wish to thank the Working Group chairs, Harald Alvestrand and Stefan
|
|
Håkansson, for their support.</p>
|
|
</div>
|
|
|
|
|
|
<div id="references" class="appendix section">
|
|
<!-- OddPage -->
|
|
<h2><span class="secno">B. </span>References</h2><div id="normative-references" class="section"><h3><span class="secno">B.1 </span>Normative references</h3><dl class="bibliography"><dt id="bib-DOM-LEVEL-3-EVENTS">[DOM-LEVEL-3-EVENTS]</dt><dd>Björn Höhrmann; Tom Pixley; Philippe Le Hégaret. <a href="http://www.w3.org/TR/2011/WD-DOM-Level-3-Events-20110531/"><cite>Document Object Model (DOM) Level 3 Events Specification.</cite></a> 31 May 2011. W3C Working Draft. (Work in progress.) URL: <a href="http://www.w3.org/TR/2011/WD-DOM-Level-3-Events-20110531/">http://www.w3.org/TR/2011/WD-DOM-Level-3-Events-20110531/</a>
|
|
</dd><dt id="bib-FILE-API">[FILE-API]</dt><dd>Arun Ranganathan. <a href="http://www.w3.org/TR/2009/WD-FileAPI-20091117/"><cite>File API.</cite></a> 17 November 2009. W3C Working Draft. (Work in progress.) URL: <a href="http://www.w3.org/TR/2009/WD-FileAPI-20091117/">http://www.w3.org/TR/2009/WD-FileAPI-20091117/</a>
|
|
</dd>
|
|
|
|
<dt id="bib-ICE">[ICE]</dt><dd>J. Rosenberg <a href="http://tools.ietf.org/html/rfc5245"><cite>Interactive Connectivity Establishment (ICE): A Protocol for Network Address Translator (NAT) Traversal for Offer/Answer Protocols.</cite></a> April 2010. Internet RFC 5245. URL: <a href="http://tools.ietf.org/html/rfc5245">http://tools.ietf.org/html/rfc5245</a></dd>
|
|
|
|
<dt id="bib-SDP">[SDP]</dt><dd>J. Rosenberg, H. Schulzrinne. <a href="http://tools.ietf.org/html/rfc3264"><cite>An Offer/Answer Model with the Session Description Protocol (SDP).</cite></a> June 2002. Internet RFC 3264. URL: <a href="http://tools.ietf.org/html/rfc3264">http://tools.ietf.org/html/rfc3264</a></dd>
|
|
|
|
<dt id="bib-SDPLABEL">[SDPLABEL]</dt><dd>O. Levin, G. Camarillo. <a href="http://tools.ietf.org/html/rfc4574"><cite>The Session Description Protocol (SDP) Label Attribute.</cite></a> August 2006. Internet RFC 4574. URL: <a href="http://tools.ietf.org/html/rfc4574">http://tools.ietf.org/html/rfc4574</a></dd>
|
|
|
|
<dt id="bib-STUN">[STUN]</dt><dd>J. Rosenberg, R. Mahy, P. Matthews, D. Wing. <a href="http://tools.ietf.org/html/rfc5389"><cite>Session Traversal Utilities for NAT (STUN).</cite></a> October 2008. Internet RFC 5389. URL: <a href="http://tools.ietf.org/html/rfc5389">http://tools.ietf.org/html/rfc5389</a></dd>
|
|
|
|
<dt id="bib-TURN">[TURN]</dt><dd>P. Mahy, P. Matthews, J. Rosenberg. <a href="http://tools.ietf.org/html/rfc5766"><cite>Traversal Using Relays around NAT (TURN): Relay Extensions to Session Traversal Utilities for NAT (STUN).</cite></a> April 2010. Internet RFC 5766. URL: <a href="http://tools.ietf.org/html/rfc5766">http://tools.ietf.org/html/rfc5766</a></dd>
|
|
|
|
<dt id="bib-WEBIDL">[WEBIDL]</dt><dd>Cameron McCormack. <a href="http://www.w3.org/TR/2008/WD-WebIDL-20081219"><cite>Web IDL.</cite></a> 19 December 2008. W3C Working Draft. (Work in progress.) URL: <a href="http://www.w3.org/TR/2008/WD-WebIDL-20081219">http://www.w3.org/TR/2008/WD-WebIDL-20081219</a>
|
|
</dd>
|
|
|
|
</dl></div><div id="informative-references" class="section"><h3><span class="secno">B.2 </span>Informative references</h3><p>No informative references.</p></div></div></body></html>
|