Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 <html> | 1 <html> |
| 2 <head> | 2 <head> |
| 3 <script type="text/javascript"> | 3 <script type="text/javascript"> |
| 4 $ = function(id) { | |
| 5 return document.getElementById(id); | |
| 6 }; | |
| 7 | |
| 8 // These must match with how the video and canvas tags are declared in html. | |
| 9 const VIDEO_TAG_WIDTH = 320; | |
| 10 const VIDEO_TAG_HEIGHT = 240; | |
| 11 | |
| 12 // Number of test events to occur before the test pass. When the test pass, | |
| 13 // the document title change to OK. | |
| 14 var gNumberOfExpectedEvents = 0; | |
| 15 | |
| 16 // Number of events that currently have occurred. | |
| 17 var gNumberOfEvents = 0; | |
| 18 | |
| 19 var gLocalStream = null; | |
| 20 | |
| 21 // This test that a MediaStream can be cloned and that the clone can | |
| 22 // be rendered. | |
|
phoglund_chromium
2013/04/09 13:16:28
Maybe getUserMediaAndClone is a better name here.
perkj_chrome
2013/04/11 10:12:41
Done.
| |
| 23 function createCloneStream() { | |
| 24 navigator.webkitGetUserMedia({video: true, audio: true}, | |
| 25 createAndRenderClone, failedCallback); | |
| 26 } | |
| 27 | |
| 4 function getUserMedia(constraints) { | 28 function getUserMedia(constraints) { |
| 5 navigator.webkitGetUserMedia(constraints, okCallback, failedCallback); | 29 navigator.webkitGetUserMedia(constraints, okCallback, failedCallback); |
| 6 } | 30 } |
| 7 | 31 |
| 8 function failedCallback(error) { | 32 function failedCallback(error) { |
| 9 document.title = 'GetUserMedia call failed with code ' + error.code; | 33 document.title = 'GetUserMedia call failed with code ' + error.code; |
| 10 } | 34 } |
| 11 | 35 |
|
phoglund_chromium
2013/04/09 13:16:28
Rename to displayAndWaitForVideo?
perkj_chrome
2013/04/11 10:12:41
Done.
| |
| 12 function okCallback(stream) { | 36 function okCallback(stream) { |
|
phoglund_chromium
2013/04/09 13:16:28
We are no longer testing the stop() method. Can yo
perkj_chrome
2013/04/11 10:12:41
Humm- I did not really want to change the behavior
| |
| 13 stream.stop(); | 37 gLocalStream = stream; |
| 14 document.title = 'OK'; | 38 waitForVideo('local-view'); |
|
phoglund_chromium
2013/04/09 13:16:28
So this wait function happens to be asynchronous,
perkj_chrome
2013/04/11 10:12:41
Done.
| |
| 39 var localStreamUrl = webkitURL.createObjectURL(stream); | |
| 40 $('local-view').src = localStreamUrl; | |
| 15 } | 41 } |
| 16 </script> | 42 |
| 43 function createAndRenderClone(stream) { | |
| 44 gLocalStream = stream; | |
| 45 waitForVideo('local-view'); | |
| 46 | |
| 47 var new_stream = new webkitMediaStream(stream.getAudioTracks()); | |
| 48 expectEquals(new_stream.getAudioTracks().length, 1); | |
| 49 new_stream.addTrack(stream.getVideoTracks()[0]); | |
| 50 expectEquals(new_stream.getVideoTracks().length, 1); | |
| 51 new_stream.removeTrack(new_stream.getAudioTracks()[0]); | |
| 52 expectEquals(new_stream.getAudioTracks().length, 0); | |
| 53 | |
| 54 var newStreamUrl = webkitURL.createObjectURL(new_stream); | |
| 55 $('local-view').src = newStreamUrl; | |
| 56 } | |
| 57 | |
| 58 | |
|
phoglund_chromium
2013/04/09 13:16:28
You should be able to extract all code 59-116 to a
perkj_chrome
2013/04/11 10:12:41
Done.
| |
| 59 function detectVideoIn(videoElementName, callback) { | |
| 60 var width = VIDEO_TAG_WIDTH; | |
| 61 var height = VIDEO_TAG_HEIGHT; | |
| 62 var videoElement = $(videoElementName); | |
| 63 var canvas = $(videoElementName + '-canvas'); | |
| 64 var waitVideo = setInterval(function() { | |
| 65 var context = canvas.getContext('2d'); | |
| 66 context.drawImage(videoElement, 0, 0, width, height); | |
| 67 var pixels = context.getImageData(0, 0, width, height).data; | |
| 68 | |
| 69 if (isVideoPlaying(pixels, width, height)) { | |
| 70 clearInterval(waitVideo); | |
| 71 callback(); | |
| 72 } | |
| 73 }, 100); | |
| 74 } | |
| 75 | |
| 76 function waitForVideo(videoElement) { | |
| 77 document.title = 'Waiting for video...'; | |
| 78 addExpectedEvent(); | |
| 79 detectVideoIn(videoElement, function () { eventOccured(); }); | |
| 80 } | |
| 81 | |
| 82 function addExpectedEvent() { | |
| 83 ++gNumberOfExpectedEvents; | |
| 84 } | |
| 85 | |
| 86 function eventOccured() { | |
| 87 ++gNumberOfEvents; | |
| 88 if (gNumberOfEvents == gNumberOfExpectedEvents) { | |
| 89 gLocalStream.stop(); | |
| 90 document.title = 'OK'; | |
| 91 } | |
| 92 } | |
| 93 | |
| 94 // This very basic video verification algorithm will be satisfied if any | |
| 95 // pixels are nonzero in a small sample area in the middle. It relies on the | |
| 96 // assumption that a video element with null source just presents zeroes. | |
| 97 function isVideoPlaying(pixels, width, height) { | |
| 98 // Sample somewhere near the middle of the image. | |
| 99 var middle = width * height / 2; | |
| 100 for (var i = 0; i < 20; i++) { | |
| 101 if (pixels[middle + i] > 0) { | |
| 102 return true; | |
| 103 } | |
| 104 } | |
| 105 return false; | |
| 106 } | |
| 107 | |
| 108 // This function matches |left| and |right| and throws an exception if the | |
| 109 // values don't match. | |
| 110 function expectEquals(left, right) { | |
| 111 if (left != right) { | |
| 112 var s = "expectEquals failed left: " + left + " right: " + right; | |
| 113 document.title = s; | |
| 114 throw s; | |
| 115 } | |
| 116 } | |
| 117 | |
| 118 </script> | |
| 17 </head> | 119 </head> |
| 120 <body> | |
| 121 <table border="0"> | |
| 122 <tr> | |
| 123 <td>Local Preview</td> | |
| 124 </tr> | |
| 125 <tr> | |
| 126 <td><video width="320" height="240" id="local-view" | |
| 127 autoplay="autoplay"></video></td> | |
| 128 <!-- Canvases are named after their corresponding video elements. --> | |
| 129 <td><canvas width="320" height="240" id="local-view-canvas" | |
| 130 style="display:none"></canvas></td> | |
| 131 </tr> | |
| 132 </table> | |
| 133 </body> | |
| 18 </html> | 134 </html> |
| OLD | NEW |