fix(resziable-filmstrip) Update video constraints on filmstrip resize (#11150)

Update video quality of large video as well
This commit is contained in:
Robert Pintilii 2022-03-16 16:57:30 +02:00 committed by GitHub
parent 8e035b03b0
commit 7bcf7bb686
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 80 additions and 6 deletions

View File

@ -13,6 +13,7 @@ import {
} from '../filmstrip/constants'; } from '../filmstrip/constants';
import { getNumberOfPartipantsForTileView } from '../filmstrip/functions.web'; import { getNumberOfPartipantsForTileView } from '../filmstrip/functions.web';
import { isVideoPlaying } from '../shared-video/functions'; import { isVideoPlaying } from '../shared-video/functions';
import { VIDEO_QUALITY_LEVELS } from '../video-quality/constants';
import { LAYOUTS } from './constants'; import { LAYOUTS } from './constants';
@ -193,3 +194,49 @@ export function updateAutoPinnedParticipant(
export function isLayoutTileView(state: Object) { export function isLayoutTileView(state: Object) {
return getCurrentLayout(state) === LAYOUTS.TILE_VIEW; return getCurrentLayout(state) === LAYOUTS.TILE_VIEW;
} }
/**
* Gets the video quality for the given height.
*
* @param {number|undefined} height - Height of the video container.
* @returns {number}
*/
function getVideoQualityForHeight(height: number) {
if (!height) {
return VIDEO_QUALITY_LEVELS.LOW;
}
const levels = Object.values(VIDEO_QUALITY_LEVELS)
.map(Number)
.sort((a, b) => a - b);
for (const level of levels) {
if (height <= level) {
return level;
}
}
return VIDEO_QUALITY_LEVELS.ULTRA;
}
/**
* Gets the video quality level for the resizable filmstrip thumbnail height.
*
* @param {Object} state - Redux state.
* @returns {number}
*/
export function getVideoQualityForResizableFilmstripThumbnails(state) {
const height = state['features/filmstrip'].verticalViewDimensions?.gridView?.thumbnailSize?.height;
return getVideoQualityForHeight(height);
}
/**
* Gets the video quality for the large video.
*
* @returns {number}
*/
export function getVideoQualityForLargeVideo() {
const wrapper = document.querySelector('#largeVideoWrapper');
return getVideoQualityForHeight(wrapper.clientHeight);
}

View File

@ -9,7 +9,11 @@ import { getLocalParticipant, getParticipantCount } from '../base/participants';
import { StateListenerRegistry } from '../base/redux'; import { StateListenerRegistry } from '../base/redux';
import { getTrackSourceNameByMediaTypeAndParticipant } from '../base/tracks'; import { getTrackSourceNameByMediaTypeAndParticipant } from '../base/tracks';
import { reportError } from '../base/util'; import { reportError } from '../base/util';
import { shouldDisplayTileView } from '../video-layout'; import {
getVideoQualityForLargeVideo,
getVideoQualityForResizableFilmstripThumbnails,
shouldDisplayTileView
} from '../video-layout';
import { setMaxReceiverVideoQuality } from './actions'; import { setMaxReceiverVideoQuality } from './actions';
import { VIDEO_QUALITY_LEVELS } from './constants'; import { VIDEO_QUALITY_LEVELS } from './constants';
@ -78,6 +82,16 @@ StateListenerRegistry.register(
_updateReceiverVideoConstraints(store); _updateReceiverVideoConstraints(store);
}); });
/**
* Updates the receiver constraints when the tiles in the resizable filmstrip change dimensions.
*/
StateListenerRegistry.register(
state => getVideoQualityForResizableFilmstripThumbnails(state),
(_, store) => {
_updateReceiverVideoConstraints(store);
}
);
/** /**
* StateListenerRegistry provides a reliable way of detecting changes to * StateListenerRegistry provides a reliable way of detecting changes to
* maxReceiverVideoQuality and preferredVideoQuality state and dispatching additional actions. * maxReceiverVideoQuality and preferredVideoQuality state and dispatching additional actions.
@ -262,13 +276,20 @@ function _updateReceiverVideoConstraints({ getState }) {
} }
if (visibleRemoteTrackSourceNames?.length) { if (visibleRemoteTrackSourceNames?.length) {
const qualityLevel = getVideoQualityForResizableFilmstripThumbnails(state);
visibleRemoteTrackSourceNames.forEach(sourceName => { visibleRemoteTrackSourceNames.forEach(sourceName => {
receiverConstraints.constraints[sourceName] = { 'maxHeight': VIDEO_QUALITY_LEVELS.LOW }; receiverConstraints.constraints[sourceName] = { 'maxHeight': qualityLevel };
}); });
} }
if (largeVideoSourceName) { if (largeVideoSourceName) {
receiverConstraints.constraints[largeVideoSourceName] = { 'maxHeight': maxFrameHeight }; let quality = maxFrameHeight;
if (!remoteScreenShares.find(id => id === largeVideoParticipantId)) {
quality = getVideoQualityForLargeVideo();
}
receiverConstraints.constraints[largeVideoSourceName] = { 'maxHeight': quality };
receiverConstraints.onStageSources = [ largeVideoSourceName ]; receiverConstraints.onStageSources = [ largeVideoSourceName ];
} }
} }
@ -283,7 +304,6 @@ function _updateReceiverVideoConstraints({ getState }) {
}; };
// Tile view. // Tile view.
// eslint-disable-next-line no-lonely-if
if (shouldDisplayTileView(state)) { if (shouldDisplayTileView(state)) {
if (!visibleRemoteParticipants?.size) { if (!visibleRemoteParticipants?.size) {
return; return;
@ -303,13 +323,20 @@ function _updateReceiverVideoConstraints({ getState }) {
} }
if (visibleRemoteParticipants?.size > 0) { if (visibleRemoteParticipants?.size > 0) {
const qualityLevel = getVideoQualityForResizableFilmstripThumbnails(state);
visibleRemoteParticipants.forEach(participantId => { visibleRemoteParticipants.forEach(participantId => {
receiverConstraints.constraints[participantId] = { 'maxHeight': VIDEO_QUALITY_LEVELS.LOW }; receiverConstraints.constraints[participantId] = { 'maxHeight': qualityLevel };
}); });
} }
if (largeVideoParticipantId) { if (largeVideoParticipantId) {
receiverConstraints.constraints[largeVideoParticipantId] = { 'maxHeight': maxFrameHeight }; let quality = maxFrameHeight;
if (!remoteScreenShares.find(id => id === largeVideoParticipantId)) {
quality = getVideoQualityForLargeVideo();
}
receiverConstraints.constraints[largeVideoParticipantId] = { 'maxHeight': quality };
receiverConstraints.onStageEndpoints = [ largeVideoParticipantId ]; receiverConstraints.onStageEndpoints = [ largeVideoParticipantId ];
} }
} }