feat: add config.startAudioOnly

When the 'startAudioOnly' config option is set to true the conference
will start in the audio only mode.
This commit is contained in:
paweldomas 2017-07-11 15:06:58 +02:00
parent d87b8823e9
commit 6493b09565
3 changed files with 63 additions and 6 deletions

View File

@ -26,6 +26,7 @@ import {
conferenceFailed, conferenceFailed,
conferenceJoined, conferenceJoined,
conferenceLeft, conferenceLeft,
toggleAudioOnly,
EMAIL_COMMAND, EMAIL_COMMAND,
lockStateChanged lockStateChanged
} from './react/features/base/conference'; } from './react/features/base/conference';
@ -459,11 +460,14 @@ export default {
* Creates local media tracks and connects to a room. Will show error * Creates local media tracks and connects to a room. Will show error
* dialogs in case accessing the local microphone and/or camera failed. Will * dialogs in case accessing the local microphone and/or camera failed. Will
* show guidance overlay for users on how to give access to camera and/or * show guidance overlay for users on how to give access to camera and/or
* microphone, * microphone.
* @param {string} roomName * @param {string} roomName
* @param {object} options * @param {object} options
* @param {boolean} options.startScreenSharing - if <tt>true</tt> should * @param {boolean} options.startAudioOnly=false - if <tt>true</tt> then
* start with screensharing instead of camera video. * only audio track will be created and the audio only mode will be turned
* on.
* @param {boolean} options.startScreenSharing=false - if <tt>true</tt>
* should start with screensharing instead of camera video.
* @returns {Promise.<JitsiLocalTrack[], JitsiConnection>} * @returns {Promise.<JitsiLocalTrack[], JitsiConnection>}
*/ */
createInitialLocalTracksAndConnect(roomName, options = {}) { createInitialLocalTracksAndConnect(roomName, options = {}) {
@ -482,8 +486,18 @@ export default {
// First try to retrieve both audio and video. // First try to retrieve both audio and video.
let tryCreateLocalTracks; let tryCreateLocalTracks;
// FIXME there is no video muted indication visible on the remote side,
// after starting in audio only (there's no video track)
// FIXME the logic about trying to go audio only on error is duplicated // FIXME the logic about trying to go audio only on error is duplicated
if (options.startScreenSharing) { if (options.startAudioOnly) {
tryCreateLocalTracks
= createLocalTracks({ devices: ['audio'] }, true)
.catch(err => {
audioOnlyError = err;
return [];
});
} else if (options.startScreenSharing) {
tryCreateLocalTracks = this._createDesktopTrack() tryCreateLocalTracks = this._createDesktopTrack()
.then(desktopStream => { .then(desktopStream => {
return createLocalTracks({ devices: ['audio'] }, true) return createLocalTracks({ devices: ['audio'] }, true)
@ -591,6 +605,7 @@ export default {
analytics.init(); analytics.init();
return this.createInitialLocalTracksAndConnect( return this.createInitialLocalTracksAndConnect(
options.roomName, { options.roomName, {
startAudioOnly: config.startAudioOnly,
startScreenSharing: config.startScreenSharing startScreenSharing: config.startScreenSharing
}); });
}).then(([tracks, con]) => { }).then(([tracks, con]) => {
@ -649,6 +664,15 @@ export default {
this.updateVideoIconEnabled(); this.updateVideoIconEnabled();
} }
// Enable audio only mode
if (config.startAudioOnly) {
// It is important to have that toggled after video muted
// state is adjusted by the code about lack of video tracks
// above. That's because audio only will store muted state
// on toggle action.
APP.store.dispatch(toggleAudioOnly());
}
this._initDeviceList(); this._initDeviceList();
if (config.iAmRecorder) if (config.iAmRecorder)
@ -2035,7 +2059,7 @@ export default {
JitsiMeetJS.mediaDevices.enumerateDevices(devices => { JitsiMeetJS.mediaDevices.enumerateDevices(devices => {
// Ugly way to synchronize real device IDs with local // Ugly way to synchronize real device IDs with local
// storage and settings menu. This is a workaround until // storage and settings menu. This is a workaround until
// getConstraints() method will be implemented // getConstraints() method will be implemented
// in browsers. // in browsers.
if (localAudio) { if (localAudio) {
APP.settings.setMicDeviceId( APP.settings.setMicDeviceId(

View File

@ -72,6 +72,7 @@ var config = { // eslint-disable-line no-unused-vars
// page redirection when call is hangup // page redirection when call is hangup
disableSimulcast: false, disableSimulcast: false,
// requireDisplayName: true, // Forces the participants that doesn't have display name to enter it when they enter the room. // requireDisplayName: true, // Forces the participants that doesn't have display name to enter it when they enter the room.
startAudioOnly: false, // Will start the conference in the audio only mode (no video is being received nor sent)
startScreenSharing: false, // Will try to start with screensharing instead of camera startScreenSharing: false, // Will try to start with screensharing instead of camera
// startAudioMuted: 10, // every participant after the Nth will start audio muted // startAudioMuted: 10, // every participant after the Nth will start audio muted
// startVideoMuted: 10, // every participant after the Nth will start video muted // startVideoMuted: 10, // every participant after the Nth will start video muted

View File

@ -15,7 +15,7 @@ import {
_setAudioOnlyVideoMuted, _setAudioOnlyVideoMuted,
setLastN setLastN
} from './actions'; } from './actions';
import { SET_AUDIO_ONLY, SET_LASTN } from './actionTypes'; import { CONFERENCE_JOINED, SET_AUDIO_ONLY, SET_LASTN } from './actionTypes';
import { import {
_addLocalTracksToConference, _addLocalTracksToConference,
_handleParticipantError, _handleParticipantError,
@ -33,6 +33,9 @@ MiddlewareRegistry.register(store => next => action => {
case CONNECTION_ESTABLISHED: case CONNECTION_ESTABLISHED:
return _connectionEstablished(store, next, action); return _connectionEstablished(store, next, action);
case CONFERENCE_JOINED:
return _conferenceJoined(store, next, action);
case PIN_PARTICIPANT: case PIN_PARTICIPANT:
return _pinParticipant(store, next, action); return _pinParticipant(store, next, action);
@ -76,6 +79,35 @@ function _connectionEstablished(store, next, action) {
return result; return result;
} }
/**
* Does extra sync up on properties that may need to be updated, after
* the conference was joined.
*
* @param {Store} store - The Redux store in which the specified action is being
* dispatched.
* @param {Dispatch} next - The Redux dispatch function to dispatch the
* specified action to the specified store.
* @param {Action} action - The Redux action CONFERENCE_JOINED which is being
* dispatched in the specified store.
* @private
* @returns {Object} The new state that is the result of the reduction of the
* specified action.
*/
function _conferenceJoined(store, next, action) {
const result = next(action);
const { audioOnly, conference }
= store.getState()['features/base/conference'];
// FIXME On Web the audio only mode for "start audio only" is toggled before
// conference is added to the redux store ("on conference joined" action)
// and the LastN value needs to be synchronized here.
if (audioOnly && conference.getLastN() !== 0) {
store.dispatch(setLastN(0));
}
return result;
}
/** /**
* Notifies the feature base/conference that the action PIN_PARTICIPANT is being * Notifies the feature base/conference that the action PIN_PARTICIPANT is being
* dispatched within a specific Redux store. Pins the specified remote * dispatched within a specific Redux store. Pins the specified remote