Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / content / test / data / media / getusermedia.html
blobfef58b76f3f8eedc8d4b9517d6548e95172fb358
1 <html>
2 <head>
3 <script type="text/javascript" src="webrtc_test_utilities.js"></script>
4 <script type="text/javascript">
5 $ = function(id) {
6 return document.getElementById(id);
7 };
9 var gLocalStream = null;
11 setAllEventsOccuredHandler(function() {
12 gLocalStream.stop();
13 reportTestSuccess();
14 });
16 function getSources() {
17 MediaStreamTrack.getSources(function(devices) {
18 document.title = 'Media devices available';
19 sendValueToTest(JSON.stringify(devices));
20 });
23 // Creates a MediaStream and renders it locally. When the video is detected to
24 // be rolling, the stream should be stopped.
25 function getUserMediaAndStop(constraints) {
26 console.log('Calling getUserMediaAndStop.');
27 navigator.webkitGetUserMedia(
28 constraints,
29 function(stream) { displayAndDetectVideo(stream, stopVideoTrack); },
30 failedCallback);
33 // Requests getusermedia and expects it to fail. The error name is returned
34 // to the test.
35 function getUserMediaAndExpectFailure(constraints) {
36 console.log('Calling getUserMediaAndExpectFailure.');
37 navigator.webkitGetUserMedia(
38 constraints,
39 function(stream) { failTest('Unexpectedly succeeded getUserMedia.'); },
40 function(error) { sendValueToTest(error.name); });
43 function renderClonedMediastreamAndStop(constraints, waitTimeInSeconds) {
44 console.log('Calling renderClonedMediastreamAndStop.');
45 navigator.webkitGetUserMedia(
46 constraints,
47 function(stream) {
48 var s = stream.clone();
49 assertEquals(stream.getVideoTracks().length, 1);
50 assertEquals(s.getVideoTracks().length, 1);
51 assertNotEquals(stream.getVideoTracks()[0].id,
52 s.getVideoTracks()[0].id);
53 displayAndDetectVideo(
55 function() {
56 reportTestSuccess();
57 });
59 failedCallback);
62 function renderDuplicatedMediastreamAndStop(constraints, waitTimeInSeconds) {
63 console.log('Calling renderDuplicateMediastreamAndStop.');
64 navigator.webkitGetUserMedia(
65 constraints,
66 function(stream) {
67 s = new webkitMediaStream(stream);
68 assertEquals(stream.getVideoTracks().length, 1);
69 assertEquals(s.getVideoTracks().length, 1);
70 assertEquals(stream.getVideoTracks()[0].id,
71 s.getVideoTracks()[0].id);
72 displayAndDetectVideo(
74 function() {
75 reportTestSuccess();
76 });
78 failedCallback);
81 function renderSameTrackMediastreamAndStop(constraints, waitTimeInSeconds) {
82 console.log('Calling renderSameTrackMediastreamAndStop.');
83 navigator.webkitGetUserMedia(
84 constraints,
85 function(stream) {
86 s = new webkitMediaStream();
87 s.addTrack(stream.getVideoTracks()[0]);
88 assertEquals(s.getVideoTracks().length, 1);
89 assertEquals(s.getVideoTracks().length, 1);
90 assertEquals(stream.getVideoTracks()[0].id, s.getVideoTracks()[0].id);
91 displayAndDetectVideo(
93 function() {
94 reportTestSuccess();
95 });
97 failedCallback);
100 function renderClonedTrackMediastreamAndStop(constraints, waitTimeInSeconds) {
101 console.log('Calling renderClonedTrackMediastreamAndStop.');
102 navigator.webkitGetUserMedia(
103 constraints,
104 function(stream) {
105 s = new webkitMediaStream();
106 s.addTrack(stream.getVideoTracks()[0].clone());
107 assertEquals(s.getVideoTracks().length, 1);
108 assertEquals(s.getVideoTracks().length, 1);
109 assertNotEquals(stream.getVideoTracks()[0].id,
110 s.getVideoTracks()[0].id)
111 displayAndDetectVideo(
113 function() {
114 reportTestSuccess();
117 failedCallback);
120 // Creates a MediaStream and renders it locally. When the video is detected to
121 // be rolling we return ok-stream-running through the automation controller.
122 function getUserMediaAndGetStreamUp(constraints, waitTimeInSeconds) {
123 console.log('Calling getUserMediaAndGetStreamUp.');
124 navigator.webkitGetUserMedia(
125 constraints,
126 function(stream) {
127 displayAndDetectVideo(
128 stream,
129 function() {
130 reportTestSuccess();
133 failedCallback);
136 function getUserMediaAndRenderInSeveralVideoTags() {
137 navigator.webkitGetUserMedia(
138 {video: true},
139 createMultipleVideoRenderersAndPause,
140 function(error) { failedCallback(); });
143 // Gets a video stream up, analyses it and returns the aspect ratio to the
144 // test through the automation controller.
145 function getUserMediaAndAnalyseAndStop(constraints) {
146 console.log('Calling getUserMediaAndAnalyseAndStop.');
147 navigator.webkitGetUserMedia(
148 constraints, displayDetectAndAnalyzeVideo, failedCallback);
151 // This test that a MediaStream can be cloned and that the clone can
152 // be rendered.
153 function getUserMediaAndClone() {
154 console.log('Calling getUserMediaAndClone.');
155 navigator.webkitGetUserMedia({video: true, audio: true},
156 createAndRenderClone, failedCallback);
159 // Creates two MediaStream and renders them locally. When the video of both
160 // streams are detected to be rolling, we stop the local video tracks one at
161 // the time.
162 function twoGetUserMediaAndStop(constraints) {
163 console.log('Calling Two GetUserMedia');
164 navigator.webkitGetUserMedia(
165 constraints,
166 function(stream) {
167 displayAndDetectVideo(stream, requestSecondGetUserMedia);
169 failedCallback);
170 var requestSecondGetUserMedia = function() {
171 navigator.webkitGetUserMedia(
172 constraints,
173 function(stream) {
174 displayIntoVideoElement(stream,
175 function() {
176 stopBothVideoTracksAndVerify(stream);
178 'local-view-2');
180 failedCallback);
183 var stopBothVideoTracksAndVerify = function(streamPlayingInLocalView2) {
184 streamPlayingInLocalView2.getVideoTracks()[0].stop();
185 waitForVideoToStop('local-view-2');
186 // Make sure the video track in gLocalStream is still playing in
187 // 'local-view1' and then stop it.
188 displayAndDetectVideo(gLocalStream, stopVideoTrack);
192 function twoGetUserMedia(constraints1,
193 constraints2) {
194 var result="";
195 navigator.webkitGetUserMedia(
196 constraints1,
197 function(stream) {
198 displayDetectAndAnalyzeVideoInElement(
199 stream,
200 function(aspectRatio) {
201 result = aspectRatio;
202 requestSecondGetUserMedia();
204 'local-view');
206 failedCallback);
207 var requestSecondGetUserMedia = function() {
208 navigator.webkitGetUserMedia(
209 constraints2,
210 function(stream) {
211 displayDetectAndAnalyzeVideoInElement(
212 stream,
213 function(aspectRatio) {
214 result = result + '-' + aspectRatio;
215 sendValueToTest(result);
217 'local-view-2');
219 failedCallback);
223 // Calls GetUserMedia twice and verify that the frame rate is as expected for
224 // both streams.
225 function twoGetUserMediaAndVerifyFrameRate(constraints1,
226 constraints2,
227 expected_frame_rate1,
228 expected_frame_rate2) {
229 addExpectedEvent();
230 addExpectedEvent();
231 var validateFrameRateCallback = function (success) {
232 if (!success)
233 failTest("Failed to validate frameRate.");
234 eventOccured();
237 navigator.webkitGetUserMedia(
238 constraints1,
239 function(stream) {
240 requestSecondGetUserMedia();
241 plugStreamIntoVideoElement(stream, 'local-view');
242 detectVideoPlaying('local-view',
243 function() {
244 validateFrameRate('local-view', expected_frame_rate1,
245 validateFrameRateCallback);
248 failedCallback);
249 var requestSecondGetUserMedia = function() {
250 navigator.webkitGetUserMedia(
251 constraints2,
252 function(stream) {
253 plugStreamIntoVideoElement(stream, 'local-view-2');
254 detectVideoPlaying('local-view-2',
255 function() {
256 validateFrameRate('local-view-2', expected_frame_rate2,
257 validateFrameRateCallback);
260 failedCallback);
264 function failedCallback(error) {
265 failTest('GetUserMedia call failed with code ' + error.code);
268 function plugStreamIntoVideoElement(stream, videoElement) {
269 gLocalStream = stream;
270 var localStreamUrl = URL.createObjectURL(stream);
271 $(videoElement).src = localStreamUrl;
274 function displayIntoVideoElement(stream, callback, videoElement) {
275 plugStreamIntoVideoElement(stream, videoElement);
276 detectVideoPlaying(videoElement, callback);
279 function displayAndDetectVideo(stream, callback) {
280 displayIntoVideoElement(stream, callback, 'local-view');
283 function displayDetectAndAnalyzeVideo(stream) {
284 displayDetectAndAnalyzeVideoInElement(stream,
285 function(aspectRatio) {
286 sendValueToTest(aspectRatio);
288 'local-view');
291 function displayDetectAndAnalyzeVideoInElement(
292 stream, callback, videoElement) {
293 plugStreamIntoVideoElement(stream, videoElement);
294 detectAspectRatio(callback, videoElement);
297 function createAndRenderClone(stream) {
298 gLocalStream = stream;
299 // TODO(perkj): --use-fake-device-for-media-stream do not currently
300 // work with audio devices and not all bots has a microphone.
301 new_stream = new webkitMediaStream();
302 new_stream.addTrack(stream.getVideoTracks()[0]);
303 assertEquals(new_stream.getVideoTracks().length, 1);
304 if (stream.getAudioTracks().length > 0) {
305 new_stream.addTrack(stream.getAudioTracks()[0]);
306 assertEquals(new_stream.getAudioTracks().length, 1);
307 new_stream.removeTrack(new_stream.getAudioTracks()[0]);
308 assertEquals(new_stream.getAudioTracks().length, 0);
311 var newStreamUrl = URL.createObjectURL(new_stream);
312 $('local-view').src = newStreamUrl;
313 waitForVideo('local-view');
316 function stopVideoTrack() {
317 gLocalStream.getVideoTracks()[0].stop();
318 waitForVideoToStop('local-view');
321 function waitAndStopVideoTrack(waitTimeInSeconds) {
322 setTimeout(stopVideoTrack, waitTimeInSeconds * 1000);
325 // This test make sure multiple video renderers can be created for the same
326 // local video track and make sure a renderer can still render if other
327 // renderers are paused. See http://crbug/352619.
328 function createMultipleVideoRenderersAndPause(stream) {
329 function createDetectableRenderer(stream, id) {
330 var video = document.createElement('video');
331 document.body.appendChild(video);
332 var localStreamUrl = URL.createObjectURL(stream);
333 video.id = id;
334 video.src = localStreamUrl;
335 video.autoplay = true;
336 video.play();
337 // The detector needs a canvas.
338 var canvas = document.createElement('canvas');
339 canvas.id = video.id + "-canvas";
340 document.body.appendChild(canvas);
343 // Once 3 renderers are created and paused, create one last renderer and
344 // make sure it can play video.
345 setAllEventsOccuredHandler(function() {
346 var id = "lastVideoTag";
347 createDetectableRenderer(stream, id);
348 detectVideoPlaying(id, function () { reportTestSuccess(); });
351 // Create 3 video renderers and pause them once video is playing.
352 for (var i = 0; i < 3; ++i) {
353 var id = "video" + i;
354 createDetectableRenderer(stream, id);
355 addExpectedEvent();
356 // |video_detected_function| creates a new function that pause the video
357 // tag |id|.
358 var video_detected_function =
359 function (j) {
360 return function () {
361 console.log("pause " + j);
362 $(j).pause();
363 eventOccured();
366 // Detect video id |id| and trigger the function returned by
367 // |video_detected_function| when video is playing.
368 detectVideoPlaying(id, video_detected_function(id));
372 // This function tries to calculate the aspect ratio shown by the fake capture
373 // device in the video tag. For this, we count the amount of light green
374 // pixels along |aperture| pixels on the positive X and Y axis starting from
375 // the center of the image. In this very center there should be a time-varying
376 // pacman; the algorithm counts for a couple of iterations and keeps the
377 // maximum amount of light green pixels on both directions. From this data
378 // the aspect ratio is calculated and the test fails if the number of green
379 // pixels are not the same along the X and Y axis.
380 // The result of the analysis is sent back to the test as a string on the
381 // format "w=xxx:h=yyy".
382 function detectAspectRatio(callback, videoElementName) {
383 var videoElement = $(videoElementName);
384 var canvas = $(videoElementName + '-canvas');
386 var maxLightGreenPixelsX = 0;
387 var maxLightGreenPixelsY = 0;
389 var iterations = 0;
390 var maxIterations = 10;
392 var detectorFunction = function() {
393 var width = videoElement.videoWidth;
394 var height = videoElement.videoHeight;
395 if (width == 0 || height == 0)
396 return;
398 canvas.width = width;
399 canvas.height = height;
400 var aperture = Math.min(width, height) / 2;
401 var context = canvas.getContext('2d');
402 context.drawImage(videoElement, 0, 0, width, height);
404 // We are interested in a window starting from the center of the image
405 // where we expect the circle from the fake video capture to be rolling.
406 var pixels = context.getImageData(width / 2, height / 2,
407 aperture, aperture);
409 var lightGreenPixelsX = 0;
410 var lightGreenPixelsY = 0;
412 // Walk horizontally counting light green pixels.
413 for (var x = 0; x < aperture; ++x) {
414 if (pixels.data[4 * x + 1] != COLOR_BACKGROUND_GREEN)
415 lightGreenPixelsX++;
417 // Walk vertically counting light green pixels.
418 for (var y = 0; y < aperture; ++y) {
419 if (pixels.data[4 * y * aperture + 1] != COLOR_BACKGROUND_GREEN)
420 lightGreenPixelsY++;
422 if (lightGreenPixelsX > maxLightGreenPixelsX)
423 maxLightGreenPixelsX = lightGreenPixelsX;
424 if (lightGreenPixelsY > maxLightGreenPixelsY)
425 maxLightGreenPixelsY = lightGreenPixelsY;
427 if (++iterations > maxIterations) {
428 clearInterval(detectorInterval);
429 // Allow maxLightGreenPixelsY = maxLightGreenPixelsX +-1 due to
430 // possible subpixel rendering on Mac and Android.
431 if (maxLightGreenPixelsY > maxLightGreenPixelsX + 1 ||
432 maxLightGreenPixelsY < maxLightGreenPixelsX -1 ||
433 maxLightGreenPixelsY == 0 ||
434 maxLightGreenPixelsX == width / 2 ||
435 maxLightGreenPixelsY == height / 2) {
436 failTest("Aspect ratio corrupted. X " + maxLightGreenPixelsX +
437 " Y " + maxLightGreenPixelsY);
440 var result = "w=" + width + ":h=" + height;
441 console.log(result);
442 callback(result);
445 var detectorInterval = setInterval(detectorFunction, 50);
447 </script>
448 </head>
449 <body>
450 <table border="0">
451 <tr>
452 <td>Local Preview</td>
453 </tr>
454 <tr>
455 <td><video width="320" height="240" id="local-view"
456 autoplay="autoplay"></video></td>
457 <td><canvas id="local-view-canvas"
458 style="display:none"></canvas></td>
459 </tr>
460 <tr>
461 <td>Local Preview 2</td>
462 </tr>
463 <tr>
464 <td><video width="320" height="240" id="local-view-2"
465 autoplay="autoplay"></video></td>
466 <!-- Canvases are named after their corresponding video elements. -->
467 <td><canvas width="320" height="240" id="local-view-2-canvas"
468 style="display:none"></canvas></td>
469 </tr>
470 </table>
471 </body>
472 </html>