ref(large-video): combine selectParticipant logic from web (#3266)
* ref(large-video): combine selectParticipant logic from web Currently native/middleware/redux has its own logic for selecting a participant on the bridge. To have the logic web respect that logic, a few changes are needed. - Web no longer has its own call to selectParticipant. - To keep in line with web logic selectParticipant action should act even when there is no track. This makes it so that when a participant does get a track that the bridge will send high quality. The bridge can already handle when the selected participant does not have a video track. - The timing of web is such that on joining an existing conference, a participant joins and the participant's tracks get updated and then the conference is joined. The result is selectParticipant does not get fired because it no-ops when there is no conference. To avoid having to make uncertain changes (to be lazy), update the selected participant on conference join as well. * squash: update comment, pass message to error handler
This commit is contained in:
parent
c62f761d67
commit
afd2aea79c
|
@ -7,8 +7,6 @@ import Recorder from './modules/recorder/Recorder';
|
||||||
|
|
||||||
import mediaDeviceHelper from './modules/devices/mediaDeviceHelper';
|
import mediaDeviceHelper from './modules/devices/mediaDeviceHelper';
|
||||||
|
|
||||||
import { reportError } from './modules/util/helpers';
|
|
||||||
|
|
||||||
import * as RemoteControlEvents
|
import * as RemoteControlEvents
|
||||||
from './service/remotecontrol/RemoteControlEvents';
|
from './service/remotecontrol/RemoteControlEvents';
|
||||||
import UIEvents from './service/UI/UIEvents';
|
import UIEvents from './service/UI/UIEvents';
|
||||||
|
@ -18,7 +16,6 @@ import * as JitsiMeetConferenceEvents from './ConferenceEvents';
|
||||||
import {
|
import {
|
||||||
createDeviceChangedEvent,
|
createDeviceChangedEvent,
|
||||||
createScreenSharingEvent,
|
createScreenSharingEvent,
|
||||||
createSelectParticipantFailedEvent,
|
|
||||||
createStreamSwitchDelayEvent,
|
createStreamSwitchDelayEvent,
|
||||||
createTrackMutedEvent,
|
createTrackMutedEvent,
|
||||||
sendAnalytics
|
sendAnalytics
|
||||||
|
@ -1813,24 +1810,6 @@ export default {
|
||||||
room.sendTextMessage(message);
|
room.sendTextMessage(message);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
APP.UI.addListener(UIEvents.SELECTED_ENDPOINT, id => {
|
|
||||||
APP.API.notifyOnStageParticipantChanged(id);
|
|
||||||
try {
|
|
||||||
// do not try to select participant if there is none (we
|
|
||||||
// are alone in the room), otherwise an error will be
|
|
||||||
// thrown cause reporting mechanism is not available
|
|
||||||
// (datachannels currently)
|
|
||||||
if (room.getParticipants().length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
room.selectParticipant(id);
|
|
||||||
} catch (e) {
|
|
||||||
sendAnalytics(createSelectParticipantFailedEvent(e));
|
|
||||||
reportError(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
room.on(JitsiConferenceEvents.CONNECTION_INTERRUPTED, () => {
|
room.on(JitsiConferenceEvents.CONNECTION_INTERRUPTED, () => {
|
||||||
|
|
|
@ -960,7 +960,7 @@ const VideoLayout = {
|
||||||
// FIXME video type is not the same thing as container type
|
// FIXME video type is not the same thing as container type
|
||||||
|
|
||||||
if (id !== currentId && videoType === VIDEO_CONTAINER_TYPE) {
|
if (id !== currentId && videoType === VIDEO_CONTAINER_TYPE) {
|
||||||
eventEmitter.emit(UIEvents.SELECTED_ENDPOINT, id);
|
APP.API.notifyOnStageParticipantChanged(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
let oldSmallVideo;
|
let oldSmallVideo;
|
||||||
|
|
|
@ -1,14 +1,19 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
|
import {
|
||||||
|
createSelectParticipantFailedEvent,
|
||||||
|
sendAnalytics
|
||||||
|
} from '../analytics';
|
||||||
import { _handleParticipantError } from '../base/conference';
|
import { _handleParticipantError } from '../base/conference';
|
||||||
import { MEDIA_TYPE, VIDEO_TYPE } from '../base/media';
|
import { MEDIA_TYPE } from '../base/media';
|
||||||
import { getTrackByMediaTypeAndParticipant } from '../base/tracks';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
SELECT_LARGE_VIDEO_PARTICIPANT,
|
SELECT_LARGE_VIDEO_PARTICIPANT,
|
||||||
UPDATE_KNOWN_LARGE_VIDEO_RESOLUTION
|
UPDATE_KNOWN_LARGE_VIDEO_RESOLUTION
|
||||||
} from './actionTypes';
|
} from './actionTypes';
|
||||||
|
|
||||||
|
declare var APP: Object;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signals conference to select a participant.
|
* Signals conference to select a participant.
|
||||||
*
|
*
|
||||||
|
@ -21,22 +26,23 @@ export function selectParticipant() {
|
||||||
|
|
||||||
if (conference) {
|
if (conference) {
|
||||||
const largeVideo = state['features/large-video'];
|
const largeVideo = state['features/large-video'];
|
||||||
const tracks = state['features/base/tracks'];
|
|
||||||
|
|
||||||
const id = largeVideo.participantId;
|
const id = largeVideo.participantId;
|
||||||
const videoTrack
|
|
||||||
= getTrackByMediaTypeAndParticipant(
|
|
||||||
tracks,
|
|
||||||
MEDIA_TYPE.VIDEO,
|
|
||||||
id);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
conference.selectParticipant(
|
conference.selectParticipant(id);
|
||||||
videoTrack && videoTrack.videoType === VIDEO_TYPE.CAMERA
|
|
||||||
? id
|
|
||||||
: null);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
_handleParticipantError(err);
|
_handleParticipantError(err);
|
||||||
|
|
||||||
|
sendAnalytics(createSelectParticipantFailedEvent(err));
|
||||||
|
|
||||||
|
if (typeof APP === 'object' && window.onerror) {
|
||||||
|
window.onerror(
|
||||||
|
`Failed to select participant ${id}`,
|
||||||
|
null, // source
|
||||||
|
null, // lineno
|
||||||
|
null, // colno
|
||||||
|
err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
|
import { CONFERENCE_JOINED } from '../base/conference';
|
||||||
import {
|
import {
|
||||||
DOMINANT_SPEAKER_CHANGED,
|
DOMINANT_SPEAKER_CHANGED,
|
||||||
PARTICIPANT_JOINED,
|
PARTICIPANT_JOINED,
|
||||||
|
@ -46,6 +47,13 @@ MiddlewareRegistry.register(store => next => action => {
|
||||||
store.dispatch(selectParticipantInLargeVideo());
|
store.dispatch(selectParticipantInLargeVideo());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CONFERENCE_JOINED:
|
||||||
|
// Ensure a participant is selected on conference join. This addresses
|
||||||
|
// the case where video tracks were received before CONFERENCE_JOINED
|
||||||
|
// fired; without the conference selection may not happen.
|
||||||
|
store.dispatch(selectParticipant());
|
||||||
|
break;
|
||||||
|
|
||||||
case TRACK_UPDATED:
|
case TRACK_UPDATED:
|
||||||
// In order to minimize re-calculations, we need to select participant
|
// In order to minimize re-calculations, we need to select participant
|
||||||
// only if the videoType of the current participant rendered in
|
// only if the videoType of the current participant rendered in
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
export default {
|
export default {
|
||||||
NICKNAME_CHANGED: 'UI.nickname_changed',
|
NICKNAME_CHANGED: 'UI.nickname_changed',
|
||||||
SELECTED_ENDPOINT: 'UI.selected_endpoint',
|
|
||||||
PINNED_ENDPOINT: 'UI.pinned_endpoint',
|
PINNED_ENDPOINT: 'UI.pinned_endpoint',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue