From 43cb965f7e93af5f7993eecc80b3654eda4d35bf Mon Sep 17 00:00:00 2001 From: Jaon EarlWolf Date: Wed, 28 Oct 2015 15:35:25 -0300 Subject: [PATCH 1/2] FS-8222 [verto_communicator] updated getScreenId.js in order to detect plugin issues and attached an 'ended' event to screenshare stream in order to detect 'stop sharing' click --- .../js/3rd-party/getScreenId.js | 149 ++++++++++++++++-- .../controllers/InCallController.js | 24 ++- .../controllers/MainController.js | 18 +-- .../src/vertoService/services/vertoService.js | 54 +++++-- 4 files changed, 207 insertions(+), 38 deletions(-) diff --git a/html5/verto/verto_communicator/js/3rd-party/getScreenId.js b/html5/verto/verto_communicator/js/3rd-party/getScreenId.js index b2cfc6d3c0..5c379b7e1a 100644 --- a/html5/verto/verto_communicator/js/3rd-party/getScreenId.js +++ b/html5/verto/verto_communicator/js/3rd-party/getScreenId.js @@ -1,10 +1,10 @@ -// Last time updated at Sep 07, 2014, 08:32:23 +// Last time updated at Oct 24, 2015, 08:32:23 // Latest file can be found here: https://cdn.webrtc-experiment.com/getScreenId.js // Muaz Khan - www.MuazKhan.com // MIT License - www.WebRTC-Experiment.com/licence -// Documentation - https://github.com/muaz-khan/WebRTC-Experiment/tree/master/getScreenId.js +// Documentation - https://github.com/muaz-khan/getScreenId. // ______________ // getScreenId.js @@ -13,7 +13,7 @@ getScreenId(function (error, sourceId, screen_constraints) { // error == null || 'permission-denied' || 'not-installed' || 'installed-disabled' || 'not-chrome' // sourceId == null || 'string' || 'firefox' - + if(sourceId == 'firefox') { navigator.mozGetUserMedia(screen_constraints, onSuccess, onFailure); } @@ -79,6 +79,11 @@ getScreenId(function (error, sourceId, screen_constraints) { } function postMessage() { + if (!iframe) { + loadIFrame(postMessage); + return; + } + if (!iframe.isLoaded) { setTimeout(postMessage, 100); return; @@ -89,11 +94,137 @@ getScreenId(function (error, sourceId, screen_constraints) { }, '*'); } - var iframe = document.createElement('iframe'); - iframe.onload = function() { - iframe.isLoaded = true; + function loadIFrame(loadCallback) { + if (iframe) { + loadCallback(); + return; + } + + iframe = document.createElement('iframe'); + iframe.onload = function() { + iframe.isLoaded = true; + + loadCallback(); + }; + iframe.src = 'https://www.webrtc-experiment.com/getSourceId/'; // https://wwww.yourdomain.com/getScreenId.html + iframe.style.display = 'none'; + (document.body || document.documentElement).appendChild(iframe); + } + + var iframe; + + // this function is used in v3.0 + window.getScreenConstraints = function(callback) { + loadIFrame(function() { + getScreenId(function(error, sourceId, screen_constraints) { + callback(error, screen_constraints.video); + }); + }); + }; +})(); + +(function() { + if(document.domain.indexOf('webrtc-experiment.com') === -1) { + return; + } + + window.getScreenId = function(callback) { + // for Firefox: + // sourceId == 'firefox' + // screen_constraints = {...} + if (!!navigator.mozGetUserMedia) { + callback(null, 'firefox', { + video: { + mozMediaSource: 'window', + mediaSource: 'window' + } + }); + return; + } + + postMessage(); + + window.addEventListener('message', onIFrameCallback); + + function onIFrameCallback(event) { + if (!event.data) return; + + if (event.data.chromeMediaSourceId) { + if (event.data.chromeMediaSourceId === 'PermissionDeniedError') { + callback('permission-denied'); + } else callback(null, event.data.chromeMediaSourceId, getScreenConstraints(null, event.data.chromeMediaSourceId)); + } + + if (event.data.chromeExtensionStatus) { + callback(event.data.chromeExtensionStatus, null, getScreenConstraints(event.data.chromeExtensionStatus)); + } + + // this event listener is no more needed + window.removeEventListener('message', onIFrameCallback); + } + }; + + function getScreenConstraints(error, sourceId) { + var screen_constraints = { + audio: false, + video: { + mandatory: { + chromeMediaSource: error ? 'screen' : 'desktop', + maxWidth: window.screen.width > 1920 ? window.screen.width : 1920, + maxHeight: window.screen.height > 1080 ? window.screen.height : 1080 + }, + optional: [] + } + }; + + if (sourceId) { + screen_constraints.video.mandatory.chromeMediaSourceId = sourceId; + } + + return screen_constraints; + } + + function postMessage() { + if (!iframe) { + loadIFrame(postMessage); + return; + } + + if (!iframe.isLoaded) { + setTimeout(postMessage, 100); + return; + } + + iframe.contentWindow.postMessage({ + captureSourceId: true + }, '*'); + } + + function loadIFrame(loadCallback) { + if (iframe) { + loadCallback(); + return; + } + + iframe = document.createElement('iframe'); + iframe.onload = function() { + iframe.isLoaded = true; + + loadCallback(); + }; + iframe.src = 'https://www.webrtc-experiment.com/getSourceId/'; // https://wwww.yourdomain.com/getScreenId.html + iframe.style.display = 'none'; + (document.body || document.documentElement).appendChild(iframe); + } + + var iframe; + + // this function is used in v3.0 + window.getScreenConstraints = function(callback) { + loadIFrame(function() { + getScreenId(function(error, sourceId, screen_constraints) { + callback(error, screen_constraints.video); + }); + }); }; - iframe.src = 'https://www.webrtc-experiment.com/getSourceId/'; - iframe.style.display = 'none'; - (document.body || document.documentElement).appendChild(iframe); })(); diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js index 84d8894b28..b3a1870963 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js @@ -19,7 +19,7 @@ if (storage.data.videoCall) { $scope.callTemplate = 'partials/video_call.html'; } - + $rootScope.$on('call.conference', function(event, data) { $timeout(function() { if($scope.chatStatus) { @@ -75,9 +75,31 @@ verto.data.conf.setVideoLayout(layout); }; + + $scope.screenshare = function() { + if(verto.data.shareCall) { + verto.screenshareHangup(); + return false; + } + verto.screenshare(storage.data.called_number); + }; + $scope.muteMic = verto.muteMic; $scope.muteVideo = verto.muteVideo; + $scope.$on('ScreenShareExtensionStatus', function(error) { + switch(error) { + case 'permission-denied': + toastr.info('Please allow the plugin in order to use Screen Share', 'Error'); break; + case 'not-installed': + toastr.warning('Please install the plugin in order to use Screen Share', 'Warning'); break; + case 'installed-disabled': + toastr.info('Please enable the plugin in order to use Screen Share', 'Error'); break; + // case 'not-chrome' + // toastr.info('Please allow the plugin in order to use Screen Share', 'Error'); + } + }); + $timeout(function() { console.log('broadcast time-start incall'); $scope.$broadcast('timer-start'); diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js index b34aad8631..571558c780 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js @@ -24,13 +24,13 @@ * @type {string} */ $rootScope.dialpadNumber = ''; - + // If verto is not connected, redirects to login page. if (!verto.data.connected) { console.debug('MainController: WebSocket not connected. Redirecting to login.'); $location.path('/'); } - + $rootScope.$on('config.http.success', function(ev) { $scope.login(false); }); @@ -58,7 +58,7 @@ } }); }; - + verto.data.connecting = true; verto.connect(connectCallback); }; @@ -135,7 +135,7 @@ templateUrl: templateUrl, controller: controller, }; - + angular.extend(options, _options); var modalInstance = $modal.open(options); @@ -154,7 +154,7 @@ jQuery.material.init(); } ); - + return modalInstance; }; @@ -454,14 +454,6 @@ $scope.incomingCall = false; }; - $scope.screenshare = function() { - if (verto.data.shareCall) { - verto.screenshareHangup(); - return false; - } - verto.screenshare(storage.data.called_number); - }; - $scope.play = function() { var file = $scope.promptInput('Please, enter filename', '', 'File', function(file) { diff --git a/html5/verto/verto_communicator/src/vertoService/services/vertoService.js b/html5/verto/verto_communicator/src/vertoService/services/vertoService.js index 26c13c6fc1..71b823fb29 100644 --- a/html5/verto/verto_communicator/src/vertoService/services/vertoService.js +++ b/html5/verto/verto_communicator/src/vertoService/services/vertoService.js @@ -169,7 +169,7 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora var height = res[1]; if(resolution.width == width && resolution.height == height) { - videoQuality.push(resolution); + videoQuality.push(resolution); } }); }); @@ -200,9 +200,9 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora refreshDevicesCallback : function refreshDevicesCallback(callback) { data.videoDevices = [{ - id: 'none', - label: 'No Camera' - }]; + id: 'none', + label: 'No Camera' + }]; data.shareDevices = [{ id: 'screen', label: 'Screen' @@ -556,10 +556,10 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora // Checking if we have a failed connection attempt before // connecting again. if (data.instance && !data.instance.rpcClient.socketReady()) { - clearTimeout(data.instance.rpcClient.to); - data.instance.logout(); - data.instance.login(); - return; + clearTimeout(data.instance.rpcClient.to); + data.instance.logout(); + data.instance.login(); + return; }; data.instance = new jQuery.verto({ login: data.login + '@' + data.hostname, @@ -583,22 +583,22 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora jQuery.verto.unloadJobs.push(function() { that.reloaded = true; }); - data.instance.deviceParams({ - useCamera: storage.data.selectedVideo, - useMic: storage.data.selectedAudio, - onResCheck: that.refreshVideoResolution - }); + data.instance.deviceParams({ + useCamera: storage.data.selectedVideo, + useMic: storage.data.selectedAudio, + onResCheck: that.refreshVideoResolution + }); } if (data.mediaPerm) { ourBootstrap(); } else { - $.FSRTC.checkPerms(ourBootstrap, true, true); + $.FSRTC.checkPerms(ourBootstrap, true, true); } }, mediaPerm: function(callback) { - $.FSRTC.checkPerms(callback, true, true); + $.FSRTC.checkPerms(callback, true, true); }, /** @@ -681,6 +681,12 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora var that = this; getScreenId(function(error, sourceId, screen_constraints) { + + if(error) { + $rootScope.$emit('ScreenShareExtensionStatus', error); + return; + } + var call = data.instance.newCall({ destination_number: destination + '-screen', caller_id_name: data.name + ' (Screen)', @@ -698,6 +704,24 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora } }); + + call.rtc.options.callbacks.onStream = function(rtc, stream) { + if(stream) { + var StreamTrack = stream.getVideoTracks()[0]; + StreamTrack.addEventListener('ended', stopSharing); + // (stream.getVideoTracks()[0]).onended = stopSharing; + } + + console.log("stream started"); + + function stopSharing() { + if(that.data.shareCall) { + that.screenshareHangup(); + console.log("screenshare ended"); + } + } + }; + data.shareCall = call; console.log('shareCall', data); From 320cf0adb837a8860c09c717b29c666ccb9a3c5b Mon Sep 17 00:00:00 2001 From: Jaon EarlWolf Date: Thu, 29 Oct 2015 15:15:27 -0300 Subject: [PATCH 2/2] Target link for the plugin url, added comment explaining override $.FSRTC callback --- html5/verto/verto_communicator/src/css/verto.css | 5 +++++ .../src/vertoControllers/controllers/InCallController.js | 9 +++++---- .../src/vertoService/services/vertoService.js | 6 +++--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/html5/verto/verto_communicator/src/css/verto.css b/html5/verto/verto_communicator/src/css/verto.css index d307eecdaf..9d75a32037 100644 --- a/html5/verto/verto_communicator/src/css/verto.css +++ b/html5/verto/verto_communicator/src/css/verto.css @@ -8,6 +8,11 @@ body { padding-top: 60px; } +.install { + color: white; + text-decoration: underline; +} + .ellipsis { text-overflow: ellipsis; overflow: hidden; diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js index b3a1870963..7f8d7b0765 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js @@ -5,7 +5,7 @@ .module('vertoControllers') .controller('InCallController', ['$rootScope', '$scope', '$http', '$location', '$modal', '$timeout', 'toastr', 'verto', 'storage', 'prompt', 'Fullscreen', - function($rootScope, $scope, $http, $location, $modal, $timeout, toatr, + function($rootScope, $scope, $http, $location, $modal, $timeout, toastr, verto, storage, prompt, Fullscreen) { console.debug('Executing InCallController.'); @@ -87,16 +87,17 @@ $scope.muteMic = verto.muteMic; $scope.muteVideo = verto.muteVideo; - $scope.$on('ScreenShareExtensionStatus', function(error) { + $rootScope.$on('ScreenShareExtensionStatus', function(event, error) { + var pluginUrl = 'https://chrome.google.com/webstore/detail/screen-capturing/ajhifddimkapgcifgcodmmfdlknahffk'; switch(error) { case 'permission-denied': toastr.info('Please allow the plugin in order to use Screen Share', 'Error'); break; case 'not-installed': - toastr.warning('Please install the plugin in order to use Screen Share', 'Warning'); break; + toastr.warning('Please install the plugin in order to use Screen Share', 'Warning', { allowHtml: true }); break; case 'installed-disabled': toastr.info('Please enable the plugin in order to use Screen Share', 'Error'); break; // case 'not-chrome' - // toastr.info('Please allow the plugin in order to use Screen Share', 'Error'); + // toastr.info('Chrome', 'Error'); } }); diff --git a/html5/verto/verto_communicator/src/vertoService/services/vertoService.js b/html5/verto/verto_communicator/src/vertoService/services/vertoService.js index 71b823fb29..6f0366740b 100644 --- a/html5/verto/verto_communicator/src/vertoService/services/vertoService.js +++ b/html5/verto/verto_communicator/src/vertoService/services/vertoService.js @@ -704,7 +704,7 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora } }); - + // Override onStream callback in $.FSRTC instance call.rtc.options.callbacks.onStream = function(rtc, stream) { if(stream) { var StreamTrack = stream.getVideoTracks()[0]; @@ -712,8 +712,8 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora // (stream.getVideoTracks()[0]).onended = stopSharing; } - console.log("stream started"); - + console.log("screenshare started"); + function stopSharing() { if(that.data.shareCall) { that.screenshareHangup();