Implements start muted feature.

This commit is contained in:
hristoterezov 2015-05-19 18:03:01 +03:00
parent 172c2d3d71
commit 099e3340bc
13 changed files with 144 additions and 32 deletions

View File

@ -32,8 +32,6 @@ var config = {
enableWelcomePage: true, enableWelcomePage: true,
enableSimulcast: false, // blocks FF support enableSimulcast: false, // blocks FF support
logStats: false, // Enable logging of PeerConnection stats via the focus logStats: false, // Enable logging of PeerConnection stats via the focus
startVideoMuted: false,
startAudioMuted: false,
/*noticeMessage: 'Service update is scheduled for 16th March 2015. ' + /*noticeMessage: 'Service update is scheduled for 16th March 2015. ' +
'During that time service will not be available. ' + 'During that time service will not be available. ' +
'Apologise for inconvenience.'*/ 'Apologise for inconvenience.'*/

View File

@ -47,3 +47,21 @@
#languages_selectbox{ #languages_selectbox{
height: 40px; height: 40px;
} }
#startMutedOptions {
padding-left: 10%;
text-indent: -10%;
}
#startAudioMuted {
width: 13px !important;
}
#startVideoMuted {
width: 13px !important;
}
.startMutedLabel {
float: left;
}

View File

@ -10,7 +10,7 @@
<meta itemprop="description" content="Join a WebRTC video conference powered by the Jitsi Videobridge"/> <meta itemprop="description" content="Join a WebRTC video conference powered by the Jitsi Videobridge"/>
<meta itemprop="image" content="/images/jitsilogo.png"/> <meta itemprop="image" content="/images/jitsilogo.png"/>
<script src="libs/jquery-2.1.1.min.js"></script> <script src="libs/jquery-2.1.1.min.js"></script>
<script src="config.js?v=7"></script><!-- adapt to your needs, i.e. set hosts and bosh path --> <script src="config.js?v=8"></script><!-- adapt to your needs, i.e. set hosts and bosh path -->
<script src="libs/strophe/strophe.min.js?v=1"></script> <script src="libs/strophe/strophe.min.js?v=1"></script>
<script src="libs/strophe/strophe.disco.min.js?v=1"></script> <script src="libs/strophe/strophe.disco.min.js?v=1"></script>
<script src="libs/strophe/strophe.caps.jsonly.min.js?v=1"></script> <script src="libs/strophe/strophe.caps.jsonly.min.js?v=1"></script>
@ -19,7 +19,7 @@
<script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib --> <script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib -->
<script src="libs/toastr.js?v=1"></script><!-- notifications lib --> <script src="libs/toastr.js?v=1"></script><!-- notifications lib -->
<script src="interface_config.js?v=5"></script> <script src="interface_config.js?v=5"></script>
<script src="libs/app.bundle.js?v=66"></script> <script src="libs/app.bundle.js?v=67"></script>
<script src="analytics.js?v=1"></script><!-- google analytics plugin --> <script src="analytics.js?v=1"></script><!-- google analytics plugin -->
<link rel="stylesheet" href="css/font.css?v=7"/> <link rel="stylesheet" href="css/font.css?v=7"/>
<link rel="stylesheet" href="css/toastr.css?v=1"> <link rel="stylesheet" href="css/toastr.css?v=1">
@ -299,6 +299,16 @@
<div class="arrow-up"></div> <div class="arrow-up"></div>
<input type="text" id="setDisplayName" data-i18n="[placeholder]settings.name" placeholder="Name"> <input type="text" id="setDisplayName" data-i18n="[placeholder]settings.name" placeholder="Name">
<input type="text" id="setEmail" placeholder="E-Mail"> <input type="text" id="setEmail" placeholder="E-Mail">
<div id = "startMutedOptions">
<label class = "startMutedLabel">
<input type="checkbox" id="startAudioMuted">
<span data-i18n="settings.startAudioMuted"></span>
</label>
<label class = "startMutedLabel">
<input type="checkbox" id="startVideoMuted">
<span data-i18n="settings.startVideoMuted"></span>
</label>
</div>
<button id="updateSettings" data-i18n="settings.update"></button> <button id="updateSettings" data-i18n="settings.update"></button>
</div> </div>
<a id="downloadlog" data-container="body" data-toggle="popover" data-placement="right" data-i18n="[data-content]downloadlogs" ><i class="fa fa-cloud-download"></i></a> <a id="downloadlog" data-container="body" data-toggle="popover" data-placement="right" data-i18n="[data-content]downloadlogs" ><i class="fa fa-cloud-download"></i></a>

View File

@ -81,7 +81,9 @@
{ {
"title": "SETTINGS", "title": "SETTINGS",
"update": "Update", "update": "Update",
"name": "Name" "name": "Name",
"startAudioMuted": "everyone join audio muted",
"startVideoMuted": "everyone join video muted"
}, },
"videothumbnail": "videothumbnail":
{ {

View File

@ -17,28 +17,26 @@ var eventEmitter = new EventEmitter();
function getMediaStreamUsage() function getMediaStreamUsage()
{ {
var result = { var result = {
audio: 1, audio: true,
video: 1 video: true
}; };
if( config.startAudioMuted === true)
result.audio = 0;
if( config.startVideoMuted === true)
result.video = 0;
/** There are some issues with the desktop sharing /** There are some issues with the desktop sharing
* when this property is enabled. * when this property is enabled.
* WARNING: We must change the implementation to start video/audio if we
* receive from the focus that the peer is not muted.
if(result.audio > 0 && result.video > 0)
return result;
var isSecureConnection = window.location.protocol == "https:"; var isSecureConnection = window.location.protocol == "https:";
if(config.disableEarlyMediaPermissionRequests || !isSecureConnection) if(config.disableEarlyMediaPermissionRequests || !isSecureConnection)
{ {
if(result.audio === 0) result = {
result.audio = -1; audio: false,
if(result.video === 0) video: false
result.video = -1; };
}**/
}
**/
return result; return result;
} }

View File

@ -300,7 +300,9 @@ RTCUtils.prototype.setAvailableDevices = function (um, available) {
* We ask for audio and video combined stream in order to get permissions and * We ask for audio and video combined stream in order to get permissions and
* not to ask twice. * not to ask twice.
*/ */
RTCUtils.prototype.obtainAudioAndVideoPermissions = function(devices, callback, usageOptions) { RTCUtils.prototype.obtainAudioAndVideoPermissions =
function(devices, callback, usageOptions)
{
var self = this; var self = this;
// Get AV // Get AV
@ -321,7 +323,7 @@ RTCUtils.prototype.obtainAudioAndVideoPermissions = function(devices, callback,
for(var i = 0; i < devices.length; i++) for(var i = 0; i < devices.length; i++)
{ {
var device = devices[i]; var device = devices[i];
if(usageOptions[device] !== -1) if(usageOptions[device] === true)
newDevices.push(device); newDevices.push(device);
} }
else else
@ -455,11 +457,12 @@ RTCUtils.prototype.handleLocalStream = function(stream, usageOptions)
videoStream = stream.videoStream; videoStream = stream.videoStream;
} }
var audioMuted = (usageOptions && usageOptions.audio != 1), var audioMuted = (usageOptions && usageOptions.audio === false),
videoMuted = (usageOptions && usageOptions.video != 1); videoMuted = (usageOptions && usageOptions.video === false);
var audioGUM = (!usageOptions || usageOptions.audio !== false),
videoGUM = (!usageOptions || usageOptions.video !== false);
var audioGUM = (!usageOptions || usageOptions.audio != -1),
videoGUM = (!usageOptions || usageOptions.video != -1);
this.service.createLocalStream(audioStream, "audio", null, null, this.service.createLocalStream(audioStream, "audio", null, null,
audioMuted, audioGUM); audioMuted, audioGUM);

View File

@ -34,10 +34,8 @@ var roomName = null;
function notifyForInitialMute() function notifyForInitialMute()
{ {
if(config.startAudioMuted || config.startVideoMuted) messageHandler.notify(null, "notify.mutedTitle", "connected",
{ "notify.muted", null, {timeOut: 120000});
messageHandler.notify(null, "notify.mutedTitle", "connected", "notify.muted", null, {timeOut: 120000});
}
} }
function setupPrezi() function setupPrezi()
@ -254,6 +252,9 @@ function registerListeners() {
APP.members.addListener(MemberEvents.DTMF_SUPPORT_CHANGED, APP.members.addListener(MemberEvents.DTMF_SUPPORT_CHANGED,
onDtmfSupportChanged); onDtmfSupportChanged);
APP.xmpp.addListener(XMPPEvents.START_MUTED, function (audio, video) {
SettingsMenu.setStartMuted(audio, video);
});
} }
@ -408,8 +409,6 @@ UI.start = function (init) {
SettingsMenu.init(); SettingsMenu.init();
notifyForInitialMute();
}; };
function chatAddError(errorMessage, originalText) function chatAddError(errorMessage, originalText)
@ -485,6 +484,7 @@ function onLocalRoleChanged(jid, info, pres, isModerator)
console.info("My role changed, new role: " + info.role); console.info("My role changed, new role: " + info.role);
onModeratorStatusChanged(isModerator); onModeratorStatusChanged(isModerator);
VideoLayout.showModeratorIndicator(); VideoLayout.showModeratorIndicator();
SettingsMenu.onRoleChanged();
if (isModerator) { if (isModerator) {
Authentication.closeAuthenticationWindow(); Authentication.closeAuthenticationWindow();
@ -729,6 +729,12 @@ UI.getRoomName = function () {
return roomName; return roomName;
}; };
UI.setInitialMuteFromFocus = function (muteAudio, muteVideo) {
if(muteAudio || muteVideo) notifyForInitialMute();
if(muteAudio) UI.setAudioMuted(true);
if(muteVideo) UI.setVideoMute(true);
}
/** /**
* Mutes/unmutes the local video. * Mutes/unmutes the local video.
*/ */

View File

@ -26,7 +26,7 @@ function generateLanguagesSelectBox()
var SettingsMenu = { var SettingsMenu = {
init: function () { init: function () {
$("#updateSettings").before(generateLanguagesSelectBox()); $("#startMutedOptions").before(generateLanguagesSelectBox());
APP.translation.translateElement($("#languages_selectbox")); APP.translation.translateElement($("#languages_selectbox"));
$('#settingsmenu>input').keyup(function(event){ $('#settingsmenu>input').keyup(function(event){
if(event.keyCode === 13) {//enter if(event.keyCode === 13) {//enter
@ -34,11 +34,36 @@ var SettingsMenu = {
} }
}); });
if(APP.xmpp.isModerator())
{
$("#startMutedOptions").css("display", "block");
}
else
{
$("#startMutedOptions").css("display", "none");
}
$("#updateSettings").click(function () { $("#updateSettings").click(function () {
SettingsMenu.update(); SettingsMenu.update();
}); });
}, },
onRoleChanged: function () {
if(APP.xmpp.isModerator())
{
$("#startMutedOptions").css("display", "block");
}
else
{
$("#startMutedOptions").css("display", "none");
}
},
setStartMuted: function (audio, video) {
$("#startAudioMuted").attr("checked", audio);
$("#startVideoMuted").attr("checked", video);
},
update: function() { update: function() {
var newDisplayName = UIUtil.escapeHtml($('#setDisplayName').get(0).value); var newDisplayName = UIUtil.escapeHtml($('#setDisplayName').get(0).value);
var newEmail = UIUtil.escapeHtml($('#setEmail').get(0).value); var newEmail = UIUtil.escapeHtml($('#setEmail').get(0).value);
@ -55,6 +80,10 @@ var SettingsMenu = {
APP.xmpp.addToPresence("email", newEmail); APP.xmpp.addToPresence("email", newEmail);
var email = Settings.setEmail(newEmail); var email = Settings.setEmail(newEmail);
var startAudioMuted = ($("#startAudioMuted").is(":checked"));
var startVideoMuted = ($("#startVideoMuted").is(":checked"));
APP.xmpp.addToPresence("startMuted",
[startAudioMuted, startVideoMuted]);
Avatar.setUserAvatar(APP.xmpp.myJid(), email); Avatar.setUserAvatar(APP.xmpp.myJid(), email);
}, },

View File

@ -177,6 +177,20 @@ var Moderator = {
{ name: 'openSctp', value: config.openSctp}) { name: 'openSctp', value: config.openSctp})
.up(); .up();
} }
if(config.startAudioMuted !== undefined)
{
elem.c(
'property',
{ name: 'startAudioMuted', value: config.startAudioMuted})
.up();
}
if(config.startVideoMuted !== undefined)
{
elem.c(
'property',
{ name: 'startVideoMuted', value: config.startVideoMuted})
.up();
}
elem.up(); elem.up();
return elem; return elem;
}, },

View File

@ -152,6 +152,13 @@ module.exports = function(XMPP, eventEmitter) {
$(document).trigger('videomuted.muc', [from, videoMuted.text()]); $(document).trigger('videomuted.muc', [from, videoMuted.text()]);
} }
var startMuted = $(pres).find('>startmuted');
if (startMuted.length)
{
eventEmitter.emit(XMPPEvents.START_MUTED,
startMuted.attr("audio") === "true", startMuted.attr("video") === "true");
}
var devices = $(pres).find('>devices'); var devices = $(pres).find('>devices');
if(devices.length) if(devices.length)
{ {
@ -506,6 +513,15 @@ module.exports = function(XMPP, eventEmitter) {
|| 'sendrecv' } || 'sendrecv' }
).up(); ).up();
} }
pres.up();
}
if(this.presMap["startMuted"] !== undefined)
{
pres.c("startmuted", {audio: this.presMap["startMuted"].audio,
video: this.presMap["startMuted"].video,
xmlns: "http://jitsi.org/jitmeet/start-muted"});
delete this.presMap["startMuted"];
} }
pres.up(); pres.up();
@ -586,6 +602,9 @@ module.exports = function(XMPP, eventEmitter) {
addUserIdToPresence: function (userId) { addUserIdToPresence: function (userId) {
this.presMap['userId'] = userId; this.presMap['userId'] = userId;
}, },
addStartMutedToPresence: function (audio, video) {
this.presMap["startMuted"] = {audio: audio, video: video};
},
isModerator: function () { isModerator: function () {
return this.role === 'moderator'; return this.role === 'moderator';
}, },

View File

@ -108,6 +108,14 @@ module.exports = function(XMPP, eventEmitter)
// see http://xmpp.org/extensions/xep-0166.html#concepts-session // see http://xmpp.org/extensions/xep-0166.html#concepts-session
switch (action) { switch (action) {
case 'session-initiate': case 'session-initiate':
var startMuted = $(iq).find('jingle>startmuted');
if(startMuted && startMuted.length > 0)
{
var audioMuted = startMuted.attr("audio");
var videoMuted = startMuted.attr("video");
APP.UI.setInitialMuteFromFocus((audioMuted === "true"),
(videoMuted === "true"));
}
sess = new JingleSession( sess = new JingleSession(
$(iq).attr('to'), $(iq).find('jingle').attr('sid'), $(iq).attr('to'), $(iq).find('jingle').attr('sid'),
this.connection, XMPP); this.connection, XMPP);

View File

@ -481,6 +481,12 @@ var XMPP = {
case "devices": case "devices":
connection.emuc.addDevicesToPresence(value); connection.emuc.addDevicesToPresence(value);
break; break;
case "startMuted":
if(!Moderator.isModerator())
return;
connection.emuc.addStartMutedToPresence(value[0],
value[1]);
break;
default : default :
console.log("Unknown tag for presence: " + name); console.log("Unknown tag for presence: " + name);
return; return;

View File

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