index.html 156 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686
<?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>&quot;<code title="">audio</code>&quot;</dt>
        <dd>The provided media needs to include audio data.</dd>

        <dt>&quot;<code title="">video</code>&quot;</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 &quot;hot&quot;
          (i.e. an &quot;on-air&quot; or &quot;recording&quot; 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>&lt;script&gt;
 navigator.getUserMedia('audio', gotAudio);
 function gotAudio(stream) {
   // ... use 'stream' ...
 }
&lt;/script&gt;
</pre>
  </div>

  <div class="example">
    <p>A video-conferencing system would ask for both audio and video:</p>
    <pre>&lt;script&gt;
 function beginCall() {
   navigator.getUserMedia('audio,video user', gotStream);
 }
 function gotStream(stream) {
   // ... use 'stream' ...
 }
&lt;/script&gt;
</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 &quot;the video currently coming from the user's
  video camera&quot;. 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 &quot;video
  mute&quot; 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 &quot;on-air&quot; 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 &quot;<code title="&quot;&quot;">audio</code>&quot; if the object's corresponding
      track is or was an audio track, &quot;<code title="&quot;&quot;">video</code>&quot; 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. &quot;Internal microphone&quot; or
      &quot;External USB Webcam&quot;). 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>&lt;input type=&quot;button&quot; value=&quot;Start&quot; onclick=&quot;start()&quot; id=&quot;startBtn&quot;&gt;
&lt;script&gt;
 var startBtn = document.getElementById('startBtn');
 function start() {
   navigator.getUserMedia('audio,video', gotStream);
   startBtn.disabled = true;
 }
 function gotStream(stream) {
   stream.onended = function () {
     startBtn.disabled = false;
   }
 }
&lt;/script&gt;
</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>&lt;input type=&quot;button&quot; value=&quot;&quot; onclick=&quot;msgRecord()&quot; id=&quot;recBtn&quot;&gt;
&lt;input type=&quot;button&quot; value=&quot;&quot; onclick=&quot;msgStop()&quot; id=&quot;stopBtn&quot; disabled&gt;
&lt;p id=&quot;status&quot;&gt;To start recording, press the ⚫ button.&lt;/p&gt;
&lt;script&gt;
 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;
 }
&lt;/script&gt;
</pre>
  </div>

  <div class="example">
    <p>This example allows people to take photos of themselves from the local video
    camera.</p>
    <pre>&lt;article&gt;
 &lt;style scoped&gt;
  video { transform: scaleX(-1); }
  p { text-align: center; }
 &lt;/style&gt;
 &lt;h1&gt;Snapshot Kiosk&lt;/h1&gt;
 &lt;section id=&quot;splash&quot;&gt;
  &lt;p id=&quot;errorMessage&quot;&gt;Loading...&lt;/p&gt;
 &lt;/section&gt;
 &lt;section id=&quot;app&quot; hidden&gt;
  &lt;p&gt;&lt;video id=&quot;monitor&quot; autoplay&gt;&lt;/video&gt; &lt;canvas id=&quot;photo&quot;&gt;&lt;/canvas&gt;
  &lt;p&gt;&lt;input type=button value=&quot;&amp;#x1F4F7;&quot; onclick=&quot;snapshot()&quot;&gt;
 &lt;/section&gt;
 &lt;script&gt;
  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);
  }
 &lt;/script&gt;
&lt;/article&gt;
</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 &quot;new <code title="dom-PeerConnection"><a href="#dom-peerconnection">PeerConnection</a></code>(<var title="">configuration</var>,
  <var title="">signalingCallback</var>)&quot; 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>&quot;<code title="&quot;&quot;"><var title="">TYPE</var> 203.0.113.2:3478</code>&quot;</dt>

    <dd>
      <p>Indicates a specific IP address and port for the server.</p>
    </dd>

    <dt>&quot;<code title="&quot;&quot;"><var title="">TYPE</var> relay.example.net:3478</code>&quot;&quot;</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>&quot;<code title="&quot;&quot;"><var title="">TYPE</var> example.net</code>&quot;&quot;</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 &quot;<code title="&quot;&quot;"><var title="">TYPE</var></code>&quot; is one of:</p>

  <dl>
    <dt><code title="&quot;&quot;">STUN</code></dt>

    <dd>Indicates a STUN server</dd>

    <dt><code title="&quot;&quot;">STUNS</code></dt>

    <dd>Indicates a STUN server that is to be contacted using a TLS session.</dd>

    <dt><code title="&quot;&quot;">TURN</code></dt>

    <dd>Indicates a TURN server</dd>

    <dt><code title="&quot;&quot;">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>&quot;<code title="">STUN</code>&quot;</li>

        <li>&quot;<code title="">STUNS</code>&quot;</li>

        <li>&quot;<code title="">TURN</code>&quot;</li>

        <li>&quot;<code title="">TURNS</code>&quot;</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 &quot;<code title="">TURN</code>&quot; or
          &quot;<code title="">TURNS</code>&quot;).</p>
        </li>

        <li>
          <p>Let <var title="">secure</var> be true if the first component of <var title="">configuration components</var> is &quot;<code title="">STUNS</code>&quot; or
          &quot;<code title="">TURNS</code>&quot;, 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
  (&quot;<code title="">a=label:</code>&quot;) 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
  (&quot;<code title="">a=label:</code>&quot;). [<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="&quot;&quot;">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
          &quot;<code title="">SDP</code>&quot; 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 &lt;video&gt; 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 &amp; email address to contact for further information:</dt>

    <dd>Daniel C. Burnett &lt;dburnett@voxeo.com&gt;</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 &lt;dburnett@voxeo.com&gt;</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>