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) { |
| 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 // TODO(phoglund): perhaps use the video detector in chrome/test/data/webrtc/? |
| 85 function waitForVideo(videoElement, width, height) { |
| 86 document.title = 'Waiting for video...'; |
| 87 var canvas = $('canvas'); |
| 88 setInterval(function() { |
| 89 var context = canvas.getContext('2d'); |
| 90 context.drawImage(videoElement, 0, 0, width, height); |
| 91 var pixels = context.getImageData(0, 0, width, height).data; |
| 92 |
| 93 if (isVideoPlaying(pixels, width, height)) |
| 94 testSuccessful(); |
| 95 }, 100); |
| 96 } |
| 97 |
| 98 // This very basic video verification algorithm will be satisfied if any |
| 99 // pixels are nonzero in a small sample area in the middle. It relies on the |
| 100 // assumption that a video element with null source just presents zeroes. |
| 101 function isVideoPlaying(pixels, width, height) { |
| 102 // Sample somewhere near the middle of the image. |
| 103 var middle = width * height / 2; |
| 104 for (var i = 0; i < 20; i++) { |
| 105 if (pixels[middle + i] > 0) { |
| 106 return true; |
| 107 } |
| 108 } |
| 109 return false; |
| 110 } |
| 111 |
| 112 function testSuccessful() { |
| 113 document.title = 'OK'; |
| 114 } |
| 115 </script> |
| 116 </head> |
| 117 <body> |
| 118 <table border="0"> |
| 119 <tr> |
| 120 <td>Local Preview</td> |
| 121 <td>Remote Stream</td> |
| 122 <td>Capturing Canvas</td> |
| 123 </tr> |
| 124 <tr> |
| 125 <td><video width="320" height="240" id="local-view" |
| 126 autoplay="autoplay"></video></td> |
| 127 <td><video width="320" height="240" id="remote-view" |
| 128 autoplay="autoplay"></video></td> |
| 129 <td><canvas width="320" height="240" id="canvas"></canvas></td> |
| 130 </tr> |
| 131 <tr> |
| 132 <td colspan="3">You should see the same animated feed in all three |
| 133 displays (the canvas will lag a bit). |
| 134 </td> |
| 135 </table> |
| 136 </body> |
| 137 </html> |
OLD | NEW |