feat(video-quality): be able to set an internal max

The internal max will be used for tile view. Whatever the
user has set for preferred video quality, the internal
maximum will be respected. This allows for the case where
the user prefers high definition video, but in tile view
it only makes sense to send low definition; ux wise the
user is allowed to continue messing with the video quality
slider.
This commit is contained in:
Leonard Kim 2018-07-24 09:23:38 -07:00 committed by virtuacoplenny
parent 4d3383c620
commit ee7d180cbb
4 changed files with 89 additions and 8 deletions

View File

@ -152,6 +152,19 @@ export const SET_FOLLOW_ME = Symbol('SET_FOLLOW_ME');
*/
export const SET_LASTN = Symbol('SET_LASTN');
/**
* The type of (redux) action which sets the maximum video height that should be
* received from remote participants, even if the user prefers a larger video
* height.
*
* {
* type: SET_MAX_RECEIVER_VIDEO_QUALITY,
* maxReceiverVideoQuality: number
* }
*/
export const SET_MAX_RECEIVER_VIDEO_QUALITY
= Symbol('SET_MAX_RECEIVER_VIDEO_QUALITY');
/**
* The type of (redux) action which sets the password to join or lock a specific
* {@code JitsiConference}.
@ -177,8 +190,8 @@ export const SET_PASSWORD = Symbol('SET_PASSWORD');
export const SET_PASSWORD_FAILED = Symbol('SET_PASSWORD_FAILED');
/**
* The type of (redux) action which sets the maximum video size should be
* received from remote participants.
* The type of (redux) action which sets the preferred maximum video height that
* should be received from remote participants.
*
* {
* type: SET_PREFERRED_RECEIVER_VIDEO_QUALITY,

View File

@ -37,6 +37,7 @@ import {
SET_DESKTOP_SHARING_ENABLED,
SET_FOLLOW_ME,
SET_LASTN,
SET_MAX_RECEIVER_VIDEO_QUALITY,
SET_PASSWORD,
SET_PASSWORD_FAILED,
SET_PREFERRED_RECEIVER_VIDEO_QUALITY,
@ -569,6 +570,23 @@ export function setLastN(lastN: ?number) {
};
}
/**
* Sets the max frame height that should be received from remote videos.
*
* @param {number} maxReceiverVideoQuality - The max video frame height to
* receive.
* @returns {{
* type: SET_MAX_RECEIVER_VIDEO_QUALITY,
* maxReceiverVideoQuality: number
* }}
*/
export function setMaxReceiverVideoQuality(maxReceiverVideoQuality: number) {
return {
type: SET_MAX_RECEIVER_VIDEO_QUALITY,
maxReceiverVideoQuality
};
}
/**
* Sets the password to join or lock a specific JitsiConference.
*
@ -641,7 +659,8 @@ export function setPassword(
}
/**
* Sets the max frame height to receive from remote participant videos.
* Sets the max frame height the user prefers to receive from remote participant
* videos.
*
* @param {number} preferredReceiverVideoQuality - The max video resolution to
* receive.

View File

@ -34,6 +34,7 @@ import {
DATA_CHANNEL_OPENED,
SET_AUDIO_ONLY,
SET_LASTN,
SET_MAX_RECEIVER_VIDEO_QUALITY,
SET_PREFERRED_RECEIVER_VIDEO_QUALITY,
SET_ROOM
} from './actionTypes';
@ -80,6 +81,9 @@ MiddlewareRegistry.register(store => next => action => {
case SET_LASTN:
return _setLastN(store, next, action);
case SET_MAX_RECEIVER_VIDEO_QUALITY:
return _setMaximumReceiverVideoQuality(store, next, action);
case SET_PREFERRED_RECEIVER_VIDEO_QUALITY:
return _setPreferredReceiverVideoQuality(store, next, action);
@ -434,7 +438,38 @@ function _setLastN({ getState }, next, action) {
}
/**
* Sets the maximum receive video quality and will turn off audio only mode if
* Sets an internal maximum for the video frame height to receive from remote
* videos. This maximum acts as a cap so user preferences cannot exceed a
* specified frame height.
*
* @private
* @param {Store} store - The redux store in which the specified {@code action}
* is being dispatched.
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
* specified {@code action} to the specified {@code store}.
* @param {Action} action - The redux action
* {@code SET_MAXIMUM_RECEIVER_VIDEO_QUALITY} which is being dispatched in the
* specified {@code store}.
* @private
* @returns {Object} The value returned by {@code next(action)}.
*/
function _setMaximumReceiverVideoQuality({ getState }, next, action) {
const { conference, preferredReceiverVideoQuality }
= getState()['features/base/conference'];
if (conference) {
if (typeof preferredReceiverVideoQuality === 'undefined'
|| preferredReceiverVideoQuality > action.maxReceiverVideoQuality) {
conference.setReceiverVideoConstraint(
action.maxReceiverVideoQuality);
}
}
return next(action);
}
/**
* Sets the preferred receive video quality and will turn off audio only mode if
* enabled.
*
* @param {Store} store - The redux store in which the specified {@code action}
@ -451,12 +486,19 @@ function _setPreferredReceiverVideoQuality(
{ dispatch, getState },
next,
action) {
const { audioOnly, conference }
= getState()['features/base/conference'];
const {
audioOnly,
conference,
maxReceiverVideoQuality
} = getState()['features/base/conference'];
if (conference) {
conference.setReceiverVideoConstraint(
action.preferredReceiverVideoQuality);
const { preferredReceiverVideoQuality } = action;
const targetQuality = typeof maxReceiverVideoQuality === 'undefined'
? preferredReceiverVideoQuality
: Math.min(maxReceiverVideoQuality, preferredReceiverVideoQuality);
conference.setReceiverVideoConstraint(targetQuality);
audioOnly && dispatch(toggleAudioOnly());
}

View File

@ -17,6 +17,7 @@ import {
SET_AUDIO_ONLY,
SET_DESKTOP_SHARING_ENABLED,
SET_FOLLOW_ME,
SET_MAX_RECEIVER_VIDEO_QUALITY,
SET_PASSWORD,
SET_PREFERRED_RECEIVER_VIDEO_QUALITY,
SET_ROOM,
@ -69,6 +70,12 @@ ReducerRegistry.register('features/base/conference', (state = {}, action) => {
case SET_LOCATION_URL:
return set(state, 'room', undefined);
case SET_MAX_RECEIVER_VIDEO_QUALITY:
return set(
state,
'maxReceiverVideoQuality',
action.maxReceiverVideoQuality);
case SET_PASSWORD:
return _setPassword(state, action);