move screensharing into single function, properly handle mute/unmute

This commit is contained in:
isymchych 2016-02-04 17:25:11 +02:00
parent 44bae94701
commit 79d5bf6cfa
8 changed files with 130 additions and 224 deletions

6
app.js
View File

@ -62,8 +62,6 @@ const APP = {
conference,
API,
init () {
this.desktopsharing =
require("./modules/desktopsharing/desktopsharing");
this.keyboardshortcut =
require("./modules/keyboardshortcut/keyboardshortcut");
this.translation = require("./modules/translation/translation");
@ -75,10 +73,6 @@ function init() {
var isUIReady = APP.UI.start();
if (isUIReady) {
APP.conference.init({roomName: buildRoomName()}).then(function () {
// init desktop before UI, in order to make sure
// autoEnableDesktopSharing works
APP.desktopsharing.init(JitsiMeetJS.isDesktopSharingEnabled());
APP.UI.initConference();
APP.UI.addListener(UIEvents.LANG_CHANGED, function (language) {

View File

@ -9,7 +9,6 @@ import ConnectionQuality from './modules/connectionquality/connectionquality';
import CQEvents from './service/connectionquality/CQEvents';
import UIEvents from './service/UI/UIEvents';
import DSEvents from './service/desktopsharing/DesktopSharingEventTypes';
const ConnectionEvents = JitsiMeetJS.events.connection;
const ConnectionErrors = JitsiMeetJS.errors.connection;
@ -18,6 +17,7 @@ const ConferenceEvents = JitsiMeetJS.events.conference;
const ConferenceErrors = JitsiMeetJS.errors.conference;
const TrackEvents = JitsiMeetJS.events.track;
const TrackErrors = JitsiMeetJS.errors.track;
let room, connection, localTracks, localAudio, localVideo, roomLocker;
@ -108,6 +108,41 @@ function muteLocalVideo (muted) {
}
}
/**
* Create local tracks of specified types.
* @param {string[]} devices required track types ('audio', 'video' etc.)
* @returns {Promise<JitsiLocalTrack[]>}
*/
function createLocalTracks (...devices) {
return JitsiMeetJS.createLocalTracks({
// copy array to avoid mutations inside library
devices: devices.slice(0),
resolution: config.resolution,
// adds any ff fake device settings if any
firefox_fake_device: config.firefox_fake_device
}).catch(function (err) {
console.error('failed to create local tracks', ...devices, err);
return Promise.reject(err);
});
}
/**
* Create local screen sharing track.
* Shows UI notification if Firefox extension is required.
* @returns {Promise<JitsiLocalTrack[]>}
*/
function createDesktopTrack () {
return createLocalTracks('desktop').catch(function (err) {
if (err === TrackErrors.FIREFOX_EXTENSION_NEEDED) {
APP.UI.showExtensionRequiredDialog(
config.desktopSharingFirefoxExtensionURL
);
}
return Promise.reject(err);
});
}
class ConferenceConnector {
constructor(resolve, reject) {
this._resolve = resolve;
@ -232,6 +267,8 @@ export default {
isModerator: false,
audioMuted: false,
videoMuted: false,
isSharingScreen: false,
isDesktopSharingEnabled: false,
/**
* Open new connection and join to the conference.
* @param {object} options
@ -244,10 +281,12 @@ export default {
return JitsiMeetJS.init(config).then(() => {
return Promise.all([
this.createLocalTracks('audio', 'video').catch(()=>{
return this.createLocalTracks('audio');
}).catch(
() => {return [];}),
// try to retrieve audio and video
createLocalTracks('audio', 'video')
// if failed then try to retrieve only audio
.catch(() => createLocalTracks('audio'))
// if audio also failed then just return empty array
.catch(() => []),
connect()
]);
}).then(([tracks, con]) => {
@ -255,6 +294,8 @@ export default {
localTracks = tracks;
connection = con;
this._createRoom();
this.isDesktopSharingEnabled =
JitsiMeetJS.isDesktopSharingEnabled();
// XXX The API will take care of disconnecting from the XMPP server
// (and, thus, leaving the room) on unload.
return new Promise((resolve, reject) => {
@ -262,24 +303,6 @@ export default {
});
});
},
/**
* Create local tracks of specified types.
* If we cannot obtain required tracks it will return empty array.
* @param {string[]} devices required track types ('audio', 'video' etc.)
* @returns {Promise<JitsiLocalTrack[]>}
*/
createLocalTracks (...devices) {
return JitsiMeetJS.createLocalTracks({
// copy array to avoid mutations inside library
devices: devices.slice(0),
resolution: config.resolution,
// adds any ff fake device settings if any
firefox_fake_device: config.firefox_fake_device
}).catch(function (err) {
console.error('failed to create local tracks', ...devices, err);
return Promise.reject(err);
});
},
/**
* Check if id is id of the local user.
* @param {string} id id to check
@ -456,6 +479,79 @@ export default {
}
return options;
},
videoSwitchInProgress: false,
toggleScreenSharing () {
if (this.videoSwitchInProgress) {
console.warn("Switch in progress.");
return;
}
if (!this.isDesktopSharingEnabled) {
console.warn("Cannot toggle screen sharing: not supported.");
return;
}
this.videoSwitchInProgress = true;
if (this.isSharingScreen) {
// stop sharing desktop and share video
createLocalTracks('video').then(function ([stream]) {
return room.addTrack(stream);
}).then((stream) => {
if (localVideo) {
localVideo.stop();
}
localVideo = stream;
this.videoMuted = stream.isMuted();
APP.UI.setVideoMuted(this.localId, this.videoMuted);
APP.UI.addLocalStream(stream);
console.log('sharing local video');
}).catch((err) => {
localVideo = null;
console.error('failed to share local video', err);
}).then(() => {
this.videoSwitchInProgress = false;
this.isSharingScreen = false;
APP.UI.updateDesktopSharingButtons();
});
} else {
// stop sharing video and share desktop
createDesktopTrack().then(([stream]) => {
stream.on(
TrackEvents.TRACK_STOPPED,
() => {
// if stream was stopped during screensharing session
// then we should switch to video
// otherwise we stopped it because we already switched
// to video, so nothing to do here
if (this.isSharingScreen) {
this.toggleScreenSharing();
}
}
);
return room.addTrack(stream);
}).then((stream) => {
if (localVideo) {
localVideo.stop();
}
localVideo = stream;
this.videoMuted = stream.isMuted();
APP.UI.setVideoMuted(this.localId, this.videoMuted);
APP.UI.addLocalStream(stream);
this.videoSwitchInProgress = false;
this.isSharingScreen = true;
APP.UI.updateDesktopSharingButtons();
console.log('sharing local desktop');
}).catch((err) => {
this.videoSwitchInProgress = false;
console.error('failed to share local desktop', err);
});
}
},
/**
* Setup interaction between conference and UI.
*/
@ -799,45 +895,8 @@ export default {
room.pinParticipant(id);
});
APP.UI.addListener(UIEvents.TOGGLE_SCREENSHARING, () => {
APP.desktopsharing.toggleScreenSharing();
});
APP.desktopsharing.addListener(DSEvents.SWITCHING_DONE,
(isSharingScreen) => {
APP.UI.updateDesktopSharingButtons(isSharingScreen);
});
APP.desktopsharing.addListener(DSEvents.FIREFOX_EXTENSION_NEEDED,
(url) => {
APP.UI.showExtensionRequiredDialog(url);
});
APP.desktopsharing.addListener(DSEvents.NEW_STREAM_CREATED,
(track, callback) => {
const localCallback = (newTrack) => {
if(!newTrack || !localVideo || !newTrack.isLocal() ||
newTrack !== localVideo)
return;
if(localVideo.isMuted() &&
localVideo.videoType !== track.videoType) {
localVideo.mute();
}
callback();
if(room)
room.off(ConferenceEvents.TRACK_ADDED, localCallback);
};
if(room) {
room.on(ConferenceEvents.TRACK_ADDED, localCallback);
}
if(localVideo)
localVideo.stop();
localVideo = track;
room.addTrack(track);
if(!room)
localCallback();
APP.UI.addLocalStream(track);
}
APP.UI.addListener(
UIEvents.TOGGLE_SCREENSHARING, this.toggleScreenSharing.bind(this)
);
}
};

View File

@ -782,10 +782,9 @@ UI.setAudioLevel = function (id, lvl) {
/**
* Update state of desktop sharing buttons.
* @param {boolean} isSharingScreen if user is currently sharing his screen
*/
UI.updateDesktopSharingButtons = function (isSharingScreen) {
Toolbar.changeDesktopSharingButtonState(isSharingScreen);
UI.updateDesktopSharingButtons = function () {
Toolbar.updateDesktopSharingButtonState();
};
/**

View File

@ -131,7 +131,7 @@ const buttonHandlers = {
emitter.emit(UIEvents.ETHERPAD_CLICKED);
},
"toolbar_button_desktopsharing": function () {
if (APP.desktopsharing.isUsingScreenStream) {
if (APP.conference.isSharingScreen) {
AnalyticsAdapter.sendEvent('toolbar.screen.disabled');
} else {
AnalyticsAdapter.sendEvent('toolbar.screen.enabled');
@ -371,13 +371,12 @@ const Toolbar = {
},
/**
* Sets the state of the button. The button has blue glow if desktop
* Update the state of the button. The button has blue glow if desktop
* streaming is active.
* @param active the state of the desktop streaming.
*/
changeDesktopSharingButtonState (active) {
updateDesktopSharingButtonState () {
let button = $("#toolbar_button_desktopsharing");
if (active) {
if (APP.conference.isSharingScreen) {
button.addClass("glow");
} else {
button.removeClass("glow");

View File

@ -7,7 +7,7 @@ let toolbarTimeoutObject;
let toolbarTimeout = interfaceConfig.INITIAL_TOOLBAR_TIMEOUT;
function showDesktopSharingButton() {
if (APP.desktopsharing.isDesktopSharingEnabled() &&
if (APP.conference.isDesktopSharingEnabled &&
UIUtil.isButtonEnabled('desktop')) {
$('#toolbar_button_desktopsharing').css({display: "inline-block"});
} else {

View File

@ -1,134 +0,0 @@
/* global APP, JitsiMeetJS, config */
var EventEmitter = require("events");
import DSEvents from '../../service/desktopsharing/DesktopSharingEventTypes';
const TrackEvents = JitsiMeetJS.events.track;
/**
* Indicates that desktop stream is currently in use (for toggle purpose).
* @type {boolean}
*/
var isUsingScreenStream = false;
/**
* Indicates that switch stream operation is in progress and prevent from
* triggering new events.
* @type {boolean}
*/
var switchInProgress = false;
/**
* true if desktop sharing is enabled and false otherwise.
*/
var isEnabled = false;
var eventEmitter = new EventEmitter();
function streamSwitchDone() {
switchInProgress = false;
eventEmitter.emit(DSEvents.SWITCHING_DONE, isUsingScreenStream);
}
function newStreamCreated(track) {
eventEmitter.emit(DSEvents.NEW_STREAM_CREATED, track, streamSwitchDone);
}
function getVideoStreamFailed(error) {
console.error("Failed to obtain the stream to switch to", error);
switchInProgress = false;
isUsingScreenStream = false;
newStreamCreated(null);
}
function getDesktopStreamFailed(error) {
console.error("Failed to obtain the stream to switch to", error);
switchInProgress = false;
}
function onEndedHandler() {
if (!switchInProgress && isUsingScreenStream) {
APP.desktopsharing.toggleScreenSharing();
}
}
module.exports = {
isUsingScreenStream: function () {
return isUsingScreenStream;
},
/**
* Initializes the desktop sharing module.
* @param {boolean} <tt>true</tt> if desktop sharing feature is available
* and enabled.
*/
init: function (enabled) {
isEnabled = enabled;
},
/**
* @returns {boolean} <tt>true</tt> if desktop sharing feature is available
* and enabled.
*/
isDesktopSharingEnabled: function () {
return isEnabled;
},
addListener: function (type, listener) {
eventEmitter.on(type, listener);
},
removeListener: function (type, listener) {
eventEmitter.removeListener(type, listener);
},
/*
* Toggles screen sharing.
*/
toggleScreenSharing: function () {
if (switchInProgress) {
console.warn("Switch in progress.");
return;
} else if (!this.isDesktopSharingEnabled()) {
console.warn("Cannot toggle screen sharing: not supported.");
return;
}
switchInProgress = true;
let type;
if (!isUsingScreenStream) {
// Switch to desktop stream
type = "desktop";
} else {
type = "video";
}
var fail = (error) => {
if (type === 'desktop') {
getDesktopStreamFailed(error);
} else {
getVideoStreamFailed(error);
}
};
APP.conference.createLocalTracks(type).then((tracks) => {
// FIXME does it mean that 'not track.length' == GUM failed ?
// And will this ever happen if promise is supposed to fail in GUM
// failed case ?
if (!tracks.length) {
fail();
return;
}
let stream = tracks[0];
// We now use screen stream
isUsingScreenStream = type === "desktop";
if (isUsingScreenStream) {
stream.on(TrackEvents.TRACK_STOPPED, onEndedHandler);
}
newStreamCreated(stream);
}).catch((error) => {
if(error === JitsiMeetJS.errors.track.FIREFOX_EXTENSION_NEEDED)
{
eventEmitter.emit(
DSEvents.FIREFOX_EXTENSION_NEEDED,
config.desktopSharingFirefoxExtensionURL);
return;
}
fail(error);
});
}
};

View File

@ -13,8 +13,8 @@ function initShortcutHandlers() {
68: {
character: "D",
id: "toggleDesktopSharingPopover",
function: function() {
APP.desktopsharing.toggleScreenSharing();
function: function () {
APP.conference.toggleScreenSharing();
}
},
70: {

View File

@ -1,11 +0,0 @@
export default {
SWITCHING_DONE: "ds.switching_done",
NEW_STREAM_CREATED: "ds.new_stream_created",
/**
* An event which indicates that the jidesha extension for Firefox is
* needed to proceed with screen sharing, and that it is not installed.
*/
FIREFOX_EXTENSION_NEEDED: "ds.firefox_extension_needed"
};