OLD | NEW |
---|---|
1 <html> | 1 <html> |
2 <head> | 2 <head> |
3 <script type="text/javascript" src="webrtc_test_utilities.js"></script> | |
3 <script type="text/javascript"> | 4 <script type="text/javascript"> |
4 $ = function(id) { | 5 $ = function(id) { |
5 return document.getElementById(id); | 6 return document.getElementById(id); |
6 }; | 7 }; |
7 | 8 |
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 var gFirstConnection = null; | 9 var gFirstConnection = null; |
13 var gSecondConnection = null; | 10 var gSecondConnection = null; |
14 var gTestWithoutMsidAndBundle = false; | 11 var gTestWithoutMsidAndBundle = false; |
15 | 12 |
16 // Number of test events to occur before the test pass. When the test pass, | |
17 // the document title change to OK. | |
18 var gNumberOfExpectedEvents = 0; | |
19 | |
20 // Number of events that currently have occured. | |
21 var gNumberOfEvents = 0; | |
22 | |
23 var gLocalStream = null; | 13 var gLocalStream = null; |
24 var gSentTones = ''; | 14 var gSentTones = ''; |
15 | |
16 // This function is called when all expected events have occurred. | |
17 gAllEventsOccured = function() { | |
18 document.title = 'OK'; | |
19 } | |
25 | 20 |
26 // Test that we can setup call with an audio and video track. | 21 // Test that we can setup call with an audio and video track. |
27 function call(constraints) { | 22 function call(constraints) { |
28 createConnections(null); | 23 createConnections(null); |
29 navigator.webkitGetUserMedia(constraints, | 24 navigator.webkitGetUserMedia(constraints, |
30 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); | 25 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); |
31 waitForVideo('remote-view-1'); | 26 waitForVideo('remote-view-1'); |
32 waitForVideo('remote-view-2'); | 27 waitForVideo('remote-view-2'); |
33 } | 28 } |
34 | 29 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
102 if (gSentTones == tones) { | 97 if (gSentTones == tones) { |
103 clearInterval(waitDtmf); | 98 clearInterval(waitDtmf); |
104 eventOccured(); | 99 eventOccured(); |
105 } | 100 } |
106 }, 100); | 101 }, 100); |
107 } | 102 } |
108 | 103 |
109 // Do the DTMF test after we have received video. | 104 // Do the DTMF test after we have received video. |
110 detectVideoIn('remote-view-2', onCallEstablished); | 105 detectVideoIn('remote-view-2', onCallEstablished); |
111 } | 106 } |
107 | |
108 // Test call with a new Video MediaStream that has been created based on a | |
109 // stream generated by getUserMedia. | |
110 function callWithNewVideoMediaStream() { | |
111 createConnections(null); | |
112 navigator.webkitGetUserMedia({audio:true, video:true}, | |
113 createNewVideoStreamAndAddToBothConnections, printGetUserMediaError); | |
114 waitForVideo('remote-view-1'); | |
115 waitForVideo('remote-view-2'); | |
116 } | |
112 | 117 |
113 // This function is used for setting up a test that: | 118 // This function is used for setting up a test that: |
114 // 1. Creates a data channel on |gFirstConnection| and sends data to | 119 // 1. Creates a data channel on |gFirstConnection| and sends data to |
115 // |gSecondConnection|. | 120 // |gSecondConnection|. |
116 // 2. When data is received on |gSecondConnection| a message | 121 // 2. When data is received on |gSecondConnection| a message |
117 // is sent to |gFirstConnection|. | 122 // is sent to |gFirstConnection|. |
118 // 3. When data is received on |gFirstConnection|, the data | 123 // 3. When data is received on |gFirstConnection|, the data |
119 // channel is closed. The test passes when the state transition completes. | 124 // channel is closed. The test passes when the state transition completes. |
120 function setupDataChannel() { | 125 function setupDataChannel() { |
121 var sendDataString = "send some text on a data channel." | 126 var sendDataString = "send some text on a data channel." |
(...skipping 26 matching lines...) Expand all Loading... | |
148 gSecondConnection.ondatachannel = function (event) { | 153 gSecondConnection.ondatachannel = function (event) { |
149 var secondDataChannel = event.channel; | 154 var secondDataChannel = event.channel; |
150 | 155 |
151 // When |secondDataChannel| receive a message, send a message back. | 156 // When |secondDataChannel| receive a message, send a message back. |
152 secondDataChannel.onmessage = function(event) { | 157 secondDataChannel.onmessage = function(event) { |
153 expectEquals(event.data, sendDataString); | 158 expectEquals(event.data, sendDataString); |
154 expectEquals('open', secondDataChannel.readyState); | 159 expectEquals('open', secondDataChannel.readyState); |
155 secondDataChannel.send(sendDataString); | 160 secondDataChannel.send(sendDataString); |
156 } | 161 } |
157 } | 162 } |
158 } | 163 } |
159 | 164 |
160 function onToneChange(tone) { | 165 function onToneChange(tone) { |
161 gSentTones += tone.tone; | 166 gSentTones += tone.tone; |
162 document.title = gSentTones; | 167 document.title = gSentTones; |
163 } | 168 } |
164 | 169 |
165 function createConnections(constraints) { | 170 function createConnections(constraints) { |
166 gFirstConnection = new webkitRTCPeerConnection(null, constraints); | 171 gFirstConnection = new webkitRTCPeerConnection(null, constraints); |
167 gFirstConnection.onicecandidate = onIceCandidateToFirst; | 172 gFirstConnection.onicecandidate = onIceCandidateToFirst; |
168 gFirstConnection.onaddstream = function(event) { | 173 gFirstConnection.onaddstream = function(event) { |
(...skipping 27 matching lines...) Expand all Loading... | |
196 gSecondConnection.addStream(localStream); | 201 gSecondConnection.addStream(localStream); |
197 negotiate(); | 202 negotiate(); |
198 } | 203 } |
199 | 204 |
200 // Called if getUserMedia succeeds when we want to send from one connection. | 205 // Called if getUserMedia succeeds when we want to send from one connection. |
201 function addStreamToTheFirstConnectionAndNegotiate(localStream) { | 206 function addStreamToTheFirstConnectionAndNegotiate(localStream) { |
202 displayAndRemember(localStream); | 207 displayAndRemember(localStream); |
203 gFirstConnection.addStream(localStream); | 208 gFirstConnection.addStream(localStream); |
204 negotiate(); | 209 negotiate(); |
205 } | 210 } |
211 | |
212 // Called if getUserMedia succeeds when we want to send a modified | |
213 // MediaStream. A new MediaStream is created and the video track from | |
214 // |localStream| is added. | |
phoglund_chromium
2013/04/11 11:16:48
Also removes the audio track.
| |
215 function createNewVideoStreamAndAddToBothConnections(localStream) { | |
216 var new_stream = new webkitMediaStream(localStream.getAudioTracks()); | |
217 new_stream.addTrack(localStream.getVideoTracks()[0]); | |
218 new_stream.removeTrack(new_stream.getAudioTracks()[0]); | |
219 addStreamToBothConnectionsAndNegotiate(new_stream); | |
220 } | |
206 | 221 |
207 function negotiate() { | 222 function negotiate() { |
208 gFirstConnection.createOffer(onOfferCreated); | 223 gFirstConnection.createOffer(onOfferCreated); |
209 } | 224 } |
210 | 225 |
211 function onOfferCreated(offer) { | 226 function onOfferCreated(offer) { |
212 gFirstConnection.setLocalDescription(offer); | 227 gFirstConnection.setLocalDescription(offer); |
213 expectEquals('have-local-offer', gFirstConnection.signalingState); | 228 expectEquals('have-local-offer', gFirstConnection.signalingState); |
214 receiveOffer(offer.sdp); | 229 receiveOffer(offer.sdp); |
215 } | 230 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
268 function onRemoteStream(e, target) { | 283 function onRemoteStream(e, target) { |
269 if (gTestWithoutMsidAndBundle && e.stream.label != "default") { | 284 if (gTestWithoutMsidAndBundle && e.stream.label != "default") { |
270 document.title = 'a default remote stream was expected but instead ' + | 285 document.title = 'a default remote stream was expected but instead ' + |
271 e.stream.label + ' was received.'; | 286 e.stream.label + ' was received.'; |
272 return; | 287 return; |
273 } | 288 } |
274 var remoteStreamUrl = webkitURL.createObjectURL(e.stream); | 289 var remoteStreamUrl = webkitURL.createObjectURL(e.stream); |
275 var remoteVideo = $(target); | 290 var remoteVideo = $(target); |
276 remoteVideo.src = remoteStreamUrl; | 291 remoteVideo.src = remoteStreamUrl; |
277 } | 292 } |
278 | 293 |
279 // TODO(phoglund): perhaps use the video detector in chrome/test/data/webrtc/? | |
280 function detectVideoIn(videoElementName, callback) { | |
281 var width = VIDEO_TAG_WIDTH; | |
282 var height = VIDEO_TAG_HEIGHT; | |
283 var videoElement = $(videoElementName); | |
284 var canvas = $(videoElementName + '-canvas'); | |
285 var waitVideo = setInterval(function() { | |
286 var context = canvas.getContext('2d'); | |
287 context.drawImage(videoElement, 0, 0, width, height); | |
288 var pixels = context.getImageData(0, 0, width, height).data; | |
289 | |
290 if (isVideoPlaying(pixels, width, height)) { | |
291 clearInterval(waitVideo); | |
292 callback(); | |
293 } | |
294 }, 100); | |
295 } | |
296 | |
297 function waitForVideo(videoElement) { | |
298 document.title = 'Waiting for video...'; | |
299 addExpectedEvent(); | |
300 detectVideoIn(videoElement, function () { eventOccured(); }); | |
301 } | |
302 | |
303 // This very basic video verification algorithm will be satisfied if any | |
304 // pixels are nonzero in a small sample area in the middle. It relies on the | |
305 // assumption that a video element with null source just presents zeroes. | |
306 function isVideoPlaying(pixels, width, height) { | |
307 // Sample somewhere near the middle of the image. | |
308 var middle = width * height / 2; | |
309 for (var i = 0; i < 20; i++) { | |
310 if (pixels[middle + i] > 0) { | |
311 return true; | |
312 } | |
313 } | |
314 return false; | |
315 } | |
316 | |
317 | |
318 // This function matches |left| and |right| and throws an exception if the | |
319 // values don't match. | |
320 function expectEquals(left, right) { | |
321 if (left != right) { | |
322 var s = "expectEquals failed left: " + left + " right: " + right; | |
323 document.title = s; | |
324 throw s; | |
325 } | |
326 } | |
327 | |
328 function addExpectedEvent() { | |
329 ++gNumberOfExpectedEvents; | |
330 } | |
331 | |
332 function eventOccured() { | |
333 ++gNumberOfEvents; | |
334 if (gNumberOfEvents == gNumberOfExpectedEvents) { | |
335 document.title = 'OK'; | |
336 } | |
337 } | |
338 </script> | 294 </script> |
339 </head> | 295 </head> |
340 <body> | 296 <body> |
341 <table border="0"> | 297 <table border="0"> |
342 <tr> | 298 <tr> |
343 <td>Local Preview</td> | 299 <td>Local Preview</td> |
344 <td>Remote Stream for Connection 1</td> | 300 <td>Remote Stream for Connection 1</td> |
345 <td>Remote Stream for Connection 2</td> | 301 <td>Remote Stream for Connection 2</td> |
346 </tr> | 302 </tr> |
347 <tr> | 303 <tr> |
348 <td><video width="320" height="240" id="local-view" | 304 <td><video width="320" height="240" id="local-view" |
349 autoplay="autoplay"></video></td> | 305 autoplay="autoplay"></video></td> |
350 <td><video width="320" height="240" id="remote-view-1" | 306 <td><video width="320" height="240" id="remote-view-1" |
351 autoplay="autoplay"></video></td> | 307 autoplay="autoplay"></video></td> |
352 <td><video width="320" height="240" id="remote-view-2" | 308 <td><video width="320" height="240" id="remote-view-2" |
353 autoplay="autoplay"></video></td> | 309 autoplay="autoplay"></video></td> |
354 <!-- Canvases are named after their corresponding video elements. --> | 310 <!-- Canvases are named after their corresponding video elements. --> |
355 <td><canvas width="320" height="240" id="remote-view-1-canvas" | 311 <td><canvas width="320" height="240" id="remote-view-1-canvas" |
356 style="display:none"></canvas></td> | 312 style="display:none"></canvas></td> |
357 <td><canvas width="320" height="240" id="remote-view-2-canvas"> | 313 <td><canvas width="320" height="240" id="remote-view-2-canvas"> |
358 style="display:none"></canvas></td> | 314 style="display:none"></canvas></td> |
359 </tr> | 315 </tr> |
360 </table> | 316 </table> |
361 </body> | 317 </body> |
362 </html> | 318 </html> |
OLD | NEW |