OLD | NEW |
1 /** | 1 /** |
2 * Copyright 2014 The Chromium Authors. All rights reserved. | 2 * Copyright 2014 The Chromium Authors. All rights reserved. |
3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 */ | 5 */ |
6 | 6 |
7 /** | 7 /** |
8 * See http://dev.w3.org/2011/webrtc/editor/getusermedia.html for more | 8 * See http://dev.w3.org/2011/webrtc/editor/getusermedia.html for more |
9 * information on getUserMedia. See | 9 * information on getUserMedia. See |
10 * http://dev.w3.org/2011/webrtc/editor/webrtc.html for more information on | 10 * http://dev.w3.org/2011/webrtc/editor/webrtc.html for more information on |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 } | 229 } |
230 | 230 |
231 if ($('screencapture').checked) { | 231 if ($('screencapture').checked) { |
232 var constraints = { | 232 var constraints = { |
233 audio: $('audio').checked, | 233 audio: $('audio').checked, |
234 video: {mandatory: {chromeMediaSource: 'screen', | 234 video: {mandatory: {chromeMediaSource: 'screen', |
235 maxWidth: screen.width, | 235 maxWidth: screen.width, |
236 maxHeight: screen.height}} | 236 maxHeight: screen.height}} |
237 }; | 237 }; |
238 if ($('audio').checked) | 238 if ($('audio').checked) |
239 print_('Audio for screencapture is not implemented yet, please ' + | 239 warning_('Audio for screencapture is not implemented yet, please ' + |
240 'try to set audio = false prior requesting screencapture'); | 240 'try to set audio = false prior requesting screencapture'); |
241 } | 241 } |
242 | 242 |
243 $('getusermedia-constraints').value = JSON.stringify(constraints, null, ' '); | 243 $('getusermedia-constraints').value = JSON.stringify(constraints, null, ' '); |
244 } | 244 } |
245 | 245 |
246 function showServerHelp() { | 246 function showServerHelp() { |
247 alert('You need to build and run a peerconnection_server on some ' + | 247 alert('You need to build and run a peerconnection_server on some ' + |
248 'suitable machine. To build it in chrome, just run make/ninja ' + | 248 'suitable machine. To build it in chrome, just run make/ninja ' + |
249 'peerconnection_server. Otherwise, read in https://code.google' + | 249 'peerconnection_server. Otherwise, read in https://code.google' + |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 global.dtmfSender.insertDTMF(tones, duration, interToneGap); | 428 global.dtmfSender.insertDTMF(tones, duration, interToneGap); |
429 } | 429 } |
430 | 430 |
431 function handleMessage(peerConnection, message) { | 431 function handleMessage(peerConnection, message) { |
432 var parsed_msg = JSON.parse(message); | 432 var parsed_msg = JSON.parse(message); |
433 if (parsed_msg.type) { | 433 if (parsed_msg.type) { |
434 var session_description = new RTCSessionDescription(parsed_msg); | 434 var session_description = new RTCSessionDescription(parsed_msg); |
435 peerConnection.setRemoteDescription( | 435 peerConnection.setRemoteDescription( |
436 session_description, | 436 session_description, |
437 function() { success_('setRemoteDescription'); }, | 437 function() { success_('setRemoteDescription'); }, |
438 function(error) { failure_('setRemoteDescription', error); }); | 438 function(error) { error_('setRemoteDescription', error); }); |
439 if (session_description.type == 'offer') { | 439 if (session_description.type == 'offer') { |
440 print_('createAnswer with constraints: ' + | 440 print_('createAnswer with constraints: ' + |
441 JSON.stringify(global.createAnswerConstraints, null, ' ')); | 441 JSON.stringify(global.createAnswerConstraints, null, ' ')); |
442 peerConnection.createAnswer( | 442 peerConnection.createAnswer( |
443 setLocalAndSendMessage_, | 443 setLocalAndSendMessage_, |
444 function(error) { failure_('createAnswer', error); }, | 444 function(error) { error_('createAnswer', error); }, |
445 global.createAnswerConstraints); | 445 global.createAnswerConstraints); |
446 } | 446 } |
447 return; | 447 return; |
448 } else if (parsed_msg.candidate) { | 448 } else if (parsed_msg.candidate) { |
449 var candidate = new RTCIceCandidate(parsed_msg); | 449 var candidate = new RTCIceCandidate(parsed_msg); |
450 peerConnection.addIceCandidate(candidate, | 450 peerConnection.addIceCandidate(candidate, |
451 function() { success_('addIceCandidate'); }, | 451 function() { success_('addIceCandidate'); }, |
452 function(error) { failure_('addIceCandidate', error); } | 452 function(error) { error_('addIceCandidate', error); } |
453 ); | 453 ); |
454 return; | 454 return; |
455 } | 455 } |
456 error_('unknown message received'); | 456 error_('unknown message received'); |
457 } | 457 } |
458 | 458 |
459 /** | 459 /** |
460 * Sets the peerConnection constraints based on checkboxes. | 460 * Sets the peerConnection constraints based on checkboxes. |
461 * TODO (jansson) Make it possible to use the text field for constraints like | 461 * TODO (jansson) Make it possible to use the text field for constraints like |
462 * for getUserMedia. | 462 * for getUserMedia. |
(...skipping 25 matching lines...) Expand all Loading... |
488 peerConnection.onicecandidate = iceCallback_; | 488 peerConnection.onicecandidate = iceCallback_; |
489 peerConnection.ondatachannel = onCreateDataChannelCallback_; | 489 peerConnection.ondatachannel = onCreateDataChannelCallback_; |
490 return peerConnection; | 490 return peerConnection; |
491 } | 491 } |
492 | 492 |
493 function setupCall(peerConnection) { | 493 function setupCall(peerConnection) { |
494 print_('createOffer with constraints: ' + | 494 print_('createOffer with constraints: ' + |
495 JSON.stringify(global.createOfferConstraints, null, ' ')); | 495 JSON.stringify(global.createOfferConstraints, null, ' ')); |
496 peerConnection.createOffer( | 496 peerConnection.createOffer( |
497 setLocalAndSendMessage_, | 497 setLocalAndSendMessage_, |
498 function(error) { failure_('createOffer', error); }, | 498 function(error) { error_('createOffer', error); }, |
499 global.createOfferConstraints); | 499 global.createOfferConstraints); |
500 } | 500 } |
501 | 501 |
502 function answerCall(peerConnection, message) { | 502 function answerCall(peerConnection, message) { |
503 handleMessage(peerConnection, message); | 503 handleMessage(peerConnection, message); |
504 } | 504 } |
505 | 505 |
506 function createDataChannel(peerConnection, label) { | 506 function createDataChannel(peerConnection, label) { |
507 if (global.dataChannel != null && global.dataChannel.readyState != 'closed') | 507 if (global.dataChannel != null && global.dataChannel.readyState != 'closed') |
508 error_('Creating DataChannel, but we already have one.'); | 508 error_('Creating DataChannel, but we already have one.'); |
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
897 source.videoId = videoSelect.options[videoSelect.selectedIndex].value; | 897 source.videoId = videoSelect.options[videoSelect.selectedIndex].value; |
898 } | 898 } |
899 return source; | 899 return source; |
900 } | 900 } |
901 | 901 |
902 /** | 902 /** |
903 * @private | 903 * @private |
904 * @param {NavigatorUserMediaError} error Error containing details. | 904 * @param {NavigatorUserMediaError} error Error containing details. |
905 */ | 905 */ |
906 function getUserMediaFailedCallback_(error) { | 906 function getUserMediaFailedCallback_(error) { |
907 print_('GetUserMedia FAILED: Maybe the camera is in use by another process?'); | 907 error_('GetUserMedia failed with error: ' + error.name); |
908 gRequestWebcamAndMicrophoneResult = 'failed-with-error-' + error.name; | |
909 print_(gRequestWebcamAndMicrophoneResult); | |
910 } | 908 } |
911 | 909 |
912 /** @private */ | 910 /** @private */ |
913 function success_(method) { | |
914 $('messages').innerHTML += '<span style="color:green;">' + method + | |
915 '(): success. </span><br>'; | |
916 } | |
917 | |
918 /** @private */ | |
919 function failure_(method, error) { | |
920 error_(method + '() failed: ' + JSON.stringify(error)); | |
921 } | |
922 | |
923 /** @private */ | |
924 function iceCallback_(event) { | 911 function iceCallback_(event) { |
925 if (event.candidate) | 912 if (event.candidate) |
926 sendToPeer(global.remotePeerId, JSON.stringify(event.candidate)); | 913 sendToPeer(global.remotePeerId, JSON.stringify(event.candidate)); |
927 } | 914 } |
928 | 915 |
929 /** @private */ | 916 /** @private */ |
930 function setLocalAndSendMessage_(session_description) { | 917 function setLocalAndSendMessage_(session_description) { |
931 session_description.sdp = | 918 session_description.sdp = |
932 global.transformOutgoingSdp(session_description.sdp); | 919 global.transformOutgoingSdp(session_description.sdp); |
933 global.peerConnection.setLocalDescription( | 920 global.peerConnection.setLocalDescription( |
934 session_description, | 921 session_description, |
935 function() { success_('setLocalDescription'); }, | 922 function() { success_('setLocalDescription'); }, |
936 function(error) { failure_('setLocalDescription', error); }); | 923 function(error) { error_('setLocalDescription', error); }); |
937 print_('Sending SDP message:\n' + session_description.sdp); | 924 print_('Sending SDP message:\n' + session_description.sdp); |
938 sendToPeer(global.remotePeerId, JSON.stringify(session_description)); | 925 sendToPeer(global.remotePeerId, JSON.stringify(session_description)); |
939 } | 926 } |
940 | 927 |
941 /** @private */ | 928 /** @private */ |
942 function addStreamCallback_(event) { | 929 function addStreamCallback_(event) { |
943 print_('Receiving remote stream...'); | 930 print_('Receiving remote stream...'); |
944 var videoTag = document.getElementById('remote-view'); | 931 var videoTag = document.getElementById('remote-view'); |
945 attachMediaStream(videoTag, event.stream); | 932 attachMediaStream(videoTag, event.stream); |
946 | 933 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1000 window.addEventListener('loadedmetadata', function() { | 987 window.addEventListener('loadedmetadata', function() { |
1001 displayVideoSize_(videoTag);}, true); | 988 displayVideoSize_(videoTag);}, true); |
1002 | 989 |
1003 // Throw an error when no video is sent from camera but gUM returns OK. | 990 // Throw an error when no video is sent from camera but gUM returns OK. |
1004 stream.getVideoTracks()[0].onended = function() { | 991 stream.getVideoTracks()[0].onended = function() { |
1005 error_(global.localStream + ' getUserMedia successful but ' + | 992 error_(global.localStream + ' getUserMedia successful but ' + |
1006 'MediaStreamTrack.onended event fired, no frames from camera.'); | 993 'MediaStreamTrack.onended event fired, no frames from camera.'); |
1007 }; | 994 }; |
1008 | 995 |
1009 // Print information on track going to mute or back from it. | 996 // Print information on track going to mute or back from it. |
1010 // TODO(mcasas): add a warning_() function and move the following print_() | |
1011 // notifications to error_() and warning_(), respectively. | |
1012 stream.getVideoTracks()[0].onmute = function() { | 997 stream.getVideoTracks()[0].onmute = function() { |
1013 print_(global.localStream + ' track onmute event has fired'); | 998 error_(global.localStream + ' MediaStreamTrack.onmute event has fired, ' + |
| 999 'no frames to the track.'); |
1014 }; | 1000 }; |
1015 stream.getVideoTracks()[0].onunmute = function() { | 1001 stream.getVideoTracks()[0].onunmute = function() { |
1016 print_(global.localStream + ' track onunmute event has fired'); | 1002 warning_(global.localStream + ' MediaStreamTrack.onunmute event has ' + |
| 1003 'fired.'); |
1017 }; | 1004 }; |
1018 } | 1005 } |
1019 } | 1006 } |
1020 | 1007 |
1021 /** | 1008 /** |
1022 * @private | 1009 * @private |
1023 * @param {string} videoTag The ID of the video tag + stream used to | 1010 * @param {string} videoTag The ID of the video tag + stream used to |
1024 * write the size to a HTML tag based on id if the div's exists. | 1011 * write the size to a HTML tag based on id if the div's exists. |
1025 */ | 1012 */ |
1026 function displayVideoSize_(videoTag) { | 1013 function displayVideoSize_(videoTag) { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1128 if (getReadyState_() == 'no-peer-connection') { | 1115 if (getReadyState_() == 'no-peer-connection') { |
1129 preparePeerConnection(); | 1116 preparePeerConnection(); |
1130 } | 1117 } |
1131 } | 1118 } |
1132 | 1119 |
1133 /** | 1120 /** |
1134 * @private | 1121 * @private |
1135 * @param {string} message Text to print. | 1122 * @param {string} message Text to print. |
1136 */ | 1123 */ |
1137 function print_(message) { | 1124 function print_(message) { |
1138 console.log(message); | 1125 print_handler_(message, 'messages', 'black'); |
1139 $('messages').innerHTML += message + '<br>'; | |
1140 } | 1126 } |
1141 | 1127 |
1142 /** | 1128 /** |
1143 * @private | 1129 * @private |
1144 * @param {string} message Text to print. | 1130 * @param {string} message Text to print. |
1145 */ | 1131 */ |
1146 function debug_(message) { | 1132 function success_(message) { |
1147 console.log(message); | 1133 print_handler_(message, 'messages', 'green'); |
1148 $('debug').innerHTML += message + '<br>'; | |
1149 } | 1134 } |
1150 | 1135 |
1151 /** | 1136 /** |
1152 * Print error message in the debug log + JS console and throw an Error. | |
1153 * @private | 1137 * @private |
1154 * @param {string} message Text to print in red. | 1138 * @param {string} message Text to print. |
1155 */ | 1139 */ |
1156 function error_(message) { | 1140 function warning_(message) { |
1157 $('debug').innerHTML += '<span style="color:red;">' + message + '</span><br>'; | 1141 print_handler_(message, 'debug', 'orange'); |
1158 throw new Error(message); | |
1159 } | 1142 } |
1160 | 1143 |
1161 /** | 1144 /** |
| 1145 * @private |
| 1146 * @param {string} message Text to print. |
| 1147 */ |
| 1148 function error_(message) { |
| 1149 print_handler_(message, 'debug', 'red'); |
| 1150 } |
| 1151 |
| 1152 /** |
| 1153 * @private |
| 1154 * @param {string} message Text to print. |
| 1155 * @param {string} textField Element ID of where to print. |
| 1156 * @param {string} color Color of the text. |
| 1157 */ |
| 1158 function print_handler_(message, textField, color) { |
| 1159 if (color == 'red' ) |
| 1160 throw new Error(message); |
| 1161 |
| 1162 if (color == 'green' ) |
| 1163 message += ' success'; |
| 1164 |
| 1165 $(textField).innerHTML += '<span style="color:' + color + ';">' + message + |
| 1166 '</span><br>' |
| 1167 |
| 1168 console.log(message); |
| 1169 } |
| 1170 |
| 1171 /** |
1162 * @private | 1172 * @private |
1163 * @param {string} stringRepresentation JavaScript as a string. | 1173 * @param {string} stringRepresentation JavaScript as a string. |
1164 * @return {Object} The PeerConnection constraints as a JavaScript dictionary. | 1174 * @return {Object} The PeerConnection constraints as a JavaScript dictionary. |
1165 */ | 1175 */ |
1166 function getEvaluatedJavaScript_(stringRepresentation) { | 1176 function getEvaluatedJavaScript_(stringRepresentation) { |
1167 try { | 1177 try { |
1168 var evaluatedJavaScript; | 1178 var evaluatedJavaScript; |
1169 eval('evaluatedJavaScript = ' + stringRepresentation); | 1179 eval('evaluatedJavaScript = ' + stringRepresentation); |
1170 return evaluatedJavaScript; | 1180 return evaluatedJavaScript; |
1171 } catch (exception) { | 1181 } catch (exception) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1241 | 1251 |
1242 track.enabled = !track.enabled; | 1252 track.enabled = !track.enabled; |
1243 print_('ok-' + audioOrVideo + '-toggled-to-' + track.enabled); | 1253 print_('ok-' + audioOrVideo + '-toggled-to-' + track.enabled); |
1244 } | 1254 } |
1245 | 1255 |
1246 /** @private */ | 1256 /** @private */ |
1247 function connectCallback_(request) { | 1257 function connectCallback_(request) { |
1248 print_('Connect callback: ' + request.status + ', ' + request.readyState); | 1258 print_('Connect callback: ' + request.status + ', ' + request.readyState); |
1249 if (request.status == 0) { | 1259 if (request.status == 0) { |
1250 print_('peerconnection_server doesn\'t seem to be up.'); | 1260 print_('peerconnection_server doesn\'t seem to be up.'); |
1251 print_('failed-to-connect'); | 1261 error_('failed connecting to peerConnection server'); |
1252 } | 1262 } |
1253 if (request.readyState == 4 && request.status == 200) { | 1263 if (request.readyState == 4 && request.status == 200) { |
1254 global.ourPeerId = parseOurPeerId_(request.responseText); | 1264 global.ourPeerId = parseOurPeerId_(request.responseText); |
1255 global.remotePeerId = parseRemotePeerIdIfConnected_(request.responseText); | 1265 global.remotePeerId = parseRemotePeerIdIfConnected_(request.responseText); |
1256 startHangingGet_(global.serverUrl, global.ourPeerId); | 1266 startHangingGet_(global.serverUrl, global.ourPeerId); |
1257 print_('ok-connected'); | 1267 print_('ok-connected'); |
1258 } | 1268 } |
1259 } | 1269 } |
1260 | 1270 |
1261 /** @private */ | 1271 /** @private */ |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1401 | 1411 |
1402 /** @private */ | 1412 /** @private */ |
1403 function readResponseHeader_(request, key) { | 1413 function readResponseHeader_(request, key) { |
1404 var value = request.getResponseHeader(key); | 1414 var value = request.getResponseHeader(key); |
1405 if (value == null || value.length == 0) { | 1415 if (value == null || value.length == 0) { |
1406 error_('Received empty value ' + value + | 1416 error_('Received empty value ' + value + |
1407 ' for response header key ' + key + '.'); | 1417 ' for response header key ' + key + '.'); |
1408 } | 1418 } |
1409 return parseInt(value); | 1419 return parseInt(value); |
1410 } | 1420 } |
OLD | NEW |