FS-8400 [verto_communicator] Added Camera and microphone preview after the splash screen.

This commit is contained in:
Jaon EarlWolf
2015-11-06 15:50:51 -03:00
parent 0d6e17b65a
commit 522547f84e
10 changed files with 384 additions and 16 deletions

View File

@@ -8,6 +8,10 @@ body {
padding-top: 60px;
}
.panel.panel-material-blue-900 .panel-heading {
background-color: #0d47a1;
}
.install {
color: white;
text-decoration: underline;
@@ -1469,3 +1473,39 @@ body:-webkit-full-screen #incall .video-footer {
}
}
.preview-wrapper {
position: relative;
}
.preview-wrapper video {
transform: scaleX(-1);
}
#mic-meter {
position: absolute;
bottom: 5px;
left: 10px;
}
#mic-meter .icon {
margin-left: 3px;
color: white;
}
#mic-meter .volumes {
width: 30px;
}
#mic-meter .volumes .volume-segment {
height: 10px;
width: 100%;
border-radius: 5px;
border: 2px solid white;
display: block;
margin-top: 1.5px;
}
#mic-meter .volumes .volume-segment.active {
background-color: white;
}
#preview .refresh {
margin: 15px 0px 0px 0px;
}

View File

@@ -95,6 +95,7 @@
<script type="text/javascript" src="js/3rd-party/getScreenId.js"></script>
<script type="text/javascript" src="js/3rd-party/md5.min.js"></script>
<script type="text/javascript" src="js/3rd-party/volume-meter.js"></script>
<script type="text/javascript" src="src/vertoApp/vertoApp.module.js"></script>
@@ -113,6 +114,7 @@
<script type="text/javascript" src="src/vertoControllers/controllers/ModalWsReconnectController.js"></script>
<script type="text/javascript" src="src/vertoControllers/controllers/ModalLoginInformationController.js"></script>
<script type="text/javascript" src="src/vertoControllers/controllers/ModalSettingsController.js"></script>
<script type="text/javascript" src="src/vertoControllers/controllers/PreviewController.js"></script>
<script type="text/javascript" src="src/vertoDirectives/vertoDirectives.module.js"></script>
<script type="text/javascript" src="src/vertoDirectives/directives/autofocus.js"></script>

View File

@@ -0,0 +1,70 @@
<!-- <div class="panel panel-default shadow-z-0">
<div class="" style="width: 100%; height: 100%;">
<div class="" ng-dblclick="goFullscreen()">
<video id="preview" style="width: 400px;"></video>
<svg ng-show="video != 'active'" class="spinner" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg">
<circle class="path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle>
</svg>
</div>
<div class="video-footer panel-body">
<div class="row">
<div class="col-md-6 col-xs-6 text-left">
</div>
<div class="col-md-6 col-xs-6 text-right">
<button class="btn btn-primary" ng-click="localVideo()">
<i class="mdi-communication-call-end"></i>
Get
</button>
</div>
</div>
</div>
</div>
</div> -->
<div class="centered-block-frame" id="preview">
<div class="col-md-4 col-sm-12 col-xs-12 centered-block">
<div class="panel panel-material-blue-900 shadow-z-2 ">
<div class="panel-heading">
<h3 class="panel-title text-center">Setup your camera and microphone settings</h3>
</div>
<div class="panel-body">
<div class="preview-wrapper">
<video id="videopreview" muted autoplay style="width: 100%;"></video>
<div id="mic-meter">
<div class="volumes">
<div class="volume-segment"></div>
<div class="volume-segment"></div>
<div class="volume-segment"></div>
<div class="volume-segment"></div>
<div class="volume-segment"></div>
</div>
<i class="icon mdi-hardware-keyboard-voice"></i>
</div>
</div>
<form name="form">
<div class="form-group col-md-5 col-sm-12 col-xs-12" ng-show="true">
<label for="settings-camera">Camera:</label>
<select name="camera" id="settings-camera" class="form-control" ng-model="storage.data.selectedVideo"
ng-options="item.id as item.label for item in verto.data.videoDevices" ng-change="localVideo()" >
</select>
</div>
<div class="form-group col-md-5 col-sm-12 col-xs-12" ng-show="true">
<label for="settings-microphone">Microphone:</label>
<select name="microphone" id="settings-microphone" class="form-control" ng-model="storage.data.selectedAudio"
ng-options="item.id as item.label for item in verto.data.audioDevices" ng-change="localVideo()">
</select>
</div>
<a class="btn btn-primary btn-sm col-md-2 refresh" ng-click="refreshDeviceList()">
<i class="icon mdi-action-autorenew"></i>
</a>
<div class="form-group text-center">
<button type="submit" class="btn btn-success" ng-click="endPreview()" title="Save">
Save
</button>
</div>
</form>
</div>
</div>
</div>
</div>

View File

@@ -21,6 +21,7 @@
userStatus: 'disconnected',
mutedVideo: false,
mutedMic: false,
preview: true,
selectedVideo: null,
selectedAudio: null,
selectedShare: null,

View File

@@ -41,6 +41,11 @@
templateUrl: 'partials/incall.html',
controller: 'InCallController'
}).
when('/preview', {
title: 'Preview Video',
templateUrl: 'partials/preview.html',
controller: 'PreviewController'
}).
when('/browser-upgrade', {
title: '',
templateUrl: 'partials/browser_upgrade.html',

View File

@@ -7,9 +7,9 @@
'$http', '$location', 'toastr', 'verto', 'storage', 'CallHistory', 'eventQueue',
function($rootScope, $scope, $http, $location, toastr, verto, storage, CallHistory, eventQueue) {
console.debug('Executing DialPadController.');
eventQueue.process();
$scope.call_history = CallHistory.all();
$scope.history_control = CallHistory.all_control();
$scope.has_history = Object.keys($scope.call_history).length;
@@ -55,6 +55,10 @@
$rootScope.dialpadNumber = number;
};
$scope.preview = function() {
$location.path('/preview');
};
$rootScope.transfer = function() {
if (!$rootScope.dialpadNumber) {
return false;

View File

@@ -52,7 +52,10 @@
storage.data.email = verto.data.email;
storage.data.login = verto.data.login;
storage.data.password = verto.data.password;
if (redirect) {
if (redirect && storage.data.preview) {
$location.path('/preview');
}
else if (redirect) {
$location.path('/dialpad');
}
}

View File

@@ -0,0 +1,142 @@
(function() {
'use strict';
angular
.module('vertoControllers')
.controller('PreviewController', ['$rootScope', '$scope',
'$http', '$location', '$modal', '$timeout', 'toastr', 'verto', 'storage', 'prompt', 'Fullscreen',
function($rootScope, $scope, $http, $location, $modal, $timeout, toastr,
verto, storage, prompt, Fullscreen) {
$scope.storage = storage;
console.debug('Executing PreviewController.');
var localVideo = document.getElementById('videopreview');
var volumes = document.querySelector('#mic-meter .volumes').children;
$scope.localVideo = function() {
var constraints = {
mirrored: true,
audio: {
optional: [{ sourceId: storage.data.selectedAudio }]
}
};
if (storage.data.selectedVideo !== 'none') {
constraints.video = {
optional: [{ sourceId: storage.data.selectedVideo }]
};
}
navigator.getUserMedia(constraints, handleMedia, function(err, data) {
});
};
var audioContext = new AudioContext();
var mediaStreamSource = null;
var meter;
var streamObj = {};
function handleMedia(stream) {
streamObj.stop ? streamObj.stop() : streamObj.active = false;
streamObj = stream;
localVideo.src = window.URL.createObjectURL(stream);
mediaStreamSource = audioContext.createMediaStreamSource(stream);
meter = createAudioMeter(audioContext);
mediaStreamSource.connect(meter);
renderMic();
}
function renderMic() {
// meter.volume;
var n = Math.round(meter.volume * 25);
for(var i = volumes.length -1, j = 0; i >= 0; i--, j++) {
var el = angular.element(volumes[j]);
if (i >= n) el.removeClass('active');
else el.addClass('active');
}
if(!verto.data.call) {
window.requestAnimationFrame(renderMic);
}
}
/**
* TODO: useless?
*/
$scope.refreshDeviceList = function() {
return verto.refreshDevices();
};
$scope.videoCall = function() {
prompt({
title: 'Would you like to activate video for this call?',
message: 'Video will be active during the next calls.'
}).then(function() {
storage.data.videoCall = true;
$scope.callTemplate = 'partials/video_call.html';
});
};
$scope.cbMuteVideo = function(event, data) {
storage.data.mutedVideo = !storage.data.mutedVideo;
}
$scope.cbMuteMic = function(event, data) {
storage.data.mutedMic = !storage.data.mutedMic;
}
$scope.confChangeVideoLayout = function(layout) {
verto.data.conf.setVideoLayout(layout);
};
$scope.endPreview = function() {
localVideo.src = null;
meter.shutdown();
meter.onaudioprocess = null;
streamObj.stop();
$location.path('/dialpad');
storage.data.preview = false;
};
$scope.screenshare = function() {
if(verto.data.shareCall) {
verto.screenshareHangup();
return false;
}
verto.screenshare(storage.data.called_number);
};
$scope.call = function() {
if($rootScope.dialpadNumber) {
localVideo.src = null;
meter.shutdown();
meter.onaudioprocess = null;
streamObj.stop();
}
$rootScope.call($rootScope.dialpadNumber);
};
$scope.muteMic = verto.muteMic;
$scope.muteVideo = verto.muteVideo;
$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 <a target="_blank" class="install" href="'+ pluginUrl +'">install</a> 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('Chrome', 'Error');
}
});
$scope.localVideo();
}
]);
})();

View File

@@ -3,10 +3,10 @@
angular
.module('vertoControllers')
.controller('SplashScreenController', ['$scope', '$rootScope', '$location', '$timeout', 'splashscreen', 'prompt', 'verto',
function($scope, $rootScope, $location, $timeout, splashscreen, prompt, verto) {
.controller('SplashScreenController', ['$scope', '$rootScope', '$location', '$timeout', 'storage', 'splashscreen', 'prompt', 'verto',
function($scope, $rootScope, $location, $timeout, storage, splashscreen, prompt, verto) {
console.debug('Executing SplashScreenController.');
$scope.progress_percentage = splashscreen.progress_percentage;
$scope.message = '';
$scope.interrupt_next = false;
@@ -18,26 +18,26 @@
link = activity;
}
}
$location.path(link);
}
var checkProgressState = function(current_progress, status, promise, activity, soft, interrupt, message) {
$scope.progress_percentage = splashscreen.calculate(current_progress);
$scope.progress_percentage = splashscreen.calculate(current_progress);
$scope.message = message;
if(interrupt && status == 'error') {
$scope.errors.push(message);
if(!soft) {
redirectTo('', activity);
redirectTo('', activity);
return;
} else {
message = message + '. Continue?';
message = message + '. Continue?';
};
if(!confirm(message)) {
$scope.interrupt_next = true;
};
$scope.interrupt_next = true;
};
};
if($scope.interrupt_next) {
@@ -48,7 +48,7 @@
return true;
};
$rootScope.$on('progress.next', function(ev, current_progress, status, promise, activity, soft, interrupt, message) {
$timeout(function() {
if(promise) {
@@ -62,11 +62,11 @@
return;
}
if(!checkProgressState(current_progress, status, promise, activity, soft, interrupt, message)) {
return;
}
splashscreen.next();
}, 400);
});
@@ -74,7 +74,12 @@
$rootScope.$on('progress.complete', function(ev, current_progress) {
$scope.message = 'Complete';
if(verto.data.connected) {
redirectTo('/dialpad');
if (storage.data.preview) {
$location.path('/preview');
}
else {
$location.path('/dialpad');
}
} else {
redirectTo('/login');
$location.path('/login');