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 |