Skip to content

Commit

Permalink
fix(largeVideo): update don't depend on thumbnails
Browse files Browse the repository at this point in the history
  • Loading branch information
hristoterezov committed Apr 17, 2020
1 parent f972ebf commit 4fda428
Show file tree
Hide file tree
Showing 11 changed files with 62 additions and 171 deletions.
13 changes: 0 additions & 13 deletions conference.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import {
createDeviceChangedEvent,
createStartSilentEvent,
createScreenSharingEvent,
createStreamSwitchDelayEvent,
createTrackMutedEvent,
sendAnalytics
} from './react/features/analytics';
Expand Down Expand Up @@ -2263,18 +2262,6 @@ export default {
});
});

/* eslint-disable max-params */
APP.UI.addListener(
UIEvents.RESOLUTION_CHANGED,
(id, oldResolution, newResolution, delay) => {
sendAnalytics(createStreamSwitchDelayEvent(
{
'old_resolution': oldResolution,
'new_resolution': newResolution,
value: delay
}));
});

APP.UI.addListener(UIEvents.AUTH_CLICKED, () => {
AuthHandler.authenticate(room);
});
Expand Down
9 changes: 0 additions & 9 deletions modules/UI/UI.js
Original file line number Diff line number Diff line change
Expand Up @@ -322,15 +322,6 @@ UI.inputDisplayNameHandler = function(newDisplayName) {
eventEmitter.emit(UIEvents.NICKNAME_CHANGED, newDisplayName);
};

/**
* Return the type of the remote video.
* @param jid the jid for the remote video
* @returns the video type video or screen.
*/
UI.getRemoteVideoType = function(jid) {
return VideoLayout.getRemoteVideoType(jid);
};

// FIXME check if someone user this
UI.showLoginPopup = function(callback) {
logger.log('password is required');
Expand Down
1 change: 0 additions & 1 deletion modules/UI/shared_video/SharedVideoThumb.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export default class SharedVideoThumb extends SmallVideo {
this.id = participant.id;
this.isLocal = false;
this.url = participant.id;
this.setVideoType(videoType);
this.videoSpanId = 'sharedVideoContainer';
this.container = this.createContainer(this.videoSpanId);
this.$container = $(this.container);
Expand Down
4 changes: 0 additions & 4 deletions modules/UI/videolayout/RemoteVideo.js
Original file line number Diff line number Diff line change
Expand Up @@ -481,10 +481,6 @@ export default class RemoteVideo extends SmallVideo {

isVideo ? this.videoStream = stream : this.audioStream = stream;

if (isVideo) {
this.setVideoType(stream.videoType);
}

if (!stream.getOriginalStream()) {
logger.debug('Remote video stream has no original stream');

Expand Down
59 changes: 1 addition & 58 deletions modules/UI/videolayout/SmallVideo.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ import {

const logger = require('jitsi-meet-logger').getLogger(__filename);

import UIEvents from '../../../service/UI/UIEvents';

/**
* Display mode constant used when video is being displayed on the small video.
* @type {number}
Expand Down Expand Up @@ -158,28 +156,6 @@ export default class SmallVideo {
return this.$container.is(':visible');
}

/**
* Sets the type of the video displayed by this instance.
* Note that this is a string without clearly defined or checked values, and
* it is NOT one of the strings defined in service/RTC/VideoType in
* lib-jitsi-meet.
* @param videoType 'camera' or 'desktop', or 'sharedvideo'.
*/
setVideoType(videoType) {
this.videoType = videoType;
}

/**
* Returns the type of the video displayed by this instance.
* Note that this is a string without clearly defined or checked values, and
* it is NOT one of the strings defined in service/RTC/VideoType in
* lib-jitsi-meet.
* @returns {String} 'camera', 'screen', 'sharedvideo', or undefined.
*/
getVideoType() {
return this.videoType;
}

/**
* Creates an audio or video element for a particular MediaStream.
*/
Expand Down Expand Up @@ -452,7 +428,7 @@ export default class SmallVideo {
* or <tt>false</tt> otherwise.
*/
isCurrentlyOnLargeVideo() {
return this.VideoLayout.isCurrentlyOnLarge(this.id);
return APP.store.getState()['features/large-video']?.participantId === this.id;
}

/**
Expand Down Expand Up @@ -640,39 +616,6 @@ export default class SmallVideo {
this.updateIndicators();
}

/**
* Adds a listener for onresize events for this video, which will monitor for
* resolution changes, will calculate the delay since the moment the listened
* is added, and will fire a RESOLUTION_CHANGED event.
*/
waitForResolutionChange() {
const beforeChange = window.performance.now();
const videos = this.selectVideoElement();

if (!videos || !videos.length || videos.length <= 0) {
return;
}
const video = videos[0];
const oldWidth = video.videoWidth;
const oldHeight = video.videoHeight;

video.onresize = () => {
// eslint-disable-next-line eqeqeq
if (video.videoWidth != oldWidth || video.videoHeight != oldHeight) {
// Only run once.
video.onresize = null;

const delay = window.performance.now() - beforeChange;
const emitter = this.VideoLayout.getEventEmitter();

if (emitter) {
emitter.emit(UIEvents.RESOLUTION_CHANGED, this.getId(), `${oldWidth}x${oldHeight}`,
`${video.videoWidth}x${video.videoHeight}`, delay);
}
}
};
}

/**
* Initalizes any browser specific properties. Currently sets the overflow
* property for Qt browsers on Windows to hidden, thus fixing the following
Expand Down
87 changes: 20 additions & 67 deletions modules/UI/videolayout/VideoLayout.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
/* global APP, $, interfaceConfig */
const logger = require('jitsi-meet-logger').getLogger(__filename);

import { VIDEO_TYPE } from '../../../react/features/base/media';
import { MEDIA_TYPE, VIDEO_TYPE } from '../../../react/features/base/media';
import {
getLocalParticipant as getLocalParticipantFromStore,
getPinnedParticipant,
getParticipantById,
pinParticipant
} from '../../../react/features/base/participants';
import { getTrackByMediaTypeAndParticipant } from '../../../react/features/base/tracks';
import { SHARED_VIDEO_CONTAINER_TYPE } from '../shared_video/SharedVideo';
import SharedVideoThumb from '../shared_video/SharedVideoThumb';

Expand Down Expand Up @@ -73,9 +75,6 @@ const VideoLayout = {
emitter,
this._updateLargeVideoIfDisplayed.bind(this));

// sets default video type of local video
// FIXME container type is totally different thing from the video type
localVideoThumbnail.setVideoType(VIDEO_CONTAINER_TYPE);
this.registerListeners();
},

Expand Down Expand Up @@ -221,10 +220,16 @@ const VideoLayout = {
* @returns {String} the video type video or screen.
*/
getRemoteVideoType(id) {
const smallVideo = VideoLayout.getSmallVideo(id);
const state = APP.store.getState();
const participant = getParticipantById(state, id);

if (participant?.isFakeParticipant) {
return SHARED_VIDEO_CONTAINER_TYPE;
}

const videoTrack = getTrackByMediaTypeAndParticipant(state['features/base/tracks'], MEDIA_TYPE.VIDEO, id);

return smallVideo ? smallVideo.getVideoType() : null;
return videoTrack?.videoType;
},

isPinned(id) {
Expand Down Expand Up @@ -308,12 +313,6 @@ const VideoLayout = {
addRemoteVideoContainer(id, remoteVideo) {
remoteVideos[id] = remoteVideo;

if (!remoteVideo.getVideoType()) {
// make video type the default one (camera)
// FIXME container type is not a video type
remoteVideo.setVideoType(VIDEO_CONTAINER_TYPE);
}

// Initialize the view
remoteVideo.updateView();
},
Expand Down Expand Up @@ -491,22 +490,6 @@ const VideoLayout = {

logger.info('Peer video type changed: ', id, newVideoType);

let smallVideo;

if (APP.conference.isLocalId(id)) {
if (!localVideoThumbnail) {
logger.warn('Local video not ready yet');

return;
}
smallVideo = localVideoThumbnail;
} else if (remoteVideos[id]) {
smallVideo = remoteVideos[id];
} else {
return;
}
smallVideo.setVideoType(newVideoType);

this._updateLargeVideoIfDisplayed(id, true);
},

Expand Down Expand Up @@ -584,17 +567,16 @@ const VideoLayout = {
}
const currentContainer = largeVideo.getCurrentContainer();
const currentContainerType = largeVideo.getCurrentContainerType();
const currentId = largeVideo.id;
const isOnLarge = this.isCurrentlyOnLarge(id);
const smallVideo = this.getSmallVideo(id);
const state = APP.store.getState();
const videoTrack = getTrackByMediaTypeAndParticipant(state['features/base/tracks'], MEDIA_TYPE.VIDEO, id);
const videoStream = videoTrack?.jitsiTrack;

if (isOnLarge && !forceUpdate
&& LargeVideoManager.isVideoContainer(currentContainerType)
&& smallVideo) {
&& videoStream) {
const currentStreamId = currentContainer.getStreamID();
const newStreamId
= smallVideo.videoStream
? smallVideo.videoStream.getId() : null;
const newStreamId = videoStream?.getId() || null;

// FIXME it might be possible to get rid of 'forceUpdate' argument
if (currentStreamId !== newStreamId) {
Expand All @@ -603,42 +585,17 @@ const VideoLayout = {
}
}

if ((!isOnLarge || forceUpdate) && smallVideo) {
if (!isOnLarge || forceUpdate) {
const videoType = this.getRemoteVideoType(id);

// FIXME video type is not the same thing as container type

if (id !== currentId && videoType === VIDEO_CONTAINER_TYPE) {
APP.API.notifyOnStageParticipantChanged(id);
}

let oldSmallVideo;

if (currentId) {
oldSmallVideo = this.getSmallVideo(currentId);
}

smallVideo.waitForResolutionChange();
if (oldSmallVideo) {
oldSmallVideo.waitForResolutionChange();
}

largeVideo.updateLargeVideo(
id,
smallVideo.videoStream,
videoStream,
videoType || VIDEO_TYPE.CAMERA
).then(() => {
// update current small video and the old one
smallVideo.updateView();
oldSmallVideo && oldSmallVideo.updateView();
}, () => {
// use clicked other video during update, nothing to do.
).catch(() => {
// do nothing
});

} else if (currentId) {
const currentSmallVideo = this.getSmallVideo(currentId);

currentSmallVideo && currentSmallVideo.updateView();
}
},

Expand Down Expand Up @@ -723,10 +680,6 @@ const VideoLayout = {
this.localFlipX = val;
},

getEventEmitter() {
return eventEmitter;
},

/**
* Handles user's features changes.
*/
Expand Down
15 changes: 0 additions & 15 deletions react/features/analytics/AnalyticsEvents.js
Original file line number Diff line number Diff line change
Expand Up @@ -688,21 +688,6 @@ export function createStartMutedConfigurationEvent(
};
}

/**
* Creates an event which indicates the delay for switching between simulcast
* streams.
*
* @param {Object} attributes - Attributes to attach to the event.
* @returns {Object} The event in a format suitable for sending via
* sendAnalytics.
*/
export function createStreamSwitchDelayEvent(attributes) {
return {
action: 'stream.switch.delay',
attributes
};
}

/**
* Automatically changing the mute state of a media track in order to match
* the current stored state in redux.
Expand Down
4 changes: 4 additions & 0 deletions react/features/base/tracks/middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ MiddlewareRegistry.register(store => next => action => {
// TODO Remove the following calls to APP.UI once components interested
// in track mute changes are moved into React and/or redux.
if (typeof APP !== 'undefined') {
const result = next(action);

const { jitsiTrack } = action.track;
const muted = jitsiTrack.isMuted();
const participantID = jitsiTrack.getParticipantId();
Expand All @@ -151,6 +153,8 @@ MiddlewareRegistry.register(store => next => action => {
} else {
APP.UI.setAudioMuted(participantID, muted);
}

return result;
}

}
Expand Down
17 changes: 17 additions & 0 deletions react/features/external-api/subscriber.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// @flow

import { MEDIA_TYPE, VIDEO_TYPE } from '../base/media';
import { getLocalParticipant } from '../base/participants';
import { StateListenerRegistry } from '../base/redux';
import { getTrackByMediaTypeAndParticipant } from '../base/tracks';
import { appendSuffix } from '../display-name';
import { shouldDisplayTileView } from '../video-layout';

Expand Down Expand Up @@ -37,3 +39,18 @@ StateListenerRegistry.register(
});
}
});

/**
* Updates the on stage participant value.
*/
StateListenerRegistry.register(
/* selector */ state => state['features/large-video'].participantId,
/* listener */ (participantId, store) => {
const videoTrack = getTrackByMediaTypeAndParticipant(
store.getState()['features/base/tracks'], MEDIA_TYPE.VIDEO, participantId);

if (videoTrack && videoTrack.videoType === VIDEO_TYPE.CAMERA) {
APP.API.notifyOnStageParticipantChanged(participantId);
}
}
);
Loading

0 comments on commit 4fda428

Please sign in to comment.