Merge pull request #487 from isymchych/video-mute-screensharing
Handle video mute/unmute during screensharing
This commit is contained in:
commit
e688a5cb9f
6
app.js
6
app.js
|
@ -62,8 +62,6 @@ const APP = {
|
||||||
conference,
|
conference,
|
||||||
API,
|
API,
|
||||||
init () {
|
init () {
|
||||||
this.desktopsharing =
|
|
||||||
require("./modules/desktopsharing/desktopsharing");
|
|
||||||
this.keyboardshortcut =
|
this.keyboardshortcut =
|
||||||
require("./modules/keyboardshortcut/keyboardshortcut");
|
require("./modules/keyboardshortcut/keyboardshortcut");
|
||||||
this.translation = require("./modules/translation/translation");
|
this.translation = require("./modules/translation/translation");
|
||||||
|
@ -75,10 +73,6 @@ function init() {
|
||||||
var isUIReady = APP.UI.start();
|
var isUIReady = APP.UI.start();
|
||||||
if (isUIReady) {
|
if (isUIReady) {
|
||||||
APP.conference.init({roomName: buildRoomName()}).then(function () {
|
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.initConference();
|
||||||
|
|
||||||
APP.UI.addListener(UIEvents.LANG_CHANGED, function (language) {
|
APP.UI.addListener(UIEvents.LANG_CHANGED, function (language) {
|
||||||
|
|
250
conference.js
250
conference.js
|
@ -9,7 +9,6 @@ import ConnectionQuality from './modules/connectionquality/connectionquality';
|
||||||
|
|
||||||
import CQEvents from './service/connectionquality/CQEvents';
|
import CQEvents from './service/connectionquality/CQEvents';
|
||||||
import UIEvents from './service/UI/UIEvents';
|
import UIEvents from './service/UI/UIEvents';
|
||||||
import DSEvents from './service/desktopsharing/DesktopSharingEventTypes';
|
|
||||||
|
|
||||||
const ConnectionEvents = JitsiMeetJS.events.connection;
|
const ConnectionEvents = JitsiMeetJS.events.connection;
|
||||||
const ConnectionErrors = JitsiMeetJS.errors.connection;
|
const ConnectionErrors = JitsiMeetJS.errors.connection;
|
||||||
|
@ -18,6 +17,7 @@ const ConferenceEvents = JitsiMeetJS.events.conference;
|
||||||
const ConferenceErrors = JitsiMeetJS.errors.conference;
|
const ConferenceErrors = JitsiMeetJS.errors.conference;
|
||||||
|
|
||||||
const TrackEvents = JitsiMeetJS.events.track;
|
const TrackEvents = JitsiMeetJS.events.track;
|
||||||
|
const TrackErrors = JitsiMeetJS.errors.track;
|
||||||
|
|
||||||
let room, connection, localTracks, localAudio, localVideo, roomLocker;
|
let room, connection, localTracks, localAudio, localVideo, roomLocker;
|
||||||
|
|
||||||
|
@ -47,19 +47,6 @@ function connect() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add local track to the conference and shares
|
|
||||||
* video type with other users if its video track.
|
|
||||||
* @param {JitsiLocalTrack} track local track
|
|
||||||
*/
|
|
||||||
function addTrack (track) {
|
|
||||||
room.addTrack(track);
|
|
||||||
|
|
||||||
if (track.isAudioTrack()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Share email with other users.
|
* Share email with other users.
|
||||||
* @param {string} email new email
|
* @param {string} email new email
|
||||||
|
@ -89,6 +76,73 @@ function getDisplayName (id) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mute or unmute local audio stream if it exists.
|
||||||
|
* @param {boolean} muted if audio stream should be muted or unmuted.
|
||||||
|
*/
|
||||||
|
function muteLocalAudio (muted) {
|
||||||
|
if (!localAudio) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (muted) {
|
||||||
|
localAudio.mute();
|
||||||
|
} else {
|
||||||
|
localAudio.unmute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mute or unmute local video stream if it exists.
|
||||||
|
* @param {boolean} muted if video stream should be muted or unmuted.
|
||||||
|
*/
|
||||||
|
function muteLocalVideo (muted) {
|
||||||
|
if (!localVideo) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (muted) {
|
||||||
|
localVideo.mute();
|
||||||
|
} else {
|
||||||
|
localVideo.unmute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 {
|
class ConferenceConnector {
|
||||||
constructor(resolve, reject) {
|
constructor(resolve, reject) {
|
||||||
this._resolve = resolve;
|
this._resolve = resolve;
|
||||||
|
@ -213,6 +267,8 @@ export default {
|
||||||
isModerator: false,
|
isModerator: false,
|
||||||
audioMuted: false,
|
audioMuted: false,
|
||||||
videoMuted: false,
|
videoMuted: false,
|
||||||
|
isSharingScreen: false,
|
||||||
|
isDesktopSharingEnabled: false,
|
||||||
/**
|
/**
|
||||||
* Open new connection and join to the conference.
|
* Open new connection and join to the conference.
|
||||||
* @param {object} options
|
* @param {object} options
|
||||||
|
@ -225,10 +281,12 @@ export default {
|
||||||
|
|
||||||
return JitsiMeetJS.init(config).then(() => {
|
return JitsiMeetJS.init(config).then(() => {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
this.createLocalTracks('audio', 'video').catch(()=>{
|
// try to retrieve audio and video
|
||||||
return this.createLocalTracks('audio');
|
createLocalTracks('audio', 'video')
|
||||||
}).catch(
|
// if failed then try to retrieve only audio
|
||||||
() => {return [];}),
|
.catch(() => createLocalTracks('audio'))
|
||||||
|
// if audio also failed then just return empty array
|
||||||
|
.catch(() => []),
|
||||||
connect()
|
connect()
|
||||||
]);
|
]);
|
||||||
}).then(([tracks, con]) => {
|
}).then(([tracks, con]) => {
|
||||||
|
@ -236,6 +294,8 @@ export default {
|
||||||
localTracks = tracks;
|
localTracks = tracks;
|
||||||
connection = con;
|
connection = con;
|
||||||
this._createRoom();
|
this._createRoom();
|
||||||
|
this.isDesktopSharingEnabled =
|
||||||
|
JitsiMeetJS.isDesktopSharingEnabled();
|
||||||
// XXX The API will take care of disconnecting from the XMPP server
|
// XXX The API will take care of disconnecting from the XMPP server
|
||||||
// (and, thus, leaving the room) on unload.
|
// (and, thus, leaving the room) on unload.
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
@ -243,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.
|
* Check if id is id of the local user.
|
||||||
* @param {string} id id to check
|
* @param {string} id id to check
|
||||||
|
@ -274,9 +316,7 @@ export default {
|
||||||
* @param mute true for mute and false for unmute.
|
* @param mute true for mute and false for unmute.
|
||||||
*/
|
*/
|
||||||
muteAudio (mute) {
|
muteAudio (mute) {
|
||||||
//FIXME: Maybe we should create method for that in the UI instead of
|
muteLocalAudio(mute);
|
||||||
//accessing directly eventEmitter????
|
|
||||||
APP.UI.eventEmitter.emit(UIEvents.AUDIO_MUTED, mute);
|
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Returns whether local audio is muted or not.
|
* Returns whether local audio is muted or not.
|
||||||
|
@ -296,9 +336,7 @@ export default {
|
||||||
* @param mute true for mute and false for unmute.
|
* @param mute true for mute and false for unmute.
|
||||||
*/
|
*/
|
||||||
muteVideo (mute) {
|
muteVideo (mute) {
|
||||||
//FIXME: Maybe we should create method for that in the UI instead of
|
muteLocalVideo(mute);
|
||||||
//accessing directly eventEmitter????
|
|
||||||
APP.UI.eventEmitter.emit(UIEvents.VIDEO_MUTED, mute);
|
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Simulates toolbar button click for video mute. Used by shortcuts and API.
|
* Simulates toolbar button click for video mute. Used by shortcuts and API.
|
||||||
|
@ -420,7 +458,7 @@ export default {
|
||||||
else if (track.isVideoTrack()) {
|
else if (track.isVideoTrack()) {
|
||||||
localVideo = track;
|
localVideo = track;
|
||||||
}
|
}
|
||||||
addTrack(track);
|
room.addTrack(track);
|
||||||
APP.UI.addLocalStream(track);
|
APP.UI.addLocalStream(track);
|
||||||
});
|
});
|
||||||
roomLocker = createRoomLocker(room);
|
roomLocker = createRoomLocker(room);
|
||||||
|
@ -448,6 +486,79 @@ export default {
|
||||||
}
|
}
|
||||||
return options;
|
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.
|
* Setup interaction between conference and UI.
|
||||||
*/
|
*/
|
||||||
|
@ -607,16 +718,8 @@ export default {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
APP.UI.addListener(UIEvents.AUDIO_MUTED, (muted) => {
|
APP.UI.addListener(UIEvents.AUDIO_MUTED, muteLocalAudio);
|
||||||
if(!localAudio)
|
APP.UI.addListener(UIEvents.VIDEO_MUTED, muteLocalVideo);
|
||||||
return;
|
|
||||||
(muted)? localAudio.mute() : localAudio.unmute();
|
|
||||||
});
|
|
||||||
APP.UI.addListener(UIEvents.VIDEO_MUTED, (muted) => {
|
|
||||||
if(!localVideo)
|
|
||||||
return;
|
|
||||||
(muted)? localVideo.mute() : localVideo.unmute();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!interfaceConfig.filmStripOnly) {
|
if (!interfaceConfig.filmStripOnly) {
|
||||||
APP.UI.addListener(UIEvents.MESSAGE_CREATED, (message) => {
|
APP.UI.addListener(UIEvents.MESSAGE_CREATED, (message) => {
|
||||||
|
@ -799,45 +902,8 @@ export default {
|
||||||
room.pinParticipant(id);
|
room.pinParticipant(id);
|
||||||
});
|
});
|
||||||
|
|
||||||
APP.UI.addListener(UIEvents.TOGGLE_SCREENSHARING, () => {
|
APP.UI.addListener(
|
||||||
APP.desktopsharing.toggleScreenSharing();
|
UIEvents.TOGGLE_SCREENSHARING, this.toggleScreenSharing.bind(this)
|
||||||
});
|
|
||||||
|
|
||||||
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;
|
|
||||||
addTrack(track);
|
|
||||||
if(!room)
|
|
||||||
localCallback();
|
|
||||||
APP.UI.addLocalStream(track);
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -782,10 +782,9 @@ UI.setAudioLevel = function (id, lvl) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update state of desktop sharing buttons.
|
* Update state of desktop sharing buttons.
|
||||||
* @param {boolean} isSharingScreen if user is currently sharing his screen
|
|
||||||
*/
|
*/
|
||||||
UI.updateDesktopSharingButtons = function (isSharingScreen) {
|
UI.updateDesktopSharingButtons = function () {
|
||||||
Toolbar.changeDesktopSharingButtonState(isSharingScreen);
|
Toolbar.updateDesktopSharingButtonState();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -131,7 +131,7 @@ const buttonHandlers = {
|
||||||
emitter.emit(UIEvents.ETHERPAD_CLICKED);
|
emitter.emit(UIEvents.ETHERPAD_CLICKED);
|
||||||
},
|
},
|
||||||
"toolbar_button_desktopsharing": function () {
|
"toolbar_button_desktopsharing": function () {
|
||||||
if (APP.desktopsharing.isUsingScreenStream) {
|
if (APP.conference.isSharingScreen) {
|
||||||
AnalyticsAdapter.sendEvent('toolbar.screen.disabled');
|
AnalyticsAdapter.sendEvent('toolbar.screen.disabled');
|
||||||
} else {
|
} else {
|
||||||
AnalyticsAdapter.sendEvent('toolbar.screen.enabled');
|
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.
|
* streaming is active.
|
||||||
* @param active the state of the desktop streaming.
|
|
||||||
*/
|
*/
|
||||||
changeDesktopSharingButtonState (active) {
|
updateDesktopSharingButtonState () {
|
||||||
let button = $("#toolbar_button_desktopsharing");
|
let button = $("#toolbar_button_desktopsharing");
|
||||||
if (active) {
|
if (APP.conference.isSharingScreen) {
|
||||||
button.addClass("glow");
|
button.addClass("glow");
|
||||||
} else {
|
} else {
|
||||||
button.removeClass("glow");
|
button.removeClass("glow");
|
||||||
|
|
|
@ -7,7 +7,7 @@ let toolbarTimeoutObject;
|
||||||
let toolbarTimeout = interfaceConfig.INITIAL_TOOLBAR_TIMEOUT;
|
let toolbarTimeout = interfaceConfig.INITIAL_TOOLBAR_TIMEOUT;
|
||||||
|
|
||||||
function showDesktopSharingButton() {
|
function showDesktopSharingButton() {
|
||||||
if (APP.desktopsharing.isDesktopSharingEnabled() &&
|
if (APP.conference.isDesktopSharingEnabled &&
|
||||||
UIUtil.isButtonEnabled('desktop')) {
|
UIUtil.isButtonEnabled('desktop')) {
|
||||||
$('#toolbar_button_desktopsharing').css({display: "inline-block"});
|
$('#toolbar_button_desktopsharing').css({display: "inline-block"});
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -13,8 +13,8 @@ function initShortcutHandlers() {
|
||||||
68: {
|
68: {
|
||||||
character: "D",
|
character: "D",
|
||||||
id: "toggleDesktopSharingPopover",
|
id: "toggleDesktopSharingPopover",
|
||||||
function: function() {
|
function: function () {
|
||||||
APP.desktopsharing.toggleScreenSharing();
|
APP.conference.toggleScreenSharing();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
70: {
|
70: {
|
||||||
|
|
|
@ -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"
|
|
||||||
};
|
|
Loading…
Reference in New Issue