Chromium Code Reviews| 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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1125 * @private | 1112 * @private |
| 1126 */ | 1113 */ |
| 1127 function ensureHasPeerConnection_() { | 1114 function ensureHasPeerConnection_() { |
| 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. |
|
mcasas
2014/08/21 12:28:36
What's the exclamation mark doing? Other methods d
jansson
2014/08/21 16:26:21
It indicates that the there has to a non-nullable
| |
| 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 == 'green' ) | |
|
mcasas
2014/08/21 12:28:36
Remove space before |color|.
jansson
2014/08/21 16:26:21
Done.
| |
| 1160 message += ' success'; | |
| 1161 | |
| 1162 $(textField).innerHTML += '<span style="color:' + color + ';">' + message + | |
| 1163 '</span><br>' | |
| 1164 if (color == 'red' ) | |
|
mcasas
2014/08/21 12:28:36
I'd move this to first thing in print_handler_()
jansson
2014/08/21 16:26:21
Done.
| |
| 1165 throw new Error(message); | |
| 1166 | |
| 1167 console.log(message); | |
| 1168 } | |
| 1169 | |
| 1170 /** | |
| 1162 * @private | 1171 * @private |
| 1163 * @param {string} stringRepresentation JavaScript as a string. | 1172 * @param {string} stringRepresentation JavaScript as a string. |
| 1164 * @return {Object} The PeerConnection constraints as a JavaScript dictionary. | 1173 * @return {Object} The PeerConnection constraints as a JavaScript dictionary. |
| 1165 */ | 1174 */ |
| 1166 function getEvaluatedJavaScript_(stringRepresentation) { | 1175 function getEvaluatedJavaScript_(stringRepresentation) { |
| 1167 try { | 1176 try { |
| 1168 var evaluatedJavaScript; | 1177 var evaluatedJavaScript; |
| 1169 eval('evaluatedJavaScript = ' + stringRepresentation); | 1178 eval('evaluatedJavaScript = ' + stringRepresentation); |
| 1170 return evaluatedJavaScript; | 1179 return evaluatedJavaScript; |
| 1171 } catch (exception) { | 1180 } catch (exception) { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1241 | 1250 |
| 1242 track.enabled = !track.enabled; | 1251 track.enabled = !track.enabled; |
| 1243 print_('ok-' + audioOrVideo + '-toggled-to-' + track.enabled); | 1252 print_('ok-' + audioOrVideo + '-toggled-to-' + track.enabled); |
| 1244 } | 1253 } |
| 1245 | 1254 |
| 1246 /** @private */ | 1255 /** @private */ |
| 1247 function connectCallback_(request) { | 1256 function connectCallback_(request) { |
| 1248 print_('Connect callback: ' + request.status + ', ' + request.readyState); | 1257 print_('Connect callback: ' + request.status + ', ' + request.readyState); |
| 1249 if (request.status == 0) { | 1258 if (request.status == 0) { |
| 1250 print_('peerconnection_server doesn\'t seem to be up.'); | 1259 print_('peerconnection_server doesn\'t seem to be up.'); |
| 1251 print_('failed-to-connect'); | 1260 error_('failed connecting to peerConnection server'); |
| 1252 } | 1261 } |
| 1253 if (request.readyState == 4 && request.status == 200) { | 1262 if (request.readyState == 4 && request.status == 200) { |
| 1254 global.ourPeerId = parseOurPeerId_(request.responseText); | 1263 global.ourPeerId = parseOurPeerId_(request.responseText); |
| 1255 global.remotePeerId = parseRemotePeerIdIfConnected_(request.responseText); | 1264 global.remotePeerId = parseRemotePeerIdIfConnected_(request.responseText); |
| 1256 startHangingGet_(global.serverUrl, global.ourPeerId); | 1265 startHangingGet_(global.serverUrl, global.ourPeerId); |
| 1257 print_('ok-connected'); | 1266 print_('ok-connected'); |
| 1258 } | 1267 } |
| 1259 } | 1268 } |
| 1260 | 1269 |
| 1261 /** @private */ | 1270 /** @private */ |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1401 | 1410 |
| 1402 /** @private */ | 1411 /** @private */ |
| 1403 function readResponseHeader_(request, key) { | 1412 function readResponseHeader_(request, key) { |
| 1404 var value = request.getResponseHeader(key); | 1413 var value = request.getResponseHeader(key); |
| 1405 if (value == null || value.length == 0) { | 1414 if (value == null || value.length == 0) { |
| 1406 error_('Received empty value ' + value + | 1415 error_('Received empty value ' + value + |
| 1407 ' for response header key ' + key + '.'); | 1416 ' for response header key ' + key + '.'); |
| 1408 } | 1417 } |
| 1409 return parseInt(value); | 1418 return parseInt(value); |
| 1410 } | 1419 } |
| OLD | NEW |