Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unify events and output single TypeScript declaration #2407

Merged
merged 10 commits into from
Dec 15, 2023
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ npm-*.log
stats.json
.vscode
dist
index.d.ts
types/auto
types/types-comparer/auto.json
types/types-comparer/hand-crafted.json
Expand Down
2 changes: 1 addition & 1 deletion JitsiConference.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { getLogger } from '@jitsi/logger';
import EventEmitter from 'events';
import $ from 'jquery';
import isEqual from 'lodash.isequal';
import { Strophe } from 'strophe.js';
Expand Down Expand Up @@ -38,6 +37,7 @@ import AvgRTPStatsReporter from './modules/statistics/AvgRTPStatsReporter';
import LocalStatsCollector from './modules/statistics/LocalStatsCollector';
import SpeakerStatsCollector from './modules/statistics/SpeakerStatsCollector';
import Statistics from './modules/statistics/statistics';
import EventEmitter from './modules/util/EventEmitter';
import { safeSubtract } from './modules/util/MathUtil';
import RandomUtil from './modules/util/RandomUtil';
import ComponentsVersions from './modules/version/ComponentsVersions';
Expand Down
37 changes: 5 additions & 32 deletions JitsiMediaDevices.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import EventEmitter from 'events';

import * as JitsiMediaDevicesEvents from './JitsiMediaDevicesEvents';
import RTC from './modules/RTC/RTC';
import browser from './modules/browser';
import Listenable from './modules/util/Listenable';
import { MediaType } from './service/RTC/MediaType';
import RTCEvents from './service/RTC/RTCEvents';

Expand All @@ -13,19 +12,19 @@ const VIDEO_PERMISSION_NAME = 'camera';
/**
* Media devices utilities for Jitsi.
*/
class JitsiMediaDevices {
class JitsiMediaDevices extends Listenable {
/**
* Initializes a {@code JitsiMediaDevices} object. There will be a single
* instance of this class.
*/
constructor() {
this._eventEmitter = new EventEmitter();
super();
this._permissions = {};

RTC.addListener(
RTCEvents.DEVICE_LIST_CHANGED,
devices =>
this._eventEmitter.emit(
this.eventEmitter.emit(
JitsiMediaDevicesEvents.DEVICE_LIST_CHANGED,
devices));

Expand Down Expand Up @@ -128,7 +127,7 @@ class JitsiMediaDevices {
...this._permissions,
...permissions
};
this._eventEmitter.emit(JitsiMediaDevicesEvents.PERMISSIONS_CHANGED, this._permissions);
this.eventEmitter.emit(JitsiMediaDevicesEvents.PERMISSIONS_CHANGED, this._permissions);

if (this._permissions[MediaType.AUDIO] || this._permissions[MediaType.VIDEO]) {
// Triggering device list update when the permissiions are granted in order to update
Expand Down Expand Up @@ -265,32 +264,6 @@ class JitsiMediaDevices {
setAudioOutputDevice(deviceId) {
return RTC.setAudioOutputDevice(deviceId);
}

/**
* Adds an event handler.
* @param {string} event - event name
* @param {function} handler - event handler
*/
addEventListener(event, handler) {
this._eventEmitter.addListener(event, handler);
}

/**
* Removes event handler.
* @param {string} event - event name
* @param {function} handler - event handler
*/
removeEventListener(event, handler) {
this._eventEmitter.removeListener(event, handler);
}

/**
* Emits an event.
* @param {string} event - event name
*/
emitEvent(event, ...args) {
this._eventEmitter.emit(event, ...args);
}
}

export default new JitsiMediaDevices();
4 changes: 2 additions & 2 deletions JitsiMeetJS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,11 +318,11 @@ export default {

if (firePermissionPrompt && !RTC.arePermissionsGrantedForAvailableDevices()) {
// @ts-ignore
JitsiMediaDevices.emitEvent(JitsiMediaDevicesEvents.PERMISSION_PROMPT_IS_SHOWN, browser.getName());
JitsiMediaDevices.emit(JitsiMediaDevicesEvents.PERMISSION_PROMPT_IS_SHOWN, browser.getName());
} else if (fireSlowPromiseEvent) {
window.setTimeout(() => {
if (!promiseFulfilled) {
JitsiMediaDevices.emitEvent(JitsiMediaDevicesEvents.SLOW_GET_USER_MEDIA);
JitsiMediaDevices.emit(JitsiMediaDevicesEvents.SLOW_GET_USER_MEDIA);
}
}, USER_MEDIA_SLOW_PROMISE_TIMEOUT);
}
Expand Down
3 changes: 0 additions & 3 deletions modules/RTC/CodecSelection.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import EventEmitter from 'events';

import * as JitsiConferenceEvents from '../../JitsiConferenceEvents.ts';
import Listenable from '../util/Listenable.js';
import JingleSessionPC from '../xmpp/JingleSessionPC.js';
Expand Down Expand Up @@ -42,7 +40,6 @@ class MockConference extends Listenable {
};

this.activeMediaSession = undefined;
this.eventEmitter = new EventEmitter();
this.mediaSessions = [];
this.participants = [];
this._signalingLayer = new MockSignalingLayerImpl();
Expand Down
6 changes: 1 addition & 5 deletions modules/RTC/JitsiTrack.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { getLogger } from '@jitsi/logger';
import EventEmitter from 'events';

import * as JitsiTrackEvents from '../../JitsiTrackEvents';
import { MediaType } from '../../service/RTC/MediaType';
import browser from '../browser';
import EventEmitter from '../util/EventEmitter';

import RTCUtils from './RTCUtils';

Expand Down Expand Up @@ -44,10 +44,6 @@ export default class JitsiTrack extends EventEmitter {
videoType) {
super();

// aliases for addListener/removeListener
this.addEventListener = this.addListener;
this.removeEventListener = this.off = this.removeListener;

/**
* Array with the HTML elements that are displaying the streams.
* @type {Array}
Expand Down
139 changes: 65 additions & 74 deletions modules/RTC/RTCUtils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { getLogger } from '@jitsi/logger';
import EventEmitter from 'events';
import clonedeep from 'lodash.clonedeep';
import 'webrtc-adapter';

Expand All @@ -18,8 +17,6 @@ import screenObtainer from './ScreenObtainer';

const logger = getLogger(__filename);

const eventEmitter = new EventEmitter();

const AVAILABLE_DEVICES_POLL_INTERVAL_TIME = 3000; // ms

/**
Expand Down Expand Up @@ -157,29 +154,6 @@ function getConstraints(um = [], options = {}) {
return constraints;
}

/**
* Updates the granted permissions based on the options we requested and the
* streams we received.
* @param um the options we requested to getUserMedia.
* @param stream the stream we received from calling getUserMedia.
*/
function updateGrantedPermissions(um, stream) {
const audioTracksReceived
= Boolean(stream) && stream.getAudioTracks().length > 0;
const videoTracksReceived
= Boolean(stream) && stream.getVideoTracks().length > 0;
const grantedPermissions = {};

if (um.indexOf('video') !== -1) {
grantedPermissions.video = videoTracksReceived;
}
if (um.indexOf('audio') !== -1) {
grantedPermissions.audio = audioTracksReceived;
}

eventEmitter.emit(RTCEvents.PERMISSIONS_CHANGED, grantedPermissions);
}

/**
* Checks if new list of available media devices differs from previous one.
* @param {MediaDeviceInfo[]} newDevices - list of new devices.
Expand Down Expand Up @@ -247,52 +221,10 @@ function sendDeviceListToAnalytics(deviceList) {
});
}


/**
* Update known devices.
*
* @param {Array<Object>} pds - The new devices.
* @returns {void}
*
* NOTE: Use this function as a shared callback to handle both the devicechange event and the polling implementations.
* This prevents duplication and works around a chrome bug (verified to occur on 68) where devicechange fires twice in
* a row, which can cause async post devicechange processing to collide.
*/
function updateKnownDevices(pds) {
if (compareAvailableMediaDevices(pds)) {
onMediaDevicesListChanged(pds);
}
}

/**
* Event handler for the 'devicechange' event.
*
* @param {MediaDeviceInfo[]} devices - list of media devices.
* @emits RTCEvents.DEVICE_LIST_CHANGED
*/
function onMediaDevicesListChanged(devicesReceived) {
availableDevices = devicesReceived.slice(0);
logger.info('list of media devices has changed:', availableDevices);

sendDeviceListToAnalytics(availableDevices);

// Used by tracks to update the real device id before the consumer of lib-jitsi-meet receives the new device list.
eventEmitter.emit(RTCEvents.DEVICE_LIST_WILL_CHANGE, availableDevices);

eventEmitter.emit(RTCEvents.DEVICE_LIST_CHANGED, availableDevices);
}

/**
*
*/
class RTCUtils extends Listenable {
/**
*
*/
constructor() {
super(eventEmitter);
}

/**
* Depending on the browser, sets difference instance methods for
* interacting with user media and adds methods to native WebRTC-related
Expand Down Expand Up @@ -347,7 +279,7 @@ class RTCUtils extends Listenable {
logger.debug('Available devices: ', availableDevices);
sendDeviceListToAnalytics(availableDevices);

eventEmitter.emit(
this.eventEmitter.emit(
RTCEvents.DEVICE_LIST_AVAILABLE,
availableDevices);

Expand All @@ -373,12 +305,12 @@ class RTCUtils extends Listenable {
enumerateDevices(callback) {
navigator.mediaDevices.enumerateDevices()
.then(devices => {
updateKnownDevices(devices);
this._updateKnownDevices(devices);
callback(devices);
})
.catch(error => {
logger.warn(`Failed to enumerate devices. ${error}`);
updateKnownDevices([]);
this._updateKnownDevices([]);
callback([]);
});
}
Expand Down Expand Up @@ -407,7 +339,7 @@ class RTCUtils extends Listenable {
navigator.mediaDevices.getUserMedia(constraints)
.then(stream => {
logger.log('onUserMediaSuccess');
updateGrantedPermissions(umDevices, stream);
this._updateGrantedPermissions(umDevices, stream);
if (!timeoutExpired) {
if (typeof gumTimeout !== 'undefined') {
clearTimeout(gumTimeout);
Expand All @@ -427,7 +359,7 @@ class RTCUtils extends Listenable {
}

if (jitsiError.name === JitsiTrackErrors.PERMISSION_DENIED) {
updateGrantedPermissions(umDevices, undefined);
this._updateGrantedPermissions(umDevices, undefined);
}

// else {
Expand Down Expand Up @@ -497,6 +429,65 @@ class RTCUtils extends Listenable {
return missingDevices;
}

/**
* Event handler for the 'devicechange' event.
*
* @param {MediaDeviceInfo[]} devices - list of media devices.
* @emits RTCEvents.DEVICE_LIST_CHANGED
*/
_onMediaDevicesListChanged(devicesReceived) {
availableDevices = devicesReceived.slice(0);
logger.info('list of media devices has changed:', availableDevices);

sendDeviceListToAnalytics(availableDevices);

// Used by tracks to update the real device id before the consumer of lib-jitsi-meet receives the
// new device list.
this.eventEmitter.emit(RTCEvents.DEVICE_LIST_WILL_CHANGE, availableDevices);

this.eventEmitter.emit(RTCEvents.DEVICE_LIST_CHANGED, availableDevices);
}

/**
* Update known devices.
*
* @param {Array<Object>} pds - The new devices.
* @returns {void}
*
* NOTE: Use this function as a shared callback to handle both the devicechange event and the
* polling implementations.
* This prevents duplication and works around a chrome bug (verified to occur on 68) where devicechange
* fires twice in a row, which can cause async post devicechange processing to collide.
*/
_updateKnownDevices(pds) {
if (compareAvailableMediaDevices(pds)) {
this._onMediaDevicesListChanged(pds);
}
}

/**
* Updates the granted permissions based on the options we requested and the
* streams we received.
* @param um the options we requested to getUserMedia.
* @param stream the stream we received from calling getUserMedia.
*/
_updateGrantedPermissions(um, stream) {
const audioTracksReceived
= Boolean(stream) && stream.getAudioTracks().length > 0;
const videoTracksReceived
= Boolean(stream) && stream.getVideoTracks().length > 0;
const grantedPermissions = {};

if (um.indexOf('video') !== -1) {
grantedPermissions.video = videoTracksReceived;
}
if (um.indexOf('audio') !== -1) {
grantedPermissions.audio = audioTracksReceived;
}

this.eventEmitter.emit(RTCEvents.PERMISSIONS_CHANGED, grantedPermissions);
}

/**
* Gets streams from specified device types. This function intentionally
* ignores errors for upstream to catch and handle instead.
Expand Down Expand Up @@ -792,7 +783,7 @@ class RTCUtils extends Listenable {

logger.log(`Audio output device set to ${deviceId}`);

eventEmitter.emit(RTCEvents.AUDIO_OUTPUT_DEVICE_CHANGED,
this.eventEmitter.emit(RTCEvents.AUDIO_OUTPUT_DEVICE_CHANGED,
deviceId);
});
}
Expand Down
2 changes: 1 addition & 1 deletion modules/RTCStats/RTCStats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { getLogger } from '@jitsi/logger';

import rtcstatsInit from '@jitsi/rtcstats/rtcstats';
import traceInit from '@jitsi/rtcstats/trace-ws';
import EventEmitter from 'events';

import {
CONFERENCE_JOINED,
Expand All @@ -12,6 +11,7 @@ import {
import JitsiConference from '../../JitsiConference';
import { IRTCStatsConfiguration } from './interfaces';
import { RTC_STATS_PC_EVENT, RTC_STATS_WC_DISCONNECTED } from './RTCStatsEvents';
import EventEmitter from '../util/EventEmitter';

const logger = getLogger(__filename);

Expand Down
3 changes: 1 addition & 2 deletions modules/detection/NoAudioSignalDetection.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import EventEmitter from 'events';

import * as JitsiConferenceEvents from '../../JitsiConferenceEvents';
import * as JitsiTrackEvents from '../../JitsiTrackEvents';
import EventEmitter from '../util/EventEmitter';

import * as DetectionEvents from './DetectionEvents';

Expand Down
3 changes: 1 addition & 2 deletions modules/detection/TrackVADEmitter.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import EventEmitter from 'events';

import RTC from '../RTC/RTC';
import EventEmitter from '../util/EventEmitter';
import { createAudioContext } from '../webaudio/WebAudioUtils';

import { VAD_SCORE_PUBLISHED } from './DetectionEvents';
Expand Down
Loading