Commit 93daa5f9 authored by Dele Olajide's avatar Dele Olajide Committed by dele

Updated ofmeet and jitmeet. video recording is still not yet working

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@14004 b35dd754-fafc-0310-a699-88a17e54d16e
parent dc695cd8
...@@ -11,4 +11,13 @@ ...@@ -11,4 +11,13 @@
<url-pattern>/proxy</url-pattern> <url-pattern>/proxy</url-pattern>
</servlet-mapping> </servlet-mapping>
<servlet>
<servlet-name>config</servlet-name>
<servlet-class>org.jitsi.videobridge.openfire.Config</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>config</servlet-name>
<url-pattern>/config</url-pattern>
</servlet-mapping>
</web-app> </web-app>
\ No newline at end of file
...@@ -96,31 +96,78 @@ var Chat = (function (my) { ...@@ -96,31 +96,78 @@ var Chat = (function (my) {
var chatspace = $('#chatspace'); var chatspace = $('#chatspace');
var videospace = $('#videospace'); var videospace = $('#videospace');
var onShow = function () { var chatSize = (chatspace.is(":visible")) ? [0, 0] : Chat.getChatSize();
resizeLarge(); var videospaceWidth = window.innerWidth - chatSize[0];
$('#chatspace').show("slide", { direction: "right", duration: 500}); var videospaceHeight = window.innerHeight;
}; var videoSize
var onHide = function () { = getVideoSize(null, null, videospaceWidth, videospaceHeight);
$('#chatspace').hide("slide", { direction: "right", duration: 500}); var videoWidth = videoSize[0];
resizeLarge(); var videoHeight = videoSize[1];
}; var videoPosition = getVideoPosition( videoWidth,
videoHeight,
videospaceWidth,
videospaceHeight);
var horizontalIndent = videoPosition[0];
var verticalIndent = videoPosition[1];
if (chatspace.is(":visible")) { if (chatspace.is(":visible")) {
videospace.animate( {right: 0}, videospace.animate( {right: chatSize[0],
width: videospaceWidth,
height: videospaceHeight},
{queue: false, {queue: false,
duration: 500, duration: 500});
progress: onHide});
$('#largeVideoContainer').animate({ width: videospaceWidth,
height: videospaceHeight},
{queue: false,
duration: 500
});
$('#largeVideo').animate({ width: videoWidth,
height: videoHeight,
top: verticalIndent,
bottom: verticalIndent,
left: horizontalIndent,
right: horizontalIndent},
{ queue: false,
duration: 500
});
$('#chatspace').hide("slide", { direction: "right",
queue: false,
duration: 500});
} }
else { else {
videospace.animate({right: chatspace.width()}, videospace.animate({right: chatSize[0],
width: videospaceWidth,
height: videospaceHeight},
{queue: false, {queue: false,
duration: 500, duration: 500,
progress: onShow,
complete: function() { complete: function() {
scrollChatToBottom(); scrollChatToBottom();
chatspace.trigger('shown'); chatspace.trigger('shown');
} }
}); });
$('#largeVideoContainer').animate({ width: videospaceWidth,
height: videospaceHeight},
{queue: false,
duration: 500
});
$('#largeVideo').animate({ width: videoWidth,
height: videoHeight,
top: verticalIndent,
bottom: verticalIndent,
left: horizontalIndent,
right: horizontalIndent},
{queue: false,
duration: 500
});
$('#chatspace').show("slide", { direction: "right",
queue: false,
duration: 500});
} }
// Request the focus in the nickname field or the chat input field. // Request the focus in the nickname field or the chat input field.
...@@ -147,6 +194,18 @@ var Chat = (function (my) { ...@@ -147,6 +194,18 @@ var Chat = (function (my) {
* Resizes the chat area. * Resizes the chat area.
*/ */
my.resizeChat = function () { my.resizeChat = function () {
var chatSize = Chat.getChatSize();
$('#chatspace').width(chatSize[0]);
$('#chatspace').height(chatSize[1]);
resizeChatConversation();
};
/**
* Returns the size of the chat.
*/
my.getChatSize = function() {
var availableHeight = window.innerHeight; var availableHeight = window.innerHeight;
var availableWidth = window.innerWidth; var availableWidth = window.innerWidth;
...@@ -154,10 +213,7 @@ var Chat = (function (my) { ...@@ -154,10 +213,7 @@ var Chat = (function (my) {
if (availableWidth*0.2 < 200) if (availableWidth*0.2 < 200)
chatWidth = availableWidth*0.2; chatWidth = availableWidth*0.2;
$('#chatspace').width(chatWidth); return [chatWidth, availableHeight];
$('#chatspace').height(availableHeight - 40);
resizeChatConversation();
}; };
/** /**
...@@ -168,10 +224,11 @@ var Chat = (function (my) { ...@@ -168,10 +224,11 @@ var Chat = (function (my) {
var usermsgHeight = usermsgStyleHeight var usermsgHeight = usermsgStyleHeight
.substring(0, usermsgStyleHeight.indexOf('px')); .substring(0, usermsgStyleHeight.indexOf('px'));
$('#usermsg').width($('#chatspace').width() - 10);
$('#chatconversation').width($('#chatspace').width() - 10); $('#chatconversation').width($('#chatspace').width() - 10);
$('#chatconversation') $('#chatconversation')
.height(window.innerHeight - 50 - parseInt(usermsgHeight)); .height(window.innerHeight - 10 - parseInt(usermsgHeight));
} };
/** /**
* Shows/hides a visual notification, indicating that a message has arrived. * Shows/hides a visual notification, indicating that a message has arrived.
...@@ -179,25 +236,35 @@ var Chat = (function (my) { ...@@ -179,25 +236,35 @@ var Chat = (function (my) {
function setVisualNotification(show) { function setVisualNotification(show) {
var unreadMsgElement = document.getElementById('unreadMessages'); var unreadMsgElement = document.getElementById('unreadMessages');
var glower = $('#chatButton');
if (unreadMessages) { if (unreadMessages) {
unreadMsgElement.innerHTML = unreadMessages.toString(); unreadMsgElement.innerHTML = unreadMessages.toString();
showToolbar();
var chatButtonElement var chatButtonElement
= document.getElementById('chat').parentNode; = document.getElementById('chatButton').parentNode;
var leftIndent = (Util.getTextWidth(chatButtonElement) var leftIndent = (Util.getTextWidth(chatButtonElement)
- Util.getTextWidth(unreadMsgElement) - 5)/2; - Util.getTextWidth(unreadMsgElement))/2;
var topIndent = (Util.getTextHeight(chatButtonElement) var topIndent = (Util.getTextHeight(chatButtonElement)
- Util.getTextHeight(unreadMsgElement))/2 - 2; - Util.getTextHeight(unreadMsgElement))/2 - 3;
unreadMsgElement.setAttribute( unreadMsgElement.setAttribute(
'style', 'style',
'top:' + topIndent 'top:' + topIndent
+ '; left:' + leftIndent +';'); + '; left:' + leftIndent +';');
if (!glower.hasClass('icon-chat-simple')) {
glower.removeClass('icon-chat');
glower.addClass('icon-chat-simple');
}
} }
else else {
unreadMsgElement.innerHTML = ''; unreadMsgElement.innerHTML = '';
glower.removeClass('icon-chat-simple');
var glower = $('#chat'); glower.addClass('icon-chat');
}
if (show && !notificationInterval) { if (show && !notificationInterval) {
notificationInterval = window.setInterval(function() { notificationInterval = window.setInterval(function() {
......
var config = { config.desktopSharing = 'webrtc'; // Desktop sharing method. Can be set to 'ext', 'webrtc' or false to disable.
hosts: { config.chromeExtensionId = 'diibjkoicjeejcmhdnailmkgecihlobk'; // Id of desktop streamer Chrome extension
domain: 'btg199251', config.minChromeExtVersion = '0.0.8'; // Required version of Chrome extension
muc: 'conference.btg199251', // FIXME: use XEP-0030
bridge: 'jitsi-videobridge.btg199251' // FIXME: use XEP-0030
},
// useStunTurn: true, // use XEP-0215 to fetch STUN and TURN server
// useIPv6: true, // ipv6 support. use at your own risk
useNicks: false,
bosh: 'https://btg199251:7443/http-bind/', // FIXME: use xep-0156 for that
desktopSharing: 'webrtc', // Desktop sharing method. Can be set to 'ext', 'webrtc' or false to disable.
chromeExtensionId: 'diibjkoicjeejcmhdnailmkgecihlobk', // Id of desktop streamer Chrome extension
minChromeExtVersion: '0.0.8', // Required version of Chrome extension
getroomnode: function (path) config.getroomnode = function (path)
{ {
console.log('getroomnode', path); console.log('getroomnode', path);
var name = "r"; var name = "r";
var roomnode = null; var roomnode = null;
var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href); var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href);
if (!results) if (!results)
roomnode = null; roomnode = null;
else roomnode = results[1] || undefined; else roomnode = results[1] || undefined;
...@@ -31,5 +19,4 @@ var config = { ...@@ -31,5 +19,4 @@ var config = {
window.history.pushState('VideoChat', 'Room: ' + roomnode, path + "?r=" + roomnode); window.history.pushState('VideoChat', 'Room: ' + roomnode, path + "?r=" + roomnode);
} }
return roomnode; return roomnode;
} }
};
@font-face {
font-family: 'jitsi';
src:url('../fonts/jitsi.eot?94d075');
src:url('../fonts/jitsi.eot?#iefix94d075') format('embedded-opentype'),
url('../fonts/jitsi.woff?94d075') format('woff'),
url('../fonts/jitsi.ttf?94d075') format('truetype'),
url('../fonts/jitsi.svg?94d075#jitsi') format('svg');
font-weight: normal;
font-style: normal;
}
[class^="icon-"], [class*=" icon-"] {
font-family: 'jitsi';
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 0.75em;
font-size: 1.22em;
/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-share-desktop:before {
content: "\e602";
}
.icon-chat-simple:before {
content: "\e606";
}
.icon-full-screen:before {
content: "\e60d";
}
.icon-exit-full-screen:before {
content: "\e60e";
}
.icon-prezi:before {
content: "\e60c";
}
.icon-link:before {
content: "\e600";
}
.icon-chat:before {
content: "\e601";
}
.icon-presentation:before {
content: "\e603";
}
.icon-security:before {
content: "\e604";
}
.icon-share-doc:before {
content: "\e605";
}
.icon-security-locked:before {
content: "\e607";
}
.icon-camera:before {
content: "\e608";
}
.icon-camera-disabled:before {
content: "\e609";
}
.icon-mic-disabled:before {
content: "\e60a";
}
.icon-microphone:before {
content: "\e60b";
}
...@@ -4,99 +4,15 @@ html, body{ ...@@ -4,99 +4,15 @@ html, body{
color: #424242; color: #424242;
font-family:'Helvetica Neue', Helvetica, sans-serif; font-family:'Helvetica Neue', Helvetica, sans-serif;
font-weight: 400; font-weight: 400;
background: #e9e9e9; background: #000000;
overflow-x: hidden; overflow-x: hidden;
} }
#videospace {
display: block;
position: absolute;
top: 39px;
left: 0px;
right: 0px;
float: left;
}
.videocontainer {
position: relative;
margin-left: auto;
margin-right: auto;
}
#presentation, #etherpad, .videocontainer>video {
position: absolute;
left: 0px;
top: 0px;
z-index: 1;
width: 100%;
height: 100%;
}
#etherpad {
z-index: 0;
}
#etherpadButton {
display: none;
}
.videocontainer>span {
display: none; /* enable when you want nicks to be shown */
position: absolute;
left: 0px;
bottom: -20px;
z-index: 0;
width: 100%;
font-size: 10pt;
}
.flipVideoX {
-moz-transform: scaleX(-1);
-webkit-transform: scaleX(-1);
-o-transform: scaleX(-1);
transform: scaleX(-1);
}
#remoteVideos {
display:block;
position:relative;
text-align:center;
height:196px;
padding: 5px 0px;
width:auto;
overflow: hidden;
border:1px solid transparent;
z-index: 2;
}
#remoteVideos>span {
display: inline-block;
z-index:0;
border:1px solid #FFFFFF;
background-image:url(../images/avatar1.png);
background-size: contain;
}
#remoteVideos>span:hover {
cursor: pointer;
cursor: hand;
transform:scale(1.08, 1.08);
-webkit-transform:scale(1.08, 1.08);
transition-duration: 0.5s;
-webkit-transition-duration: 0.5s;
background-color: #FFFFFF;
-webkit-animation-name: greyPulse;
-webkit-animation-duration: 2s;
-webkit-animation-iteration-count: 1;
-webkit-box-shadow: 0 0 18px #515151;
border:1px solid #FFFFFF;
z-index: 10;
}
#chatspace { #chatspace {
display:none; display:none;
position:absolute; position:absolute;
float: right; float: right;
top: 40px; top: 0px;
bottom: 0px; bottom: 0px;
right: 0px; right: 0px;
width: 20%; width: 20%;
...@@ -105,9 +21,11 @@ html, body{ ...@@ -105,9 +21,11 @@ html, body{
/* background-color:#dfebf1;*/ /* background-color:#dfebf1;*/
background-color:#FFFFFF; background-color:#FFFFFF;
border-left:1px solid #424242; border-left:1px solid #424242;
z-index: 5;
} }
#chatconversation { #chatconversation {
visibility: hidden;
position: relative; position: relative;
top: 5px; top: 5px;
padding: 5px; padding: 5px;
...@@ -119,7 +37,6 @@ html, body{ ...@@ -119,7 +37,6 @@ html, body{
overflow-y: scroll; overflow-y: scroll;
overflow-x: hidden; overflow-x: hidden;
word-wrap: break-word; word-wrap: break-word;
visibility: hidden;
} }
.localuser { .localuser {
...@@ -131,20 +48,20 @@ html, body{ ...@@ -131,20 +48,20 @@ html, body{
} }
#usermsg { #usermsg {
visibility:hidden;
position: relative; position: relative;
width: 100%; width: 100%;
height: 5%; height: 5%;
padding: 5px; padding: 5px;
z-index: 5;
max-height:150px; max-height:150px;
min-height:50px; min-height:50px;
visibility:hidden;
border: 0px none; border: 0px none;
border-top: 1px solid #cccccc; border-top: 1px solid #cccccc;
background: #FFFFFF; background: #FFFFFF;
box-shadow: none; box-shadow: none;
border-radius:0; border-radius:0;
font-size: 10pt; font-size: 10pt;
overflow: hidden;
} }
#usermsg: hover { #usermsg: hover {
...@@ -169,10 +86,6 @@ html, body{ ...@@ -169,10 +86,6 @@ html, body{
font-size: 14; font-size: 14;
} }
#spacer {
height:5px;
}
#settings { #settings {
display:none; display:none;
} }
...@@ -181,47 +94,6 @@ html, body{ ...@@ -181,47 +94,6 @@ html, body{
display:none; display:none;
} }
#header{
display:block;
height:39px;
text-align:center;
background-color: #2591e5;
}
#left {
display:block;
position: absolute;
left: 0px;
top: 0px;
width: 100px;
height: 39px;
background-image:url(../images/left1.png);
background-repeat:no-repeat;
margin: 0;
padding: 0;
}
#leftlogo {
position:absolute;
top: 5px;
left: 15px;
background-image:url(../images/jitsilogo.png);
background-repeat:no-repeat;
height: 31px;
width: 68px;
z-index:1;
}
#toolbar {
display:block;
position:relative;
height:39px;
width:auto;
overflow: hidden;
z-index:0;
visibility: hidden;
}
#settingsButton { #settingsButton {
visibility: hidden; visibility: hidden;
} }
...@@ -254,18 +126,16 @@ html, body{ ...@@ -254,18 +126,16 @@ html, body{
cursor: pointer; cursor: pointer;
} }
#chat { #chatButton {
font-size:1.65em;
-webkit-transition: all .5s ease-in-out;; -webkit-transition: all .5s ease-in-out;;
-moz-transition: all .5s ease-in-out;; -moz-transition: all .5s ease-in-out;;
transition: all .5s ease-in-out;; transition: all .5s ease-in-out;;
} }
#chat.active { #chatButton.active {
-webkit-text-shadow: 0 0 10px #ffffff; -webkit-text-shadow: 0 0 10px #ffffff;
-moz-text-shadow: 0 0 10px #ffffff; -moz-text-shadow: 0 0 10px #ffffff;
text-shadow: 0 0 10px #ffffff; text-shadow: 0 0 10px #ffffff;
/* -webkit-transform: scale(1.1); */
} }
a.button:hover { a.button:hover {
...@@ -282,44 +152,13 @@ a.button:hover { ...@@ -282,44 +152,13 @@ a.button:hover {
color: #636363; color: #636363;
} }
.fade_line {
height: 1px;
background: black;
background: -webkit-gradient(linear, 0 0, 100% 0, from(#e9e9e9), to(#e9e9e9), color-stop(50%, black));
}
.header_button_separator { .header_button_separator {
display: inline-block; display: inline-block;
position:relative; position:relative;
top: 7; top: 5;
width: 1px; width: 1px;
height: 25px; height: 20px;
background: white; background: #676767;
background: -webkit-gradient(linear, 0 0, 0 100%, from(#087dba), to(#087dba), color-stop(50%, white));
}
#right {
display:block;
position:absolute;
right: 0px;
top: 0px;
background-image:url(../images/right1.png);
background-repeat:no-repeat;
margin:0;
padding:0;
width:100px;
height:39px;
}
#rightlogo {
position:absolute;
top: 6px;
right: 15px;
background-image:url(../images/estoslogo.png);
background-repeat:no-repeat;
height: 25px;
width: 62px;
z-index:1;
} }
input[type='text'], textarea { input[type='text'], textarea {
...@@ -387,70 +226,3 @@ form { ...@@ -387,70 +226,3 @@ form {
overflow: visible; overflow: visible;
z-index: 100; z-index: 100;
} }
.videocontainer>span.focusindicator {
display: inline-block;
position: absolute;
color: #FFFFFF;
top: 0;
padding: 5px 0px;
width: 25px;
font-size: 11pt;
text-shadow: 0px 1px 0px rgba(255,255,255,.3), 0px -1px 0px rgba(0,0,0,.7);
border: 0px;
z-index: 2;
}
.videocontainer>span.displayname,
.videocontainer>input.displayname {
display: inline-block;
position: absolute;
background: -webkit-linear-gradient(left, rgba(0,0,0,.7), rgba(0,0,0,0));
color: #b7b7b7;
bottom: 0;
left: 0;
padding: 3px 5px;
width: 100%;
height: auto;
max-height: 18px;
font-size: 9pt;
text-align: left;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
z-index: 2;
box-sizing: border-box;
}
#localVideoContainer>span.displayname:hover {
cursor: text;
}
.videocontainer>a.displayname {
display: inline-block;
position: absolute;
color: #b7b7b7;
bottom: 0;
right: 0;
padding: 3px 5px;
font-size: 9pt;
cursor: pointer;
z-index: 2;
}
#reloadPresentation {
display: none;
position: absolute;
color: #FFFFFF;
top: 0;
right: 0;
padding: 10px 10px;
font-size: 11pt;
cursor: pointer;
background: rgba(0, 0, 0, 0.3);
border-radius: 5px;
background-clip: padding-box;
-webkit-border-radius: 5px;
-webkit-background-clip: padding-box;
z-index: 3;
}
#videospace {
display: block;
position: absolute;
top: 0px;
left: 0px;
right: 0px;
}
#remoteVideos {
display:block;
position:absolute;
text-align:right;
height:196px;
padding: 18px;
bottom: 0;
left: 0;
right: 0;
width:auto;
overflow: hidden;
border:1px solid transparent;
z-index: 2;
}
.videocontainer {
position: relative;
margin-left: auto;
margin-right: auto;
}
#remoteVideos .videocontainer {
display: inline-block;
background-image:url(../images/avatar1.png);
background-size: contain;
border-radius:8px;
border: 2px solid #212425;
}
#remoteVideos .videocontainer:hover {
width: 100%;
height: 100%;
content:"";
cursor: pointer;
cursor: hand;
transform:scale(1.08, 1.08);
-webkit-transform:scale(1.08, 1.08);
transition-duration: 0.5s;
-webkit-transition-duration: 0.5s;
-webkit-animation-name: greyPulse;
-webkit-animation-duration: 2s;
-webkit-animation-iteration-count: 1;
-webkit-box-shadow: 0 0 18px #388396;
border: 2px solid #388396;
z-index: 3;
}
#localVideoWrapper {
display:inline-block;
-webkit-mask-box-image: url(http://emcho.com/db/videomask.svg);
border-radius:0px !important;
border: 0px !important;
}
#remoteVideos .videocontainer>video {
border-radius:6px;
}
.flipVideoX {
transform: scale(-1, 1);
-moz-transform: scale(-1, 1);
-webkit-transform: scale(-1, 1);
-o-transform: scale(-1, 1);
}
#localVideoWrapper>video {
border-radius:0px !important;
}
#largeVideo,
#largeVideoContainer {
overflow: hidden;
text-align: center;
}
#presentation,
#etherpad,
#localVideoWrapper>video,
#localVideoWrapper,
.videocontainer>video {
position: absolute;
left: 0;
top: 0;
z-index: 1;
width: 100%;
height: 100%;
}
#etherpad,
#presentation {
text-align: center;
}
#etherpad {
z-index: 0;
}
#etherpadButton {
display: none;
}
#remoteVideos .videocontainer>span.focusindicator {
display: inline-block;
position: absolute;
color: #FFFFFF;
top: 0;
left: 0;
padding: 5px 0px;
width: 25px;
font-size: 11pt;
text-shadow: 0px 1px 0px rgba(255,255,255,.3), 0px -1px 0px rgba(0,0,0,.7);
border: 0px;
z-index: 2;
}
#remoteVideos .nick {
display: none; /* enable when you want nicks to be shown */
position: absolute;
left: 0px;
bottom: -20px;
z-index: 0;
width: 100%;
font-size: 10pt;
}
.videocontainer>span.displayname,
.videocontainer>input.displayname {
display: inline-block;
position: absolute;
background: -webkit-linear-gradient(left, rgba(0,0,0,.7), rgba(0,0,0,0));
color: #FFFFFF;
bottom: 0;
left: 0;
padding: 3px 5px;
width: 100%;
height: auto;
max-height: 18px;
font-size: 9pt;
text-align: left;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
z-index: 2;
box-sizing: border-box;
border-bottom-left-radius:6px;
border-bottom-right-radius:6px;
}
#localVideoContainer>span.displayname:hover {
cursor: text;
}
.videocontainer>a.displayname {
display: inline-block;
position: absolute;
color: #FFFFFF;
bottom: 0;
right: 0;
padding: 3px 5px;
font-size: 9pt;
cursor: pointer;
z-index: 2;
}
#reloadPresentation {
display: none;
position: absolute;
color: #FFFFFF;
top: 0;
right:0;
padding: 10px 10px;
font-size: 11pt;
cursor: pointer;
background: rgba(0, 0, 0, 0.3);
border-radius: 5px;
background-clip: padding-box;
-webkit-border-radius: 5px;
-webkit-background-clip: padding-box;
z-index: 20; /*The reload button should appear on top of the header!*/
}
#header{
display:none;
position:absolute;
height:39px;
text-align:center;
top:0;
left:0;
right:0;
z-index:10;
}
#toolbar {
display:inline-block;
position:relative;
margin-left:auto;
margin-right:auto;
height:39px;
width:auto;
overflow: hidden;
background: linear-gradient(to bottom, rgba(103,103,103,.65) , rgba(0,0,0,.65));
-webkit-box-shadow: 0 0 2px #000000, 0 0 10px #000000;
border-bottom-left-radius: 12px;
border-bottom-right-radius: 12px;
}
#watermark {
display: block;
position: absolute;
left: 15;
top: 15;
width: 20%;
height: 10%;
background-image:url(../images/watermark.png);
background-size: contain;
background-repeat: no-repeat;
z-index: 2;
}
\ No newline at end of file
...@@ -16,20 +16,29 @@ var switchInProgress = false; ...@@ -16,20 +16,29 @@ var switchInProgress = false;
*/ */
var obtainDesktopStream = null; var obtainDesktopStream = null;
/**
* Flag used to cache desktop sharing enabled state. Do not use directly as it can be <tt>null</tt>.
* @type {null|boolean}
*/
var _desktopSharingEnabled = null;
/** /**
* @returns {boolean} <tt>true</tt> if desktop sharing feature is available and enabled. * @returns {boolean} <tt>true</tt> if desktop sharing feature is available and enabled.
*/ */
function isDesktopSharingEnabled() { function isDesktopSharingEnabled() {
if(obtainDesktopStream === obtainScreenFromExtension) { if(_desktopSharingEnabled === null){
// Parse chrome version if(obtainDesktopStream === obtainScreenFromExtension) {
var userAgent = navigator.userAgent.toLowerCase(); // Parse chrome version
// We can assume that user agent is chrome, because it's enforced when 'ext' streaming method is set var userAgent = navigator.userAgent.toLowerCase();
var ver = parseInt(userAgent.match(/chrome\/(\d+)\./)[1], 10); // We can assume that user agent is chrome, because it's enforced when 'ext' streaming method is set
console.log("Chrome version" + userAgent, ver); var ver = parseInt(userAgent.match(/chrome\/(\d+)\./)[1], 10);
return ver >= 35; console.log("Chrome version" + userAgent, ver);
} else { _desktopSharingEnabled = ver >= 35;
return obtainDesktopStream === obtainWebRTCScreen; } else {
_desktopSharingEnabled = obtainDesktopStream === obtainWebRTCScreen;
}
} }
return _desktopSharingEnabled;
} }
/** /**
...@@ -39,21 +48,21 @@ function isDesktopSharingEnabled() { ...@@ -39,21 +48,21 @@ function isDesktopSharingEnabled() {
* must be enabled), pass any other string or nothing in order to disable this feature completely. * must be enabled), pass any other string or nothing in order to disable this feature completely.
*/ */
function setDesktopSharing(method) { function setDesktopSharing(method) {
if(method == "ext") { // Check if we are running chrome
if(RTC.browser === 'chrome') { if(!navigator.webkitGetUserMedia){
obtainDesktopStream = obtainScreenFromExtension;
console.info("Using Chrome extension for desktop sharing");
} else {
console.error("Chrome is required to use extension method");
obtainDesktopStream = null;
}
} else if(method == "webrtc") {
obtainDesktopStream = obtainWebRTCScreen;
console.info("Using WebRTC for desktop sharing");
} else {
obtainDesktopStream = null; obtainDesktopStream = null;
console.info("Desktop sharing disabled"); console.info("Desktop sharing disabled");
} else if(method == "ext") {
obtainDesktopStream = obtainScreenFromExtension;
console.info("Using Chrome extension for desktop sharing");
} else if(method == "webrtc") {
obtainDesktopStream = obtainWebRTCScreen;
console.info("Using Chrome WebRTC for desktop sharing");
} }
// Reset enabled cache
_desktopSharingEnabled = null;
showDesktopSharingButton(); showDesktopSharingButton();
} }
......
...@@ -33,21 +33,23 @@ var Etherpad = (function (my) { ...@@ -33,21 +33,23 @@ var Etherpad = (function (my) {
if (!etherpadIFrame) if (!etherpadIFrame)
createIFrame(); createIFrame();
// TODO FIX large video and prezi toggling. Too many calls from different places.
var largeVideo = null; var largeVideo = null;
if (isPresentationVisible()) if (Prezi.isPresentationVisible())
largeVideo = $('#presentation>iframe'); largeVideo = $('#presentation>iframe');
else else
largeVideo = $('#largeVideo'); largeVideo = $('#largeVideo');
if ($('#etherpad>iframe').css('visibility') === 'hidden') { if ($('#etherpad>iframe').css('visibility') === 'hidden') {
largeVideo.fadeOut(300, function () { largeVideo.fadeOut(300, function () {
if (isPresentationVisible()) if (Prezi.isPresentationVisible())
largeVideo.css({opacity:'0'}); largeVideo.css({opacity:'0'});
else else {
largeVideo.css({visibility:'hidden'}); setLargeVideoVisible(false);
dockToolbar(true);
}
$('#etherpad>iframe').fadeIn(300, function() { $('#etherpad>iframe').fadeIn(300, function() {
document.body.style.background = '#eeeeee';
$('#etherpad>iframe').css({visibility:'visible'}); $('#etherpad>iframe').css({visibility:'visible'});
$('#etherpad').css({zIndex:2}); $('#etherpad').css({zIndex:2});
}); });
...@@ -57,15 +59,33 @@ var Etherpad = (function (my) { ...@@ -57,15 +59,33 @@ var Etherpad = (function (my) {
$('#etherpad>iframe').fadeOut(300, function () { $('#etherpad>iframe').fadeOut(300, function () {
$('#etherpad>iframe').css({visibility:'hidden'}); $('#etherpad>iframe').css({visibility:'hidden'});
$('#etherpad').css({zIndex:0}); $('#etherpad').css({zIndex:0});
document.body.style.background = 'black';
if (!isPresentation) { if (!isPresentation) {
$('#largeVideo').fadeIn(300, function() { $('#largeVideo').fadeIn(300, function() {
$('#largeVideo').css({visibility:'visible'}); setLargeVideoVisible(true);
dockToolbar(false);
}); });
} }
}); });
} }
resize();
}; };
/**
* Resizes the etherpad.
*/
function resize() {
if ($('#etherpad>iframe').length) {
var remoteVideos = $('#remoteVideos');
var availableHeight
= window.innerHeight - remoteVideos.outerHeight();
var availableWidth = Util.getAvailableVideoWidth();
$('#etherpad>iframe').width(availableWidth);
$('#etherpad>iframe').height(availableHeight);
}
}
/** /**
* Shares the Etherpad name with other participants. * Shares the Etherpad name with other participants.
*/ */
...@@ -127,5 +147,12 @@ var Etherpad = (function (my) { ...@@ -127,5 +147,12 @@ var Etherpad = (function (my) {
Etherpad.toggleEtherpad(isPresentation); Etherpad.toggleEtherpad(isPresentation);
}); });
/**
* Resizes the etherpad, when the window is resized.
*/
$(window).resize(function () {
resize();
});
return my; return my;
}(Etherpad || {})); }(Etherpad || {}));
This diff is collapsed.
<html> <html>
<head> <head>
<title>WebRTC, meet the Jitsi Videobridge</title> <title>WebRTC, meet the Jitsi Videobridge</title>
<script src="/jitsi/config"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="libs/strophe/strophe.jingle.adapter.js?v=1"></script><!-- strophe.jingle bundles --> <script src="libs/strophe/strophe.jingle.adapter.js?v=1"></script><!-- strophe.jingle bundles -->
<script src="libs/strophe/strophe.jingle.bundle.js?v=8"></script> <script src="libs/strophe/strophe.jingle.bundle.js?v=8"></script>
...@@ -16,14 +17,17 @@ ...@@ -16,14 +17,17 @@
<script src="muc.js?v=9"></script><!-- simple MUC library --> <script src="muc.js?v=9"></script><!-- simple MUC library -->
<script src="estos_log.js?v=2"></script><!-- simple stanza logger --> <script src="estos_log.js?v=2"></script><!-- simple stanza logger -->
<script src="desktopsharing.js?v=1"></script><!-- desktop sharing --> <script src="desktopsharing.js?v=1"></script><!-- desktop sharing -->
<script src="app.js?v=23"></script><!-- application logic --> <script src="app.js?v=24"></script><!-- application logic -->
<script src="chat.js?v=3"></script><!-- chat logic --> <script src="chat.js?v=4"></script><!-- chat logic -->
<script src="util.js?v=2"></script><!-- utility functions --> <script src="util.js?v=3"></script><!-- utility functions -->
<script src="etherpad.js?v=5"></script><!-- etherpad plugin --> <script src="etherpad.js?v=7"></script><!-- etherpad plugin -->
<script src="prezi.js?v=2"></script><!-- prezi plugin -->
<script src="smileys.js?v=1"></script><!-- smiley images --> <script src="smileys.js?v=1"></script><!-- smiley images -->
<script src="replacement.js?v=5"></script><!-- link and smiley replacement --> <script src="replacement.js?v=5"></script><!-- link and smiley replacement -->
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet"> <link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=19"/> <link rel="stylesheet" href="css/font.css"/>
<link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=20"/>
<link rel="stylesheet" type="text/css" media="screen" href="css/videolayout_default.css?v=1" id="videolayout_default"/>
<link rel="stylesheet" href="css/jquery-impromptu.css?v=4"> <link rel="stylesheet" href="css/jquery-impromptu.css?v=4">
<link rel="stylesheet" href="css/modaldialog.css?v=3"> <link rel="stylesheet" href="css/modaldialog.css?v=3">
<!-- <!--
...@@ -39,32 +43,32 @@ ...@@ -39,32 +43,32 @@
<a href="http://jitsi.org" target="_blank"><div id="leftlogo"></div></a> <a href="http://jitsi.org" target="_blank"><div id="leftlogo"></div></a>
<a href="http://www.estos.com/" target="_blank"><div id="rightlogo"></div></a> <a href="http://www.estos.com/" target="_blank"><div id="rightlogo"></div></a>
<span id="toolbar"> <span id="toolbar">
<a class="button" onclick='buttonClick("#mute", "fa fa-microphone fa-lg fa fa-microphone-slash fa-lg");toggleAudio();'> <a class="button" onclick='buttonClick("#mute", "icon-microphone icon-mic-disabled");toggleAudio();'>
<i id="mute" title="Mute / unmute" class="fa fa-microphone fa-lg"></i></a> <i id="mute" title="Mute / unmute" class="icon-microphone"></i></a>
<div class="header_button_separator"></div> <div class="header_button_separator"></div>
<a class="button" onclick='buttonClick("#video");toggleVideo();'> <a class="button" onclick='buttonClick("#video", "icon-camera icon-camera-disabled");toggleVideo();'>
<i id="video" title="Start / stop camera" class="fa fa-video-camera fa-lg"></i></a> <i id="video" title="Start / stop camera" class="icon-camera"></i></a>
<div class="header_button_separator"></div> <div class="header_button_separator"></div>
<a class="button" onclick="openLockDialog();"><i id="lockIcon" title="Lock/unlock room" class="fa fa-unlock fa-lg"></i></a> <a class="button" onclick="openLockDialog();"><i id="lockIcon" title="Lock/unlock room" class="icon-security"></i></a>
<div class="header_button_separator"></div> <div class="header_button_separator"></div>
<a class="button" onclick="openLinkDialog();"><i title="Invite others" class="fa fa-link fa-lg"></i></a> <a class="button" onclick="openLinkDialog();"><i title="Invite others" class="icon-link"></i></a>
<div class="header_button_separator"></div> <div class="header_button_separator"></div>
<span class="toolbar_span"> <span class="toolbar_span">
<a class="button" onclick='Chat.toggleChat();'><i id="chat" title="Open chat" class="fa fa-comments-o fa-lg"></i></a> <a class="button" onclick='Chat.toggleChat();'><i id="chatButton" title="Open chat" class="icon-chat"></i></a>
<span id="unreadMessages"></span> <span id="unreadMessages"></span>
</span> </span>
<div class="header_button_separator"></div> <div class="header_button_separator"></div>
<a class="button" onclick='openPreziDialog();'><i title="Share prezi" class="fa fa-picture-o fa-lg"></i></a> <a class="button" onclick='Prezi.openPreziDialog();'><i title="Share prezi" class="icon-prezi"></i></a>
<span id="etherpadButton"> <span id="etherpadButton">
<div class="header_button_separator"></div> <div class="header_button_separator"></div>
<a class="button" onclick='Etherpad.toggleEtherpad(0);'><i title="Open shared document" class="fa fa-file-text fa-lg"></i></a> <a class="button" onclick='Etherpad.toggleEtherpad(0);'><i title="Open shared document" class="icon-share-doc"></i></a>
</span> </span>
<div class="header_button_separator"></div> <div class="header_button_separator"></div>
<span id="desktopsharing" style="display: none"> <span id="desktopsharing" style="display: none">
<a class="button" onclick="toggleScreenSharing();"><i title="Share screen" class="fa fa-desktop fa-lg"></i></a> <a class="button" onclick="toggleScreenSharing();"><i title="Share screen" class="icon-share-desktop"></i></a>
<div class="header_button_separator"></div> <div class="header_button_separator"></div>
</span> </span>
<a class="button" onclick='toggleFullScreen();'><i title="Enter / Exit Full Screen" class="fa fa-arrows-alt fa-lg"></i></a> <a class="button" onclick='buttonClick("#fullScreen", "icon-full-screen icon-exit-full-screen");toggleFullScreen();'><i id="fullScreen" title="Enter / Exit Full Screen" class="icon-full-screen"></i></a>
</span> </span>
</div> </div>
<div id="settings"> <div id="settings">
...@@ -76,20 +80,20 @@ ...@@ -76,20 +80,20 @@
<input id="connect" type="submit" value="Connect" /> <input id="connect" type="submit" value="Connect" />
</form> </form>
</div> </div>
<div id="reloadPresentation"><a onclick='Prezi.reloadPresentation();'><i title="Reload Prezi" class="fa fa-repeat fa-lg"></i></a></div>
<div id="videospace"> <div id="videospace" onmousemove="showToolbar();">
<div class="fade_line"></div>
<div id="largeVideoContainer" class="videocontainer"> <div id="largeVideoContainer" class="videocontainer">
<div id="reloadPresentation"><a onclick='reloadPresentation();'><i title="Reload Prezi" class="fa fa-repeat fa-lg"></i></a></div>
<div id="presentation"></div> <div id="presentation"></div>
<div id="etherpad"></div> <div id="etherpad"></div>
<a href="http://jitsi.org" target="_new"><div id="watermark"></div></a>
<video id="largeVideo" autoplay oncontextmenu="return false;"></video> <video id="largeVideo" autoplay oncontextmenu="return false;"></video>
</div> </div>
<div class="fade_line"></div>
<div id="remoteVideos"> <div id="remoteVideos">
<span id="localVideoContainer" class="videocontainer"> <span id="localVideoContainer" class="videocontainer">
<span id="localNick"></span> <span id="localNick" class="nick"></span>
<!--<video id="localVideo" autoplay oncontextmenu="return false;" muted></video> - is now per stream generated --> <span id="localVideoWrapper">
<!--<video id="localVideo" autoplay oncontextmenu="return false;" muted></video> - is now per stream generated -->
</span>
<audio id="localAudio" autoplay oncontextmenu="return false;" muted></audio> <audio id="localAudio" autoplay oncontextmenu="return false;" muted></audio>
<span class="focusindicator"></span> <span class="focusindicator"></span>
</span> </span>
......
...@@ -75,11 +75,16 @@ ColibriFocus.prototype.makeConference = function (peers) { ...@@ -75,11 +75,16 @@ ColibriFocus.prototype.makeConference = function (peers) {
self.channels.push([]); self.channels.push([]);
}); });
if(connection.jingle.localAudio) { this.peerconnection
this.peerconnection.addStream(connection.jingle.localAudio); = new TraceablePeerConnection(
this.connection.jingle.ice_config,
this.connection.jingle.pc_constraints );
if(this.connection.jingle.localAudio) {
this.peerconnection.addStream(this.connection.jingle.localAudio);
} }
if(connection.jingle.localVideo) { if(this.connection.jingle.localVideo) {
this.peerconnection.addStream(connection.jingle.localVideo); this.peerconnection.addStream(this.connection.jingle.localVideo);
} }
this.peerconnection.oniceconnectionstatechange = function (event) { this.peerconnection.oniceconnectionstatechange = function (event) {
console.warn('ice connection state changed to', self.peerconnection.iceConnectionState); console.warn('ice connection state changed to', self.peerconnection.iceConnectionState);
......
...@@ -328,6 +328,12 @@ TraceablePeerConnection.prototype.modifySources = function(successCallback) { ...@@ -328,6 +328,12 @@ TraceablePeerConnection.prototype.modifySources = function(successCallback) {
sdp.raw = sdp.session + sdp.media.join(''); sdp.raw = sdp.session + sdp.media.join('');
this.setRemoteDescription(new RTCSessionDescription({type: 'offer', sdp: sdp.raw}), this.setRemoteDescription(new RTCSessionDescription({type: 'offer', sdp: sdp.raw}),
function() { function() {
if(self.signalingState == 'closed') {
console.error("createAnswer attempt on closed state");
return;
}
self.createAnswer( self.createAnswer(
function(modifiedAnswer) { function(modifiedAnswer) {
// change video direction, see https://github.com/jitsi/jitmeet/issues/41 // change video direction, see https://github.com/jitsi/jitmeet/issues/41
...@@ -531,7 +537,10 @@ function getUserMediaWithConstraints(um, success_callback, failure_callback, res ...@@ -531,7 +537,10 @@ function getUserMediaWithConstraints(um, success_callback, failure_callback, res
} }
} }
if (resolution && !constraints.video) { // Check if we are running on Android device
var isAndroid = navigator.userAgent.indexOf('Android') != -1;
if (resolution && !constraints.video || isAndroid) {
constraints.video = {mandatory: {}};// same behaviour as true constraints.video = {mandatory: {}};// same behaviour as true
} }
// see https://code.google.com/p/chromium/issues/detail?id=143631#c9 for list of supported resolutions // see https://code.google.com/p/chromium/issues/detail?id=143631#c9 for list of supported resolutions
...@@ -574,7 +583,7 @@ function getUserMediaWithConstraints(um, success_callback, failure_callback, res ...@@ -574,7 +583,7 @@ function getUserMediaWithConstraints(um, success_callback, failure_callback, res
constraints.video.mandatory.minHeight = 240; constraints.video.mandatory.minHeight = 240;
break; break;
default: default:
if (navigator.userAgent.indexOf('Android') != -1) { if (isAndroid) {
constraints.video.mandatory.minWidth = 320; constraints.video.mandatory.minWidth = 320;
constraints.video.mandatory.minHeight = 240; constraints.video.mandatory.minHeight = 240;
constraints.video.mandatory.maxFrameRate = 15; constraints.video.mandatory.maxFrameRate = 15;
......
...@@ -53,6 +53,12 @@ JingleSession.prototype.initiate = function (peerjid, isInitiator) { ...@@ -53,6 +53,12 @@ JingleSession.prototype.initiate = function (peerjid, isInitiator) {
this.hadstuncandidate = false; this.hadstuncandidate = false;
this.hadturncandidate = false; this.hadturncandidate = false;
this.lasticecandidate = false; this.lasticecandidate = false;
this.peerconnection
= new TraceablePeerConnection(
this.connection.jingle.ice_config,
this.connection.jingle.pc_constraints );
this.peerconnection.onicecandidate = function (event) { this.peerconnection.onicecandidate = function (event) {
self.sendIceCandidate(event.candidate); self.sendIceCandidate(event.candidate);
}; };
......
...@@ -8,10 +8,6 @@ function SessionBase(connection, sid){ ...@@ -8,10 +8,6 @@ function SessionBase(connection, sid){
this.connection = connection; this.connection = connection;
this.sid = sid; this.sid = sid;
this.peerconnection
= new TraceablePeerConnection(
connection.jingle.ice_config,
connection.jingle.pc_constraints);
} }
...@@ -48,26 +44,27 @@ SessionBase.prototype.switchStreams = function (new_stream, oldStream, success_c ...@@ -48,26 +44,27 @@ SessionBase.prototype.switchStreams = function (new_stream, oldStream, success_c
var self = this; var self = this;
// Remember SDP to figure out added/removed SSRCs
var oldSdp = null;
if(self.peerconnection.localDescription) {
oldSdp = new SDP(self.peerconnection.localDescription.sdp);
}
// Stop the stream to trigger onended event for old stream // Stop the stream to trigger onended event for old stream
oldStream.stop(); oldStream.stop();
self.peerconnection.removeStream(oldStream); // Remember SDP to figure out added/removed SSRCs
var oldSdp = null;
if(self.peerconnection) {
if(self.peerconnection.localDescription) {
oldSdp = new SDP(self.peerconnection.localDescription.sdp);
}
self.peerconnection.removeStream(oldStream);
self.peerconnection.addStream(new_stream);
}
self.connection.jingle.localVideo = new_stream; self.connection.jingle.localVideo = new_stream;
self.peerconnection.addStream(self.connection.jingle.localVideo);
self.connection.jingle.localStreams = []; self.connection.jingle.localStreams = [];
self.connection.jingle.localStreams.push(self.connection.jingle.localAudio); self.connection.jingle.localStreams.push(self.connection.jingle.localAudio);
self.connection.jingle.localStreams.push(self.connection.jingle.localVideo); self.connection.jingle.localStreams.push(self.connection.jingle.localVideo);
// Conference is not active // Conference is not active
if(!oldSdp) { if(!oldSdp || !self.peerconnection) {
success_callback(); success_callback();
return; return;
} }
......
...@@ -98,17 +98,15 @@ Strophe.addConnectionPlugin('emuc', { ...@@ -98,17 +98,15 @@ Strophe.addConnectionPlugin('emuc', {
$(document).trigger('joined.muc', [from, member]); $(document).trigger('joined.muc', [from, member]);
this.list_members.push(from); this.list_members.push(from);
} }
else
$(document).trigger('presence.muc', [from, member, pres]);
} else if (this.members[from] === undefined) { } else if (this.members[from] === undefined) {
// new participant // new participant
this.members[from] = member; this.members[from] = member;
this.list_members.push(from); this.list_members.push(from);
$(document).trigger('entered.muc', [from, member, pres]); $(document).trigger('entered.muc', [from, member, pres]);
} else {
console.log('presence change from', from);
$(document).trigger('presence.muc', [from, member, pres]);
} }
// Always trigger presence to update bindings
console.log('presence change from', from);
$(document).trigger('presence.muc', [from, member, pres]);
return true; return true;
}, },
onPresenceUnavailable: function (pres) { onPresenceUnavailable: function (pres) {
......
This diff is collapsed.
...@@ -47,14 +47,14 @@ var Util = (function (my) { ...@@ -47,14 +47,14 @@ var Util = (function (my) {
}; };
/** /**
* Indicates if the given string is an alphanumeric string. * Returns the available video width.
* Note that some special characters are also allowed (-, _ , /) for the
* purpose of checking URIs. (FIXME: This should maybe moved to another not
* so generic method in the future.)
*/ */
my.isAlphanumeric = function(unsafeText) { my.getAvailableVideoWidth = function() {
var regex = /^[a-z0-9-_\/]+$/i; var chatspaceWidth = $('#chatspace').is(":visible")
return regex.test(unsafeText); ? $('#chatspace').width()
: 0;
return window.innerWidth - chatspaceWidth;
}; };
return my; return my;
......
...@@ -2,84 +2,85 @@ html, body{ ...@@ -2,84 +2,85 @@ html, body{
margin:0px; margin:0px;
height:100%; height:100%;
color: #424242; color: #424242;
font-family:'YanoneKaffeesatzLight',Verdana,Tahoma,Arial; font-family:'Helvetica Neue', Helvetica, sans-serif;
font-weight: 400; font-weight: 400;
background: #e9e9e9; background: #363636;
overflow: hidden;
} }
#unreadMessages {
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}
#videospace { #videospace {
display: block; display: block;
position: absolute; position: absolute;
top: 39px; top: 0px;
left: 0px; left: 0px;
right: 0px; right: 0px;
float: left;
} }
#largeVideo { #largeVideo {
display:block; overflow: hidden;
position:relative; text-align: center;
width:1280px;
height:720px;
margin-left:auto;
margin-right:auto;
z-index: 0;
} }
#pdfViewer { #pdfViewer {
display:block; display:block;
position:relative; position:absolute;
width:auto; width:auto;
height:auto; height:auto;
z-index: 1;
} }
#remoteVideos { #remoteVideos {
display:block; display:block;
position:relative; position:absolute;
text-align:center; text-align:right;
height:170px; height:196px;
padding: 18px;
bottom: 0;
left: 0;
right: 0;
width:auto; width:auto;
overflow: hidden; overflow: hidden;
border:1px solid transparent; border:1px solid transparent;
font-size:0;
z-index: 2; z-index: 2;
} }
#remoteVideos video { #remoteVideos video {
position:relative; display: inline-block;
top:18px;
height:160px;
width:auto;
z-index:0;
border:1px solid #FFFFFF;
background-repeat:no-repeat;
background-image:url(../images/avatar1.png); background-image:url(../images/avatar1.png);
background-size: contain; background-size: contain;
border-radius:8px;
border: 2px solid #212425;
} }
#remoteVideos video:hover { #remoteVideos video:hover {
width: 100%;
height: 100%;
content:"";
cursor: pointer; cursor: pointer;
cursor: hand; cursor: hand;
transform:scale(1.08, 1.08); transform:scale(1.08, 1.08);
-webkit-transform:scale(1.08, 1.08); -webkit-transform:scale(1.08, 1.08);
transition-duration: 0.5s; transition-duration: 0.5s;
-webkit-transition-duration: 0.5s; -webkit-transition-duration: 0.5s;
background-color: #FFFFFF;
-webkit-animation-name: greyPulse; -webkit-animation-name: greyPulse;
-webkit-animation-duration: 2s; -webkit-animation-duration: 2s;
-webkit-animation-iteration-count: 1; -webkit-animation-iteration-count: 1;
-webkit-box-shadow: 0 0 18px #515151; -webkit-box-shadow: 0 0 18px #388396;
border:1px solid #FFFFFF; border: 2px solid #388396;
z-index: 10; z-index: 3;
} }
#chatspace { #chatspace {
display:block; display:block;
position:absolute; position:absolute;
float: right; float: right;
top: 40px; top: 0px;
bottom: 0px; bottom: 0px;
right: 0px; right: 0px;
width:450px; width:450px;
...@@ -166,11 +167,28 @@ html, body{ ...@@ -166,11 +167,28 @@ html, body{
} }
#header{ #header{
display:block; display:none;
position:absolute;
height:39px; height:39px;
z-index: 1;
text-align:center; text-align:center;
background-color:#087dba; top:0;
left:0;
right:0;
z-index:20;
}
#toolbar {
display:inline-block;
position:relative;
margin-left:auto;
margin-right:auto;
height:39px;
width:auto;
overflow: hidden;
background: linear-gradient(to bottom, rgba(103,103,103,.65) , rgba(0,0,0,.65));
-webkit-box-shadow: 0 0 2px #000000, 0 0 10px #000000;
border-bottom-left-radius: 12px;
border-bottom-right-radius: 12px;
} }
#left { #left {
...@@ -196,15 +214,6 @@ html, body{ ...@@ -196,15 +214,6 @@ html, body{
z-index:1; z-index:1;
} }
#toolbar {
display:block;
position:relative;
height:39px;
width:auto;
overflow: hidden;
z-index:0;
visibility: hidden;
}
.button { .button {
display: inline-block; display: inline-block;
......
...@@ -6,8 +6,6 @@ div#ofmeet { ...@@ -6,8 +6,6 @@ div#ofmeet {
background-color: #F9F9F9; background-color: #F9F9F9;
-moz-border-radius: 5px; -moz-border-radius: 5px;
-webkit-border-radius: 5px; -webkit-border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
display:block; display:block;
position:relative; position:relative;
top: -100px; top: -100px;
...@@ -17,7 +15,8 @@ div#ofmeet { ...@@ -17,7 +15,8 @@ div#ofmeet {
font-size:14px; font-size:14px;
padding:5px; padding:5px;
overflow:scroll; overflow:scroll;
visibility:hidden; visibility:hidden;
overflow: hidden;
} }
...@@ -26,8 +25,8 @@ div#ofmeet div.ofmeet-clear { ...@@ -26,8 +25,8 @@ div#ofmeet div.ofmeet-clear {
} }
div#ofmeet form { div#ofmeet form {
margin: 0; margin: 10px;
padding: 0; padding: 10px;
} }
div#ofmeet div#ofmeet-login { div#ofmeet div#ofmeet-login {
......
<html> <html>
<head> <head>
<title>Openfire Meet</title> <title>Openfire Meet</title>
<script src="/jitsi/config"></script>
<script src="js/jquery.min.js"></script> <script src="js/jquery.min.js"></script>
<script src="js/jquery-ui.js"></script>
<script src="js/jquery-impromptu.js"></script> <script src="js/jquery-impromptu.js"></script>
<script src="js/jquery.autosize.js"></script> <script src="js/jquery.autosize.js"></script>
<script src="js/md5.js"></script> <script src="js/md5.js"></script>
<script src="js/base64.js"></script> <script src="js/base64.js"></script>
<script src="js/strophe.js"></script> <script src="js/strophe.js"></script>
<script src="js/muc.js"></script> <script src="js/muc.js"></script>
<script src="js/config.js"></script>
<script src="js/webrtc.sdp.js"></script> <script src="js/webrtc.sdp.js"></script>
<script src="js/strophe-openfire.js"></script> <script src="js/strophe-openfire.js"></script>
<script src="js/main.js"></script> <script src="js/main.js"></script>
...@@ -26,7 +27,7 @@ ...@@ -26,7 +27,7 @@
<div id="header"> <div id="header">
<a href="http://community.igniterealtime.org/community/support/jitsi_videobridge_plugin" target="_blank"><div id="leftlogo"><nobr>OfMeet</nobr></div></a> <a href="http://community.igniterealtime.org/community/support/jitsi_videobridge_plugin" target="_blank"><div id="leftlogo"><nobr>OfMeet</nobr></div></a>
<a href="http://jitsi.org" target="_blank"><div id="rightlogo"></div></a> <a href="http://jitsi.org" target="_blank"><div id="rightlogo"></div></a>
<div id="toolbar"> <span id="toolbar">
<a class="button" onclick='toggleScreenShare();'><i id="screen" title="share/unshare desktop" class="fa fa-desktop fa-lg"></i></a> <a class="button" onclick='toggleScreenShare();'><i id="screen" title="share/unshare desktop" class="fa fa-desktop fa-lg"></i></a>
<div class="header_button_separator"></div> <div class="header_button_separator"></div>
<a class="button" onclick='buttonClick("#mute", "fa fa-microphone fa-lg fa fa-microphone-slash fa-lg");toggleAudio();'><i id="mute" title="Mute / unmute" class="fa fa-microphone fa-lg"></i></a> <a class="button" onclick='buttonClick("#mute", "fa fa-microphone fa-lg fa fa-microphone-slash fa-lg");toggleAudio();'><i id="mute" title="Mute / unmute" class="fa fa-microphone fa-lg"></i></a>
...@@ -38,25 +39,21 @@ ...@@ -38,25 +39,21 @@
<a class="button" onclick="openLinkDialog();"><i title="Invite others" class="fa fa-link fa-lg"></i></a> <a class="button" onclick="openLinkDialog();"><i title="Invite others" class="fa fa-link fa-lg"></i></a>
<div class="header_button_separator"></div> <div class="header_button_separator"></div>
<span class="toolbar_span"> <span class="toolbar_span">
<a class="button" onclick='openChat();'><i id="chat" title="Open chat" class="fa fa-comments-o fa-lg"></i></a> <a class="button" onclick='openChat();'><i id="chatButton" title="Open chat" class="fa fa-comments-o fa-lg"></i></a>
<span id="unreadMessages"></span> <span id="unreadMessages"></span>
</span> </span>
<div class="header_button_separator"></div> <div class="header_button_separator"></div>
<a class="button" onclick='openPDFDialog();'><i id="pdf" title="Share PDF" class="fa fa-file fa-lg"></i></a> <a class="button" onclick='openPDFDialog();'><i id="pdf" title="Share PDF" class="fa fa-file fa-lg"></i></a>
<div class="header_button_separator"></div> <div class="header_button_separator"></div>
<a class="button" onclick='goFullScreen();'><i id="fullscreen" title="Full Screen" class="fa fa-arrows-alt fa-lg"></i></a> <a class="button" onclick='toggleFullScreen();'><i id="fullscreen" title="Full Screen" class="fa fa-arrows-alt fa-lg"></i></a>
<div class="header_button_separator"></div> <div class="header_button_separator"></div>
<a class="button" onclick='inviteParticipant();'><i id="invite" title="Invite Participant" class="fa fa-phone fa-lg"></i></a> <a class="button" onclick='inviteParticipant();'><i id="invite" title="Invite Participant" class="fa fa-phone fa-lg"></i></a>
<!-- </span>
<div class="header_button_separator"></div>
<a class="button" onclick='goAltView();'><i id="altview" title="Alternate View" class="fa fa-stop fa-lg"></i></a>
-->
</div>
</div> </div>
<div id="videospace"> <div id="videospace" onmousemove="showToolbar();">
<div class="fade_line"></div> <div class="fade_line"></div>
<video id="largeVideo" onDblClick="goFullScreen();" autoplay oncontextmenu="return false;"></video> <video id="largeVideo" onDblClick="toggleFullScreen();" autoplay oncontextmenu="return false;"></video>
<iframe id="pdfViewer" style="display:none"></iframe> <iframe id="pdfViewer" style="display:none"></iframe>
<div class="fade_line"></div> <div class="fade_line"></div>
<div id="remoteVideos"> <div id="remoteVideos">
...@@ -72,8 +69,9 @@ ...@@ -72,8 +69,9 @@
</form> </form>
</div> </div>
<div id="ofmeet"><div id="ofmeet-messaging"><div id="ofmeet-log"></div></div></div> <div id="ofmeet"><div id="ofmeet-messaging"><div id="ofmeet-log"></div></div>
<textarea id="usermsg" class= "animated" placeholder='Enter text...' autofocus></textarea> </div>
<textarea id="usermsg" class= "animated" placeholder='Enter text...' autofocus ></textarea>
</div> </div>
<script> <script>
</script> </script>
......
var config = {
hosts: {
domain: window.location.hostname,
muc: 'conference.' + window.location.hostname, // FIXME: use XEP-0030
bridge: 'jitsi-videobridge.' + window.location.hostname // FIXME: use XEP-0030
},
useIPv6: false, // ipv6 support. use at your own risk
useNicks: false,
useWebsockets: true,
resolution: "360",
bosh: window.location.protocol + "//" + window.location.host + '/http-bind/' // FIXME: use xep-0156 for that
};
This diff is collapsed.
/*
* Jitsi Videobridge, OpenSource video conferencing.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jitsi.videobridge.openfire;
import org.jivesoftware.util.*;
import org.jivesoftware.openfire.*;
import org.slf4j.*;
import org.slf4j.Logger;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletOutputStream;
import java.io.*;
import java.net.*;
import java.util.*;
import java.text.*;
public class Config extends HttpServlet
{
private static final Logger Log = LoggerFactory.getLogger(Config.class);
public static final long serialVersionUID = 24362462L;
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
Log.info("Config servlet");
String hostname = XMPPServer.getInstance().getServerInfo().getHostname();
String domain = XMPPServer.getInstance().getServerInfo().getXMPPDomain();
boolean websockets = XMPPServer.getInstance().getPluginManager().getPlugin("websockets") != null;
writeHeader(response);
ServletOutputStream out = response.getOutputStream();
out.println("var config = {");
out.println(" hosts: {");
out.println(" domain: '" + domain + "',");
out.println(" muc: 'conference." + domain + "',");
out.println(" bridge: 'jitsi-videobridge." + domain + "',");
out.println(" },");
out.println(" useIPv6: false,");
out.println(" useNicks: false,");
out.println(" useWebsockets: " + (websockets ? "true" : "false") + ",");
out.println(" resolution: '720',");
out.println(" bosh: window.location.protocol + '//' + window.location.host + '/http-bind/'");
out.println("}; ");
}
catch(Exception e) {
Log.info("Config doGet Error", e);
}
}
private void writeHeader(HttpServletResponse response)
{
try {
response.setHeader("Expires", "Sat, 6 May 1995 12:00:00 GMT");
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
response.setHeader("Pragma", "no-cache");
response.setHeader("Content-Type", "application/javascript");
response.setHeader("Connection", "close");
}
catch(Exception e)
{
Log.info("Config writeHeader Error", e);
}
}
}
...@@ -263,7 +263,7 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -263,7 +263,7 @@ public class PluginImpl implements Plugin, PropertyEventListener
Properties properties = new Properties(); Properties properties = new Properties();
String hostName = XMPPServer.getInstance().getServerInfo().getHostname(); String hostName = XMPPServer.getInstance().getServerInfo().getHostname();
String logDir = pluginDirectory.getAbsolutePath() + File.separator + ".." + File.separator + ".." + File.separator + "logs" + File.separator; String logDir = pluginDirectory.getAbsolutePath() + File.separator + ".." + File.separator + ".." + File.separator + "logs" + File.separator;
String port = JiveGlobals.getProperty(SIP_PORT_PROPERTY_NAME, "5060"); String port = JiveGlobals.getProperty(SIP_PORT_PROPERTY_NAME, "5070");
properties.setProperty("com.voxbone.kelpie.hostname", hostName); properties.setProperty("com.voxbone.kelpie.hostname", hostName);
properties.setProperty("com.voxbone.kelpie.ip", hostName); properties.setProperty("com.voxbone.kelpie.ip", hostName);
...@@ -1016,7 +1016,7 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -1016,7 +1016,7 @@ public class PluginImpl implements Plugin, PropertyEventListener
private byte partial[]; private byte partial[];
private int lastseqnum = -1; private int lastseqnum = -1;
private Participant me = this; private Participant me = this;
private boolean snapshot = false; private int snapshot = 0;
/** /**
* *
* *
...@@ -1052,7 +1052,7 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -1052,7 +1052,7 @@ public class PluginImpl implements Plugin, PropertyEventListener
*/ */
public void recordData(RawPacket packet) public void recordData(RawPacket packet)
{ {
if (!snapshot) Log.info("transferData " + packet.getPayloadLength() + " " + packet.getHeaderLength() + " " + packet.getExtensionLength()); if (snapshot < 10) Log.info("transferData " + packet.getPayloadLength() + " " + packet.getHeaderLength() + " " + packet.getExtensionLength());
try { try {
...@@ -1069,42 +1069,56 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -1069,42 +1069,56 @@ public class PluginImpl implements Plugin, PropertyEventListener
partial = new byte[0]; partial = new byte[0];
} }
if (!snapshot) Log.info("expecting X R N S PartID"); if (snapshot < 10) Log.info("expecting X R N S PartID");
byte x = rtp[payloadOffset]; //X R N S PartID byte x = rtp[payloadOffset]; //X R N S PartID
payloadOffset++; payloadOffset++;
vp8Length--; vp8Length--;
if ((x & 0x80) != 0) if ((x & 0x80) != 0) // extened bits
{ {
if (!snapshot) Log.info("found I L T RSV-A"); if (snapshot < 10) Log.info("found I L T RSV-A");
byte ilt = rtp[payloadOffset]; //I L T RSV-A byte ilt = rtp[payloadOffset]; //I L T RSV-A
payloadOffset++; payloadOffset++;
vp8Length--; vp8Length--;
if ((ilt & 0x80) != 0) { //picture ID if ((ilt & 0x80) != 0) { //picture ID
if (!snapshot) Log.info("found picture ID"); if (snapshot < 10) Log.info("found picture ID 1");
payloadOffset++; payloadOffset++;
vp8Length--; vp8Length--;
byte m = rtp[payloadOffset]; //picture ID
if ((m & 0x80) != 0)
{
if (snapshot < 10) Log.info("found picture ID 2");
payloadOffset++;
vp8Length--;
}
} }
if ((ilt & 0x40) != 0) { //TL0PICIDX if ((ilt & 0x40) != 0) { //TL0PICIDX
if (!snapshot) Log.info("found TL0PICIDX"); if (snapshot < 10) Log.info("found TL0PICIDX");
payloadOffset++; payloadOffset++;
vp8Length--; vp8Length--;
} }
if ((ilt & 0x20) != 0) { //TID RSV-B
if (!snapshot) Log.info("found TID RSV-B"); if ((ilt & 0x20) != 0 || (ilt & 0x10) != 0) { //TID RSV-B
if (snapshot < 10) Log.info("found TID RSV-B or keyframe index");
payloadOffset++; payloadOffset++;
vp8Length--; vp8Length--;
} }
} }
if ((x & 0x10) != 0) // start of partition if ((x & 0x10) != 0 && (x & 0x0f) == 0 && vp8Length >= 3) // start of partition
{ {
if (!snapshot) Log.info("found start of partition " + x); if (snapshot < 10) Log.info("found start of partition " + x);
partial = new byte[0]; partial = new byte[0];
} }
boolean isKeyframe = (rtp[payloadOffset] & 0x1) == 0;
int partialLength = partial.length; int partialLength = partial.length;
partial = Arrays.copyOf(partial, partial.length + vp8Length); partial = Arrays.copyOf(partial, partial.length + vp8Length);
System.arraycopy(rtp, payloadOffset, partial, partialLength, vp8Length); System.arraycopy(rtp, payloadOffset, partial, partialLength, vp8Length);
...@@ -1112,7 +1126,7 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -1112,7 +1126,7 @@ public class PluginImpl implements Plugin, PropertyEventListener
int thisseqnum = packet.getSequenceNumber(); int thisseqnum = packet.getSequenceNumber();
if (lastseqnum != -1 && thisseqnum != lastseqnum + 1) { if (lastseqnum != -1 && thisseqnum != lastseqnum + 1) {
if (!snapshot) Log.info("VP8:Received packet out of order, discarding frame."); if (snapshot < 10) Log.info("VP8:Received packet out of order, discarding frame.");
partial = null; partial = null;
lastseqnum = -1; lastseqnum = -1;
return; return;
...@@ -1124,15 +1138,14 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -1124,15 +1138,14 @@ public class PluginImpl implements Plugin, PropertyEventListener
if (recorder != null && partial != null) if (recorder != null && partial != null)
{ {
byte[] full = Arrays.copyOf(partial, partial.length); byte[] full = Arrays.copyOf(partial, partial.length);
boolean isKeyframe = (full[0] & 0x1) == 0; if (snapshot < 10) Log.info("recordData " + " " + packet.getPayloadType() + " " + full + " " + packet.getSequenceNumber() + " " + isKeyframe);
if (!snapshot) Log.info("recordData " + " " + packet.getPayloadType() + " " + full + " " + packet.getSequenceNumber() + " " + isKeyframe);
recorder.write(full, 0, full.length, isKeyframe, packet.getTimestamp()); recorder.write(full, 0, full.length, isKeyframe, packet.getTimestamp());
if (isKeyframe && snapshot == false) if (isKeyframe && snapshot < 10)
{ {
recorder.writeWebPImage(full, 0, full.length, packet.getTimestamp()); recorder.writeWebPImage(full, 0, full.length, packet.getTimestamp());
snapshot = true; snapshot++;
} }
} }
...@@ -1225,7 +1238,7 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -1225,7 +1238,7 @@ public class PluginImpl implements Plugin, PropertyEventListener
{ {
recorder.done(); recorder.done();
recorder = null; recorder = null;
snapshot = false; snapshot = 0;
} }
} }
} }
...@@ -1383,7 +1396,8 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -1383,7 +1396,8 @@ public class PluginImpl implements Plugin, PropertyEventListener
if (videoChannel != null) if (videoChannel != null)
{ {
participant.addMediaStream(videoChannel.getMediaStream()); // webm file creation not working yet
//participant.addMediaStream(videoChannel.getMediaStream());
} }
} }
} }
......
<%@ page import="org.jitsi.videobridge.openfire.*" %>
<%@ page import="org.jivesoftware.openfire.*" %>
<%@ page import="org.jivesoftware.openfire.container.*" %>
<%@ page import="org.jivesoftware.util.*" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
<%
String hostname = XMPPServer.getInstance().getServerInfo().getHostname();
String domain = XMPPServer.getInstance().getServerInfo().getXMPPDomain();
boolean websockets = XMPPServer.getInstance().getPluginManager().getPlugin("websockets") != null;
response.setHeader("Content-Type", "application/javascript");
%>
var config = {
hosts: {
domain: <%=domain%>,
muc: 'conference.<%=domain%>',
bridge: 'jitsi-videobridge.<%=domain%>',
},
useIPv6: false,
useNicks: false,
useWebsockets: <%= websockets ? "true" : "false" %>,
resolution: "360",
bosh: window.location.protocol + "//" + window.location.host + '/http-bind/'
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment