Merge remote-tracking branch 'upstream/master'

pull/87/head
turint 11 years ago
commit f90c277a49
  1. 2
      app.js
  2. 33
      chat.js
  3. 3
      config.js
  4. 23
      css/main.css
  5. 2
      css/videolayout_default.css
  6. 61
      data_channels.js
  7. 12
      index.html
  8. 167
      libs/colibri/colibri.focus.js
  9. 2
      libs/strophe/strophe.jingle.adapter.js
  10. 88
      toolbar.js
  11. 82
      videolayout.js

@ -562,7 +562,7 @@ $(document).bind('callactive.jingle', function (event, videoelem, sid) {
// Update the large video to the last added video only if there's no
// current active or focused speaker.
if (!focusedVideoSrc && !VideoLayout.getActiveSpeakerResourceJid())
if (!focusedVideoSrc && !VideoLayout.getDominantSpeakerResourceJid())
VideoLayout.updateLargeVideo(videoelem.attr('src'), 1);
VideoLayout.showFocusIndicator();

@ -115,8 +115,7 @@ var Chat = (function (my) {
+ '</div>');
$('#chatconversation').animate(
{ scrollTop: $('#chatconversation')[0].scrollHeight}, 1000);
}
};
/**
* Sets the subject to the UI
@ -135,8 +134,7 @@ var Chat = (function (my) {
{
$("#subject").css({display: "block"});
}
}
};
/**
* Opens / closes the chat area.
@ -159,6 +157,10 @@ var Chat = (function (my) {
var horizontalIndent = videoPosition[0];
var verticalIndent = videoPosition[1];
var thumbnailSize = VideoLayout.calculateThumbnailSize(videospaceWidth);
var thumbnailsWidth = thumbnailSize[0];
var thumbnailsHeight = thumbnailSize[1];
if (chatspace.is(":visible")) {
videospace.animate({right: chatSize[0],
width: videospaceWidth,
@ -166,6 +168,15 @@ var Chat = (function (my) {
{queue: false,
duration: 500});
$('#remoteVideos').animate({height: thumbnailsHeight},
{queue: false,
duration: 500});
$('#remoteVideos>span').animate({height: thumbnailsHeight,
width: thumbnailsWidth},
{queue: false,
duration: 500});
$('#largeVideoContainer').animate({ width: videospaceWidth,
height: videospaceHeight},
{queue: false,
@ -187,6 +198,9 @@ var Chat = (function (my) {
duration: 500});
}
else {
// Undock the toolbar when the chat is shown.
Toolbar.dockToolbar(false);
videospace.animate({right: chatSize[0],
width: videospaceWidth,
height: videospaceHeight},
@ -198,6 +212,15 @@ var Chat = (function (my) {
}
});
$('#remoteVideos').animate({height: thumbnailsHeight},
{queue: false,
duration: 500});
$('#remoteVideos>span').animate({height: thumbnailsHeight,
width: thumbnailsWidth},
{queue: false,
duration: 500});
$('#largeVideoContainer').animate({ width: videospaceWidth,
height: videospaceHeight},
{queue: false,
@ -290,7 +313,7 @@ var Chat = (function (my) {
if (unreadMessages) {
unreadMsgElement.innerHTML = unreadMessages.toString();
Toolbar.showToolbar();
Toolbar.dockToolbar(true);
var chatButtonElement
= document.getElementById('chatButton').parentNode;

@ -13,6 +13,7 @@ var config = {
chromeExtensionId: 'diibjkoicjeejcmhdnailmkgecihlobk', // Id of desktop streamer Chrome extension
minChromeExtVersion: '0.1', // Required version of Chrome extension
enableRtpStats: false, // Enables RTP stats processing
openSctp: true, //Toggle to enable/disable SCTP channels
openSctp: true, // Toggle to enable/disable SCTP channels
// channelLastN: -1, // The default value of the channel attribute last-n.
enableRecording: false
};

@ -131,15 +131,24 @@ html, body{
}
#chatButton {
-webkit-transition: all .5s ease-in-out;;
-moz-transition: all .5s ease-in-out;;
transition: all .5s ease-in-out;;
-webkit-transition: all .5s ease-in-out;
-moz-transition: all .5s ease-in-out;
transition: all .5s ease-in-out;
}
/*#ffde00*/
#chatButton.active {
-webkit-text-shadow: 0 0 10px #ffffff;
-moz-text-shadow: 0 0 10px #ffffff;
text-shadow: 0 0 10px #ffffff;
-webkit-text-shadow: -1px 0 10px #00ccff,
0 1px 10px #00ccff,
1px 0 10px #00ccff,
0 -1px 10px #00ccff;
-moz-text-shadow: 1px 0 10px #00ccff,
0 1px 10px #00ccff,
1px 0 10px #00ccff,
0 -1px 10px #00ccff;
text-shadow: -1px 0 10px #00ccff,
0 1px 10px #00ccff,
1px 0 10px #00ccff,
0 -1px 10px #00ccff;
}
a.button:hover {

@ -94,7 +94,7 @@
height: 100%;
}
.activespeaker {
.dominantspeaker {
background: #000 !important;
}

@ -10,7 +10,7 @@ function onDataChannel(event)
dataChannel.onopen = function ()
{
console.info("Data channel opened by the bridge !!!", dataChannel);
console.info("Data channel opened by the Videobridge!", dataChannel);
// Code sample for sending string and/or binary data
// Sends String message to the bridge
@ -26,18 +26,56 @@ function onDataChannel(event)
dataChannel.onmessage = function (event)
{
var msgData = event.data;
console.info("Got Data Channel Message:", msgData, dataChannel);
var data = event.data;
// JSON
var obj;
// Active speaker event
if (msgData.indexOf('activeSpeaker') === 0)
try
{
obj = JSON.parse(data);
}
catch (e)
{
console.error(
"Failed to parse data channel message as JSON: ",
data,
dataChannel);
}
if (('undefined' !== typeof(obj)) && (null !== obj))
{
// Endpoint ID from the bridge
var resourceJid = msgData.split(":")[1];
var colibriClass = obj.colibriClass;
console.info(
"Data channel new active speaker event: " + resourceJid);
$(document).trigger('activespeakerchanged', [resourceJid]);
if ("DominantSpeakerEndpointChangeEvent" === colibriClass)
{
// Endpoint ID from the Videobridge.
var dominantSpeakerEndpoint = obj.dominantSpeakerEndpoint;
console.info(
"Data channel new dominant speaker event: ",
dominantSpeakerEndpoint);
$(document).trigger(
'dominantspeakerchanged',
[dominantSpeakerEndpoint]);
}
else if ("LastNEndpointsChangeEvent" === colibriClass)
{
// The new/latest list of last-n endpoint IDs.
var lastNEndpoints = obj.lastNEndpoints;
/*
* The list of endpoint IDs which are entering the list of
* last-n at this time i.e. were not in the old list of last-n
* endpoint IDs.
*/
var endpointsEnteringLastN = obj.endpointsEnteringLastN;
console.debug(
"Data channel new last-n event: ",
lastNEndpoints);
}
else
{
console.debug("Data channel JSON-formatted message: ", obj);
}
}
};
@ -77,4 +115,5 @@ function bindDataChannelListener(peerConnection)
var msgData = event.data;
console.info("Got My Data Channel Message:", msgData, dataChannel);
};*/
}
}

@ -27,9 +27,9 @@
<script src="estos_log.js?v=2"></script><!-- simple stanza logger -->
<script src="desktopsharing.js?v=2"></script><!-- desktop sharing -->
<script src="data_channels.js?v=2"></script><!-- data channels -->
<script src="app.js?v=29"></script><!-- application logic -->
<script src="app.js?v=3"></script><!-- application logic -->
<script src="commands.js?v=1"></script><!-- application logic -->
<script src="chat.js?v=6"></script><!-- chat logic -->
<script src="chat.js?v=7"></script><!-- chat logic -->
<script src="util.js?v=5"></script><!-- utility functions -->
<script src="etherpad.js?v=8"></script><!-- etherpad plugin -->
<script src="prezi.js?v=4"></script><!-- prezi plugin -->
@ -39,11 +39,11 @@
<script src="analytics.js?v=1"></script><!-- google analytics plugin -->
<script src="rtp_stats.js?v=1"></script><!-- RTP stats processing -->
<script src="local_stats.js?v=1"></script><!-- Local stats processing -->
<script src="videolayout.js?v=4"></script><!-- video ui -->
<script src="toolbar.js?v=2"></script><!-- toolbar ui -->
<script src="videolayout.js?v=6"></script><!-- video ui -->
<script src="toolbar.js?v=3"></script><!-- toolbar ui -->
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
<link rel="stylesheet" href="css/font.css"/>
<link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=21"/>
<link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=22"/>
<link rel="stylesheet" type="text/css" media="screen" href="css/videolayout_default.css?v=7" id="videolayout_default"/>
<link rel="stylesheet" href="css/jquery-impromptu.css?v=4">
<link rel="stylesheet" href="css/modaldialog.css?v=3">
@ -123,7 +123,7 @@
<!--<video id="localVideo" autoplay oncontextmenu="return false;" muted></video> - is now per stream generated -->
</span>
<audio id="localAudio" autoplay oncontextmenu="return false;" muted></audio>
<span class="focusindicator" data-content="The owner of&#10;this conference" data-toggle="popover" data-placement="top"></span>
<span class="focusindicator"></span>
</span>
<audio id="userJoined" src="sounds/joined.wav" preload="auto"></audio>
<audio id="userLeft" src="sounds/left.wav" preload="auto"></audio>

@ -54,17 +54,22 @@ function ColibriFocus(connection, bridgejid) {
* Default channel expire value in seconds.
* @type {number}
*/
this.channelExpire = 60;
this.channelExpire
= ('number' === typeof(config.channelExpire))
? config.channelExpire
: 15;
/**
* Default channel last-n value.
* @type {number}
*/
this.channelLastN
= ('number' === typeof(config.channelLastN)) ? config.channelLastN : -1;
// media types of the conference
if (config.openSctp)
{
this.media = ['audio', 'video', 'data'];
}
else
{
this.media = ['audio', 'video'];
}
this.connection.jingle.sessions[this.sid] = this;
this.mychannel = [];
@ -202,29 +207,33 @@ ColibriFocus.prototype._makeConference = function () {
elem.c('conference', {xmlns: 'http://jitsi.org/protocol/colibri'});
this.media.forEach(function (name) {
var isData = name === 'data';
var channel = isData ? 'sctpconnection' : 'channel';
var elemName;
var elemAttrs = { initiator: 'true', expire: self.channelExpire };
if ('data' === name)
{
elemName = 'sctpconnection';
elemAttrs['port'] = 5000;
}
else
{
elemName = 'channel';
if (('video' === name) && (this.channelLastN >= 0))
elemAttrs['last-n'] = this.channelLastN;
}
elem.c('content', {name: name});
elem.c(channel, {
initiator: 'true',
expire: '15',
endpoint: self.myMucResource
});
if (isData)
elem.attrs({port: 5000});
elem.up();// end of channel
elem.c(elemName, elemAttrs);
elem.attrs({ endpoint: self.myMucResource });
elem.up();// end of channel/sctpconnection
for (var j = 0; j < self.peers.length; j++) {
elem.c(channel, {
initiator: 'true',
expire: '15',
endpoint: self.peers[j].substr(1 + self.peers[j].lastIndexOf('/'))
});
if (isData)
elem.attrs({port: 5000});
elem.up(); // end of channel
var peer = self.peers[j];
elem.c(elemName, elemAttrs);
elem.attrs({ endpoint: peer.substr(1 + peer.lastIndexOf('/')) });
elem.up(); // end of channel/sctpconnection
}
elem.up(); // end of content
});
@ -233,7 +242,7 @@ ColibriFocus.prototype._makeConference = function () {
localSDP.media.forEach(function (media, channel) {
var name = SDPUtil.parse_mline(media.split('\r\n')[0]).media;
elem.c('content', {name: name});
elem.c('channel', {initiator: 'false', expire: '15'});
elem.c('channel', {initiator: 'false', expire: self.channelExpire});
// FIXME: should reuse code from .toJingle
var mline = SDPUtil.parse_mline(media.split('\r\n')[0]);
@ -247,7 +256,7 @@ ColibriFocus.prototype._makeConference = function () {
elem.up(); // end of channel
for (j = 0; j < self.peers.length; j++) {
elem.c('channel', {initiator: 'true', expire:'15' }).up();
elem.c('channel', {initiator: 'true', expire: self.channelExpire }).up();
}
elem.up(); // end of content
});
@ -540,7 +549,8 @@ ColibriFocus.prototype.initiate = function (peer, isInitiator) {
if (1) { //i > 0) { // not for audio FIXME: does not work as intended
// re-add all remote a=ssrcs
for (var jid in this.remotessrc) {
if (jid == peer) continue;
if (jid == peer || !this.remotessrc[jid][i])
continue;
sdp.media[i] += this.remotessrc[jid][i];
}
// and local a=ssrc lines
@ -661,24 +671,28 @@ ColibriFocus.prototype.addNewParticipant = function (peer) {
var localSDP = new SDP(this.peerconnection.localDescription.sdp);
localSDP.media.forEach(function (media, channel) {
var name = SDPUtil.parse_mid(SDPUtil.find_line(media, 'a=mid:'));
elem.c('content', {name: name});
if (name !== 'data')
{
elem.c('channel', {
var elemName;
var elemAttrs
= {
initiator: 'true',
expire: self.channelExpire,
endpoint: peer.substr(1 + peer.lastIndexOf('/'))
});
};
if ('data' == name)
{
elemName = 'sctpconnection';
elemAttrs['port'] = 5000;
}
else
{
elem.c('sctpconnection', {
endpoint: peer.substr(1 + peer.lastIndexOf('/')),
initiator: 'true',
expire: self.channelExpire,
port: 5000
});
elemName = 'channel';
if (('video' === name) && (this.channelLastN >= 0))
elemAttrs['last-n'] = this.channelLastN;
}
elem.c('content', {name: name});
elem.c(elemName, elemAttrs);
elem.up(); // end of channel/sctpconnection
elem.up(); // end of content
});
@ -714,6 +728,9 @@ ColibriFocus.prototype.updateChannel = function (remoteSDP, participant) {
change.c('conference', {xmlns: 'http://jitsi.org/protocol/colibri', id: this.confid});
for (channel = 0; channel < this.channels[participant].length; channel++)
{
if (!remoteSDP.media[channel])
continue;
var name = SDPUtil.parse_mid(SDPUtil.find_line(remoteSDP.media[channel], 'a=mid:'));
change.c('content', {name: name});
if (name !== 'data')
@ -894,6 +911,9 @@ ColibriFocus.prototype.setRemoteDescription = function (session, elem, desctype)
this.remotessrc[session.peerjid] = [];
for (channel = 0; channel < this.channels[participant].length; channel++) {
//if (channel == 0) continue; FIXME: does not work as intended
if (!remoteSDP.media[channel])
continue;
if (SDPUtil.find_lines(remoteSDP.media[channel], 'a=ssrc:').length)
{
this.remotessrc[session.peerjid][channel] =
@ -905,6 +925,9 @@ ColibriFocus.prototype.setRemoteDescription = function (session, elem, desctype)
// ACT 4: add new a=ssrc lines to local remotedescription
for (channel = 0; channel < this.channels[participant].length; channel++) {
//if (channel == 0) continue; FIXME: does not work as intended
if (!remoteSDP.media[channel])
continue;
if (SDPUtil.find_lines(remoteSDP.media[channel], 'a=ssrc:').length) {
this.peerconnection.enqueueAddSsrc(
channel,
@ -1153,3 +1176,73 @@ ColibriFocus.prototype.sendTerminate = function (session, reason, text) {
this.statsinterval = null;
}
};
ColibriFocus.prototype.setRTCPTerminationStrategy = function (strategyFQN) {
var self = this;
var strategyIQ = $iq({to: this.bridgejid, type: 'set'});
strategyIQ.c('conference', {
xmlns: 'http://jitsi.org/protocol/colibri',
id: this.confid,
});
strategyIQ.c('rtcp-termination-strategy', {name: strategyFQN });
strategyIQ.c('content', {name: "video"});
strategyIQ.up(); // end of content
console.log('setting RTCP termination strategy', strategyFQN);
this.connection.sendIQ(strategyIQ,
function (res) {
console.log('got result');
},
function (err) {
console.error('got error', err);
}
);
};
/**
* Sets the default value of the channel last-n attribute in this conference and
* updates/patches the existing channels.
*/
ColibriFocus.prototype.setChannelLastN = function (channelLastN) {
if (('number' === typeof(channelLastN))
&& (this.channelLastN !== channelLastN))
{
this.channelLastN = channelLastN;
// Update/patch the existing channels.
var patch = $iq({ to:this.bridgejid, type:'set' });
patch.c(
'conference',
{ xmlns:'http://jitsi.org/protocol/colibri', id:this.confid });
patch.c('content', { name:'video' });
patch.c(
'channel',
{
id:$(this.mychannel[1 /* video */]).attr('id'),
'last-n':this.channelLastN
});
patch.up(); // end of channel
for (var p = 0; p < this.channels.length; p++)
{
patch.c(
'channel',
{
id:$(this.channels[p][1 /* video */]).attr('id'),
'last-n':this.channelLastN
});
patch.up(); // end of channel
}
this.connection.sendIQ(
patch,
function (res) {
console.info('Set channel last-n succeeded: ', res);
},
function (err) {
console.error('Set channel last-n failed: ', err);
});
}
};

@ -519,6 +519,7 @@ function getUserMediaWithConstraints(um, success_callback, failure_callback, res
constraints.video = {
mandatory: {
chromeMediaSource: "screen",
googLeakyBucket: true,
maxWidth: window.screen.width,
maxHeight: window.screen.height,
maxFrameRate: 3
@ -530,6 +531,7 @@ function getUserMediaWithConstraints(um, success_callback, failure_callback, res
mandatory: {
chromeMediaSource: "desktop",
chromeMediaSourceId: desktopStream,
googLeakyBucket: true,
maxWidth: window.screen.width,
maxHeight: window.screen.height,
maxFrameRate: 3

@ -5,7 +5,7 @@ var Toolbar = (function (my) {
/**
* Opens the lock room dialog.
*/
my.openLockDialog = function() {
my.openLockDialog = function () {
// Only the focus is able to set a shared key.
if (focus === null) {
if (sharedKey)
@ -54,7 +54,7 @@ var Toolbar = (function (my) {
submit: function (e, v, m, f) {
if (v) {
var lockKey = document.getElementById('lockKey');
if (lockKey.value) {
setSharedKey(Util.escapeHtml(lockKey.value));
lockRoom(true);
@ -70,24 +70,75 @@ var Toolbar = (function (my) {
/**
* Opens the invite link dialog.
*/
my.openLinkDialog = function() {
my.openLinkDialog = function () {
var inviteLink;
if (roomUrl == null)
inviteLink = "Your conference is currently being created...";
else
inviteLink = encodeURI(roomUrl);
$.prompt('<input id="inviteLinkRef" type="text" value="' +
encodeURI(roomUrl) + '" onclick="this.select();" readonly>',
{
title: "Share this link with everyone you want to invite",
persistent: false,
buttons: { "Cancel": false},
loaded: function (event) {
document.getElementById('inviteLinkRef').select();
inviteLink + '" onclick="this.select();" readonly>',
{
title: "Share this link with everyone you want to invite",
persistent: false,
buttons: { "Invite": true, "Cancel": false},
defaultButton: 1,
loaded: function (event) {
if (roomUrl)
document.getElementById('inviteLinkRef').select();
else
document.getElementById('jqi_state0_buttonInvite')
.disabled = true;
},
submit: function (e, v, m, f) {
if (v) {
if (roomUrl) {
inviteParticipants();
}
}
}
}
}
);
);
};
/**
* Invite participants to conference.
*/
function inviteParticipants() {
if (roomUrl == null)
return;
var sharedKeyText = "";
if (sharedKey && sharedKey.length > 0)
sharedKeyText
= "This conference is password protected. Please use the "
+ "following pin when joining:%0D%0A%0D%0A"
+ sharedKey + "%0D%0A%0D%0A";
var conferenceName = roomUrl.substring(roomUrl.lastIndexOf('/') + 1);
var subject = "Invitation to a Jitsi Meet (" + conferenceName + ")";
var body = "Hey there, I%27d like to invite you to a Jitsi Meet"
+ " conference I%27ve just set up.%0D%0A%0D%0A"
+ "Please click on the following link in order"
+ " to join the conference.%0D%0A%0D%0A"
+ roomUrl + "%0D%0A%0D%0A"
+ sharedKeyText
+ "Note that Jitsi Meet is currently only supported by Chromim,"
+ " Google Chrome and Opera, so you need"
+ " to be using one of these browsers.%0D%0A%0D%0A"
+ "Talk to you in a sec!";
if (window.localStorage.displayname)
body += "%0D%0A%0D%0A" + window.localStorage.displayname;
window.open("mailto:?subject=" + subject + "&body=" + body, '_blank');
}
/**
* Opens the settings dialog.
*/
my.openSettingsDialog = function() {
my.openSettingsDialog = function () {
$.prompt('<h2>Configure your conference</h2>' +
'<input type="checkbox" id="initMuted"> Participants join muted<br/>' +
'<input type="checkbox" id="requireNicknames"> Require nicknames<br/><br/>' +
@ -104,13 +155,13 @@ var Toolbar = (function (my) {
if ($('#initMuted').is(":checked")) {
// it is checked
}
if ($('#requireNicknames').is(":checked")) {
// it is checked
}
/*
var lockKey = document.getElementById('lockKey');
if (lockKey.value)
{
setSharedKey(lockKey.value);
@ -185,9 +236,12 @@ var Toolbar = (function (my) {
if (!$('#header').is(':visible')) {
Toolbar.showToolbar();
}
// Then clear the time out, to dock the toolbar.
clearTimeout(toolbarTimeout);
toolbarTimeout = null;
if (toolbarTimeout) {
clearTimeout(toolbarTimeout);
toolbarTimeout = null;
}
}
else {
if (!$('#header').is(':visible')) {

@ -1,6 +1,6 @@
var VideoLayout = (function (my) {
var preMuted = false;
var currentActiveSpeaker = null;
var currentDominantSpeaker = null;
my.changeLocalAudio = function(stream) {
connection.jingle.localAudio = stream;
@ -139,19 +139,19 @@ var VideoLayout = (function (my) {
if (isVisible) {
// Only if the large video is currently visible.
// Disable previous active speaker video.
// Disable previous dominant speaker video.
var oldJid = getJidFromVideoSrc(oldSrc);
if (oldJid) {
var oldResourceJid = Strophe.getResourceFromJid(oldJid);
VideoLayout.enableActiveSpeaker(oldResourceJid, false);
VideoLayout.enableDominantSpeaker(oldResourceJid, false);
}
// Enable new active speaker in the remote videos section.
// Enable new dominant speaker in the remote videos section.
var userJid = getJidFromVideoSrc(newSrc);
if (userJid)
{
var resourceJid = Strophe.getResourceFromJid(userJid);
VideoLayout.enableActiveSpeaker(resourceJid, true);
VideoLayout.enableDominantSpeaker(resourceJid, true);
}
$(this).fadeIn(300);
@ -173,15 +173,15 @@ var VideoLayout = (function (my) {
if (focusedVideoSrc === videoSrc)
{
focusedVideoSrc = null;
var activeSpeakerVideo = null;
// Enable the currently set active speaker.
if (currentActiveSpeaker) {
activeSpeakerVideo
= $('#participant_' + currentActiveSpeaker + '>video')
var dominantSpeakerVideo = null;
// Enable the currently set dominant speaker.
if (currentDominantSpeaker) {
dominantSpeakerVideo
= $('#participant_' + currentDominantSpeaker + '>video')
.get(0);
if (activeSpeakerVideo)
VideoLayout.updateLargeVideo(activeSpeakerVideo.src, 1);
if (dominantSpeakerVideo)
VideoLayout.updateLargeVideo(dominantSpeakerVideo.src, 1);
}
return;
@ -254,12 +254,12 @@ var VideoLayout = (function (my) {
if (isVisible) {
$('#largeVideo').css({visibility: 'visible'});
$('.watermark').css({visibility: 'visible'});
VideoLayout.enableActiveSpeaker(resourceJid, true);
VideoLayout.enableDominantSpeaker(resourceJid, true);
}
else {
$('#largeVideo').css({visibility: 'hidden'});
$('.watermark').css({visibility: 'hidden'});
VideoLayout.enableActiveSpeaker(resourceJid, false);
VideoLayout.enableDominantSpeaker(resourceJid, false);
}
};
@ -477,9 +477,7 @@ var VideoLayout = (function (my) {
if (!indicatorSpan || indicatorSpan.length === 0) {
indicatorSpan = document.createElement('span');
indicatorSpan.className = 'focusindicator';
Util.setTooltip(indicatorSpan,
"The owner of<br/>this conference",
"top");
focusContainer.appendChild(indicatorSpan);
createFocusIndicatorElement(indicatorSpan);
@ -570,7 +568,9 @@ var VideoLayout = (function (my) {
* Resizes thumbnails.
*/
my.resizeThumbnails = function() {
var thumbnailSize = calculateThumbnailSize();
var videoSpaceWidth = $('#remoteVideos').width();
var thumbnailSize = VideoLayout.calculateThumbnailSize(videoSpaceWidth);
var width = thumbnailSize[0];
var height = thumbnailSize[1];
@ -582,20 +582,20 @@ var VideoLayout = (function (my) {
};
/**
* Enables the active speaker UI.
* Enables the dominant speaker UI.
*
* @param resourceJid the jid indicating the video element to
* activate/deactivate
* @param isEnable indicates if the active speaker should be enabled or
* @param isEnable indicates if the dominant speaker should be enabled or
* disabled
*/
my.enableActiveSpeaker = function(resourceJid, isEnable) {
my.enableDominantSpeaker = function(resourceJid, isEnable) {
var displayName = resourceJid;
var nameSpan = $('#participant_' + resourceJid + '>span.displayname');
if (nameSpan.length > 0)
displayName = nameSpan.text();
console.log("UI enable active speaker",
console.log("UI enable dominant speaker",
displayName,
resourceJid,
isEnable);
@ -625,16 +625,16 @@ var VideoLayout = (function (my) {
if (isEnable) {
VideoLayout.showDisplayName(videoContainerId, true);
if (!videoSpan.classList.contains("activespeaker"))
videoSpan.classList.add("activespeaker");
if (!videoSpan.classList.contains("dominantspeaker"))
videoSpan.classList.add("dominantspeaker");
video.css({visibility: 'hidden'});
}
else {
VideoLayout.showDisplayName(videoContainerId, false);
if (videoSpan.classList.contains("activespeaker"))
videoSpan.classList.remove("activespeaker");
if (videoSpan.classList.contains("dominantspeaker"))
videoSpan.classList.remove("dominantspeaker");
video.css({visibility: 'visible'});
}
@ -682,7 +682,7 @@ var VideoLayout = (function (my) {
/**
* Calculates the thumbnail size.
*/
var calculateThumbnailSize = function () {
my.calculateThumbnailSize = function (videoSpaceWidth) {
// Calculate the available height, which is the inner window height minus
// 39px for the header minus 2px for the delimiter lines on the top and
// bottom of the large video, minus the 36px space inside the remoteVideos
@ -691,8 +691,10 @@ var VideoLayout = (function (my) {
var numvids = $('#remoteVideos>span:visible').length;
// Remove the 1px borders arround videos and the chat width.
var availableWinWidth = $('#remoteVideos').width() - 2 * numvids - 50;
// Remove the 3px borders arround videos and border around the remote
// videos area
var availableWinWidth = videoSpaceWidth - 2 * 3 * numvids - 50;
var availableWidth = availableWinWidth / numvids;
var aspectRatio = 16.0 / 9.0;
var maxHeight = Math.min(160, availableHeight);
@ -768,6 +770,10 @@ var VideoLayout = (function (my) {
var focusIndicator = document.createElement('i');
focusIndicator.className = 'fa fa-star';
parentElement.appendChild(focusIndicator);
Util.setTooltip(parentElement,
"The owner of<br/>this conference",
"top");
}
/**
@ -799,10 +805,10 @@ var VideoLayout = (function (my) {
};
/**
* Returns the current active speaker resource jid.
* Returns the current dominant speaker resource jid.
*/
my.getActiveSpeakerResourceJid = function () {
return currentActiveSpeaker;
my.getDominantSpeakerResourceJid = function () {
return currentDominantSpeaker;
};
/**
@ -920,21 +926,21 @@ var VideoLayout = (function (my) {
});
/**
* On active speaker changed event.
* On dominant speaker changed event.
*/
$(document).bind('activespeakerchanged', function (event, resourceJid) {
$(document).bind('dominantspeakerchanged', function (event, resourceJid) {
// We ignore local user events.
if (resourceJid
=== Strophe.getResourceFromJid(connection.emuc.myroomjid))
return;
// Obtain container for new active speaker.
// Obtain container for new dominant speaker.
var container = document.getElementById(
'participant_' + resourceJid);
// Update the current active speaker.
if (resourceJid !== currentActiveSpeaker)
currentActiveSpeaker = resourceJid;
// Update the current dominant speaker.
if (resourceJid !== currentDominantSpeaker)
currentDominantSpeaker = resourceJid;
else
return;

Loading…
Cancel
Save