blob: 6f251a12abaf6e270d15b40ce97b0e422b83d841 [file] [log] [blame]
vikasmarwaha@webrtc.org98fce152013-02-27 23:22:10 +00001<html>
2<head>
3<title>Constraints and Statistics</title>
hta@webrtc.orgdb3f4272013-03-05 15:23:40 +00004<!-- Load the polyfill to switch-hit between Chrome and Firefox -->
5<script src="../../base/adapter.js"></script>
6
vikasmarwaha@webrtc.org98fce152013-02-27 23:22:10 +00007<script>
8var mystream;
9var pc1;
10var pc2;
11
12$ = function(id) {
13 return document.getElementById(id);
14}
15
16function log(txt) {
17 console.log(txt);
18}
19
20function openCamera() {
21 if (mystream) {
22 mystream.stop();
23 }
24 navigator.webkitGetUserMedia(cameraConstraints(), gotStream, function() {
25 log("GetUserMedia failed");
26 });
27}
28
29function gotStream(stream) {
30 log("GetUserMedia succeeded");
31 mystream = stream;
32 $("local-video").src = webkitURL.createObjectURL(stream);
33}
34
35function cameraConstraints() {
36 var constraints = {};
37 constraints.audio = true;
38 constraints.video = { mandatory: {}, optional: [] };
39 if ($("minwidth").value != "0") {
40 constraints.video.mandatory.minWidth = $("minwidth").value;
41 }
42 if ($("maxwidth").value != "0") {
43 constraints.video.mandatory.maxWidth = $("maxwidth").value;
44 }
45 if ($("minheight").value != "0") {
46 constraints.video.mandatory.minHeight = $("minheight").value;
47 }
48 if ($("maxheight").value != "0") {
49 constraints.video.mandatory.maxHeight = $("maxheight").value;
50 }
51 if ($("frameRate").value != "0") {
52 constraints.video.mandatory.minFrameRate = $("frameRate").value;
53 }
54 log('Camera constraints are ' + JSON.stringify(constraints));
55 $("cameraConstraints").innerHTML = JSON.stringify(constraints, null, ' ');
56 return constraints;
57}
58
59function streamConstraints() {
60 var constraints = { mandatory: {}, optional: [] };
61 if ($("bandwidth").value != "0") {
62 constraints.optional[0] = { 'bandwidth' : $('bandwidth').value };
63 }
64 log('Constraints are ' + JSON.stringify(constraints));
65 $("addStreamConstraints").innerHTML = JSON.stringify(constraints, null, ' ');
66 return constraints;
67}
68
69
70
71function connect() {
72 pc1 = new webkitRTCPeerConnection(null);
73 pc2 = new webkitRTCPeerConnection(null);
74 pc1.addStream(mystream, streamConstraints());
75 log('PC1 creating offer');
76 pc1.onnegotiationeeded = function() {
77 log('Negotiation needed - PC1');
78 }
79 pc2.onnegotiationeeded = function() {
80 log('Negotiation needed - PC2');
81 }
82 pc1.onicecandidate = function(e) {
83 log('Candidate PC1');
84 if (e.candidate) {
85 pc2.addIceCandidate(new RTCIceCandidate(e.candidate));
86 }
87 }
88 pc2.onicecandidate = function(e) {
89 log('Candidate PC2');
90 if (e.candidate) {
91 pc1.addIceCandidate(new RTCIceCandidate(e.candidate));
92 }
93 }
94 pc2.onaddstream = function(e) {
95 log('PC2 got stream');
96 $('remote-video').src = webkitURL.createObjectURL(e.stream);
97 log('Remote video is ' + $('remote-video').src);
98 }
99 pc1.createOffer(function(desc) {
100 log('PC1 offering');
101 pc1.setLocalDescription(desc);
102 pc2.setRemoteDescription(desc);
103 pc2.createAnswer(function(desc2) {
104 log('PC2 answering');
105 pc2.setLocalDescription(desc2);
106 pc1.setRemoteDescription(desc2);
107 });
108 });
109}
110
111// Display statistics
112var statCollector = setInterval(function() {
113 var display = function(str) {
114 $('bitrate').innerHTML = str;
115 }
116
117 display("No stream");
hta@webrtc.orgdb3f4272013-03-05 15:23:40 +0000118 if (pc2 && pc2.getRemoteStreams()[0]) {
vikasmarwaha@webrtc.org98fce152013-02-27 23:22:10 +0000119 if (pc2.getStats) {
120 display('No stats callback');
121 pc2.getStats(function(stats) {
122 log('Raw stats ' + stats);
123 var statsString = '';
124 var results = stats.result();
125 log('Raw results ' + results);
126 for (var i = 0; i < results.length; ++i) {
127 var res = results[i];
vikasmarwaha@webrtc.org98fce152013-02-27 23:22:10 +0000128 statsString += '<h3>Report ';
129 statsString += i;
130 statsString += '</h3>';
hta@webrtc.orgecfd3282013-03-19 08:45:47 +0000131 if (!res.local || res.local === res) {
132 statsString += dumpStats(res);
133 } else {
134 // Pre-227.0.1445 (188719) browser
135 if (res.local) {
136 statsString += "<p>Local ";
137 statsString += dumpStats(res.local);
138 }
139 if (res.remote) {
140 statsString += "<p>Remote ";
141 statsString += dumpStats(res.remote);
142 }
vikasmarwaha@webrtc.org98fce152013-02-27 23:22:10 +0000143 }
144 }
145 $('stats').innerHTML = statsString;
146 display('No bitrate stats');
147 });
148 } else {
149 display('No stats function. Use at least Chrome 24.0.1285');
150 }
151 } else {
152 log('Not connected yet');
153 }
154 // Collect some stats from the video tags.
155 local_video = $('local-video');
156 if (local_video) {
157 $('local-video-stats').innerHTML = local_video.videoWidth +
158 'x' + local_video.videoHeight;
159 }
160 remote_video = $('remote-video');
161 if (remote_video) {
162 $('remote-video-stats').innerHTML = remote_video.videoWidth +
163 'x' + remote_video.videoHeight;
164 }
165}, 1000);
166
167// Dumping a stats variable as a string.
168// might be named toString?
169function dumpStats(obj) {
170 var statsString = 'Timestamp:';
171 statsString += obj.timestamp;
172 if (obj.names) {
173 log('Have names function');
174 names = obj.names();
175 for (var i = 0; i < names.length; ++i) {
176 statsString += '<br>';
177 statsString += names[i];
178 statsString += ':';
179 statsString += obj.stat(names[i]);
180 }
181 } else {
182 log('No names function');
183 if (obj.stat('audioOutputLevel')) {
184 statsString += "audioOutputLevel: ";
185 statsString += obj.stat('audioOutputLevel');
186 statsString += "<br>";
187 }
188 }
189 return statsString;
190}
191
192
193// Utility to show the value of a field in a span called name+Display
194function showValue(name, value) {
195 $(name + 'Display').innerHTML = value;
196}
197</script>
198</head>
199<body>
200<h1>Constraints and Statistics</h1>
201This page is meant to give some hints on how one can use constraints and statistics in WebRTC applications.
202<p>
203The form to the left gives constraints you can set on the getUserMedia call.
204When you hit "open", it will (re)open the camera with these constraints.
205<p>
206The left picture is the local preview. The right picture is the picture
207after being passed through the PeerConnection (locally).
208<p>
209Underneath the picture you will see a running display of how many Kbits/sec
210the video feed uses for transmission.
211<hr>
212<table>
213<tr>
214<td align="top">
215<h2>getUserMedia constraints</h2>
216<table>
217<tr><td><td>Min<td>Max
218<tr><td>Horizontal
219<td><input type="range" id="minwidth" min="0" max="1280" value="300"
220 onchange="showValue(this.id, this.value)">
221<td><input type="range" id="maxwidth" min="0" max="1280" value="640"
222 onchange="showValue(this.id, this.value)">
223<td><span id="minwidthDisplay">300</span>-<span id="maxwidthDisplay">640</span>
224<tr><td>Vertical
225<td><input type="range" id="minheight" min="0" max="1280" value="200"
226 onchange="showValue(this.id, this.value)">
227<td><input type="range" id="maxheight" min="0" max="1280" value="480"
228 onchange="showValue(this.id, this.value)">
229<td><span id="minheightDisplay">200</span>-<span id="maxheightDisplay">480</span>
230<tr><td>
231FrameRate
232<td colspan=2><input type="range" id="frameRate" min="0" max="60" value="30"
233 onchange="showValue(this.id, this.value)">
234<td><span id="frameRateDisplay">30</span>
235</table>
236<input type="submit" name="capture" value="Capture!" onclick="openCamera()">
237</td>
238<td align="top">
239<h2>addStream constraints</h2>
240Maximum bitrate
241<input type="range" id="bandwidth" min="0" max="2000" value="1000"
242 onchange="showValue(this.id, this.value)">
243<span id="bandwidthDisplay">1000</span>
244<br>
245<input type="submit" name="connect" value="Connect!" onclick="connect()">
246</td>
247</tr>
248<tr>
249<td>
vikasmarwaha@webrtc.orgda0f7082013-03-11 16:58:07 +0000250<video id="local-video" autoplay width=400 muted="true"></video>
vikasmarwaha@webrtc.org98fce152013-02-27 23:22:10 +0000251</td>
252<td>
253<video id="remote-video" autoplay width=400></video>
254</td>
255<tr>
256<td><span id="local-video-stats"></span>
257<td><span id="remote-video-stats"></span>
258<br>
259<span id="bitrate">Bitrate unknown</span>
260</td>
261</tr>
262<tr>
263<td><pre><span id="cameraConstraints"></span></pre>
264<td><pre><span id="addStreamConstraints"></span></pre>
265</table>
266<h2>Statistics report display</h2>
267<div id="stats">Stats will appear here.</div>
268</body>
269</html>