diff --git a/react/features/app/middlewares.any.js b/react/features/app/middlewares.any.js index 019cae38e..ec46cb67a 100644 --- a/react/features/app/middlewares.any.js +++ b/react/features/app/middlewares.any.js @@ -41,6 +41,7 @@ import '../subtitles/middleware'; import '../toolbox/middleware'; import '../transcribing/middleware'; import '../video-layout/middleware'; +import '../video-quality/middleware'; import '../videosipgw/middleware'; import './middleware'; diff --git a/react/features/base/conference/middleware.js b/react/features/base/conference/middleware.js index 130729bea..a5b0c233f 100644 --- a/react/features/base/conference/middleware.js +++ b/react/features/base/conference/middleware.js @@ -460,7 +460,10 @@ function _sendTones({ getState }, next, action) { */ function _setReceiverVideoConstraint(conference, preferred, max) { if (conference) { - conference.setReceiverVideoConstraint(Math.min(preferred, max)); + const value = Math.min(preferred, max); + + conference.setReceiverVideoConstraint(value); + logger.info(`setReceiverVideoConstraint: ${value}`); } } diff --git a/react/features/base/config/middleware.js b/react/features/base/config/middleware.js index 96c2954a6..4fb82b3b3 100644 --- a/react/features/base/config/middleware.js +++ b/react/features/base/config/middleware.js @@ -3,6 +3,7 @@ import { jitsiLocalStorage } from 'js-utils'; import { APP_WILL_MOUNT } from '../app'; +import { getFeatureFlag } from '../flags/functions'; import { addKnownDomains } from '../known-domains'; import { MiddlewareRegistry } from '../redux'; import { parseURIString } from '../util'; @@ -107,6 +108,12 @@ function _setConfig({ dispatch, getState }, next, action) { config.p2p = { enabled: !settings.disableP2P }; } + const resolutionFlag = getFeatureFlag(state, 'resolution'); + + if (typeof resolutionFlag !== 'undefined') { + config.resolution = resolutionFlag; + } + dispatch({ type: _UPDATE_CONFIG, config diff --git a/react/features/base/flags/constants.js b/react/features/base/flags/constants.js index bc94c382d..7592cc901 100644 --- a/react/features/base/flags/constants.js +++ b/react/features/base/flags/constants.js @@ -81,6 +81,13 @@ export const RAISE_HAND_ENABLED = 'raise-hand.enabled'; */ export const RECORDING_ENABLED = 'recording.enabled'; +/** + * Flag indicating the local and (maximum) remote video resolution. Overrides + * the server configuration. + * Default: (unset). + */ +export const RESOLUTION = 'resolution'; + /** * Flag indicating if server URL change is enabled. * Default: enabled (true) diff --git a/react/features/conference/middleware.js b/react/features/conference/middleware.js index cf8fcf42f..6348e8d32 100644 --- a/react/features/conference/middleware.js +++ b/react/features/conference/middleware.js @@ -6,7 +6,7 @@ import { VIDEO_QUALITY_LEVELS, conferenceLeft, getCurrentConference, - setPreferredVideoQuality + setMaxReceiverVideoQuality } from '../base/conference'; import { hideDialog, isDialogOpen } from '../base/dialog'; import { setActiveModalId } from '../base/modal'; @@ -33,7 +33,7 @@ MiddlewareRegistry.register(store => next => action => { dispatch(setFilmstripEnabled(!reducedUI)); dispatch( - setPreferredVideoQuality( + setMaxReceiverVideoQuality( reducedUI ? VIDEO_QUALITY_LEVELS.LOW : VIDEO_QUALITY_LEVELS.HIGH)); diff --git a/react/features/video-layout/subscriber.js b/react/features/video-layout/subscriber.js index 17a74dfa5..fb76d35ea 100644 --- a/react/features/video-layout/subscriber.js +++ b/react/features/video-layout/subscriber.js @@ -32,8 +32,7 @@ StateListenerRegistry.register( dispatch(selectParticipant()); if (!displayTileView) { - dispatch( - setMaxReceiverVideoQuality(VIDEO_QUALITY_LEVELS.HIGH)); + dispatch(setMaxReceiverVideoQuality(VIDEO_QUALITY_LEVELS.HIGH)); if (_getAutoPinSetting()) { _updateAutoPinnedParticipant(store); diff --git a/react/features/video-quality/middleware.js b/react/features/video-quality/middleware.js new file mode 100644 index 000000000..227178dc0 --- /dev/null +++ b/react/features/video-quality/middleware.js @@ -0,0 +1,33 @@ +// @flow + +import { CONFERENCE_JOINED } from '../base/conference/actionTypes'; +import { setPreferredVideoQuality } from '../base/conference/actions'; +import { MiddlewareRegistry } from '../base/redux'; + +import logger from './logger'; + +/** + * Implements the middleware of the feature video-quality. + * + * @param {Store} store - The redux store. + * @returns {Function} + */ +MiddlewareRegistry.register(({ dispatch, getState }) => next => action => { + const result = next(action); + + switch (action.type) { + case CONFERENCE_JOINED: { + if (navigator.product === 'ReactNative') { + const { resolution } = getState()['features/base/config']; + + if (typeof resolution !== 'undefined') { + dispatch(setPreferredVideoQuality(Number.parseInt(resolution, 10))); + logger.info(`Configured preferred receiver video frame height to: ${resolution}`); + } + } + break; + } + } + + return result; +});