2017-04-03 15:48:46 +00:00
|
|
|
import EventEmitter from 'events';
|
2017-04-18 03:17:23 +00:00
|
|
|
|
2017-09-07 17:21:56 +00:00
|
|
|
import { urlObjectToString } from '../../../react/features/base/util/uri';
|
2017-04-28 20:24:20 +00:00
|
|
|
import {
|
|
|
|
PostMessageTransportBackend,
|
|
|
|
Transport
|
|
|
|
} from '../../transport';
|
2016-06-17 20:35:40 +00:00
|
|
|
|
2018-06-12 22:40:12 +00:00
|
|
|
import electronPopupsConfig from './electronPopupsConfig.json';
|
2019-03-21 12:33:40 +00:00
|
|
|
import {
|
|
|
|
getAvailableDevices,
|
|
|
|
getCurrentDevices,
|
|
|
|
isDeviceChangeAvailable,
|
|
|
|
isDeviceListAvailable,
|
|
|
|
isMultipleAudioInputSupported,
|
|
|
|
setAudioInputDevice,
|
|
|
|
setAudioOutputDevice,
|
|
|
|
setVideoInputDevice
|
|
|
|
} from './functions';
|
2018-06-12 22:40:12 +00:00
|
|
|
|
2017-04-03 15:48:46 +00:00
|
|
|
const logger = require('jitsi-meet-logger').getLogger(__filename);
|
2016-06-17 20:35:40 +00:00
|
|
|
|
2017-07-26 20:44:22 +00:00
|
|
|
const ALWAYS_ON_TOP_FILENAMES = [
|
2017-08-04 08:15:11 +00:00
|
|
|
'css/all.css', 'libs/alwaysontop.min.js'
|
2017-07-26 20:44:22 +00:00
|
|
|
];
|
|
|
|
|
2016-06-17 20:35:40 +00:00
|
|
|
/**
|
|
|
|
* Maps the names of the commands expected by the API with the name of the
|
|
|
|
* commands expected by jitsi-meet
|
|
|
|
*/
|
2017-03-30 21:15:56 +00:00
|
|
|
const commands = {
|
2017-04-03 15:48:46 +00:00
|
|
|
avatarUrl: 'avatar-url',
|
|
|
|
displayName: 'display-name',
|
|
|
|
email: 'email',
|
|
|
|
hangup: 'video-hangup',
|
2019-02-17 14:40:24 +00:00
|
|
|
subject: 'subject',
|
2018-01-19 22:19:55 +00:00
|
|
|
submitFeedback: 'submit-feedback',
|
2017-04-03 15:48:46 +00:00
|
|
|
toggleAudio: 'toggle-audio',
|
|
|
|
toggleChat: 'toggle-chat',
|
|
|
|
toggleFilmStrip: 'toggle-film-strip',
|
|
|
|
toggleShareScreen: 'toggle-share-screen',
|
|
|
|
toggleVideo: 'toggle-video'
|
2016-06-17 20:35:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Maps the names of the events expected by the API with the name of the
|
|
|
|
* events expected by jitsi-meet
|
|
|
|
*/
|
2017-03-30 21:15:56 +00:00
|
|
|
const events = {
|
2017-12-05 03:27:17 +00:00
|
|
|
'avatar-changed': 'avatarChanged',
|
2017-08-04 08:15:11 +00:00
|
|
|
'audio-availability-changed': 'audioAvailabilityChanged',
|
|
|
|
'audio-mute-status-changed': 'audioMuteStatusChanged',
|
2019-03-28 12:21:38 +00:00
|
|
|
'device-list-changed': 'deviceListChanged',
|
2017-04-18 03:17:23 +00:00
|
|
|
'display-name-change': 'displayNameChange',
|
2018-06-18 09:19:07 +00:00
|
|
|
'email-change': 'emailChange',
|
2018-01-19 22:19:55 +00:00
|
|
|
'feedback-submitted': 'feedbackSubmitted',
|
2019-02-19 22:18:49 +00:00
|
|
|
'feedback-prompt-displayed': 'feedbackPromptDisplayed',
|
2019-03-11 18:17:28 +00:00
|
|
|
'filmstrip-display-changed': 'filmstripDisplayChanged',
|
2017-04-18 03:17:23 +00:00
|
|
|
'incoming-message': 'incomingMessage',
|
|
|
|
'outgoing-message': 'outgoingMessage',
|
|
|
|
'participant-joined': 'participantJoined',
|
|
|
|
'participant-left': 'participantLeft',
|
2019-01-26 20:53:11 +00:00
|
|
|
'proxy-connection-event': 'proxyConnectionEvent',
|
2017-04-18 03:17:23 +00:00
|
|
|
'video-ready-to-close': 'readyToClose',
|
|
|
|
'video-conference-joined': 'videoConferenceJoined',
|
2017-08-04 08:15:11 +00:00
|
|
|
'video-conference-left': 'videoConferenceLeft',
|
|
|
|
'video-availability-changed': 'videoAvailabilityChanged',
|
2018-01-30 13:43:06 +00:00
|
|
|
'video-mute-status-changed': 'videoMuteStatusChanged',
|
2019-02-17 14:40:24 +00:00
|
|
|
'screen-sharing-status-changed': 'screenSharingStatusChanged',
|
|
|
|
'subject-change': 'subjectChange'
|
2016-06-17 20:35:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2017-04-03 15:48:46 +00:00
|
|
|
* Last id of api object
|
|
|
|
* @type {number}
|
2016-06-17 20:35:40 +00:00
|
|
|
*/
|
2017-04-03 15:48:46 +00:00
|
|
|
let id = 0;
|
|
|
|
|
2017-01-18 19:20:32 +00:00
|
|
|
/**
|
|
|
|
* Adds given number to the numberOfParticipants property of given APIInstance.
|
2017-04-03 15:48:46 +00:00
|
|
|
*
|
|
|
|
* @param {JitsiMeetExternalAPI} APIInstance - The instance of the API.
|
|
|
|
* @param {int} number - The number of participants to be added to
|
2017-01-18 19:20:32 +00:00
|
|
|
* numberOfParticipants property (this parameter can be negative number if the
|
|
|
|
* numberOfParticipants should be decreased).
|
2017-04-03 15:48:46 +00:00
|
|
|
* @returns {void}
|
2017-01-18 19:20:32 +00:00
|
|
|
*/
|
|
|
|
function changeParticipantNumber(APIInstance, number) {
|
2017-07-13 18:20:00 +00:00
|
|
|
APIInstance._numberOfParticipants += number;
|
2017-01-18 19:20:32 +00:00
|
|
|
}
|
|
|
|
|
2017-04-03 15:48:46 +00:00
|
|
|
/**
|
|
|
|
* Generates the URL for the iframe.
|
|
|
|
*
|
|
|
|
* @param {string} domain - The domain name of the server that hosts the
|
|
|
|
* conference.
|
|
|
|
* @param {string} [options] - Another optional parameters.
|
|
|
|
* @param {Object} [options.configOverwrite] - Object containing configuration
|
|
|
|
* options defined in config.js to be overridden.
|
|
|
|
* @param {Object} [options.interfaceConfigOverwrite] - Object containing
|
|
|
|
* configuration options defined in interface_config.js to be overridden.
|
|
|
|
* @param {string} [options.jwt] - The JWT token if needed by jitsi-meet for
|
|
|
|
* authentication.
|
2017-07-27 18:50:09 +00:00
|
|
|
* @param {boolean} [options.noSSL] - If the value is true https won't be used.
|
2017-04-03 15:48:46 +00:00
|
|
|
* @param {string} [options.roomName] - The name of the room to join.
|
|
|
|
* @returns {string} The URL.
|
|
|
|
*/
|
|
|
|
function generateURL(domain, options = {}) {
|
2017-07-27 18:50:09 +00:00
|
|
|
return urlObjectToString({
|
|
|
|
...options,
|
|
|
|
url:
|
2017-10-02 23:08:07 +00:00
|
|
|
`${options.noSSL ? 'http' : 'https'}://${
|
|
|
|
domain}/#jitsi_meet_external_api_id=${id}`
|
2017-07-27 18:50:09 +00:00
|
|
|
});
|
2017-04-03 15:48:46 +00:00
|
|
|
}
|
|
|
|
|
2017-07-13 19:23:54 +00:00
|
|
|
/**
|
|
|
|
* Parses the arguments passed to the constructor. If the old format is used
|
|
|
|
* the function translates the arguments to the new format.
|
|
|
|
*
|
|
|
|
* @param {Array} args - The arguments to be parsed.
|
|
|
|
* @returns {Object} JS object with properties.
|
|
|
|
*/
|
|
|
|
function parseArguments(args) {
|
|
|
|
if (!args.length) {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
const firstArg = args[0];
|
|
|
|
|
|
|
|
switch (typeof firstArg) {
|
|
|
|
case 'string': // old arguments format
|
2018-10-02 13:03:23 +00:00
|
|
|
case undefined: {
|
|
|
|
// Not sure which format but we are trying to parse the old
|
|
|
|
// format because if the new format is used everything will be undefined
|
|
|
|
// anyway.
|
2017-07-13 19:23:54 +00:00
|
|
|
const [
|
|
|
|
roomName,
|
|
|
|
width,
|
|
|
|
height,
|
|
|
|
parentNode,
|
|
|
|
configOverwrite,
|
|
|
|
interfaceConfigOverwrite,
|
|
|
|
noSSL,
|
2018-01-22 23:47:18 +00:00
|
|
|
jwt,
|
|
|
|
onload
|
2017-07-13 19:23:54 +00:00
|
|
|
] = args;
|
|
|
|
|
|
|
|
return {
|
|
|
|
roomName,
|
|
|
|
width,
|
|
|
|
height,
|
|
|
|
parentNode,
|
|
|
|
configOverwrite,
|
|
|
|
interfaceConfigOverwrite,
|
|
|
|
noSSL,
|
2018-01-22 23:47:18 +00:00
|
|
|
jwt,
|
|
|
|
onload
|
2017-07-13 19:23:54 +00:00
|
|
|
};
|
2018-10-02 13:03:23 +00:00
|
|
|
}
|
2017-07-13 19:23:54 +00:00
|
|
|
case 'object': // new arguments format
|
|
|
|
return args[0];
|
|
|
|
default:
|
|
|
|
throw new Error('Can\'t parse the arguments!');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-13 20:24:44 +00:00
|
|
|
/**
|
|
|
|
* Compute valid values for height and width. If a number is specified it's
|
|
|
|
* treated as pixel units. If the value is expressed in px, em, pt or
|
|
|
|
* percentage, it's used as is.
|
|
|
|
*
|
|
|
|
* @param {any} value - The value to be parsed.
|
|
|
|
* @returns {string|undefined} The parsed value that can be used for setting
|
|
|
|
* sizes through the style property. If invalid value is passed the method
|
|
|
|
* retuns undefined.
|
|
|
|
*/
|
|
|
|
function parseSizeParam(value) {
|
|
|
|
let parsedValue;
|
|
|
|
|
|
|
|
// This regex parses values of the form 100px, 100em, 100pt or 100%.
|
|
|
|
// Values like 100 or 100px are handled outside of the regex, and
|
|
|
|
// invalid values will be ignored and the minimum will be used.
|
|
|
|
const re = /([0-9]*\.?[0-9]+)(em|pt|px|%)$/;
|
|
|
|
|
|
|
|
if (typeof value === 'string' && String(value).match(re) !== null) {
|
|
|
|
parsedValue = value;
|
|
|
|
} else if (typeof value === 'number') {
|
|
|
|
parsedValue = `${value}px`;
|
|
|
|
}
|
|
|
|
|
|
|
|
return parsedValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-06-17 20:35:40 +00:00
|
|
|
/**
|
2017-03-30 21:15:56 +00:00
|
|
|
* The IFrame API interface class.
|
2016-06-17 20:35:40 +00:00
|
|
|
*/
|
2017-06-14 18:13:41 +00:00
|
|
|
export default class JitsiMeetExternalAPI extends EventEmitter {
|
2017-03-30 21:15:56 +00:00
|
|
|
/**
|
2017-04-03 15:48:46 +00:00
|
|
|
* Constructs new API instance. Creates iframe and loads Jitsi Meet in it.
|
|
|
|
*
|
|
|
|
* @param {string} domain - The domain name of the server that hosts the
|
|
|
|
* conference.
|
2017-07-13 19:23:54 +00:00
|
|
|
* @param {Object} [options] - Optional arguments.
|
|
|
|
* @param {string} [options.roomName] - The name of the room to join.
|
2017-07-13 20:24:44 +00:00
|
|
|
* @param {number|string} [options.width] - Width of the iframe. Check
|
|
|
|
* parseSizeParam for format details.
|
|
|
|
* @param {number|string} [options.height] - Height of the iframe. Check
|
|
|
|
* parseSizeParam for format details.
|
2017-07-13 19:23:54 +00:00
|
|
|
* @param {DOMElement} [options.parentNode] - The node that will contain the
|
2017-04-03 15:48:46 +00:00
|
|
|
* iframe.
|
2017-07-13 19:23:54 +00:00
|
|
|
* @param {Object} [options.configOverwrite] - Object containing
|
|
|
|
* configuration options defined in config.js to be overridden.
|
|
|
|
* @param {Object} [options.interfaceConfigOverwrite] - Object containing
|
2017-04-03 15:48:46 +00:00
|
|
|
* configuration options defined in interface_config.js to be overridden.
|
2017-07-13 19:23:54 +00:00
|
|
|
* @param {boolean} [options.noSSL] - If the value is true https won't be
|
|
|
|
* used.
|
|
|
|
* @param {string} [options.jwt] - The JWT token if needed by jitsi-meet for
|
2017-03-30 21:15:56 +00:00
|
|
|
* authentication.
|
2018-01-22 23:47:18 +00:00
|
|
|
* @param {string} [options.onload] - The onload function that will listen
|
|
|
|
* for iframe onload event.
|
2018-04-30 12:08:11 +00:00
|
|
|
* @param {Array<Object>} [options.invitees] - Array of objects containing
|
|
|
|
* information about new participants that will be invited in the call.
|
2019-03-25 11:33:41 +00:00
|
|
|
* @param {Array<Object>} [options.devices] - Array of objects containing
|
|
|
|
* information about the initial devices that will be used in the call.
|
2017-03-30 21:15:56 +00:00
|
|
|
*/
|
2017-07-13 19:23:54 +00:00
|
|
|
constructor(domain, ...args) {
|
2017-03-31 16:38:44 +00:00
|
|
|
super();
|
2017-07-13 19:23:54 +00:00
|
|
|
const {
|
|
|
|
roomName = '',
|
2017-07-13 20:24:44 +00:00
|
|
|
width = '100%',
|
|
|
|
height = '100%',
|
2017-07-13 19:23:54 +00:00
|
|
|
parentNode = document.body,
|
|
|
|
configOverwrite = {},
|
|
|
|
interfaceConfigOverwrite = {},
|
|
|
|
noSSL = false,
|
2018-01-22 23:47:18 +00:00
|
|
|
jwt = undefined,
|
2018-04-30 12:08:11 +00:00
|
|
|
onload = undefined,
|
2019-03-25 11:33:41 +00:00
|
|
|
invitees,
|
|
|
|
devices
|
2017-07-13 19:23:54 +00:00
|
|
|
} = parseArguments(args);
|
|
|
|
|
2017-07-13 18:20:00 +00:00
|
|
|
this._parentNode = parentNode;
|
|
|
|
this._url = generateURL(domain, {
|
2017-04-03 15:48:46 +00:00
|
|
|
configOverwrite,
|
|
|
|
interfaceConfigOverwrite,
|
|
|
|
jwt,
|
|
|
|
noSSL,
|
2019-03-25 11:33:41 +00:00
|
|
|
roomName,
|
|
|
|
devices
|
2017-04-03 15:48:46 +00:00
|
|
|
});
|
2018-01-22 23:47:18 +00:00
|
|
|
this._createIFrame(height, width, onload);
|
2017-04-18 03:17:23 +00:00
|
|
|
this._transport = new Transport({
|
2017-04-28 20:24:20 +00:00
|
|
|
backend: new PostMessageTransportBackend({
|
2017-04-18 03:17:23 +00:00
|
|
|
postisOptions: {
|
|
|
|
scope: `jitsi_meet_external_api_${id}`,
|
2017-07-13 18:20:00 +00:00
|
|
|
window: this._frame.contentWindow
|
2017-04-18 03:17:23 +00:00
|
|
|
}
|
|
|
|
})
|
2017-04-03 15:48:46 +00:00
|
|
|
});
|
2018-08-03 17:06:06 +00:00
|
|
|
if (Array.isArray(invitees) && invitees.length > 0) {
|
|
|
|
this.invite(invitees);
|
|
|
|
}
|
2017-12-05 03:27:17 +00:00
|
|
|
this._isLargeVideoVisible = true;
|
|
|
|
this._numberOfParticipants = 0;
|
|
|
|
this._participants = {};
|
|
|
|
this._myUserID = undefined;
|
|
|
|
this._onStageParticipant = undefined;
|
2017-04-03 15:48:46 +00:00
|
|
|
this._setupListeners();
|
|
|
|
id++;
|
|
|
|
}
|
2017-03-31 16:38:44 +00:00
|
|
|
|
2017-04-03 15:48:46 +00:00
|
|
|
/**
|
|
|
|
* Creates the iframe element.
|
|
|
|
*
|
2017-07-13 20:24:44 +00:00
|
|
|
* @param {number|string} height - The height of the iframe. Check
|
|
|
|
* parseSizeParam for format details.
|
|
|
|
* @param {number|string} width - The with of the iframe. Check
|
|
|
|
* parseSizeParam for format details.
|
2018-01-22 23:47:18 +00:00
|
|
|
* @param {Function} onload - The function that will listen
|
|
|
|
* for onload event.
|
2017-04-03 15:48:46 +00:00
|
|
|
* @returns {void}
|
|
|
|
*
|
|
|
|
* @private
|
|
|
|
*/
|
2018-01-22 23:47:18 +00:00
|
|
|
_createIFrame(height, width, onload) {
|
2017-07-13 18:20:00 +00:00
|
|
|
const frameName = `jitsiConferenceFrame${id}`;
|
|
|
|
|
|
|
|
this._frame = document.createElement('iframe');
|
2017-09-08 08:33:53 +00:00
|
|
|
this._frame.allow = 'camera; microphone';
|
2017-07-13 18:20:00 +00:00
|
|
|
this._frame.src = this._url;
|
|
|
|
this._frame.name = frameName;
|
|
|
|
this._frame.id = frameName;
|
2017-07-13 20:24:44 +00:00
|
|
|
this._setSize(height, width);
|
2017-07-13 18:20:00 +00:00
|
|
|
this._frame.setAttribute('allowFullScreen', 'true');
|
|
|
|
this._frame.style.border = 0;
|
2018-01-22 23:47:18 +00:00
|
|
|
|
|
|
|
if (onload) {
|
|
|
|
// waits for iframe resources to load
|
|
|
|
// and fires event when it is done
|
|
|
|
this._frame.onload = onload;
|
|
|
|
}
|
|
|
|
|
2017-07-13 18:23:32 +00:00
|
|
|
this._frame = this._parentNode.appendChild(this._frame);
|
2016-06-17 20:35:40 +00:00
|
|
|
}
|
|
|
|
|
2017-07-26 20:44:22 +00:00
|
|
|
/**
|
|
|
|
* Returns arrays with the all resources for the always on top feature.
|
|
|
|
*
|
|
|
|
* @returns {Array<string>}
|
|
|
|
*/
|
|
|
|
_getAlwaysOnTopResources() {
|
2017-11-13 22:29:38 +00:00
|
|
|
const iframeWindow = this._frame.contentWindow;
|
|
|
|
const iframeDocument = iframeWindow.document;
|
|
|
|
let baseURL = '';
|
|
|
|
const base = iframeDocument.querySelector('base');
|
|
|
|
|
|
|
|
if (base && base.href) {
|
|
|
|
baseURL = base.href;
|
|
|
|
} else {
|
|
|
|
const { protocol, host } = iframeWindow.location;
|
|
|
|
|
|
|
|
baseURL = `${protocol}//${host}`;
|
|
|
|
}
|
|
|
|
|
2017-07-26 20:44:22 +00:00
|
|
|
return ALWAYS_ON_TOP_FILENAMES.map(
|
2017-11-13 22:29:38 +00:00
|
|
|
filename => (new URL(filename, baseURL)).href
|
2017-07-26 20:44:22 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2017-12-05 03:27:17 +00:00
|
|
|
/**
|
|
|
|
* Returns the id of the on stage participant.
|
|
|
|
*
|
|
|
|
* @returns {string} - The id of the on stage participant.
|
|
|
|
*/
|
|
|
|
_getOnStageParticipant() {
|
|
|
|
return this._onStageParticipant;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Getter for the large video element in Jitsi Meet.
|
|
|
|
*
|
|
|
|
* @returns {HTMLElement|undefined} - The large video.
|
|
|
|
*/
|
|
|
|
_getLargeVideo() {
|
|
|
|
const iframe = this.getIFrame();
|
|
|
|
|
|
|
|
if (!this._isLargeVideoVisible
|
|
|
|
|| !iframe
|
|
|
|
|| !iframe.contentWindow
|
|
|
|
|| !iframe.contentWindow.document) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
return iframe.contentWindow.document.getElementById('largeVideo');
|
|
|
|
}
|
|
|
|
|
2017-07-13 20:24:44 +00:00
|
|
|
/**
|
|
|
|
* Sets the size of the iframe element.
|
|
|
|
*
|
|
|
|
* @param {number|string} height - The height of the iframe.
|
|
|
|
* @param {number|string} width - The with of the iframe.
|
|
|
|
* @returns {void}
|
|
|
|
*
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
_setSize(height, width) {
|
|
|
|
const parsedHeight = parseSizeParam(height);
|
|
|
|
const parsedWidth = parseSizeParam(width);
|
|
|
|
|
|
|
|
if (parsedHeight !== undefined) {
|
|
|
|
this._frame.style.height = parsedHeight;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (parsedWidth !== undefined) {
|
|
|
|
this._frame.style.width = parsedWidth;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-30 21:15:56 +00:00
|
|
|
/**
|
2017-04-03 15:48:46 +00:00
|
|
|
* Setups listeners that are used internally for JitsiMeetExternalAPI.
|
|
|
|
*
|
|
|
|
* @returns {void}
|
|
|
|
*
|
|
|
|
* @private
|
2017-03-30 21:15:56 +00:00
|
|
|
*/
|
2017-04-03 15:48:46 +00:00
|
|
|
_setupListeners() {
|
2017-05-01 20:59:18 +00:00
|
|
|
this._transport.on('event', ({ name, ...data }) => {
|
2017-12-05 03:27:17 +00:00
|
|
|
const userID = data.id;
|
|
|
|
|
|
|
|
switch (name) {
|
|
|
|
case 'video-conference-joined':
|
|
|
|
this._myUserID = userID;
|
|
|
|
this._participants[userID] = {
|
|
|
|
avatarURL: data.avatarURL
|
|
|
|
};
|
|
|
|
|
|
|
|
// eslint-disable-next-line no-fallthrough
|
|
|
|
case 'participant-joined': {
|
|
|
|
this._participants[userID] = this._participants[userID] || {};
|
|
|
|
this._participants[userID].displayName = data.displayName;
|
|
|
|
this._participants[userID].formattedDisplayName
|
|
|
|
= data.formattedDisplayName;
|
2017-04-18 03:17:23 +00:00
|
|
|
changeParticipantNumber(this, 1);
|
2017-12-05 03:27:17 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 'participant-left':
|
2017-04-18 03:17:23 +00:00
|
|
|
changeParticipantNumber(this, -1);
|
2017-12-05 03:27:17 +00:00
|
|
|
delete this._participants[userID];
|
|
|
|
break;
|
|
|
|
case 'display-name-change': {
|
|
|
|
const user = this._participants[userID];
|
|
|
|
|
|
|
|
if (user) {
|
|
|
|
user.displayName = data.displayname;
|
|
|
|
user.formattedDisplayName = data.formattedDisplayName;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2018-06-18 09:19:07 +00:00
|
|
|
case 'email-change': {
|
|
|
|
const user = this._participants[userID];
|
|
|
|
|
|
|
|
if (user) {
|
|
|
|
user.email = data.email;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2017-12-05 03:27:17 +00:00
|
|
|
case 'avatar-changed': {
|
|
|
|
const user = this._participants[userID];
|
|
|
|
|
|
|
|
if (user) {
|
|
|
|
user.avatarURL = data.avatarURL;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 'on-stage-participant-changed':
|
|
|
|
this._onStageParticipant = userID;
|
|
|
|
this.emit('largeVideoChanged');
|
|
|
|
break;
|
|
|
|
case 'large-video-visibility-changed':
|
|
|
|
this._isLargeVideoVisible = data.isVisible;
|
|
|
|
this.emit('largeVideoChanged');
|
|
|
|
break;
|
|
|
|
case 'video-conference-left':
|
|
|
|
changeParticipantNumber(this, -1);
|
|
|
|
delete this._participants[this._myUserID];
|
|
|
|
break;
|
2017-04-18 03:17:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const eventName = events[name];
|
|
|
|
|
|
|
|
if (eventName) {
|
|
|
|
this.emit(eventName, data);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
});
|
2017-03-30 21:15:56 +00:00
|
|
|
}
|
2016-06-17 20:35:40 +00:00
|
|
|
|
2017-03-30 21:15:56 +00:00
|
|
|
/**
|
2017-04-03 15:48:46 +00:00
|
|
|
* Adds event listener to Meet Jitsi.
|
|
|
|
*
|
|
|
|
* @param {string} event - The name of the event.
|
|
|
|
* @param {Function} listener - The listener.
|
|
|
|
* @returns {void}
|
|
|
|
*
|
|
|
|
* @deprecated
|
|
|
|
* NOTE: This method is not removed for backward comatability purposes.
|
2017-03-30 21:15:56 +00:00
|
|
|
*/
|
2017-04-03 15:48:46 +00:00
|
|
|
addEventListener(event, listener) {
|
|
|
|
this.on(event, listener);
|
2017-03-30 21:15:56 +00:00
|
|
|
}
|
2016-06-17 20:35:40 +00:00
|
|
|
|
2017-03-30 21:15:56 +00:00
|
|
|
/**
|
2017-04-03 15:48:46 +00:00
|
|
|
* Adds event listeners to Meet Jitsi.
|
|
|
|
*
|
|
|
|
* @param {Object} listeners - The object key should be the name of
|
2017-03-30 21:15:56 +00:00
|
|
|
* the event and value - the listener.
|
|
|
|
* Currently we support the following
|
|
|
|
* events:
|
2018-11-08 12:25:02 +00:00
|
|
|
* {@code incomingMessage} - receives event notifications about incoming
|
2017-03-30 21:15:56 +00:00
|
|
|
* messages. The listener will receive object with the following structure:
|
|
|
|
* {{
|
2017-04-03 15:48:46 +00:00
|
|
|
* 'from': from,//JID of the user that sent the message
|
|
|
|
* 'nick': nick,//the nickname of the user that sent the message
|
|
|
|
* 'message': txt//the text of the message
|
2017-03-30 21:15:56 +00:00
|
|
|
* }}
|
2018-11-08 12:25:02 +00:00
|
|
|
* {@code outgoingMessage} - receives event notifications about outgoing
|
2017-03-30 21:15:56 +00:00
|
|
|
* messages. The listener will receive object with the following structure:
|
|
|
|
* {{
|
2017-04-03 15:48:46 +00:00
|
|
|
* 'message': txt//the text of the message
|
2017-03-30 21:15:56 +00:00
|
|
|
* }}
|
2018-11-08 12:25:02 +00:00
|
|
|
* {@code displayNameChanged} - receives event notifications about display
|
|
|
|
* name change. The listener will receive object with the following
|
|
|
|
* structure:
|
2017-03-30 21:15:56 +00:00
|
|
|
* {{
|
|
|
|
* jid: jid,//the JID of the participant that changed his display name
|
|
|
|
* displayname: displayName //the new display name
|
|
|
|
* }}
|
2018-11-08 12:25:02 +00:00
|
|
|
* {@code participantJoined} - receives event notifications about new
|
|
|
|
* participant.
|
2017-03-30 21:15:56 +00:00
|
|
|
* The listener will receive object with the following structure:
|
|
|
|
* {{
|
|
|
|
* jid: jid //the jid of the participant
|
|
|
|
* }}
|
2018-11-08 12:25:02 +00:00
|
|
|
* {@code participantLeft} - receives event notifications about the
|
|
|
|
* participant that left the room.
|
2017-03-30 21:15:56 +00:00
|
|
|
* The listener will receive object with the following structure:
|
|
|
|
* {{
|
|
|
|
* jid: jid //the jid of the participant
|
|
|
|
* }}
|
2018-11-08 12:25:02 +00:00
|
|
|
* {@code video-conference-joined} - receives event notifications about the
|
|
|
|
* local user has successfully joined the video conference.
|
2017-03-30 21:15:56 +00:00
|
|
|
* The listener will receive object with the following structure:
|
|
|
|
* {{
|
|
|
|
* roomName: room //the room name of the conference
|
|
|
|
* }}
|
2018-11-08 12:25:02 +00:00
|
|
|
* {@code video-conference-left} - receives event notifications about the
|
|
|
|
* local user has left the video conference.
|
2017-03-30 21:15:56 +00:00
|
|
|
* The listener will receive object with the following structure:
|
|
|
|
* {{
|
|
|
|
* roomName: room //the room name of the conference
|
|
|
|
* }}
|
2018-11-08 12:25:02 +00:00
|
|
|
* {@code screenSharingStatusChanged} - receives event notifications about
|
2018-01-30 13:43:06 +00:00
|
|
|
* turning on/off the local user screen sharing.
|
|
|
|
* The listener will receive object with the following structure:
|
|
|
|
* {{
|
|
|
|
* on: on //whether screen sharing is on
|
|
|
|
* }}
|
2018-11-08 12:25:02 +00:00
|
|
|
* {@code readyToClose} - all hangup operations are completed and Jitsi Meet
|
|
|
|
* is ready to be disposed.
|
2017-04-03 15:48:46 +00:00
|
|
|
* @returns {void}
|
2017-03-31 16:38:44 +00:00
|
|
|
*
|
2017-04-03 15:48:46 +00:00
|
|
|
* @deprecated
|
2017-03-31 16:38:44 +00:00
|
|
|
* NOTE: This method is not removed for backward comatability purposes.
|
2017-03-30 21:15:56 +00:00
|
|
|
*/
|
2017-04-03 15:48:46 +00:00
|
|
|
addEventListeners(listeners) {
|
|
|
|
for (const event in listeners) { // eslint-disable-line guard-for-in
|
|
|
|
this.addEventListener(event, listeners[event]);
|
2017-03-30 21:15:56 +00:00
|
|
|
}
|
2016-06-17 20:35:40 +00:00
|
|
|
}
|
2017-03-30 21:15:56 +00:00
|
|
|
|
|
|
|
/**
|
2017-04-03 15:48:46 +00:00
|
|
|
* Removes the listeners and removes the Jitsi Meet frame.
|
2017-03-31 16:38:44 +00:00
|
|
|
*
|
2017-04-03 15:48:46 +00:00
|
|
|
* @returns {void}
|
2017-03-30 21:15:56 +00:00
|
|
|
*/
|
2017-04-03 15:48:46 +00:00
|
|
|
dispose() {
|
2019-02-25 15:34:54 +00:00
|
|
|
this.emit('_willDispose');
|
2017-04-18 03:17:23 +00:00
|
|
|
this._transport.dispose();
|
2017-04-18 22:54:56 +00:00
|
|
|
this.removeAllListeners();
|
2017-07-13 18:23:32 +00:00
|
|
|
if (this._frame) {
|
|
|
|
this._frame.parentNode.removeChild(this._frame);
|
2017-04-18 22:54:56 +00:00
|
|
|
}
|
2017-01-18 19:24:30 +00:00
|
|
|
}
|
2016-06-17 20:35:40 +00:00
|
|
|
|
2017-03-30 21:15:56 +00:00
|
|
|
/**
|
2017-04-03 15:48:46 +00:00
|
|
|
* Executes command. The available commands are:
|
2018-11-08 12:25:02 +00:00
|
|
|
* {@code displayName} - Sets the display name of the local participant to
|
|
|
|
* the value passed in the arguments array.
|
2019-02-17 14:40:24 +00:00
|
|
|
* {@code subject} - Sets the subject of the conference, the value passed
|
2019-03-12 17:45:53 +00:00
|
|
|
* in the arguments array. Note: Available only for moderator.
|
2019-02-17 14:40:24 +00:00
|
|
|
*
|
2018-11-08 12:25:02 +00:00
|
|
|
* {@code toggleAudio} - Mutes / unmutes audio with no arguments.
|
|
|
|
* {@code toggleVideo} - Mutes / unmutes video with no arguments.
|
|
|
|
* {@code toggleFilmStrip} - Hides / shows the filmstrip with no arguments.
|
|
|
|
*
|
2017-04-03 15:48:46 +00:00
|
|
|
* If the command doesn't require any arguments the parameter should be set
|
|
|
|
* to empty array or it may be omitted.
|
|
|
|
*
|
|
|
|
* @param {string} name - The name of the command.
|
|
|
|
* @returns {void}
|
2017-03-30 21:15:56 +00:00
|
|
|
*/
|
2017-04-03 15:48:46 +00:00
|
|
|
executeCommand(name, ...args) {
|
|
|
|
if (!(name in commands)) {
|
|
|
|
logger.error('Not supported command name.');
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
2017-04-18 03:17:23 +00:00
|
|
|
this._transport.sendEvent({
|
2017-04-27 20:21:01 +00:00
|
|
|
data: args,
|
|
|
|
name: commands[name]
|
2017-04-03 15:48:46 +00:00
|
|
|
});
|
2016-06-17 20:35:40 +00:00
|
|
|
}
|
|
|
|
|
2017-03-30 21:15:56 +00:00
|
|
|
/**
|
2017-04-03 15:48:46 +00:00
|
|
|
* Executes commands. The available commands are:
|
2018-11-08 12:25:02 +00:00
|
|
|
* {@code displayName} - Sets the display name of the local participant to
|
|
|
|
* the value passed in the arguments array.
|
|
|
|
* {@code toggleAudio} - Mutes / unmutes audio. No arguments.
|
|
|
|
* {@code toggleVideo} - Mutes / unmutes video. No arguments.
|
|
|
|
* {@code toggleFilmStrip} - Hides / shows the filmstrip. No arguments.
|
|
|
|
* {@code toggleChat} - Hides / shows chat. No arguments.
|
|
|
|
* {@code toggleShareScreen} - Starts / stops screen sharing. No arguments.
|
2017-04-03 15:48:46 +00:00
|
|
|
*
|
|
|
|
* @param {Object} commandList - The object with commands to be executed.
|
|
|
|
* The keys of the object are the commands that will be executed and the
|
|
|
|
* values are the arguments for the command.
|
|
|
|
* @returns {void}
|
2017-03-30 21:15:56 +00:00
|
|
|
*/
|
2017-04-03 15:48:46 +00:00
|
|
|
executeCommands(commandList) {
|
|
|
|
for (const key in commandList) { // eslint-disable-line guard-for-in
|
|
|
|
this.executeCommand(key, commandList[key]);
|
2017-03-30 21:15:56 +00:00
|
|
|
}
|
|
|
|
}
|
2016-06-17 20:35:40 +00:00
|
|
|
|
2019-03-21 12:33:40 +00:00
|
|
|
/**
|
2019-03-28 16:29:30 +00:00
|
|
|
* Returns Promise that resolves with a list of available devices.
|
2019-03-21 12:33:40 +00:00
|
|
|
*
|
|
|
|
* @returns {Promise}
|
|
|
|
*/
|
|
|
|
getAvailableDevices() {
|
|
|
|
return getAvailableDevices(this._transport);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns Promise that resolves with current selected devices.
|
|
|
|
*
|
|
|
|
* @returns {Promise}
|
|
|
|
*/
|
|
|
|
getCurrentDevices() {
|
|
|
|
return getCurrentDevices(this._transport);
|
|
|
|
}
|
|
|
|
|
2017-08-04 08:15:11 +00:00
|
|
|
/**
|
|
|
|
* Check if the audio is available.
|
|
|
|
*
|
|
|
|
* @returns {Promise} - Resolves with true if the audio available, with
|
|
|
|
* false if not and rejects on failure.
|
|
|
|
*/
|
|
|
|
isAudioAvailable() {
|
|
|
|
return this._transport.sendRequest({
|
|
|
|
name: 'is-audio-available'
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-03-21 12:33:40 +00:00
|
|
|
/**
|
|
|
|
* Returns Promise that resolves with true if the device change is available
|
|
|
|
* and with false if not.
|
|
|
|
*
|
|
|
|
* @param {string} [deviceType] - Values - 'output', 'input' or undefined.
|
|
|
|
* Default - 'input'.
|
|
|
|
* @returns {Promise}
|
|
|
|
*/
|
|
|
|
isDeviceChangeAvailable(deviceType) {
|
|
|
|
return isDeviceChangeAvailable(this._transport, deviceType);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns Promise that resolves with true if the device list is available
|
|
|
|
* and with false if not.
|
|
|
|
*
|
|
|
|
* @returns {Promise}
|
|
|
|
*/
|
|
|
|
isDeviceListAvailable() {
|
|
|
|
return isDeviceListAvailable(this._transport);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-03-28 16:29:30 +00:00
|
|
|
* Returns Promise that resolves with true if multiple audio input is supported
|
2019-03-21 12:33:40 +00:00
|
|
|
* and with false if not.
|
|
|
|
*
|
|
|
|
* @returns {Promise}
|
|
|
|
*/
|
|
|
|
isMultipleAudioInputSupported() {
|
|
|
|
return isMultipleAudioInputSupported(this._transport);
|
|
|
|
}
|
|
|
|
|
2018-04-30 12:08:11 +00:00
|
|
|
/**
|
|
|
|
* Invite people to the call.
|
|
|
|
*
|
|
|
|
* @param {Array<Object>} invitees - The invitees.
|
|
|
|
* @returns {Promise} - Resolves on success and rejects on failure.
|
|
|
|
*/
|
|
|
|
invite(invitees) {
|
2018-08-03 17:06:06 +00:00
|
|
|
if (!Array.isArray(invitees) || invitees.length === 0) {
|
|
|
|
return Promise.reject(new TypeError('Invalid Argument'));
|
|
|
|
}
|
|
|
|
|
2018-04-30 12:08:11 +00:00
|
|
|
return this._transport.sendRequest({
|
|
|
|
name: 'invite',
|
|
|
|
invitees
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-08-04 08:15:11 +00:00
|
|
|
/**
|
|
|
|
* Returns the audio mute status.
|
|
|
|
*
|
|
|
|
* @returns {Promise} - Resolves with the audio mute status and rejects on
|
|
|
|
* failure.
|
|
|
|
*/
|
|
|
|
isAudioMuted() {
|
|
|
|
return this._transport.sendRequest({
|
|
|
|
name: 'is-audio-muted'
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-12-05 03:27:17 +00:00
|
|
|
/**
|
|
|
|
* Returns the avatar URL of a participant.
|
|
|
|
*
|
|
|
|
* @param {string} participantId - The id of the participant.
|
|
|
|
* @returns {string} The avatar URL.
|
|
|
|
*/
|
|
|
|
getAvatarURL(participantId) {
|
|
|
|
const { avatarURL } = this._participants[participantId] || {};
|
|
|
|
|
|
|
|
return avatarURL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the display name of a participant.
|
|
|
|
*
|
|
|
|
* @param {string} participantId - The id of the participant.
|
|
|
|
* @returns {string} The display name.
|
|
|
|
*/
|
|
|
|
getDisplayName(participantId) {
|
|
|
|
const { displayName } = this._participants[participantId] || {};
|
|
|
|
|
|
|
|
return displayName;
|
|
|
|
}
|
|
|
|
|
2018-06-18 09:19:07 +00:00
|
|
|
/**
|
|
|
|
* Returns the email of a participant.
|
|
|
|
*
|
|
|
|
* @param {string} participantId - The id of the participant.
|
|
|
|
* @returns {string} The email.
|
|
|
|
*/
|
|
|
|
getEmail(participantId) {
|
|
|
|
const { email } = this._participants[participantId] || {};
|
|
|
|
|
|
|
|
return email;
|
|
|
|
}
|
|
|
|
|
2017-12-05 03:27:17 +00:00
|
|
|
/**
|
|
|
|
* Returns the formatted display name of a participant.
|
|
|
|
*
|
|
|
|
* @param {string} participantId - The id of the participant.
|
|
|
|
* @returns {string} The formatted display name.
|
|
|
|
*/
|
|
|
|
_getFormattedDisplayName(participantId) {
|
|
|
|
const { formattedDisplayName }
|
|
|
|
= this._participants[participantId] || {};
|
|
|
|
|
|
|
|
return formattedDisplayName;
|
|
|
|
}
|
|
|
|
|
2017-07-13 18:10:32 +00:00
|
|
|
/**
|
|
|
|
* Returns the iframe that loads Jitsi Meet.
|
|
|
|
*
|
|
|
|
* @returns {HTMLElement} The iframe.
|
|
|
|
*/
|
|
|
|
getIFrame() {
|
2017-07-13 18:20:00 +00:00
|
|
|
return this._frame;
|
2017-07-13 18:10:32 +00:00
|
|
|
}
|
|
|
|
|
2017-03-30 21:15:56 +00:00
|
|
|
/**
|
2017-04-03 15:48:46 +00:00
|
|
|
* Returns the number of participants in the conference. The local
|
|
|
|
* participant is included.
|
|
|
|
*
|
|
|
|
* @returns {int} The number of participants in the conference.
|
2017-03-30 21:15:56 +00:00
|
|
|
*/
|
|
|
|
getNumberOfParticipants() {
|
2017-07-13 18:20:00 +00:00
|
|
|
return this._numberOfParticipants;
|
2017-03-30 21:15:56 +00:00
|
|
|
}
|
2017-01-18 19:20:32 +00:00
|
|
|
|
2017-08-04 08:15:11 +00:00
|
|
|
/**
|
|
|
|
* Check if the video is available.
|
|
|
|
*
|
|
|
|
* @returns {Promise} - Resolves with true if the video available, with
|
|
|
|
* false if not and rejects on failure.
|
|
|
|
*/
|
|
|
|
isVideoAvailable() {
|
|
|
|
return this._transport.sendRequest({
|
|
|
|
name: 'is-video-available'
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the audio mute status.
|
|
|
|
*
|
|
|
|
* @returns {Promise} - Resolves with the audio mute status and rejects on
|
|
|
|
* failure.
|
|
|
|
*/
|
|
|
|
isVideoMuted() {
|
|
|
|
return this._transport.sendRequest({
|
|
|
|
name: 'is-video-muted'
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-03-30 21:15:56 +00:00
|
|
|
/**
|
2017-04-03 15:48:46 +00:00
|
|
|
* Removes event listener.
|
|
|
|
*
|
|
|
|
* @param {string} event - The name of the event.
|
|
|
|
* @returns {void}
|
|
|
|
*
|
|
|
|
* @deprecated
|
|
|
|
* NOTE: This method is not removed for backward comatability purposes.
|
2017-03-30 21:15:56 +00:00
|
|
|
*/
|
2017-04-03 15:48:46 +00:00
|
|
|
removeEventListener(event) {
|
2017-04-18 22:54:56 +00:00
|
|
|
this.removeAllListeners(event);
|
2017-03-30 21:15:56 +00:00
|
|
|
}
|
2017-01-18 19:20:32 +00:00
|
|
|
|
2017-03-30 21:15:56 +00:00
|
|
|
/**
|
2017-04-03 15:48:46 +00:00
|
|
|
* Removes event listeners.
|
|
|
|
*
|
|
|
|
* @param {Array<string>} eventList - Array with the names of the events.
|
|
|
|
* @returns {void}
|
|
|
|
*
|
|
|
|
* @deprecated
|
|
|
|
* NOTE: This method is not removed for backward comatability purposes.
|
2017-03-30 21:15:56 +00:00
|
|
|
*/
|
2017-04-03 15:48:46 +00:00
|
|
|
removeEventListeners(eventList) {
|
|
|
|
eventList.forEach(event => this.removeEventListener(event));
|
2017-03-30 21:15:56 +00:00
|
|
|
}
|
2018-06-12 22:40:12 +00:00
|
|
|
|
2019-01-26 20:53:11 +00:00
|
|
|
/**
|
|
|
|
* Passes an event along to the local conference participant to establish
|
|
|
|
* or update a direct peer connection. This is currently used for developing
|
|
|
|
* wireless screensharing with room integration and it is advised against to
|
|
|
|
* use as its api may change.
|
|
|
|
*
|
|
|
|
* @param {Object} event - An object with information to pass along.
|
|
|
|
* @param {Object} event.data - The payload of the event.
|
|
|
|
* @param {string} event.from - The jid of the sender of the event. Needed
|
|
|
|
* when a reply is to be sent regarding the event.
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
sendProxyConnectionEvent(event) {
|
|
|
|
this._transport.sendEvent({
|
|
|
|
data: [ event ],
|
|
|
|
name: 'proxy-connection-event'
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-03-21 12:33:40 +00:00
|
|
|
/**
|
2019-03-28 16:29:30 +00:00
|
|
|
* Sets the audio input device to the one with the label or id that is
|
|
|
|
* passed.
|
2019-03-21 12:33:40 +00:00
|
|
|
*
|
2019-03-28 16:29:30 +00:00
|
|
|
* @param {string} label - The label of the new device.
|
2019-03-21 12:33:40 +00:00
|
|
|
* @param {string} deviceId - The id of the new device.
|
|
|
|
* @returns {Promise}
|
|
|
|
*/
|
2019-03-28 16:29:30 +00:00
|
|
|
setAudioInputDevice(label, deviceId) {
|
|
|
|
return setAudioInputDevice(this._transport, label, deviceId);
|
2019-03-21 12:33:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-03-28 16:29:30 +00:00
|
|
|
* Sets the audio output device to the one with the label or id that is
|
|
|
|
* passed.
|
2019-03-21 12:33:40 +00:00
|
|
|
*
|
2019-03-28 16:29:30 +00:00
|
|
|
* @param {string} label - The label of the new device.
|
2019-03-21 12:33:40 +00:00
|
|
|
* @param {string} deviceId - The id of the new device.
|
|
|
|
* @returns {Promise}
|
|
|
|
*/
|
2019-03-28 16:29:30 +00:00
|
|
|
setAudioOutputDevice(label, deviceId) {
|
|
|
|
return setAudioOutputDevice(this._transport, label, deviceId);
|
2019-03-21 12:33:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-03-28 16:29:30 +00:00
|
|
|
* Sets the video input device to the one with the label or id that is
|
|
|
|
* passed.
|
2019-03-21 12:33:40 +00:00
|
|
|
*
|
2019-03-28 16:29:30 +00:00
|
|
|
* @param {string} label - The label of the new device.
|
2019-03-21 12:33:40 +00:00
|
|
|
* @param {string} deviceId - The id of the new device.
|
|
|
|
* @returns {Promise}
|
|
|
|
*/
|
2019-03-28 16:29:30 +00:00
|
|
|
setVideoInputDevice(label, deviceId) {
|
|
|
|
return setVideoInputDevice(this._transport, label, deviceId);
|
2019-03-21 12:33:40 +00:00
|
|
|
}
|
|
|
|
|
2018-06-12 22:40:12 +00:00
|
|
|
/**
|
|
|
|
* Returns the configuration for electron for the windows that are open
|
|
|
|
* from Jitsi Meet.
|
|
|
|
*
|
|
|
|
* @returns {Promise<Object>}
|
|
|
|
*
|
|
|
|
* NOTE: For internal use only.
|
|
|
|
*/
|
|
|
|
_getElectronPopupsConfig() {
|
|
|
|
return Promise.resolve(electronPopupsConfig);
|
|
|
|
}
|
2017-03-30 21:15:56 +00:00
|
|
|
}
|