fix(tracks): Remove code that handles TRACK_OWNER_CHANGED event. (#14652)

This commit is contained in:
Jaya Allamsetty
2024-04-25 06:28:45 -04:00
committed by GitHub
parent 393c78aad3
commit f995eb2698
12 changed files with 116 additions and 109 deletions

View File

@@ -11,6 +11,7 @@ import { createScreenSharingIssueEvent } from '../../../react/features/analytics
import { sendAnalytics } from '../../../react/features/analytics/functions';
import Avatar from '../../../react/features/base/avatar/components/Avatar';
import theme from '../../../react/features/base/components/themes/participantsPaneTheme.json';
import { getSsrcRewritingFeatureFlag } from '../../../react/features/base/config/functions.any';
import i18next from '../../../react/features/base/i18n/i18next';
import { JitsiTrackEvents } from '../../../react/features/base/lib-jitsi-meet';
import { VIDEO_TYPE } from '../../../react/features/base/media/constants';
@@ -221,10 +222,10 @@ export default class LargeVideoManager {
this.updateInProcess = true;
// Include hide()/fadeOut only if we're switching between users
// eslint-disable-next-line eqeqeq
// Include hide()/fadeOut if we're switching between users or between different sources of the same user.
const container = this.getCurrentContainer();
const isUserSwitch = this.newStreamData.id !== container.id;
const isUserSwitch = container.id !== this.newStreamData.id
|| container.stream?.getSourceName() !== this.newStreamData.stream?.getSourceName();
const preUpdate = isUserSwitch ? container.hide() : Promise.resolve();
preUpdate.then(() => {

View File

@@ -501,8 +501,7 @@ export class VideoContainer extends LargeContainer {
* @param {string} videoType video type
*/
setStream(userID, stream, videoType) {
this.userId = userID;
if (this.stream === stream && !stream?.forceStreamToReattach) {
if (this.userId === userID && this.stream === stream && !stream?.forceStreamToReattach) {
logger.debug(`SetStream on the large video for user ${userID} ignored: the stream is not changed!`);
// Handles the use case for the remote participants when the
@@ -516,6 +515,8 @@ export class VideoContainer extends LargeContainer {
return;
}
this.userId = userID;
if (stream?.forceStreamToReattach) {
delete stream.forceStreamToReattach;
}
@@ -540,9 +541,8 @@ export class VideoContainer extends LargeContainer {
logger.error(`Attaching the remote track ${stream} to large video has failed with `, error);
});
// Ensure large video gets play() called on it when a new stream is attached to it. This is necessary in the
// case of Safari as autoplay doesn't kick-in automatically on Safari 15 and newer versions.
browser.isWebKitBased() && this._play();
// Ensure large video gets play() called on it when a new stream is attached to it.
this._play();
const flipX = stream.isLocal() && this.localFlipX && !this.isScreenSharing();

10
package-lock.json generated
View File

@@ -61,7 +61,7 @@
"js-md5": "0.6.1",
"js-sha512": "0.8.0",
"jwt-decode": "2.2.0",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1815.0.0+c4cee681/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1816.0.0+f16cadce/lib-jitsi-meet.tgz",
"lodash": "4.17.21",
"moment": "2.29.4",
"moment-duration-format": "2.2.2",
@@ -12866,8 +12866,8 @@
},
"node_modules/lib-jitsi-meet": {
"version": "0.0.0",
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1815.0.0+c4cee681/lib-jitsi-meet.tgz",
"integrity": "sha512-ZpaxL3IHL4sY0+Irpljhj5jONphho2rlU53ykSBaGcTbWhcjpmB8aJuycI1cxatojlnr3kgsni6lsiIpSu+0YA==",
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1816.0.0+f16cadce/lib-jitsi-meet.tgz",
"integrity": "sha512-ilIfYiJjBEATv8/+l537rcIUlaYep34UVcf3PCzWGOHlTIZeON5zFBPWZT7P9X+HLhOHBtLU5F49xNlGElCwSQ==",
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
@@ -29374,8 +29374,8 @@
}
},
"lib-jitsi-meet": {
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1815.0.0+c4cee681/lib-jitsi-meet.tgz",
"integrity": "sha512-ZpaxL3IHL4sY0+Irpljhj5jONphho2rlU53ykSBaGcTbWhcjpmB8aJuycI1cxatojlnr3kgsni6lsiIpSu+0YA==",
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1816.0.0+f16cadce/lib-jitsi-meet.tgz",
"integrity": "sha512-ilIfYiJjBEATv8/+l537rcIUlaYep34UVcf3PCzWGOHlTIZeON5zFBPWZT7P9X+HLhOHBtLU5F49xNlGElCwSQ==",
"requires": {
"@jitsi/js-utils": "2.2.1",
"@jitsi/logger": "2.0.2",

View File

@@ -67,7 +67,7 @@
"js-md5": "0.6.1",
"js-sha512": "0.8.0",
"jwt-decode": "2.2.0",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1815.0.0+c4cee681/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1816.0.0+f16cadce/lib-jitsi-meet.tgz",
"lodash": "4.17.21",
"moment": "2.29.4",
"moment-duration-format": "2.2.2",

View File

@@ -12,9 +12,9 @@ import { getCurrentConference } from '../conference/functions';
import { ADD_PEOPLE_ENABLED } from '../flags/constants';
import { getFeatureFlag } from '../flags/functions';
import i18next from '../i18n/i18next';
import { MEDIA_TYPE, VIDEO_TYPE } from '../media/constants';
import { MEDIA_TYPE, MediaType, VIDEO_TYPE } from '../media/constants';
import { toState } from '../redux/functions';
import { getScreenShareTrack } from '../tracks/functions.any';
import { getScreenShareTrack, isLocalTrackMuted } from '../tracks/functions.any';
import { createDeferred } from '../util/helpers';
import {
@@ -362,6 +362,42 @@ export function getRemoteParticipantCountWithFake(stateful: IStateful) {
return participantsState.remote.size;
}
/**
* Returns the muted state of the given media source for a given participant.
*
* @param {(Function|Object)} stateful - The (whole) redux state, or redux's.
* @param {IParticipant} participant - The participant entity.
* @param {MediaType} mediaType - The media type.
* @returns {boolean} - True its muted, false otherwise.
*/
export function getMutedStateByParticipantAndMediaType(
stateful: IStateful,
participant: IParticipant,
mediaType: MediaType): boolean {
const type = mediaType === MEDIA_TYPE.SCREENSHARE ? 'video' : mediaType;
if (participant.local) {
const state = toState(stateful);
const tracks = state['features/base/tracks'];
return isLocalTrackMuted(tracks, mediaType);
}
const sources = participant.sources?.get(type);
if (!sources) {
return true;
}
if (mediaType === MEDIA_TYPE.AUDIO) {
return Array.from(sources.values())[0].muted;
}
const videoType = mediaType === MEDIA_TYPE.VIDEO ? VIDEO_TYPE.CAMERA : VIDEO_TYPE.SCREENSHARE;
const source = Array.from(sources.values()).find(src => src.videoType === videoType);
return source?.muted ?? true;
}
/**
* Returns a count of the known participants in the passed in redux state,
* including fake participants.
@@ -468,28 +504,28 @@ export function getScreenshareParticipantIds(stateful: IStateful): Array<string>
}
/**
* Returns a list source name associated with a given remote participant and for the given media type.
* Returns a list of source names associated with a given remote participant and for the given media type.
*
* @param {(Function|Object)} stateful - The (whole) redux state, or redux's {@code getState} function to be used to
* retrieve the state.
* @param {string} id - The id of the participant whose source names are to be retrieved.
* @param {string} mediaType - The type of source, audio or video.
* @returns {Array<string>|undefined}
* @returns {Array<string>}
*/
export function getSourceNamesByMediaType(
export function getSourceNamesByMediaTypeAndParticipant(
stateful: IStateful,
id: string,
mediaType: string): Array<string> | undefined {
mediaType: string): Array<string> {
const participant: IParticipant | undefined = getParticipantById(stateful, id);
if (!participant) {
return;
return [];
}
const sources = participant.sources;
if (!sources) {
return;
return [];
}
return Array.from(sources.get(mediaType) ?? new Map())
@@ -497,6 +533,37 @@ export function getSourceNamesByMediaType(
.map(s => s[0]);
}
/**
* Returns a list of source names associated with a given remote participant and for the given video type (only for
* video sources).
*
* @param {(Function|Object)} stateful - The (whole) redux state, or redux's {@code getState} function to be used to
* retrieve the state.
* @param {string} id - The id of the participant whose source names are to be retrieved.
* @param {string} videoType - The type of video, camera or desktop.
* @returns {Array<string>}
*/
export function getSourceNamesByVideoTypeAndParticipant(
stateful: IStateful,
id: string,
videoType: string): Array<string> {
const participant: IParticipant | undefined = getParticipantById(stateful, id);
if (!participant) {
return [];
}
const sources = participant.sources;
if (!sources) {
return [];
}
return Array.from(sources.get(MEDIA_TYPE.VIDEO) ?? new Map())
.filter(source => source[1].videoType === videoType && (videoType === VIDEO_TYPE.CAMERA || !source[1].muted))
.map(s => s[0]);
}
/**
* Returns the presence status of a participant associated with the passed id.
*

View File

@@ -66,16 +66,6 @@ export const TRACK_MUTE_UNMUTE_FAILED = 'TRACK_MUTE_UNMUTE_FAILED';
*/
export const TRACK_NO_DATA_FROM_SOURCE = 'TRACK_NO_DATA_FROM_SOURCE';
/**
* The type of redux action dispatched when the owner of a track changes due to ssrc remapping.
*
* {
* type: TRACK_OWNER_CHANGED,
* track: Track
* }
*/
export const TRACK_OWNER_CHANGED = 'TRACK_OWNER_CHANGED';
/**
* The type of redux action dispatched when a track has been (locally or
* remotely) removed from the conference.

View File

@@ -26,7 +26,6 @@ import {
TRACK_CREATE_ERROR,
TRACK_MUTE_UNMUTE_FAILED,
TRACK_NO_DATA_FROM_SOURCE,
TRACK_OWNER_CHANGED,
TRACK_REMOVED,
TRACK_STOPPED,
TRACK_UPDATED,
@@ -381,9 +380,6 @@ export function trackAdded(track: any) {
track.on(
JitsiTrackEvents.TRACK_VIDEOTYPE_CHANGED,
(type: VideoType) => dispatch(trackVideoTypeChanged(track, type)));
track.on(
JitsiTrackEvents.TRACK_OWNER_CHANGED,
(owner: string) => dispatch(trackOwnerChanged(track, owner)));
const local = track.isLocal();
const mediaType = track.getVideoType() === VIDEO_TYPE.DESKTOP
? MEDIA_TYPE.SCREENSHARE
@@ -625,32 +621,6 @@ export function trackStreamingStatusChanged(track: any, streamingStatus: string)
};
}
/**
* Create an action for when the owner of the track changes due to ssrc remapping.
*
* @param {(JitsiRemoteTrack)} track - JitsiTrack instance.
* @param {string} participantId - New owner's participant ID.
* @returns {{
* type: TRACK_OWNER_CHANGED,
* track: Track
* }}
*/
export function trackOwnerChanged(track: any, participantId: string): {
track: {
jitsiTrack: any;
participantId: string;
};
type: 'TRACK_OWNER_CHANGED';
} {
return {
type: TRACK_OWNER_CHANGED,
track: {
jitsiTrack: track,
participantId
}
};
}
/**
* Signals passed tracks to be added.
*

View File

@@ -15,7 +15,6 @@ import {
TRACK_ADDED,
TRACK_MUTE_UNMUTE_FAILED,
TRACK_NO_DATA_FROM_SOURCE,
TRACK_OWNER_CHANGED,
TRACK_REMOVED,
TRACK_STOPPED,
TRACK_UPDATED
@@ -82,23 +81,6 @@ MiddlewareRegistry.register(store => next => action => {
return result;
}
case TRACK_OWNER_CHANGED: {
const oldTrack = getTrackByJitsiTrack(store.getState()['features/base/tracks'], action.track?.jitsiTrack);
const oldOwner = oldTrack?.participantId;
const result = next(action);
const newOwner = action.track?.participantId;
if (oldOwner) {
logTracksForParticipant(store.getState()['features/base/tracks'], oldOwner, 'Owner changed');
}
if (newOwner) {
logTracksForParticipant(store.getState()['features/base/tracks'], newOwner, 'Owner changed');
}
return result;
}
case TRACK_MUTE_UNMUTE_FAILED: {
const { jitsiTrack } = action.track;
const muted = action.wasMuted;

View File

@@ -10,7 +10,6 @@ import {
TRACK_CREATE_CANCELED,
TRACK_CREATE_ERROR,
TRACK_NO_DATA_FROM_SOURCE,
TRACK_OWNER_CHANGED,
TRACK_REMOVED,
TRACK_UPDATED,
TRACK_WILL_CREATE
@@ -43,18 +42,6 @@ function track(state: ITrack, action: AnyAction) {
}
break;
case TRACK_OWNER_CHANGED: {
const t = action.track;
if (state.jitsiTrack === t.jitsiTrack) {
return {
...state,
participantId: t.participantId
};
}
break;
}
case TRACK_UPDATED: {
const t = action.track;
@@ -104,7 +91,6 @@ ReducerRegistry.register<ITracksState>('features/base/tracks', (state = [], acti
switch (action.type) {
case PARTICIPANT_ID_CHANGED:
case TRACK_NO_DATA_FROM_SOURCE:
case TRACK_OWNER_CHANGED:
case TRACK_UPDATED:
return state.map((t: ITrack) => track(t, action));
case TRACK_ADDED: {

View File

@@ -2,9 +2,12 @@ import React, { PureComponent } from 'react';
import { connect } from 'react-redux';
import { IReduxState, IStore } from '../../../app/types';
import { getSsrcRewritingFeatureFlag } from '../../../base/config/functions.any';
import { translate } from '../../../base/i18n/functions';
import { MEDIA_TYPE } from '../../../base/media/constants';
import {
getLocalParticipant,
getMutedStateByParticipantAndMediaType,
getParticipantById,
getParticipantDisplayName,
hasRaisedHand,
@@ -166,8 +169,12 @@ function mapStateToProps(state: IReduxState, ownProps: any) {
const { participant } = ownProps;
const { ownerId } = state['features/shared-video'];
const localParticipantId = getLocalParticipant(state)?.id;
const _isAudioMuted = Boolean(participant && isParticipantAudioMuted(participant, state));
const _isVideoMuted = isParticipantVideoMuted(participant, state);
const _isAudioMuted = getSsrcRewritingFeatureFlag(state)
? Boolean(participant && getMutedStateByParticipantAndMediaType(state, participant, MEDIA_TYPE.AUDIO))
: Boolean(participant && isParticipantAudioMuted(participant, state));
const _isVideoMuted = getSsrcRewritingFeatureFlag(state)
? Boolean(participant && getMutedStateByParticipantAndMediaType(state, participant, MEDIA_TYPE.VIDEO))
: isParticipantVideoMuted(participant, state);
const audioMediaState = getParticipantAudioMediaState(participant, _isAudioMuted, state);
const videoMediaState = getParticipantVideoMediaState(participant, _isVideoMuted, state);
const { disableModeratorIndicator } = state['features/base/config'];

View File

@@ -2,10 +2,12 @@ import React, { useCallback, useEffect, useState } from 'react';
import { connect } from 'react-redux';
import { IReduxState } from '../../../app/types';
import { getSsrcRewritingFeatureFlag } from '../../../base/config/functions.any';
import { JitsiTrackEvents } from '../../../base/lib-jitsi-meet';
import { MEDIA_TYPE } from '../../../base/media/constants';
import {
getLocalParticipant,
getMutedStateByParticipantAndMediaType,
getParticipantByIdOrUndefined,
getParticipantDisplayName,
hasRaisedHand,
@@ -299,15 +301,15 @@ function _mapStateToProps(state: IReduxState, ownProps: any) {
const { participantID, searchString } = ownProps;
const { ownerId } = state['features/shared-video'];
const localParticipantId = getLocalParticipant(state)?.id;
const participant = getParticipantByIdOrUndefined(state, participantID);
const _displayName = getParticipantDisplayName(state, participant?.id ?? '');
const _matchesSearch = participantMatchesSearch(participant, searchString);
const _isAudioMuted = Boolean(participant && isParticipantAudioMuted(participant, state));
const _isVideoMuted = isParticipantVideoMuted(participant, state);
const _isAudioMuted = getSsrcRewritingFeatureFlag(state)
? Boolean(participant && getMutedStateByParticipantAndMediaType(state, participant, MEDIA_TYPE.AUDIO))
: Boolean(participant && isParticipantAudioMuted(participant, state));
const _isVideoMuted = getSsrcRewritingFeatureFlag(state)
? Boolean(participant && getMutedStateByParticipantAndMediaType(state, participant, MEDIA_TYPE.VIDEO))
: isParticipantVideoMuted(participant, state);
const _audioMediaState = getParticipantAudioMediaState(participant, _isAudioMuted, state);
const _videoMediaState = getParticipantVideoMediaState(participant, _isVideoMuted, state);
const _quickActionButtonType = getQuickActionButtonType(participant, _isAudioMuted, _isVideoMuted, state);

View File

@@ -3,10 +3,11 @@ import debounce from 'lodash/debounce';
import { IReduxState, IStore } from '../app/types';
import { _handleParticipantError } from '../base/conference/functions';
import { getSsrcRewritingFeatureFlag } from '../base/config/functions.any';
import { MEDIA_TYPE } from '../base/media/constants';
import { MEDIA_TYPE, VIDEO_TYPE } from '../base/media/constants';
import {
getLocalParticipant,
getSourceNamesByMediaType
getSourceNamesByMediaTypeAndParticipant,
getSourceNamesByVideoTypeAndParticipant
} from '../base/participants/functions';
import StateListenerRegistry from '../base/redux/StateListenerRegistry';
import { getTrackSourceNameByMediaTypeAndParticipant } from '../base/tracks/functions';
@@ -321,10 +322,10 @@ function _getSourceNames(participantList: Array<string>, state: IReduxState): Ar
participantList.forEach(participantId => {
if (getSsrcRewritingFeatureFlag(state)) {
const sourceNames: string[] | undefined
= getSourceNamesByMediaType(state, participantId, MEDIA_TYPE.VIDEO);
const sourceNames: string[]
= getSourceNamesByMediaTypeAndParticipant(state, participantId, MEDIA_TYPE.VIDEO);
sourceNames?.length && sourceNamesList.push(...sourceNames);
sourceNames.length && sourceNamesList.push(...sourceNames);
} else {
let sourceName: string;
@@ -428,8 +429,9 @@ function _updateReceiverVideoConstraints({ getState }: IStore) {
if (remoteScreenShares.includes(largeVideoParticipantId)) {
largeVideoSourceName = largeVideoParticipantId;
} else {
largeVideoSourceName = getTrackSourceNameByMediaTypeAndParticipant(
tracks, MEDIA_TYPE.VIDEO, largeVideoParticipantId);
largeVideoSourceName = getSsrcRewritingFeatureFlag(state)
? getSourceNamesByVideoTypeAndParticipant(state, largeVideoParticipantId, VIDEO_TYPE.CAMERA)[0]
: getTrackSourceNameByMediaTypeAndParticipant(tracks, MEDIA_TYPE.VIDEO, largeVideoParticipantId);
}
}