/* global $, config, JitsiMeetJS */ import 'jquery'; import { setConfigFromURLParams } from '../../react/features/base/config/functions'; import { parseURLParams } from '../../react/features/base/util/parseURLParams'; import { parseURIString } from '../../react/features/base/util/uri'; import { validateLastNLimits, limitLastN } from '../../react/features/base/lastn/functions'; setConfigFromURLParams(config, {}, {}, window.location); const params = parseURLParams(window.location, false, 'hash'); const { isHuman = false } = params; const { localVideo = config.startWithVideoMuted !== true, remoteVideo = isHuman, remoteAudio = isHuman, autoPlayVideo = config.testing.noAutoPlayVideo !== true, stageView = config.disableTileView, numClients = 1, clientInterval = 100 // ms } = params; let { localAudio = config.startWithAudioMuted !== true, } = params; const { room: roomName } = parseURIString(window.location.toString()); class LoadTestClient { constructor(id) { this.id = id; this.connection = null; this.connected = false; this.room = null; this.numParticipants = 1; this.localTracks = []; this.remoteTracks = {}; this.maxFrameHeight = 0; this.selectedParticipant = null; } /** * Simple emulation of jitsi-meet's screen layout behavior */ updateMaxFrameHeight() { if (!this.connected) { return; } let newMaxFrameHeight; if (stageView) { newMaxFrameHeight = 2160; } else { if (this.numParticipants <= 2) { newMaxFrameHeight = 720; } else if (this.numParticipants <= 4) { newMaxFrameHeight = 360; } else { this.newMaxFrameHeight = 180; } } if (this.room && this.maxFrameHeight !== newMaxFrameHeight) { this.maxFrameHeight = newMaxFrameHeight; this.room.setReceiverVideoConstraint(this.maxFrameHeight); } } /** * Simple emulation of jitsi-meet's lastN behavior */ updateLastN() { if (!this.connected) { return; } let lastN = typeof config.channelLastN === 'undefined' ? -1 : config.channelLastN; const limitedLastN = limitLastN(this.numParticipants, validateLastNLimits(config.lastNLimits)); if (limitedLastN !== undefined) { lastN = lastN === -1 ? limitedLastN : Math.min(limitedLastN, lastN); } if (lastN === this.room.getLastN()) { return; } this.room.setLastN(lastN); } /** * Helper function to query whether a participant ID is a valid ID * for stage view. */ isValidStageViewParticipant(id) { return (id !== room.myUserId() && room.getParticipantById(id)); } /** * Simple emulation of jitsi-meet's stage view participant selection behavior. * Doesn't take into account pinning or screen sharing, and the initial behavior * is slightly different. * @returns Whether the selected participant changed. */ selectStageViewParticipant(selected, previous) { let newSelectedParticipant; if (this.isValidStageViewParticipant(selected)) { newSelectedParticipant = selected; } else { newSelectedParticipant = previous.find(isValidStageViewParticipant); } if (newSelectedParticipant && newSelectedParticipant !== this.selectedParticipant) { this.selectedParticipant = newSelectedParticipant; return true; } return false; } /** * Simple emulation of jitsi-meet's selectParticipants behavior */ selectParticipants() { if (!this.connected) { return; } if (stageView) { if (this.selectedParticipant) { this.room.selectParticipants([this.selectedParticipant]); } } else { /* jitsi-meet's current Tile View behavior. */ const ids = this.room.getParticipants().map(participant => participant.getId()); this.room.selectParticipants(ids); } } /** * Called when number of participants changes. */ setNumberOfParticipants() { if (this.id === 0) { $('#participants').text(this.numParticipants); } if (!stageView) { this.selectParticipants(); this.updateMaxFrameHeight(); } this.updateLastN(); } /** * Called when ICE connects */ onConnectionEstablished() { this.connected = true; this.selectParticipants(); this.updateMaxFrameHeight(); this.updateLastN(); } /** * Handles dominant speaker changed. * @param id */ onDominantSpeakerChanged(selected, previous) { if (this.selectStageViewParticipant(selected, previous)) { this.selectParticipants(); } this.updateMaxFrameHeight(); } /** * Handles local tracks. * @param tracks Array with JitsiTrack objects */ onLocalTracks(tracks = []) { this.localTracks = tracks; for (let i = 0; i < this.localTracks.length; i++) { if (this.localTracks[i].getType() === 'video') { if (this.id === 0) { $('body').append(`