OLD | NEW |
---|---|
(Empty) | |
1 <html> | |
2 <head> | |
3 <script type="text/javascript"> | |
4 $ = function(id) { | |
5 return document.getElementById(id); | |
6 }; | |
7 | |
8 var gFirstConnection = null; | |
9 var gSecondConnection = null; | |
10 | |
11 function call(constraints) { | |
perkj_chrome
2012/12/04 10:51:43
Can we instead use the example in http://dev.w3.or
phoglund_chromium
2012/12/04 13:03:27
In that case we would need to run two tabs and imp
| |
12 navigator.webkitGetUserMedia(constraints, okCallback, failedCallback); | |
13 } | |
14 | |
15 function failedCallback(error) { | |
16 document.title = 'getUserMedia request failed with code ' + error.code; | |
17 } | |
18 | |
19 function okCallback(localStream) { | |
20 var localStreamUrl = webkitURL.createObjectURL(localStream); | |
21 $('local-view').src = localStreamUrl; | |
22 | |
23 callUsingStream(localStream); | |
24 } | |
25 | |
26 function callUsingStream(localStream) { | |
27 gFirstConnection = new webkitRTCPeerConnection(null, null); | |
28 gFirstConnection.onicecandidate = onIceCandidateToFirst; | |
29 gFirstConnection.addStream(localStream); | |
30 gFirstConnection.createOffer(onOfferCreated); | |
31 } | |
32 | |
33 function onOfferCreated(offer) { | |
34 gFirstConnection.setLocalDescription(offer); | |
35 | |
36 receiveCall(offer.sdp); | |
37 } | |
38 | |
39 function receiveCall(offerSdp) { | |
40 gSecondConnection = new webkitRTCPeerConnection(null, null); | |
41 gSecondConnection.onicecandidate = onIceCandidateToSecond; | |
42 gSecondConnection.onaddstream = onRemoteStream; | |
43 | |
44 var parsedOffer = new RTCSessionDescription({ type: 'offer', | |
45 sdp: offerSdp }); | |
46 gSecondConnection.setRemoteDescription(parsedOffer); | |
47 | |
48 gSecondConnection.createAnswer(onAnswerCreated); | |
49 } | |
50 | |
51 function onAnswerCreated(answer) { | |
52 gSecondConnection.setLocalDescription(answer); | |
53 handleAnswer(answer.sdp); | |
54 } | |
55 | |
56 function handleAnswer(answerSdp) { | |
57 var parsedAnswer = new RTCSessionDescription({ type: 'answer', | |
58 sdp: answerSdp }); | |
59 gFirstConnection.setRemoteDescription(parsedAnswer); | |
60 } | |
61 | |
62 function onIceCandidateToFirst(event) { | |
63 if (event.candidate) { | |
64 var candidate = new RTCIceCandidate(event.candidate); | |
65 gSecondConnection.addIceCandidate(candidate); | |
66 } | |
67 } | |
68 | |
69 function onIceCandidateToSecond(event) { | |
70 if (event.candidate) { | |
71 var candidate = new RTCIceCandidate(event.candidate); | |
72 gFirstConnection.addIceCandidate(candidate); | |
73 } | |
74 } | |
75 | |
76 function onRemoteStream(e) { | |
77 var remoteStreamUrl = webkitURL.createObjectURL(e.stream); | |
78 var remoteVideo = $('remote-view'); | |
79 remoteVideo.src = remoteStreamUrl; | |
80 | |
81 waitForVideo(remoteVideo, 320, 240); | |
82 } | |
83 | |
84 function waitForVideo(videoElement, width, height) { | |
85 document.title = 'Waiting for video...'; | |
86 var canvas = $('canvas'); | |
87 setInterval(function() { | |
88 var context = canvas.getContext('2d'); | |
89 context.drawImage(videoElement, 0, 0, 320, 240); | |
90 var pixels = context.getImageData(0, 0, 320, 240).data; | |
91 | |
92 if (isVideoPlaying(pixels, width, height)) | |
93 testSuccessful(); | |
94 }, 100); | |
95 } | |
96 | |
97 // This very basic video verification algorithm will be satisfied if any | |
98 // pixels are nonzero in a small sample area in the middle. It relies on the | |
99 // assumption that a video element with null source just presents zeroes. | |
100 function isVideoPlaying(pixels, width, height) { | |
perkj_chrome
2012/12/04 10:51:43
Why not use your existing video checker?
phoglund_chromium
2012/12/04 13:03:27
Good point. I thought about it, but then I would h
| |
101 // Sample somewhere near the middle of the image. | |
102 var middle = width * height / 2; | |
103 for (var i = 0; i < 20; i++) { | |
104 if (pixels[middle + i] > 0) { | |
105 return true; | |
106 } | |
107 } | |
108 return false; | |
109 } | |
110 | |
111 function testSuccessful() { | |
112 document.title = 'OK'; | |
113 } | |
114 </script> | |
115 </head> | |
116 <body> | |
117 <table border="0"> | |
118 <tr> | |
119 <td>Local Preview</td> | |
120 <td>Remote Stream</td> | |
121 <td>Capturing Canvas</td> | |
122 </tr> | |
123 <tr> | |
124 <td><video width="320" height="240" id="local-view" | |
125 autoplay="autoplay"></video></td> | |
126 <td><video width="320" height="240" id="remote-view" | |
127 autoplay="autoplay"></video></td> | |
128 <td><canvas width="320" height="240" id="canvas"></canvas></td> | |
129 </tr> | |
130 <tr> | |
131 <td colspan="3">You should see the same animated feed in all three | |
132 displays (the canvas will lag a bit). | |
133 </td> | |
134 </table> | |
135 </body> | |
136 </html> | |
OLD | NEW |