Changes the implementation to show availability of video and sound devices.

This commit is contained in:
hristoterezov 2015-03-27 11:36:39 +02:00
parent 8ac44491d0
commit 58cc21d417
13 changed files with 18608 additions and 18357 deletions

View File

@ -415,3 +415,28 @@
left: 35px;
border-radius: 200px;
}
.noMic {
position: absolute;
border-radius: 8px;
z-index: 1;
width: 100%;
height: 100%;
background-image: url("../images/noMic.png");
background-color: #000;
background-repeat: no-repeat;
background-position: center;
}
.noVideo {
position: absolute;
border-radius: 8px;
z-index: 1;
width: 100%;
height: 100%;
background-image: url("../images/noVideo.png");
background-color: #000;
background-repeat: no-repeat;
background-position: center;
}

BIN
images/noMic.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
images/noVideo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -19,12 +19,12 @@
<script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib -->
<script src="libs/toastr.js?v=1"></script><!-- notifications lib -->
<script src="interface_config.js?v=5"></script>
<script src="libs/app.bundle.js?v=47"></script>
<script src="libs/app.bundle.js?v=48"></script>
<script src="analytics.js?v=1"></script><!-- google analytics plugin -->
<link rel="stylesheet" href="css/font.css?v=6"/>
<link rel="stylesheet" href="css/toastr.css?v=1">
<link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=30"/>
<link rel="stylesheet" type="text/css" media="screen" href="css/videolayout_default.css?v=16" id="videolayout_default"/>
<link rel="stylesheet" type="text/css" media="screen" href="css/videolayout_default.css?v=17" id="videolayout_default"/>
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
<link rel="stylesheet" href="css/jquery-impromptu.css?v=4">
<link rel="stylesheet" href="css/modaldialog.css?v=3">

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,7 @@ var DesktopSharingEventTypes
= require("../../service/desktopsharing/DesktopSharingEventTypes");
var MediaStreamType = require("../../service/RTC/MediaStreamTypes");
var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js");
var RTCEvents = require("../../service/RTC/RTCEvents.js");
var XMPPEvents = require("../../service/xmpp/XMPPEvents");
var UIEvents = require("../../service/UI/UIEvents");
@ -14,6 +15,10 @@ var eventEmitter = new EventEmitter();
var RTC = {
rtcUtils: null,
devices: {
audio: false,
video: false
},
localStreams: [],
remoteStreams: {},
localAudio: null,
@ -37,6 +42,7 @@ var RTC = {
if(this.localStreams.length == 0 ||
this.localStreams[0].getOriginalStream() != stream)
this.localStreams.push(localStream);
if(type == "audio")
{
this.localAudio = localStream;
@ -224,6 +230,11 @@ var RTC = {
callback,
options);
}
},
setDeviceAvailability: function (devices) {
this.devices.audio = (devices && devices.audio === true);
this.devices.video = (devices && devices.video === true);
eventEmitter.emit(RTCEvents.AVAILABLE_DEVICES_CHANGED, this.devices);
}
};

View File

@ -225,6 +225,8 @@ RTCUtils.prototype.getUserMediaWithConstraints = function(
var isFF = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
var self = this;
try {
if (config.enableSimulcast
&& constraints.video
@ -236,10 +238,12 @@ RTCUtils.prototype.getUserMediaWithConstraints = function(
&& !isFF) {
APP.simulcast.getUserMedia(constraints, function (stream) {
console.log('onUserMediaSuccess');
self.setAvailableDevices(um, true);
success_callback(stream);
},
function (error) {
console.warn('Failed to get access to local media. Error ', error);
self.setAvailableDevices(um, false);
if (failure_callback) {
failure_callback(error);
}
@ -249,9 +253,11 @@ RTCUtils.prototype.getUserMediaWithConstraints = function(
this.getUserMedia(constraints,
function (stream) {
console.log('onUserMediaSuccess');
self.setAvailableDevices(um, true);
success_callback(stream);
},
function (error) {
self.setAvailableDevices(um, false);
console.warn('Failed to get access to local media. Error ',
error, constraints);
if (failure_callback) {
@ -268,6 +274,19 @@ RTCUtils.prototype.getUserMediaWithConstraints = function(
}
};
RTCUtils.prototype.setAvailableDevices = function (um, available) {
var devices = {};
if(um.indexOf("video") != -1)
{
devices.video = available;
}
if(um.indexOf("audio") != -1)
{
devices.audio = available;
}
this.service.setDeviceAvailability(devices);
}
/**
* We ask for audio and video combined stream in order to get permissions and
* not to ask twice.
@ -328,8 +347,6 @@ RTCUtils.prototype.errorCallback = function (error) {
function (error) {
console.error('failed to obtain audio/video stream - stop',
error);
// APP.UI.messageHandler.showError("dialog.error",
// "dialog.failedpermissions");
return self.successCallback(null);
}
);

View File

@ -105,7 +105,10 @@ function registerListeners() {
function (endpointSimulcastLayers) {
VideoLayout.onSimulcastLayersChanging(endpointSimulcastLayers);
});
APP.RTC.addListener(RTCEvents.AVAILABLE_DEVICES_CHANGED,
function (devices) {
VideoLayout.setDeviceAvailabilityIcons(null, devices);
})
APP.statistics.addAudioLevelListener(function(jid, audioLevel)
{
var resourceJid;
@ -214,8 +217,12 @@ function registerListeners() {
APP.xmpp.addListener(XMPPEvents.PASSWORD_REQUIRED, onPasswordReqiured);
APP.xmpp.addListener(XMPPEvents.CHAT_ERROR_RECEIVED, chatAddError);
APP.xmpp.addListener(XMPPEvents.ETHERPAD, initEtherpad);
APP.xmpp.addListener(XMPPEvents.AUTHENTICATION_REQUIRED, onAuthenticationRequired);
APP.xmpp.addListener(XMPPEvents.AUTHENTICATION_REQUIRED,
onAuthenticationRequired);
APP.xmpp.addListener(XMPPEvents.DEVICE_AVAILABLE,
function (resource, devices) {
VideoLayout.setDeviceAvailabilityIcons(resource, devices);
});
}

View File

@ -639,6 +639,48 @@ var VideoLayout = (function (my) {
};
/**
* Adds or removes icons for not available camera and microphone.
* @param resourceJid the jid of user
* @param devices available devices
*/
my.setDeviceAvailabilityIcons = function (resourceJid, devices) {
if(!devices)
return;
var container = null
if(!resourceJid)
{
container = $("#localVideoContainer")[0];
}
else
{
container = $("#participant_" + resourceJid)[0];
}
if(!container)
return;
$("#" + container.id + " > .noMic").remove();
$("#" + container.id + " > .noVideo").remove();
if(!devices.audio)
{
container.appendChild(document.createElement("div")).setAttribute("class","noMic");
}
if(!devices.video)
{
container.appendChild(document.createElement("div")).setAttribute("class","noVideo");
}
if(!devices.audio && !devices.video)
{
$("#" + container.id + " > .noMic").css("background-position", "75%");
$("#" + container.id + " > .noVideo").css("background-position", "25%");
$("#" + container.id + " > .noVideo").css("background-color", "transparent");
}
}
/**
* Checks if removed video is currently displayed and tries to display
* another one instead.

View File

@ -143,6 +143,25 @@ module.exports = function(XMPP, eventEmitter) {
$(document).trigger('videomuted.muc', [from, videoMuted.text()]);
}
var devices = $(pres).find('>devices');
if(devices.length)
{
var audio = devices.find('>audio');
var video = devices.find('>video');
var devicesValues = {audio: false, video: false};
if(audio.length && audio.text() === "true")
{
devicesValues.audio = true;
}
if(video.length && video.text() === "true")
{
devicesValues.video = true;
}
eventEmitter.emit(XMPPEvents.DEVICE_AVAILABLE,
Strophe.getResourceFromJid(from), devicesValues);
}
var stats = $(pres).find('>stats');
if (stats.length) {
var statsObj = {};
@ -422,6 +441,11 @@ module.exports = function(XMPP, eventEmitter) {
.t(this.presMap['displayName']).up();
}
if(this.presMap["devices"])
{
pres.c('devices').c('audio').t(this.presMap['devices'].audio).up()
.c('video').t(this.presMap['devices'].video).up().up();
}
if (this.presMap['audions']) {
pres.c('audiomuted', {xmlns: this.presMap['audions']})
.t(this.presMap['audiomuted']).up();
@ -485,6 +509,9 @@ module.exports = function(XMPP, eventEmitter) {
this.presMap['source' + sourceNumber + '_ssrc'] = ssrcs;
this.presMap['source' + sourceNumber + '_direction'] = direction;
},
addDevicesToPresence: function (devices) {
this.presMap['devices'] = devices;
},
clearPresenceMedia: function () {
var self = this;
Object.keys(this.presMap).forEach(function (key) {

View File

@ -6,6 +6,7 @@ var SDP = require("./SDP");
var Settings = require("../settings/Settings");
var Pako = require("pako");
var StreamEventTypes = require("../../service/RTC/StreamEventTypes");
var RTCEvents = require("../../service/RTC/RTCEvents");
var UIEvents = require("../../service/UI/UIEvents");
var XMPPEvents = require("../../service/xmpp/XMPPEvents");
@ -102,6 +103,9 @@ function initStrophePlugins()
function registerListeners() {
APP.RTC.addStreamListener(maybeDoJoin,
StreamEventTypes.EVENT_TYPE_LOCAL_CREATED);
APP.RTC.addListener(RTCEvents.AVAILABLE_DEVICES_CHANGED, function (devices) {
XMPP.addToPresence("devices", devices);
})
APP.UI.addListener(UIEvents.NICKNAME_CHANGED, function (nickname) {
XMPP.addToPresence("displayName", nickname);
});
@ -385,6 +389,9 @@ var XMPP = {
case "email":
connection.emuc.addEmailToPresence(value);
break;
case "devices":
connection.emuc.addDevicesToPresence(value);
break;
default :
console.log("Unknown tag for presence: " + name);
return;

View File

@ -5,7 +5,8 @@ var RTCEvents = {
SIMULCAST_LAYER_CHANGED: "rtc.simulcast_layer_changed",
SIMULCAST_LAYER_CHANGING: "rtc.simulcast_layer_changing",
SIMULCAST_START: "rtc.simlcast_start",
SIMULCAST_STOP: "rtc.simlcast_stop"
SIMULCAST_STOP: "rtc.simlcast_stop",
AVAILABLE_DEVICES_CHANGED: "rtc.available_devices_changed"
};
module.exports = RTCEvents;

View File

@ -24,6 +24,7 @@ var XMPPEvents = {
PASSWORD_REQUIRED: "xmpp.password_required",
AUTHENTICATION_REQUIRED: "xmpp.authentication_required",
CHAT_ERROR_RECEIVED: "xmpp.chat_error_received",
ETHERPAD: "xmpp.etherpad"
ETHERPAD: "xmpp.etherpad",
DEVICE_AVAILABLE: "xmpp.device_available"
};
module.exports = XMPPEvents;