@webex/web-client-media-engine 3.20.4 → 3.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.js +1395 -1343
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +1395 -1343
- package/dist/esm/index.js.map +1 -1
- package/dist/types/index.d.ts +19 -12
- package/package.json +2 -2
package/dist/cjs/index.js
CHANGED
|
@@ -330,149 +330,149 @@ var logger$1$1 = {exports: {}};
|
|
|
330
330
|
|
|
331
331
|
var Logger$2 = logger$1$1.exports;
|
|
332
332
|
|
|
333
|
-
const DEFAULT_LOGGER_NAME$1 = 'webrtc-core';
|
|
334
|
-
const logger$3 = Logger$2.get(DEFAULT_LOGGER_NAME$1);
|
|
335
|
-
Logger$2.useDefaults({
|
|
336
|
-
defaultLevel: Logger$2.DEBUG,
|
|
337
|
-
/* eslint-disable-next-line jsdoc/require-jsdoc */
|
|
338
|
-
formatter: (messages, context) => {
|
|
339
|
-
messages.unshift(`[${context.name}]`);
|
|
340
|
-
},
|
|
333
|
+
const DEFAULT_LOGGER_NAME$1 = 'webrtc-core';
|
|
334
|
+
const logger$3 = Logger$2.get(DEFAULT_LOGGER_NAME$1);
|
|
335
|
+
Logger$2.useDefaults({
|
|
336
|
+
defaultLevel: Logger$2.DEBUG,
|
|
337
|
+
/* eslint-disable-next-line jsdoc/require-jsdoc */
|
|
338
|
+
formatter: (messages, context) => {
|
|
339
|
+
messages.unshift(`[${context.name}]`);
|
|
340
|
+
},
|
|
341
341
|
});
|
|
342
342
|
|
|
343
|
-
var DeviceKind$1;
|
|
344
|
-
(function (DeviceKind) {
|
|
345
|
-
DeviceKind["AudioInput"] = "audioinput";
|
|
346
|
-
DeviceKind["AudioOutput"] = "audiooutput";
|
|
347
|
-
DeviceKind["VideoInput"] = "videoinput";
|
|
348
|
-
})(DeviceKind$1 || (DeviceKind$1 = {}));
|
|
349
|
-
/**
|
|
350
|
-
* Prompts the user for permission to use a media input which produces a MediaStream with tracks
|
|
351
|
-
* containing the requested types of media.
|
|
352
|
-
*
|
|
353
|
-
* @param constraints - A MediaStreamConstraints object specifying the types of media to request,
|
|
354
|
-
* along with any requirements for each type.
|
|
355
|
-
* @returns A Promise whose fulfillment handler receives a MediaStream object when the requested
|
|
356
|
-
* media has successfully been obtained.
|
|
357
|
-
*/
|
|
358
|
-
function getUserMedia(constraints) {
|
|
359
|
-
return __awaiter$2(this, void 0, void 0, function* () {
|
|
360
|
-
return navigator.mediaDevices.getUserMedia(constraints);
|
|
361
|
-
});
|
|
362
|
-
}
|
|
363
|
-
/**
|
|
364
|
-
* Prompts the user for permission to use a user's display media and audio. If a video track is
|
|
365
|
-
* absent from the constraints argument, one will still be provided.
|
|
366
|
-
*
|
|
367
|
-
* @param constraints - A MediaStreamConstraints object specifying the types of media to request,
|
|
368
|
-
* along with any requirements for each type.
|
|
369
|
-
* @returns A Promise whose fulfillment handler receives a MediaStream object when the requested
|
|
370
|
-
* media has successfully been obtained.
|
|
371
|
-
*/
|
|
372
|
-
function getDisplayMedia(constraints) {
|
|
373
|
-
return navigator.mediaDevices.getDisplayMedia(constraints);
|
|
374
|
-
}
|
|
375
|
-
/**
|
|
376
|
-
* Requests a list of the available media input and output devices, such as microphones, cameras,
|
|
377
|
-
* headsets, and so forth.
|
|
378
|
-
*
|
|
379
|
-
* @returns A Promise that receives an array of MediaDeviceInfo objects when the promise is
|
|
380
|
-
* fulfilled.
|
|
381
|
-
*/
|
|
382
|
-
function enumerateDevices() {
|
|
383
|
-
return __awaiter$2(this, void 0, void 0, function* () {
|
|
384
|
-
return navigator.mediaDevices.enumerateDevices();
|
|
385
|
-
});
|
|
386
|
-
}
|
|
387
|
-
/**
|
|
388
|
-
* Adds the callback handler to be notified of a media device change (for example, a headset is
|
|
389
|
-
* unplugged from the user's computer).
|
|
390
|
-
*
|
|
391
|
-
* @param handler - The callback function to execute.
|
|
392
|
-
*/
|
|
393
|
-
function setOnDeviceChangeHandler$1(handler) {
|
|
394
|
-
navigator.mediaDevices.ondevicechange = handler;
|
|
395
|
-
}
|
|
396
|
-
/**
|
|
397
|
-
* Checks permissions using the navigator's permissions api.
|
|
398
|
-
*
|
|
399
|
-
* @param deviceKinds - Array of DeviceKind items.
|
|
400
|
-
* @throws An error if camera or microphone aren't available options for query() (Firefox), or if
|
|
401
|
-
* navigator.permissions is undefined (Safari and others).
|
|
402
|
-
* @returns Array of Permission Status objects.
|
|
403
|
-
*/
|
|
404
|
-
function checkNavigatorPermissions(deviceKinds) {
|
|
405
|
-
return __awaiter$2(this, void 0, void 0, function* () {
|
|
406
|
-
const permissionRequests = [];
|
|
407
|
-
if (deviceKinds.includes(DeviceKind$1.VideoInput)) {
|
|
408
|
-
permissionRequests.push(navigator.permissions.query({ name: 'camera' }));
|
|
409
|
-
}
|
|
410
|
-
if (deviceKinds.includes(DeviceKind$1.AudioInput)) {
|
|
411
|
-
permissionRequests.push(navigator.permissions.query({ name: 'microphone' }));
|
|
412
|
-
}
|
|
413
|
-
return Promise.all(permissionRequests);
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
/**
|
|
417
|
-
* Check to see if the user has granted the application permission to use their devices.
|
|
418
|
-
*
|
|
419
|
-
* @param deviceKinds - Array of DeviceKind items.
|
|
420
|
-
* @returns True if device permissions exist, false if otherwise.
|
|
421
|
-
*/
|
|
422
|
-
function checkDevicePermissions(deviceKinds) {
|
|
423
|
-
return __awaiter$2(this, void 0, void 0, function* () {
|
|
424
|
-
try {
|
|
425
|
-
const permissions = yield checkNavigatorPermissions(deviceKinds);
|
|
426
|
-
if (permissions.every((permission) => permission.state === 'granted')) {
|
|
427
|
-
return true;
|
|
428
|
-
}
|
|
429
|
-
// eslint-disable-next-line no-empty
|
|
430
|
-
}
|
|
431
|
-
catch (e) { }
|
|
432
|
-
try {
|
|
433
|
-
const devices = yield enumerateDevices();
|
|
434
|
-
// If permissions are granted, the MediaDeviceInfo objects will have labels.
|
|
435
|
-
return devices
|
|
436
|
-
.filter((device) => deviceKinds.includes(device.kind))
|
|
437
|
-
.every((device) => device.label);
|
|
438
|
-
// eslint-disable-next-line no-empty
|
|
439
|
-
}
|
|
440
|
-
catch (e) { }
|
|
441
|
-
return false;
|
|
442
|
-
});
|
|
443
|
-
}
|
|
444
|
-
/**
|
|
445
|
-
* Ensures that the user has granted permissions to the microphone and camera.
|
|
446
|
-
*
|
|
447
|
-
* @param deviceKinds - Array of DeviceKind items.
|
|
448
|
-
* @param callback - Function that will be executed while device permissions are granted. After this
|
|
449
|
-
* returns, permissions (for example device labels in Firefox) may not be available anymore.
|
|
450
|
-
* @returns The callback's response.
|
|
451
|
-
*/
|
|
452
|
-
function ensureDevicePermissions(deviceKinds, callback) {
|
|
453
|
-
return __awaiter$2(this, void 0, void 0, function* () {
|
|
454
|
-
try {
|
|
455
|
-
const hasDevicePermissions = yield checkDevicePermissions(deviceKinds);
|
|
456
|
-
if (!hasDevicePermissions) {
|
|
457
|
-
const stream = yield getUserMedia({
|
|
458
|
-
audio: deviceKinds.includes(DeviceKind$1.AudioInput),
|
|
459
|
-
video: deviceKinds.includes(DeviceKind$1.VideoInput),
|
|
460
|
-
});
|
|
461
|
-
// Callback is here to call a function while an active capture exists, so that the browser
|
|
462
|
-
// (Firefox) will allow the user to access device information.
|
|
463
|
-
const callbackRes = yield callback();
|
|
464
|
-
// Stop tracks in the stream so the browser (Safari) will know that there is not an active
|
|
465
|
-
// stream running.
|
|
466
|
-
stream.getTracks().forEach((track) => track.stop());
|
|
467
|
-
return callbackRes;
|
|
468
|
-
}
|
|
469
|
-
return callback();
|
|
470
|
-
}
|
|
471
|
-
catch (e) {
|
|
472
|
-
logger$3.error(e);
|
|
473
|
-
throw new Error('Failed to ensure device permissions.');
|
|
474
|
-
}
|
|
475
|
-
});
|
|
343
|
+
var DeviceKind$1;
|
|
344
|
+
(function (DeviceKind) {
|
|
345
|
+
DeviceKind["AudioInput"] = "audioinput";
|
|
346
|
+
DeviceKind["AudioOutput"] = "audiooutput";
|
|
347
|
+
DeviceKind["VideoInput"] = "videoinput";
|
|
348
|
+
})(DeviceKind$1 || (DeviceKind$1 = {}));
|
|
349
|
+
/**
|
|
350
|
+
* Prompts the user for permission to use a media input which produces a MediaStream with tracks
|
|
351
|
+
* containing the requested types of media.
|
|
352
|
+
*
|
|
353
|
+
* @param constraints - A MediaStreamConstraints object specifying the types of media to request,
|
|
354
|
+
* along with any requirements for each type.
|
|
355
|
+
* @returns A Promise whose fulfillment handler receives a MediaStream object when the requested
|
|
356
|
+
* media has successfully been obtained.
|
|
357
|
+
*/
|
|
358
|
+
function getUserMedia(constraints) {
|
|
359
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
360
|
+
return navigator.mediaDevices.getUserMedia(constraints);
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Prompts the user for permission to use a user's display media and audio. If a video track is
|
|
365
|
+
* absent from the constraints argument, one will still be provided.
|
|
366
|
+
*
|
|
367
|
+
* @param constraints - A MediaStreamConstraints object specifying the types of media to request,
|
|
368
|
+
* along with any requirements for each type.
|
|
369
|
+
* @returns A Promise whose fulfillment handler receives a MediaStream object when the requested
|
|
370
|
+
* media has successfully been obtained.
|
|
371
|
+
*/
|
|
372
|
+
function getDisplayMedia(constraints) {
|
|
373
|
+
return navigator.mediaDevices.getDisplayMedia(constraints);
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Requests a list of the available media input and output devices, such as microphones, cameras,
|
|
377
|
+
* headsets, and so forth.
|
|
378
|
+
*
|
|
379
|
+
* @returns A Promise that receives an array of MediaDeviceInfo objects when the promise is
|
|
380
|
+
* fulfilled.
|
|
381
|
+
*/
|
|
382
|
+
function enumerateDevices() {
|
|
383
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
384
|
+
return navigator.mediaDevices.enumerateDevices();
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Adds the callback handler to be notified of a media device change (for example, a headset is
|
|
389
|
+
* unplugged from the user's computer).
|
|
390
|
+
*
|
|
391
|
+
* @param handler - The callback function to execute.
|
|
392
|
+
*/
|
|
393
|
+
function setOnDeviceChangeHandler$1(handler) {
|
|
394
|
+
navigator.mediaDevices.ondevicechange = handler;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Checks permissions using the navigator's permissions api.
|
|
398
|
+
*
|
|
399
|
+
* @param deviceKinds - Array of DeviceKind items.
|
|
400
|
+
* @throws An error if camera or microphone aren't available options for query() (Firefox), or if
|
|
401
|
+
* navigator.permissions is undefined (Safari and others).
|
|
402
|
+
* @returns Array of Permission Status objects.
|
|
403
|
+
*/
|
|
404
|
+
function checkNavigatorPermissions(deviceKinds) {
|
|
405
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
406
|
+
const permissionRequests = [];
|
|
407
|
+
if (deviceKinds.includes(DeviceKind$1.VideoInput)) {
|
|
408
|
+
permissionRequests.push(navigator.permissions.query({ name: 'camera' }));
|
|
409
|
+
}
|
|
410
|
+
if (deviceKinds.includes(DeviceKind$1.AudioInput)) {
|
|
411
|
+
permissionRequests.push(navigator.permissions.query({ name: 'microphone' }));
|
|
412
|
+
}
|
|
413
|
+
return Promise.all(permissionRequests);
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Check to see if the user has granted the application permission to use their devices.
|
|
418
|
+
*
|
|
419
|
+
* @param deviceKinds - Array of DeviceKind items.
|
|
420
|
+
* @returns True if device permissions exist, false if otherwise.
|
|
421
|
+
*/
|
|
422
|
+
function checkDevicePermissions(deviceKinds) {
|
|
423
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
424
|
+
try {
|
|
425
|
+
const permissions = yield checkNavigatorPermissions(deviceKinds);
|
|
426
|
+
if (permissions.every((permission) => permission.state === 'granted')) {
|
|
427
|
+
return true;
|
|
428
|
+
}
|
|
429
|
+
// eslint-disable-next-line no-empty
|
|
430
|
+
}
|
|
431
|
+
catch (e) { }
|
|
432
|
+
try {
|
|
433
|
+
const devices = yield enumerateDevices();
|
|
434
|
+
// If permissions are granted, the MediaDeviceInfo objects will have labels.
|
|
435
|
+
return devices
|
|
436
|
+
.filter((device) => deviceKinds.includes(device.kind))
|
|
437
|
+
.every((device) => device.label);
|
|
438
|
+
// eslint-disable-next-line no-empty
|
|
439
|
+
}
|
|
440
|
+
catch (e) { }
|
|
441
|
+
return false;
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Ensures that the user has granted permissions to the microphone and camera.
|
|
446
|
+
*
|
|
447
|
+
* @param deviceKinds - Array of DeviceKind items.
|
|
448
|
+
* @param callback - Function that will be executed while device permissions are granted. After this
|
|
449
|
+
* returns, permissions (for example device labels in Firefox) may not be available anymore.
|
|
450
|
+
* @returns The callback's response.
|
|
451
|
+
*/
|
|
452
|
+
function ensureDevicePermissions(deviceKinds, callback) {
|
|
453
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
454
|
+
try {
|
|
455
|
+
const hasDevicePermissions = yield checkDevicePermissions(deviceKinds);
|
|
456
|
+
if (!hasDevicePermissions) {
|
|
457
|
+
const stream = yield getUserMedia({
|
|
458
|
+
audio: deviceKinds.includes(DeviceKind$1.AudioInput),
|
|
459
|
+
video: deviceKinds.includes(DeviceKind$1.VideoInput),
|
|
460
|
+
});
|
|
461
|
+
// Callback is here to call a function while an active capture exists, so that the browser
|
|
462
|
+
// (Firefox) will allow the user to access device information.
|
|
463
|
+
const callbackRes = yield callback();
|
|
464
|
+
// Stop tracks in the stream so the browser (Safari) will know that there is not an active
|
|
465
|
+
// stream running.
|
|
466
|
+
stream.getTracks().forEach((track) => track.stop());
|
|
467
|
+
return callbackRes;
|
|
468
|
+
}
|
|
469
|
+
return callback();
|
|
470
|
+
}
|
|
471
|
+
catch (e) {
|
|
472
|
+
logger$3.error(e);
|
|
473
|
+
throw new Error('Failed to ensure device permissions.');
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
476
|
}
|
|
477
477
|
|
|
478
478
|
var media = /*#__PURE__*/Object.freeze({
|
|
@@ -486,175 +486,175 @@ var media = /*#__PURE__*/Object.freeze({
|
|
|
486
486
|
ensureDevicePermissions: ensureDevicePermissions
|
|
487
487
|
});
|
|
488
488
|
|
|
489
|
-
exports.WebrtcCoreErrorType = void 0;
|
|
490
|
-
(function (WebrtcCoreErrorType) {
|
|
491
|
-
WebrtcCoreErrorType["DEVICE_PERMISSION_DENIED"] = "DEVICE_PERMISSION_DENIED";
|
|
492
|
-
WebrtcCoreErrorType["CREATE_STREAM_FAILED"] = "CREATE_STREAM_FAILED";
|
|
493
|
-
WebrtcCoreErrorType["ADD_EFFECT_FAILED"] = "ADD_EFFECT_FAILED";
|
|
494
|
-
})(exports.WebrtcCoreErrorType || (exports.WebrtcCoreErrorType = {}));
|
|
495
|
-
/**
|
|
496
|
-
* Represents a WebRTC core error, which contains error type and error message.
|
|
497
|
-
*/
|
|
498
|
-
class WebrtcCoreError {
|
|
499
|
-
/**
|
|
500
|
-
* Creates new error.
|
|
501
|
-
*
|
|
502
|
-
* @param type - Error type.
|
|
503
|
-
* @param message - Error message.
|
|
504
|
-
*/
|
|
505
|
-
constructor(type, message = '') {
|
|
506
|
-
this.type = type;
|
|
507
|
-
this.message = message;
|
|
508
|
-
}
|
|
489
|
+
exports.WebrtcCoreErrorType = void 0;
|
|
490
|
+
(function (WebrtcCoreErrorType) {
|
|
491
|
+
WebrtcCoreErrorType["DEVICE_PERMISSION_DENIED"] = "DEVICE_PERMISSION_DENIED";
|
|
492
|
+
WebrtcCoreErrorType["CREATE_STREAM_FAILED"] = "CREATE_STREAM_FAILED";
|
|
493
|
+
WebrtcCoreErrorType["ADD_EFFECT_FAILED"] = "ADD_EFFECT_FAILED";
|
|
494
|
+
})(exports.WebrtcCoreErrorType || (exports.WebrtcCoreErrorType = {}));
|
|
495
|
+
/**
|
|
496
|
+
* Represents a WebRTC core error, which contains error type and error message.
|
|
497
|
+
*/
|
|
498
|
+
class WebrtcCoreError {
|
|
499
|
+
/**
|
|
500
|
+
* Creates new error.
|
|
501
|
+
*
|
|
502
|
+
* @param type - Error type.
|
|
503
|
+
* @param message - Error message.
|
|
504
|
+
*/
|
|
505
|
+
constructor(type, message = '') {
|
|
506
|
+
this.type = type;
|
|
507
|
+
this.message = message;
|
|
508
|
+
}
|
|
509
509
|
}
|
|
510
510
|
|
|
511
|
-
/**
|
|
512
|
-
* Creates a camera stream. Please note that the constraint params in second getUserMedia call would NOT take effect when:
|
|
513
|
-
*
|
|
514
|
-
* 1. Previous captured video stream from the same device is not stopped.
|
|
515
|
-
* 2. Previous createCameraStream() call for the same device is in progress.
|
|
516
|
-
*
|
|
517
|
-
* @param constructor - Constructor for the local camera stream.
|
|
518
|
-
* @param constraints - Video device constraints.
|
|
519
|
-
* @returns A LocalCameraStream object or an error.
|
|
520
|
-
*/
|
|
521
|
-
function createCameraStream(constructor, constraints) {
|
|
522
|
-
return __awaiter$2(this, void 0, void 0, function* () {
|
|
523
|
-
let stream;
|
|
524
|
-
try {
|
|
525
|
-
stream = yield getUserMedia({ video: Object.assign({}, constraints) });
|
|
526
|
-
}
|
|
527
|
-
catch (error) {
|
|
528
|
-
throw new WebrtcCoreError(exports.WebrtcCoreErrorType.CREATE_STREAM_FAILED, `Failed to create camera stream: ${error}`);
|
|
529
|
-
}
|
|
530
|
-
return new constructor(stream);
|
|
531
|
-
});
|
|
532
|
-
}
|
|
533
|
-
/**
|
|
534
|
-
* Creates a LocalMicrophoneStream with the given constraints.
|
|
535
|
-
*
|
|
536
|
-
* @param constructor - Constructor for the local microphone stream.
|
|
537
|
-
* @param constraints - Audio device constraints.
|
|
538
|
-
* @returns A LocalMicrophoneStream object or an error.
|
|
539
|
-
*/
|
|
540
|
-
function createMicrophoneStream(constructor, constraints) {
|
|
541
|
-
return __awaiter$2(this, void 0, void 0, function* () {
|
|
542
|
-
let stream;
|
|
543
|
-
try {
|
|
544
|
-
stream = yield getUserMedia({ audio: Object.assign({}, constraints) });
|
|
545
|
-
}
|
|
546
|
-
catch (error) {
|
|
547
|
-
throw new WebrtcCoreError(exports.WebrtcCoreErrorType.CREATE_STREAM_FAILED, `Failed to create microphone stream: ${error}`);
|
|
548
|
-
}
|
|
549
|
-
return new constructor(stream);
|
|
550
|
-
});
|
|
551
|
-
}
|
|
552
|
-
/**
|
|
553
|
-
* Creates a LocalDisplayStream with the given parameters.
|
|
554
|
-
*
|
|
555
|
-
* @param constructor - Constructor for the local display stream.
|
|
556
|
-
* @param videoContentHint - An optional parameter to give a hint for the content of the stream.
|
|
557
|
-
* @returns A Promise that resolves to a LocalDisplayStream or an error.
|
|
558
|
-
*/
|
|
559
|
-
function createDisplayStream(constructor, videoContentHint) {
|
|
560
|
-
return __awaiter$2(this, void 0, void 0, function* () {
|
|
561
|
-
let stream;
|
|
562
|
-
try {
|
|
563
|
-
stream = yield getDisplayMedia({ video: true });
|
|
564
|
-
}
|
|
565
|
-
catch (error) {
|
|
566
|
-
throw new WebrtcCoreError(exports.WebrtcCoreErrorType.CREATE_STREAM_FAILED, `Failed to create display stream: ${error}`);
|
|
567
|
-
}
|
|
568
|
-
const localDisplayStream = new constructor(stream);
|
|
569
|
-
if (videoContentHint) {
|
|
570
|
-
localDisplayStream.contentHint = videoContentHint;
|
|
571
|
-
}
|
|
572
|
-
return localDisplayStream;
|
|
573
|
-
});
|
|
574
|
-
}
|
|
575
|
-
/**
|
|
576
|
-
* Creates a LocalDisplayStream and a LocalSystemAudioStream with the given parameters.
|
|
577
|
-
*
|
|
578
|
-
* @param displayStreamConstructor - Constructor for the local display stream.
|
|
579
|
-
* @param systemAudioStreamConstructor - Constructor for the local system audio stream.
|
|
580
|
-
* @param videoContentHint - An optional parameter to give a hint for the content of the stream.
|
|
581
|
-
* @returns A Promise that resolves to a LocalDisplayStream and a LocalSystemAudioStream or an
|
|
582
|
-
* error. If no system audio is available, the LocalSystemAudioStream will be resolved as null
|
|
583
|
-
* instead.
|
|
584
|
-
*/
|
|
585
|
-
function createDisplayStreamWithAudio(displayStreamConstructor, systemAudioStreamConstructor, videoContentHint) {
|
|
586
|
-
return __awaiter$2(this, void 0, void 0, function* () {
|
|
587
|
-
let stream;
|
|
588
|
-
try {
|
|
589
|
-
stream = yield getDisplayMedia({ video: true, audio: true });
|
|
590
|
-
}
|
|
591
|
-
catch (error) {
|
|
592
|
-
throw new WebrtcCoreError(exports.WebrtcCoreErrorType.CREATE_STREAM_FAILED, `Failed to create display and system audio streams: ${error}`);
|
|
593
|
-
}
|
|
594
|
-
// eslint-disable-next-line new-cap
|
|
595
|
-
const localDisplayStream = new displayStreamConstructor(new MediaStream(stream.getVideoTracks()));
|
|
596
|
-
if (videoContentHint) {
|
|
597
|
-
localDisplayStream.contentHint = videoContentHint;
|
|
598
|
-
}
|
|
599
|
-
let localSystemAudioStream = null;
|
|
600
|
-
if (stream.getAudioTracks().length > 0) {
|
|
601
|
-
// eslint-disable-next-line new-cap
|
|
602
|
-
localSystemAudioStream = new systemAudioStreamConstructor(new MediaStream(stream.getAudioTracks()));
|
|
603
|
-
}
|
|
604
|
-
return [localDisplayStream, localSystemAudioStream];
|
|
605
|
-
});
|
|
606
|
-
}
|
|
607
|
-
/**
|
|
608
|
-
* Enumerates the media input and output devices available.
|
|
609
|
-
*
|
|
610
|
-
* @param deviceKind - Optional filter to return a specific device kind.
|
|
611
|
-
* @returns List of media devices in an array of MediaDeviceInfo objects.
|
|
612
|
-
*/
|
|
613
|
-
function getDevices(deviceKind) {
|
|
614
|
-
return __awaiter$2(this, void 0, void 0, function* () {
|
|
615
|
-
let devices;
|
|
616
|
-
try {
|
|
617
|
-
devices = yield ensureDevicePermissions([DeviceKind$1.AudioInput, DeviceKind$1.VideoInput], enumerateDevices);
|
|
618
|
-
}
|
|
619
|
-
catch (error) {
|
|
620
|
-
throw new WebrtcCoreError(exports.WebrtcCoreErrorType.DEVICE_PERMISSION_DENIED, 'Failed to ensure device permissions');
|
|
621
|
-
}
|
|
622
|
-
return devices.filter((v) => (deviceKind ? v.kind === deviceKind : true));
|
|
623
|
-
});
|
|
624
|
-
}
|
|
625
|
-
/**
|
|
626
|
-
* Helper function to get a list of microphone devices.
|
|
627
|
-
*
|
|
628
|
-
* @returns List of microphone devices in an array of MediaDeviceInfo objects.
|
|
629
|
-
*/
|
|
630
|
-
function getAudioInputDevices() {
|
|
631
|
-
return __awaiter$2(this, void 0, void 0, function* () {
|
|
632
|
-
return getDevices(DeviceKind$1.AudioInput);
|
|
633
|
-
});
|
|
634
|
-
}
|
|
635
|
-
/**
|
|
636
|
-
* Helper function to get a list of speaker devices.
|
|
637
|
-
*
|
|
638
|
-
* @returns List of speaker devices in an array of MediaDeviceInfo objects.
|
|
639
|
-
*/
|
|
640
|
-
function getAudioOutputDevices() {
|
|
641
|
-
return __awaiter$2(this, void 0, void 0, function* () {
|
|
642
|
-
return getDevices(DeviceKind$1.AudioOutput);
|
|
643
|
-
});
|
|
644
|
-
}
|
|
645
|
-
/**
|
|
646
|
-
* Helper function to get a list of camera devices.
|
|
647
|
-
*
|
|
648
|
-
* @returns List of camera devices in an array of MediaDeviceInfo objects.
|
|
649
|
-
*/
|
|
650
|
-
function getVideoInputDevices() {
|
|
651
|
-
return __awaiter$2(this, void 0, void 0, function* () {
|
|
652
|
-
return getDevices(DeviceKind$1.VideoInput);
|
|
653
|
-
});
|
|
654
|
-
}
|
|
655
|
-
/**
|
|
656
|
-
* Export the setOnDeviceChangeHandler method directly from the core lib.
|
|
657
|
-
*/
|
|
511
|
+
/**
|
|
512
|
+
* Creates a camera stream. Please note that the constraint params in second getUserMedia call would NOT take effect when:
|
|
513
|
+
*
|
|
514
|
+
* 1. Previous captured video stream from the same device is not stopped.
|
|
515
|
+
* 2. Previous createCameraStream() call for the same device is in progress.
|
|
516
|
+
*
|
|
517
|
+
* @param constructor - Constructor for the local camera stream.
|
|
518
|
+
* @param constraints - Video device constraints.
|
|
519
|
+
* @returns A LocalCameraStream object or an error.
|
|
520
|
+
*/
|
|
521
|
+
function createCameraStream(constructor, constraints) {
|
|
522
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
523
|
+
let stream;
|
|
524
|
+
try {
|
|
525
|
+
stream = yield getUserMedia({ video: Object.assign({}, constraints) });
|
|
526
|
+
}
|
|
527
|
+
catch (error) {
|
|
528
|
+
throw new WebrtcCoreError(exports.WebrtcCoreErrorType.CREATE_STREAM_FAILED, `Failed to create camera stream: ${error}`);
|
|
529
|
+
}
|
|
530
|
+
return new constructor(stream);
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
/**
|
|
534
|
+
* Creates a LocalMicrophoneStream with the given constraints.
|
|
535
|
+
*
|
|
536
|
+
* @param constructor - Constructor for the local microphone stream.
|
|
537
|
+
* @param constraints - Audio device constraints.
|
|
538
|
+
* @returns A LocalMicrophoneStream object or an error.
|
|
539
|
+
*/
|
|
540
|
+
function createMicrophoneStream(constructor, constraints) {
|
|
541
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
542
|
+
let stream;
|
|
543
|
+
try {
|
|
544
|
+
stream = yield getUserMedia({ audio: Object.assign({}, constraints) });
|
|
545
|
+
}
|
|
546
|
+
catch (error) {
|
|
547
|
+
throw new WebrtcCoreError(exports.WebrtcCoreErrorType.CREATE_STREAM_FAILED, `Failed to create microphone stream: ${error}`);
|
|
548
|
+
}
|
|
549
|
+
return new constructor(stream);
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Creates a LocalDisplayStream with the given parameters.
|
|
554
|
+
*
|
|
555
|
+
* @param constructor - Constructor for the local display stream.
|
|
556
|
+
* @param videoContentHint - An optional parameter to give a hint for the content of the stream.
|
|
557
|
+
* @returns A Promise that resolves to a LocalDisplayStream or an error.
|
|
558
|
+
*/
|
|
559
|
+
function createDisplayStream(constructor, videoContentHint) {
|
|
560
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
561
|
+
let stream;
|
|
562
|
+
try {
|
|
563
|
+
stream = yield getDisplayMedia({ video: true });
|
|
564
|
+
}
|
|
565
|
+
catch (error) {
|
|
566
|
+
throw new WebrtcCoreError(exports.WebrtcCoreErrorType.CREATE_STREAM_FAILED, `Failed to create display stream: ${error}`);
|
|
567
|
+
}
|
|
568
|
+
const localDisplayStream = new constructor(stream);
|
|
569
|
+
if (videoContentHint) {
|
|
570
|
+
localDisplayStream.contentHint = videoContentHint;
|
|
571
|
+
}
|
|
572
|
+
return localDisplayStream;
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Creates a LocalDisplayStream and a LocalSystemAudioStream with the given parameters.
|
|
577
|
+
*
|
|
578
|
+
* @param displayStreamConstructor - Constructor for the local display stream.
|
|
579
|
+
* @param systemAudioStreamConstructor - Constructor for the local system audio stream.
|
|
580
|
+
* @param videoContentHint - An optional parameter to give a hint for the content of the stream.
|
|
581
|
+
* @returns A Promise that resolves to a LocalDisplayStream and a LocalSystemAudioStream or an
|
|
582
|
+
* error. If no system audio is available, the LocalSystemAudioStream will be resolved as null
|
|
583
|
+
* instead.
|
|
584
|
+
*/
|
|
585
|
+
function createDisplayStreamWithAudio(displayStreamConstructor, systemAudioStreamConstructor, videoContentHint) {
|
|
586
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
587
|
+
let stream;
|
|
588
|
+
try {
|
|
589
|
+
stream = yield getDisplayMedia({ video: true, audio: true });
|
|
590
|
+
}
|
|
591
|
+
catch (error) {
|
|
592
|
+
throw new WebrtcCoreError(exports.WebrtcCoreErrorType.CREATE_STREAM_FAILED, `Failed to create display and system audio streams: ${error}`);
|
|
593
|
+
}
|
|
594
|
+
// eslint-disable-next-line new-cap
|
|
595
|
+
const localDisplayStream = new displayStreamConstructor(new MediaStream(stream.getVideoTracks()));
|
|
596
|
+
if (videoContentHint) {
|
|
597
|
+
localDisplayStream.contentHint = videoContentHint;
|
|
598
|
+
}
|
|
599
|
+
let localSystemAudioStream = null;
|
|
600
|
+
if (stream.getAudioTracks().length > 0) {
|
|
601
|
+
// eslint-disable-next-line new-cap
|
|
602
|
+
localSystemAudioStream = new systemAudioStreamConstructor(new MediaStream(stream.getAudioTracks()));
|
|
603
|
+
}
|
|
604
|
+
return [localDisplayStream, localSystemAudioStream];
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* Enumerates the media input and output devices available.
|
|
609
|
+
*
|
|
610
|
+
* @param deviceKind - Optional filter to return a specific device kind.
|
|
611
|
+
* @returns List of media devices in an array of MediaDeviceInfo objects.
|
|
612
|
+
*/
|
|
613
|
+
function getDevices(deviceKind) {
|
|
614
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
615
|
+
let devices;
|
|
616
|
+
try {
|
|
617
|
+
devices = yield ensureDevicePermissions([DeviceKind$1.AudioInput, DeviceKind$1.VideoInput], enumerateDevices);
|
|
618
|
+
}
|
|
619
|
+
catch (error) {
|
|
620
|
+
throw new WebrtcCoreError(exports.WebrtcCoreErrorType.DEVICE_PERMISSION_DENIED, 'Failed to ensure device permissions');
|
|
621
|
+
}
|
|
622
|
+
return devices.filter((v) => (deviceKind ? v.kind === deviceKind : true));
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* Helper function to get a list of microphone devices.
|
|
627
|
+
*
|
|
628
|
+
* @returns List of microphone devices in an array of MediaDeviceInfo objects.
|
|
629
|
+
*/
|
|
630
|
+
function getAudioInputDevices() {
|
|
631
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
632
|
+
return getDevices(DeviceKind$1.AudioInput);
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* Helper function to get a list of speaker devices.
|
|
637
|
+
*
|
|
638
|
+
* @returns List of speaker devices in an array of MediaDeviceInfo objects.
|
|
639
|
+
*/
|
|
640
|
+
function getAudioOutputDevices() {
|
|
641
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
642
|
+
return getDevices(DeviceKind$1.AudioOutput);
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Helper function to get a list of camera devices.
|
|
647
|
+
*
|
|
648
|
+
* @returns List of camera devices in an array of MediaDeviceInfo objects.
|
|
649
|
+
*/
|
|
650
|
+
function getVideoInputDevices() {
|
|
651
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
652
|
+
return getDevices(DeviceKind$1.VideoInput);
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
/**
|
|
656
|
+
* Export the setOnDeviceChangeHandler method directly from the core lib.
|
|
657
|
+
*/
|
|
658
658
|
const { setOnDeviceChangeHandler } = media;
|
|
659
659
|
|
|
660
660
|
var events$1$1 = {exports: {}};
|
|
@@ -1167,627 +1167,627 @@ function AddEvents(Base) {
|
|
|
1167
1167
|
};
|
|
1168
1168
|
}
|
|
1169
1169
|
|
|
1170
|
-
var _a$2$1;
|
|
1171
|
-
exports.StreamEventNames = void 0;
|
|
1172
|
-
(function (StreamEventNames) {
|
|
1173
|
-
StreamEventNames["Ended"] = "stream-ended";
|
|
1174
|
-
})(exports.StreamEventNames || (exports.StreamEventNames = {}));
|
|
1175
|
-
/**
|
|
1176
|
-
* Base stream class.
|
|
1177
|
-
*/
|
|
1178
|
-
class _Stream {
|
|
1179
|
-
/**
|
|
1180
|
-
* Create a Stream from the given values.
|
|
1181
|
-
*
|
|
1182
|
-
* @param stream - The initial output MediaStream for this Stream.
|
|
1183
|
-
*/
|
|
1184
|
-
constructor(stream) {
|
|
1185
|
-
// TODO: these should be protected, but we need the helper type in ts-events
|
|
1186
|
-
// to hide the 'emit' method from TypedEvent.
|
|
1187
|
-
this[_a$2$1] = new TypedEvent$1();
|
|
1188
|
-
this.outputStream = stream;
|
|
1189
|
-
this.handleTrackEnded = this.handleTrackEnded.bind(this);
|
|
1190
|
-
this.addTrackHandlersForStreamEvents(this.outputTrack);
|
|
1191
|
-
}
|
|
1192
|
-
/**
|
|
1193
|
-
* Handler which is called when a track's ended event fires.
|
|
1194
|
-
*/
|
|
1195
|
-
handleTrackEnded() {
|
|
1196
|
-
this[exports.StreamEventNames.Ended].emit();
|
|
1197
|
-
}
|
|
1198
|
-
/**
|
|
1199
|
-
* Helper function to add event handlers to a MediaStreamTrack. Unlike the virtual
|
|
1200
|
-
* {@link addTrackHandlers} function, which can be overridden, this function is internal to this
|
|
1201
|
-
* class and will only add the event handlers relevant to this class. It prevents, for example,
|
|
1202
|
-
* accidentally adding the same event handlers multiple times, which could happen if the virtual
|
|
1203
|
-
* `addTrackHandlers` method was called from a subclass's constructor.
|
|
1204
|
-
*
|
|
1205
|
-
* @param track - The MediaStreamTrack.
|
|
1206
|
-
*/
|
|
1207
|
-
addTrackHandlersForStreamEvents(track) {
|
|
1208
|
-
track.addEventListener('ended', this.handleTrackEnded);
|
|
1209
|
-
}
|
|
1210
|
-
/**
|
|
1211
|
-
* Add event handlers to a MediaStreamTrack.
|
|
1212
|
-
*
|
|
1213
|
-
* @param track - The MediaStreamTrack.
|
|
1214
|
-
*/
|
|
1215
|
-
addTrackHandlers(track) {
|
|
1216
|
-
this.addTrackHandlersForStreamEvents(track);
|
|
1217
|
-
}
|
|
1218
|
-
/**
|
|
1219
|
-
* Remove event handlers from a MediaStreamTrack.
|
|
1220
|
-
*
|
|
1221
|
-
* @param track - The MediaStreamTrack.
|
|
1222
|
-
*/
|
|
1223
|
-
removeTrackHandlers(track) {
|
|
1224
|
-
track.removeEventListener('ended', this.handleTrackEnded);
|
|
1225
|
-
}
|
|
1226
|
-
/**
|
|
1227
|
-
* Get the ID of the output stream.
|
|
1228
|
-
*
|
|
1229
|
-
* @returns The ID of the output stream.
|
|
1230
|
-
*/
|
|
1231
|
-
get id() {
|
|
1232
|
-
return this.outputStream.id;
|
|
1233
|
-
}
|
|
1234
|
-
/**
|
|
1235
|
-
* Get the track of the output stream.
|
|
1236
|
-
*
|
|
1237
|
-
* @returns The output track.
|
|
1238
|
-
*/
|
|
1239
|
-
get outputTrack() {
|
|
1240
|
-
return this.outputStream.getTracks()[0];
|
|
1241
|
-
}
|
|
1242
|
-
}
|
|
1243
|
-
_a$2$1 = exports.StreamEventNames.Ended;
|
|
1170
|
+
var _a$2$1;
|
|
1171
|
+
exports.StreamEventNames = void 0;
|
|
1172
|
+
(function (StreamEventNames) {
|
|
1173
|
+
StreamEventNames["Ended"] = "stream-ended";
|
|
1174
|
+
})(exports.StreamEventNames || (exports.StreamEventNames = {}));
|
|
1175
|
+
/**
|
|
1176
|
+
* Base stream class.
|
|
1177
|
+
*/
|
|
1178
|
+
class _Stream {
|
|
1179
|
+
/**
|
|
1180
|
+
* Create a Stream from the given values.
|
|
1181
|
+
*
|
|
1182
|
+
* @param stream - The initial output MediaStream for this Stream.
|
|
1183
|
+
*/
|
|
1184
|
+
constructor(stream) {
|
|
1185
|
+
// TODO: these should be protected, but we need the helper type in ts-events
|
|
1186
|
+
// to hide the 'emit' method from TypedEvent.
|
|
1187
|
+
this[_a$2$1] = new TypedEvent$1();
|
|
1188
|
+
this.outputStream = stream;
|
|
1189
|
+
this.handleTrackEnded = this.handleTrackEnded.bind(this);
|
|
1190
|
+
this.addTrackHandlersForStreamEvents(this.outputTrack);
|
|
1191
|
+
}
|
|
1192
|
+
/**
|
|
1193
|
+
* Handler which is called when a track's ended event fires.
|
|
1194
|
+
*/
|
|
1195
|
+
handleTrackEnded() {
|
|
1196
|
+
this[exports.StreamEventNames.Ended].emit();
|
|
1197
|
+
}
|
|
1198
|
+
/**
|
|
1199
|
+
* Helper function to add event handlers to a MediaStreamTrack. Unlike the virtual
|
|
1200
|
+
* {@link addTrackHandlers} function, which can be overridden, this function is internal to this
|
|
1201
|
+
* class and will only add the event handlers relevant to this class. It prevents, for example,
|
|
1202
|
+
* accidentally adding the same event handlers multiple times, which could happen if the virtual
|
|
1203
|
+
* `addTrackHandlers` method was called from a subclass's constructor.
|
|
1204
|
+
*
|
|
1205
|
+
* @param track - The MediaStreamTrack.
|
|
1206
|
+
*/
|
|
1207
|
+
addTrackHandlersForStreamEvents(track) {
|
|
1208
|
+
track.addEventListener('ended', this.handleTrackEnded);
|
|
1209
|
+
}
|
|
1210
|
+
/**
|
|
1211
|
+
* Add event handlers to a MediaStreamTrack.
|
|
1212
|
+
*
|
|
1213
|
+
* @param track - The MediaStreamTrack.
|
|
1214
|
+
*/
|
|
1215
|
+
addTrackHandlers(track) {
|
|
1216
|
+
this.addTrackHandlersForStreamEvents(track);
|
|
1217
|
+
}
|
|
1218
|
+
/**
|
|
1219
|
+
* Remove event handlers from a MediaStreamTrack.
|
|
1220
|
+
*
|
|
1221
|
+
* @param track - The MediaStreamTrack.
|
|
1222
|
+
*/
|
|
1223
|
+
removeTrackHandlers(track) {
|
|
1224
|
+
track.removeEventListener('ended', this.handleTrackEnded);
|
|
1225
|
+
}
|
|
1226
|
+
/**
|
|
1227
|
+
* Get the ID of the output stream.
|
|
1228
|
+
*
|
|
1229
|
+
* @returns The ID of the output stream.
|
|
1230
|
+
*/
|
|
1231
|
+
get id() {
|
|
1232
|
+
return this.outputStream.id;
|
|
1233
|
+
}
|
|
1234
|
+
/**
|
|
1235
|
+
* Get the track of the output stream.
|
|
1236
|
+
*
|
|
1237
|
+
* @returns The output track.
|
|
1238
|
+
*/
|
|
1239
|
+
get outputTrack() {
|
|
1240
|
+
return this.outputStream.getTracks()[0];
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
_a$2$1 = exports.StreamEventNames.Ended;
|
|
1244
1244
|
const Stream = AddEvents(_Stream);
|
|
1245
1245
|
|
|
1246
|
-
var _a$1$1, _b, _c, _d, _e;
|
|
1247
|
-
exports.LocalStreamEventNames = void 0;
|
|
1248
|
-
(function (LocalStreamEventNames) {
|
|
1249
|
-
LocalStreamEventNames["UserMuteStateChange"] = "user-mute-state-change";
|
|
1250
|
-
LocalStreamEventNames["SystemMuteStateChange"] = "system-mute-state-change";
|
|
1251
|
-
LocalStreamEventNames["ConstraintsChange"] = "constraints-change";
|
|
1252
|
-
LocalStreamEventNames["OutputTrackChange"] = "output-track-change";
|
|
1253
|
-
LocalStreamEventNames["EffectAdded"] = "effect-added";
|
|
1254
|
-
})(exports.LocalStreamEventNames || (exports.LocalStreamEventNames = {}));
|
|
1255
|
-
/**
|
|
1256
|
-
* A stream which originates on the local device.
|
|
1257
|
-
*/
|
|
1258
|
-
class _LocalStream extends Stream {
|
|
1259
|
-
/**
|
|
1260
|
-
* Create a LocalStream from the given values.
|
|
1261
|
-
*
|
|
1262
|
-
* @param stream - The initial output MediaStream for this Stream.
|
|
1263
|
-
*/
|
|
1264
|
-
constructor(stream) {
|
|
1265
|
-
super(stream);
|
|
1266
|
-
this[_a$1$1] = new TypedEvent$1();
|
|
1267
|
-
this[_b] = new TypedEvent$1();
|
|
1268
|
-
this[_c] = new TypedEvent$1();
|
|
1269
|
-
this[_d] = new TypedEvent$1();
|
|
1270
|
-
this[_e] = new TypedEvent$1();
|
|
1271
|
-
this.effects = [];
|
|
1272
|
-
this.loadingEffects = new Map();
|
|
1273
|
-
this.inputStream = stream;
|
|
1274
|
-
this.handleTrackMutedBySystem = this.handleTrackMutedBySystem.bind(this);
|
|
1275
|
-
this.handleTrackUnmutedBySystem = this.handleTrackUnmutedBySystem.bind(this);
|
|
1276
|
-
this.addTrackHandlersForLocalStreamEvents(this.inputTrack);
|
|
1277
|
-
}
|
|
1278
|
-
/**
|
|
1279
|
-
* Handler which is called when a track's mute event fires.
|
|
1280
|
-
*/
|
|
1281
|
-
handleTrackMutedBySystem() {
|
|
1282
|
-
this[exports.LocalStreamEventNames.SystemMuteStateChange].emit(true);
|
|
1283
|
-
}
|
|
1284
|
-
/**
|
|
1285
|
-
* Handler which is called when a track's unmute event fires.
|
|
1286
|
-
*/
|
|
1287
|
-
handleTrackUnmutedBySystem() {
|
|
1288
|
-
this[exports.LocalStreamEventNames.SystemMuteStateChange].emit(false);
|
|
1289
|
-
}
|
|
1290
|
-
/**
|
|
1291
|
-
* Helper function to add event handlers to a MediaStreamTrack. See
|
|
1292
|
-
* {@link Stream.addTrackHandlersForStreamEvents} for why this is useful.
|
|
1293
|
-
*
|
|
1294
|
-
* @param track - The MediaStreamTrack.
|
|
1295
|
-
*/
|
|
1296
|
-
addTrackHandlersForLocalStreamEvents(track) {
|
|
1297
|
-
track.addEventListener('mute', this.handleTrackMutedBySystem);
|
|
1298
|
-
track.addEventListener('unmute', this.handleTrackUnmutedBySystem);
|
|
1299
|
-
}
|
|
1300
|
-
/**
|
|
1301
|
-
* @inheritdoc
|
|
1302
|
-
*/
|
|
1303
|
-
addTrackHandlers(track) {
|
|
1304
|
-
super.addTrackHandlers(track);
|
|
1305
|
-
this.addTrackHandlersForLocalStreamEvents(track);
|
|
1306
|
-
}
|
|
1307
|
-
/**
|
|
1308
|
-
* @inheritdoc
|
|
1309
|
-
*/
|
|
1310
|
-
removeTrackHandlers(track) {
|
|
1311
|
-
super.removeTrackHandlers(track);
|
|
1312
|
-
track.removeEventListener('mute', this.handleTrackMutedBySystem);
|
|
1313
|
-
track.removeEventListener('unmute', this.handleTrackUnmutedBySystem);
|
|
1314
|
-
}
|
|
1315
|
-
/**
|
|
1316
|
-
* Get the track within the MediaStream with which this LocalStream was created.
|
|
1317
|
-
*
|
|
1318
|
-
* @returns The track within the MediaStream with which this LocalStream
|
|
1319
|
-
* was created.
|
|
1320
|
-
*/
|
|
1321
|
-
get inputTrack() {
|
|
1322
|
-
return this.inputStream.getTracks()[0];
|
|
1323
|
-
}
|
|
1324
|
-
/**
|
|
1325
|
-
* Check whether or not this stream is muted. This considers both whether the stream has been
|
|
1326
|
-
* muted by the user (see {@link userMuted}) and whether the stream has been muted by the system
|
|
1327
|
-
* (see {@link systemMuted}).
|
|
1328
|
-
*
|
|
1329
|
-
* @returns True if the stream is muted, false otherwise.
|
|
1330
|
-
*/
|
|
1331
|
-
get muted() {
|
|
1332
|
-
return this.userMuted || this.systemMuted;
|
|
1333
|
-
}
|
|
1334
|
-
/**
|
|
1335
|
-
* Check whether or not this stream has been muted by the user. This is equivalent to checking the
|
|
1336
|
-
* MediaStreamTrack "enabled" state.
|
|
1337
|
-
*
|
|
1338
|
-
* @returns True if the stream has been muted by the user, false otherwise.
|
|
1339
|
-
*/
|
|
1340
|
-
get userMuted() {
|
|
1341
|
-
return !this.inputTrack.enabled;
|
|
1342
|
-
}
|
|
1343
|
-
/**
|
|
1344
|
-
* Check whether or not this stream has been muted by the user. This is equivalent to checking the
|
|
1345
|
-
* MediaStreamTrack "muted" state.
|
|
1346
|
-
*
|
|
1347
|
-
* @returns True if the stream has been muted by the system, false otherwise.
|
|
1348
|
-
*/
|
|
1349
|
-
get systemMuted() {
|
|
1350
|
-
return this.inputTrack.muted;
|
|
1351
|
-
}
|
|
1352
|
-
/**
|
|
1353
|
-
* Set the user mute state of this stream.
|
|
1354
|
-
*
|
|
1355
|
-
* Note: This sets the user-toggled mute state, equivalent to changing the "enabled" state of the
|
|
1356
|
-
* track. It is separate from the system-toggled mute state.
|
|
1357
|
-
*
|
|
1358
|
-
* @param isMuted - True to mute, false to unmute.
|
|
1359
|
-
*/
|
|
1360
|
-
setUserMuted(isMuted) {
|
|
1361
|
-
if (this.inputTrack.enabled === isMuted) {
|
|
1362
|
-
this.inputTrack.enabled = !isMuted;
|
|
1363
|
-
this[exports.LocalStreamEventNames.UserMuteStateChange].emit(isMuted);
|
|
1364
|
-
}
|
|
1365
|
-
}
|
|
1366
|
-
/**
|
|
1367
|
-
* @inheritdoc
|
|
1368
|
-
*/
|
|
1369
|
-
getSettings() {
|
|
1370
|
-
return this.inputTrack.getSettings();
|
|
1371
|
-
}
|
|
1372
|
-
/**
|
|
1373
|
-
* Get the label of the input track on this stream.
|
|
1374
|
-
*
|
|
1375
|
-
* @returns The label of the track.
|
|
1376
|
-
*/
|
|
1377
|
-
get label() {
|
|
1378
|
-
return this.inputTrack.label;
|
|
1379
|
-
}
|
|
1380
|
-
/**
|
|
1381
|
-
* Get the readyState of the input track on this stream.
|
|
1382
|
-
*
|
|
1383
|
-
* @returns The readyState of the track.
|
|
1384
|
-
*/
|
|
1385
|
-
get readyState() {
|
|
1386
|
-
return this.inputTrack.readyState;
|
|
1387
|
-
}
|
|
1388
|
-
/**
|
|
1389
|
-
* Change the track of the output stream to a different track.
|
|
1390
|
-
*
|
|
1391
|
-
* Note: this method assumes and enforces that if both input and output streams have the same
|
|
1392
|
-
* track, then they must also be the same stream.
|
|
1393
|
-
*
|
|
1394
|
-
* @param newTrack - The track to be used in the output stream.
|
|
1395
|
-
*/
|
|
1396
|
-
changeOutputTrack(newTrack) {
|
|
1397
|
-
if (this.outputTrack.id !== newTrack.id) {
|
|
1398
|
-
// If the input track and the *old* output track are currently the same, then the streams must
|
|
1399
|
-
// be the same too. We want to apply the new track to the output stream without affecting the
|
|
1400
|
-
// input stream, so we separate them by setting the input stream to be its own stream.
|
|
1401
|
-
if (this.inputTrack.id === this.outputTrack.id) {
|
|
1402
|
-
this.inputStream = new MediaStream(this.inputStream);
|
|
1403
|
-
}
|
|
1404
|
-
this.outputStream.removeTrack(this.outputTrack);
|
|
1405
|
-
this.outputStream.addTrack(newTrack);
|
|
1406
|
-
// If the input track and the *new* output track are now the same, then we want the streams to
|
|
1407
|
-
// be the same too.
|
|
1408
|
-
if (this.inputTrack.id === this.outputTrack.id) {
|
|
1409
|
-
this.inputStream = this.outputStream;
|
|
1410
|
-
}
|
|
1411
|
-
this[exports.LocalStreamEventNames.OutputTrackChange].emit(newTrack);
|
|
1412
|
-
}
|
|
1413
|
-
}
|
|
1414
|
-
/**
|
|
1415
|
-
* @inheritdoc
|
|
1416
|
-
*/
|
|
1417
|
-
stop() {
|
|
1418
|
-
this.inputTrack.stop();
|
|
1419
|
-
this.outputTrack.stop();
|
|
1420
|
-
this.disposeEffects();
|
|
1421
|
-
// calling stop() will not automatically emit Ended, so we emit it here
|
|
1422
|
-
this[exports.StreamEventNames.Ended].emit();
|
|
1423
|
-
}
|
|
1424
|
-
/**
|
|
1425
|
-
* Adds an effect to a local stream.
|
|
1426
|
-
*
|
|
1427
|
-
* @param effect - The effect to add.
|
|
1428
|
-
*/
|
|
1429
|
-
addEffect(effect) {
|
|
1430
|
-
return __awaiter$2(this, void 0, void 0, function* () {
|
|
1431
|
-
// Check if the effect has already been added.
|
|
1432
|
-
if (this.effects.some((e) => e.id === effect.id)) {
|
|
1433
|
-
return;
|
|
1434
|
-
}
|
|
1435
|
-
// Load the effect. Because loading is asynchronous, keep track of the loading effects.
|
|
1436
|
-
this.loadingEffects.set(effect.kind, effect);
|
|
1437
|
-
yield effect.load(this.outputTrack);
|
|
1438
|
-
// After loading, check whether or not we still want to use this effect. If another effect of
|
|
1439
|
-
// the same kind was added while this effect was loading, we only want to use the latest effect,
|
|
1440
|
-
// so dispose this one. If the effects list was cleared while this effect was loading, also
|
|
1441
|
-
// dispose it.
|
|
1442
|
-
if (effect !== this.loadingEffects.get(effect.kind)) {
|
|
1443
|
-
yield effect.dispose();
|
|
1444
|
-
throw new WebrtcCoreError(exports.WebrtcCoreErrorType.ADD_EFFECT_FAILED, `Another effect with kind ${effect.kind} was added while effect ${effect.id} was loading, or the effects list was cleared.`);
|
|
1445
|
-
}
|
|
1446
|
-
this.loadingEffects.delete(effect.kind);
|
|
1447
|
-
/**
|
|
1448
|
-
* Handle when the effect's output track has been changed. This will update the input of the
|
|
1449
|
-
* next effect in the effects list of the output of the stream.
|
|
1450
|
-
*
|
|
1451
|
-
* @param track - The new output track of the effect.
|
|
1452
|
-
*/
|
|
1453
|
-
const handleEffectTrackUpdated = (track) => {
|
|
1454
|
-
var _f;
|
|
1455
|
-
const effectIndex = this.effects.findIndex((e) => e.id === effect.id);
|
|
1456
|
-
if (effectIndex === this.effects.length - 1) {
|
|
1457
|
-
this.changeOutputTrack(track);
|
|
1458
|
-
}
|
|
1459
|
-
else if (effectIndex >= 0) {
|
|
1460
|
-
(_f = this.effects[effectIndex + 1]) === null || _f === void 0 ? void 0 : _f.replaceInputTrack(track);
|
|
1461
|
-
}
|
|
1462
|
-
else {
|
|
1463
|
-
logger$3.error(`Effect with ID ${effect.id} not found in effects list.`);
|
|
1464
|
-
}
|
|
1465
|
-
};
|
|
1466
|
-
/**
|
|
1467
|
-
* Handle when the effect has been disposed. This will remove all event listeners from the
|
|
1468
|
-
* effect.
|
|
1469
|
-
*/
|
|
1470
|
-
const handleEffectDisposed = () => {
|
|
1471
|
-
effect.off('track-updated', handleEffectTrackUpdated);
|
|
1472
|
-
effect.off('disposed', handleEffectDisposed);
|
|
1473
|
-
};
|
|
1474
|
-
// TODO: using EffectEvent.TrackUpdated or EffectEvent.Disposed will cause the entire
|
|
1475
|
-
// web-media-effects lib to be rebuilt and inflates the size of the webrtc-core build, so
|
|
1476
|
-
// we use type assertion here as a temporary workaround.
|
|
1477
|
-
effect.on('track-updated', handleEffectTrackUpdated);
|
|
1478
|
-
effect.on('disposed', handleEffectDisposed);
|
|
1479
|
-
// Add the effect to the effects list. If an effect of the same kind has already been added,
|
|
1480
|
-
// dispose the existing effect and replace it with the new effect. If the existing effect was
|
|
1481
|
-
// enabled, also enable the new effect.
|
|
1482
|
-
const existingEffectIndex = this.effects.findIndex((e) => e.kind === effect.kind);
|
|
1483
|
-
if (existingEffectIndex >= 0) {
|
|
1484
|
-
const [existingEffect] = this.effects.splice(existingEffectIndex, 1, effect);
|
|
1485
|
-
if (existingEffect.isEnabled) {
|
|
1486
|
-
// If the existing effect is not the first effect in the effects list, then the input of the
|
|
1487
|
-
// new effect should be the output of the previous effect in the effects list. We know the
|
|
1488
|
-
// output track of the previous effect must exist because it must have been loaded (and all
|
|
1489
|
-
// loaded effects have an output track).
|
|
1490
|
-
const inputTrack = existingEffectIndex === 0
|
|
1491
|
-
? this.inputTrack
|
|
1492
|
-
: this.effects[existingEffectIndex - 1].getOutputTrack();
|
|
1493
|
-
yield effect.replaceInputTrack(inputTrack);
|
|
1494
|
-
// Enabling the new effect will trigger the track-updated event, which will handle the new
|
|
1495
|
-
// effect's updated output track.
|
|
1496
|
-
yield effect.enable();
|
|
1497
|
-
}
|
|
1498
|
-
yield existingEffect.dispose();
|
|
1499
|
-
}
|
|
1500
|
-
else {
|
|
1501
|
-
this.effects.push(effect);
|
|
1502
|
-
}
|
|
1503
|
-
// Emit an event with the effect so others can listen to the effect events.
|
|
1504
|
-
this[exports.LocalStreamEventNames.EffectAdded].emit(effect);
|
|
1505
|
-
});
|
|
1506
|
-
}
|
|
1507
|
-
/**
|
|
1508
|
-
* Get an effect from the effects list by ID.
|
|
1509
|
-
*
|
|
1510
|
-
* @param id - The id of the effect you want to get.
|
|
1511
|
-
* @returns The effect or undefined.
|
|
1512
|
-
*/
|
|
1513
|
-
getEffectById(id) {
|
|
1514
|
-
return this.effects.find((effect) => effect.id === id);
|
|
1515
|
-
}
|
|
1516
|
-
/**
|
|
1517
|
-
* Get an effect from the effects list by kind.
|
|
1518
|
-
*
|
|
1519
|
-
* @param kind - The kind of the effect you want to get.
|
|
1520
|
-
* @returns The effect or undefined.
|
|
1521
|
-
*/
|
|
1522
|
-
getEffectByKind(kind) {
|
|
1523
|
-
return this.effects.find((effect) => effect.kind === kind);
|
|
1524
|
-
}
|
|
1525
|
-
/**
|
|
1526
|
-
* Get all the effects from the effects list.
|
|
1527
|
-
*
|
|
1528
|
-
* @returns A list of effects.
|
|
1529
|
-
*/
|
|
1530
|
-
getEffects() {
|
|
1531
|
-
return this.effects;
|
|
1532
|
-
}
|
|
1533
|
-
/**
|
|
1534
|
-
* Method to serialize data about input, output streams
|
|
1535
|
-
* and also effects from LocalStream.
|
|
1536
|
-
*
|
|
1537
|
-
* @returns - A JSON-compatible object representation with data from LocalStream.
|
|
1538
|
-
*/
|
|
1539
|
-
toJSON() {
|
|
1540
|
-
return {
|
|
1541
|
-
muted: this.muted,
|
|
1542
|
-
label: this.label,
|
|
1543
|
-
readyState: this.readyState,
|
|
1544
|
-
inputStream: {
|
|
1545
|
-
active: this.inputStream.active,
|
|
1546
|
-
id: this.inputStream.id,
|
|
1547
|
-
enabled: this.inputTrack.enabled,
|
|
1548
|
-
muted: this.inputTrack.muted,
|
|
1549
|
-
},
|
|
1550
|
-
outputStream: {
|
|
1551
|
-
active: this.outputStream.active,
|
|
1552
|
-
id: this.outputStream.id,
|
|
1553
|
-
},
|
|
1554
|
-
effects: this.effects.map((effect) => {
|
|
1555
|
-
return {
|
|
1556
|
-
id: effect.id,
|
|
1557
|
-
kind: effect.kind,
|
|
1558
|
-
isEnabled: effect.isEnabled,
|
|
1559
|
-
};
|
|
1560
|
-
}),
|
|
1561
|
-
};
|
|
1562
|
-
}
|
|
1563
|
-
/**
|
|
1564
|
-
* Cleanup the local effects.
|
|
1565
|
-
*/
|
|
1566
|
-
disposeEffects() {
|
|
1567
|
-
return __awaiter$2(this, void 0, void 0, function* () {
|
|
1568
|
-
this.loadingEffects.clear();
|
|
1569
|
-
// Dispose of any effects currently in use
|
|
1570
|
-
if (this.effects.length > 0) {
|
|
1571
|
-
this.changeOutputTrack(this.inputTrack);
|
|
1572
|
-
yield Promise.all(this.effects.map((effect) => effect.dispose()));
|
|
1573
|
-
this.effects = [];
|
|
1574
|
-
}
|
|
1575
|
-
});
|
|
1576
|
-
}
|
|
1577
|
-
}
|
|
1578
|
-
_a$1$1 = exports.LocalStreamEventNames.UserMuteStateChange, _b = exports.LocalStreamEventNames.SystemMuteStateChange, _c = exports.LocalStreamEventNames.ConstraintsChange, _d = exports.LocalStreamEventNames.OutputTrackChange, _e = exports.LocalStreamEventNames.EffectAdded;
|
|
1246
|
+
var _a$1$1, _b, _c, _d, _e;
|
|
1247
|
+
exports.LocalStreamEventNames = void 0;
|
|
1248
|
+
(function (LocalStreamEventNames) {
|
|
1249
|
+
LocalStreamEventNames["UserMuteStateChange"] = "user-mute-state-change";
|
|
1250
|
+
LocalStreamEventNames["SystemMuteStateChange"] = "system-mute-state-change";
|
|
1251
|
+
LocalStreamEventNames["ConstraintsChange"] = "constraints-change";
|
|
1252
|
+
LocalStreamEventNames["OutputTrackChange"] = "output-track-change";
|
|
1253
|
+
LocalStreamEventNames["EffectAdded"] = "effect-added";
|
|
1254
|
+
})(exports.LocalStreamEventNames || (exports.LocalStreamEventNames = {}));
|
|
1255
|
+
/**
|
|
1256
|
+
* A stream which originates on the local device.
|
|
1257
|
+
*/
|
|
1258
|
+
class _LocalStream extends Stream {
|
|
1259
|
+
/**
|
|
1260
|
+
* Create a LocalStream from the given values.
|
|
1261
|
+
*
|
|
1262
|
+
* @param stream - The initial output MediaStream for this Stream.
|
|
1263
|
+
*/
|
|
1264
|
+
constructor(stream) {
|
|
1265
|
+
super(stream);
|
|
1266
|
+
this[_a$1$1] = new TypedEvent$1();
|
|
1267
|
+
this[_b] = new TypedEvent$1();
|
|
1268
|
+
this[_c] = new TypedEvent$1();
|
|
1269
|
+
this[_d] = new TypedEvent$1();
|
|
1270
|
+
this[_e] = new TypedEvent$1();
|
|
1271
|
+
this.effects = [];
|
|
1272
|
+
this.loadingEffects = new Map();
|
|
1273
|
+
this.inputStream = stream;
|
|
1274
|
+
this.handleTrackMutedBySystem = this.handleTrackMutedBySystem.bind(this);
|
|
1275
|
+
this.handleTrackUnmutedBySystem = this.handleTrackUnmutedBySystem.bind(this);
|
|
1276
|
+
this.addTrackHandlersForLocalStreamEvents(this.inputTrack);
|
|
1277
|
+
}
|
|
1278
|
+
/**
|
|
1279
|
+
* Handler which is called when a track's mute event fires.
|
|
1280
|
+
*/
|
|
1281
|
+
handleTrackMutedBySystem() {
|
|
1282
|
+
this[exports.LocalStreamEventNames.SystemMuteStateChange].emit(true);
|
|
1283
|
+
}
|
|
1284
|
+
/**
|
|
1285
|
+
* Handler which is called when a track's unmute event fires.
|
|
1286
|
+
*/
|
|
1287
|
+
handleTrackUnmutedBySystem() {
|
|
1288
|
+
this[exports.LocalStreamEventNames.SystemMuteStateChange].emit(false);
|
|
1289
|
+
}
|
|
1290
|
+
/**
|
|
1291
|
+
* Helper function to add event handlers to a MediaStreamTrack. See
|
|
1292
|
+
* {@link Stream.addTrackHandlersForStreamEvents} for why this is useful.
|
|
1293
|
+
*
|
|
1294
|
+
* @param track - The MediaStreamTrack.
|
|
1295
|
+
*/
|
|
1296
|
+
addTrackHandlersForLocalStreamEvents(track) {
|
|
1297
|
+
track.addEventListener('mute', this.handleTrackMutedBySystem);
|
|
1298
|
+
track.addEventListener('unmute', this.handleTrackUnmutedBySystem);
|
|
1299
|
+
}
|
|
1300
|
+
/**
|
|
1301
|
+
* @inheritdoc
|
|
1302
|
+
*/
|
|
1303
|
+
addTrackHandlers(track) {
|
|
1304
|
+
super.addTrackHandlers(track);
|
|
1305
|
+
this.addTrackHandlersForLocalStreamEvents(track);
|
|
1306
|
+
}
|
|
1307
|
+
/**
|
|
1308
|
+
* @inheritdoc
|
|
1309
|
+
*/
|
|
1310
|
+
removeTrackHandlers(track) {
|
|
1311
|
+
super.removeTrackHandlers(track);
|
|
1312
|
+
track.removeEventListener('mute', this.handleTrackMutedBySystem);
|
|
1313
|
+
track.removeEventListener('unmute', this.handleTrackUnmutedBySystem);
|
|
1314
|
+
}
|
|
1315
|
+
/**
|
|
1316
|
+
* Get the track within the MediaStream with which this LocalStream was created.
|
|
1317
|
+
*
|
|
1318
|
+
* @returns The track within the MediaStream with which this LocalStream
|
|
1319
|
+
* was created.
|
|
1320
|
+
*/
|
|
1321
|
+
get inputTrack() {
|
|
1322
|
+
return this.inputStream.getTracks()[0];
|
|
1323
|
+
}
|
|
1324
|
+
/**
|
|
1325
|
+
* Check whether or not this stream is muted. This considers both whether the stream has been
|
|
1326
|
+
* muted by the user (see {@link userMuted}) and whether the stream has been muted by the system
|
|
1327
|
+
* (see {@link systemMuted}).
|
|
1328
|
+
*
|
|
1329
|
+
* @returns True if the stream is muted, false otherwise.
|
|
1330
|
+
*/
|
|
1331
|
+
get muted() {
|
|
1332
|
+
return this.userMuted || this.systemMuted;
|
|
1333
|
+
}
|
|
1334
|
+
/**
|
|
1335
|
+
* Check whether or not this stream has been muted by the user. This is equivalent to checking the
|
|
1336
|
+
* MediaStreamTrack "enabled" state.
|
|
1337
|
+
*
|
|
1338
|
+
* @returns True if the stream has been muted by the user, false otherwise.
|
|
1339
|
+
*/
|
|
1340
|
+
get userMuted() {
|
|
1341
|
+
return !this.inputTrack.enabled;
|
|
1342
|
+
}
|
|
1343
|
+
/**
|
|
1344
|
+
* Check whether or not this stream has been muted by the user. This is equivalent to checking the
|
|
1345
|
+
* MediaStreamTrack "muted" state.
|
|
1346
|
+
*
|
|
1347
|
+
* @returns True if the stream has been muted by the system, false otherwise.
|
|
1348
|
+
*/
|
|
1349
|
+
get systemMuted() {
|
|
1350
|
+
return this.inputTrack.muted;
|
|
1351
|
+
}
|
|
1352
|
+
/**
|
|
1353
|
+
* Set the user mute state of this stream.
|
|
1354
|
+
*
|
|
1355
|
+
* Note: This sets the user-toggled mute state, equivalent to changing the "enabled" state of the
|
|
1356
|
+
* track. It is separate from the system-toggled mute state.
|
|
1357
|
+
*
|
|
1358
|
+
* @param isMuted - True to mute, false to unmute.
|
|
1359
|
+
*/
|
|
1360
|
+
setUserMuted(isMuted) {
|
|
1361
|
+
if (this.inputTrack.enabled === isMuted) {
|
|
1362
|
+
this.inputTrack.enabled = !isMuted;
|
|
1363
|
+
this[exports.LocalStreamEventNames.UserMuteStateChange].emit(isMuted);
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
/**
|
|
1367
|
+
* @inheritdoc
|
|
1368
|
+
*/
|
|
1369
|
+
getSettings() {
|
|
1370
|
+
return this.inputTrack.getSettings();
|
|
1371
|
+
}
|
|
1372
|
+
/**
|
|
1373
|
+
* Get the label of the input track on this stream.
|
|
1374
|
+
*
|
|
1375
|
+
* @returns The label of the track.
|
|
1376
|
+
*/
|
|
1377
|
+
get label() {
|
|
1378
|
+
return this.inputTrack.label;
|
|
1379
|
+
}
|
|
1380
|
+
/**
|
|
1381
|
+
* Get the readyState of the input track on this stream.
|
|
1382
|
+
*
|
|
1383
|
+
* @returns The readyState of the track.
|
|
1384
|
+
*/
|
|
1385
|
+
get readyState() {
|
|
1386
|
+
return this.inputTrack.readyState;
|
|
1387
|
+
}
|
|
1388
|
+
/**
|
|
1389
|
+
* Change the track of the output stream to a different track.
|
|
1390
|
+
*
|
|
1391
|
+
* Note: this method assumes and enforces that if both input and output streams have the same
|
|
1392
|
+
* track, then they must also be the same stream.
|
|
1393
|
+
*
|
|
1394
|
+
* @param newTrack - The track to be used in the output stream.
|
|
1395
|
+
*/
|
|
1396
|
+
changeOutputTrack(newTrack) {
|
|
1397
|
+
if (this.outputTrack.id !== newTrack.id) {
|
|
1398
|
+
// If the input track and the *old* output track are currently the same, then the streams must
|
|
1399
|
+
// be the same too. We want to apply the new track to the output stream without affecting the
|
|
1400
|
+
// input stream, so we separate them by setting the input stream to be its own stream.
|
|
1401
|
+
if (this.inputTrack.id === this.outputTrack.id) {
|
|
1402
|
+
this.inputStream = new MediaStream(this.inputStream);
|
|
1403
|
+
}
|
|
1404
|
+
this.outputStream.removeTrack(this.outputTrack);
|
|
1405
|
+
this.outputStream.addTrack(newTrack);
|
|
1406
|
+
// If the input track and the *new* output track are now the same, then we want the streams to
|
|
1407
|
+
// be the same too.
|
|
1408
|
+
if (this.inputTrack.id === this.outputTrack.id) {
|
|
1409
|
+
this.inputStream = this.outputStream;
|
|
1410
|
+
}
|
|
1411
|
+
this[exports.LocalStreamEventNames.OutputTrackChange].emit(newTrack);
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
/**
|
|
1415
|
+
* @inheritdoc
|
|
1416
|
+
*/
|
|
1417
|
+
stop() {
|
|
1418
|
+
this.inputTrack.stop();
|
|
1419
|
+
this.outputTrack.stop();
|
|
1420
|
+
this.disposeEffects();
|
|
1421
|
+
// calling stop() will not automatically emit Ended, so we emit it here
|
|
1422
|
+
this[exports.StreamEventNames.Ended].emit();
|
|
1423
|
+
}
|
|
1424
|
+
/**
|
|
1425
|
+
* Adds an effect to a local stream.
|
|
1426
|
+
*
|
|
1427
|
+
* @param effect - The effect to add.
|
|
1428
|
+
*/
|
|
1429
|
+
addEffect(effect) {
|
|
1430
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
1431
|
+
// Check if the effect has already been added.
|
|
1432
|
+
if (this.effects.some((e) => e.id === effect.id)) {
|
|
1433
|
+
return;
|
|
1434
|
+
}
|
|
1435
|
+
// Load the effect. Because loading is asynchronous, keep track of the loading effects.
|
|
1436
|
+
this.loadingEffects.set(effect.kind, effect);
|
|
1437
|
+
yield effect.load(this.outputTrack);
|
|
1438
|
+
// After loading, check whether or not we still want to use this effect. If another effect of
|
|
1439
|
+
// the same kind was added while this effect was loading, we only want to use the latest effect,
|
|
1440
|
+
// so dispose this one. If the effects list was cleared while this effect was loading, also
|
|
1441
|
+
// dispose it.
|
|
1442
|
+
if (effect !== this.loadingEffects.get(effect.kind)) {
|
|
1443
|
+
yield effect.dispose();
|
|
1444
|
+
throw new WebrtcCoreError(exports.WebrtcCoreErrorType.ADD_EFFECT_FAILED, `Another effect with kind ${effect.kind} was added while effect ${effect.id} was loading, or the effects list was cleared.`);
|
|
1445
|
+
}
|
|
1446
|
+
this.loadingEffects.delete(effect.kind);
|
|
1447
|
+
/**
|
|
1448
|
+
* Handle when the effect's output track has been changed. This will update the input of the
|
|
1449
|
+
* next effect in the effects list of the output of the stream.
|
|
1450
|
+
*
|
|
1451
|
+
* @param track - The new output track of the effect.
|
|
1452
|
+
*/
|
|
1453
|
+
const handleEffectTrackUpdated = (track) => {
|
|
1454
|
+
var _f;
|
|
1455
|
+
const effectIndex = this.effects.findIndex((e) => e.id === effect.id);
|
|
1456
|
+
if (effectIndex === this.effects.length - 1) {
|
|
1457
|
+
this.changeOutputTrack(track);
|
|
1458
|
+
}
|
|
1459
|
+
else if (effectIndex >= 0) {
|
|
1460
|
+
(_f = this.effects[effectIndex + 1]) === null || _f === void 0 ? void 0 : _f.replaceInputTrack(track);
|
|
1461
|
+
}
|
|
1462
|
+
else {
|
|
1463
|
+
logger$3.error(`Effect with ID ${effect.id} not found in effects list.`);
|
|
1464
|
+
}
|
|
1465
|
+
};
|
|
1466
|
+
/**
|
|
1467
|
+
* Handle when the effect has been disposed. This will remove all event listeners from the
|
|
1468
|
+
* effect.
|
|
1469
|
+
*/
|
|
1470
|
+
const handleEffectDisposed = () => {
|
|
1471
|
+
effect.off('track-updated', handleEffectTrackUpdated);
|
|
1472
|
+
effect.off('disposed', handleEffectDisposed);
|
|
1473
|
+
};
|
|
1474
|
+
// TODO: using EffectEvent.TrackUpdated or EffectEvent.Disposed will cause the entire
|
|
1475
|
+
// web-media-effects lib to be rebuilt and inflates the size of the webrtc-core build, so
|
|
1476
|
+
// we use type assertion here as a temporary workaround.
|
|
1477
|
+
effect.on('track-updated', handleEffectTrackUpdated);
|
|
1478
|
+
effect.on('disposed', handleEffectDisposed);
|
|
1479
|
+
// Add the effect to the effects list. If an effect of the same kind has already been added,
|
|
1480
|
+
// dispose the existing effect and replace it with the new effect. If the existing effect was
|
|
1481
|
+
// enabled, also enable the new effect.
|
|
1482
|
+
const existingEffectIndex = this.effects.findIndex((e) => e.kind === effect.kind);
|
|
1483
|
+
if (existingEffectIndex >= 0) {
|
|
1484
|
+
const [existingEffect] = this.effects.splice(existingEffectIndex, 1, effect);
|
|
1485
|
+
if (existingEffect.isEnabled) {
|
|
1486
|
+
// If the existing effect is not the first effect in the effects list, then the input of the
|
|
1487
|
+
// new effect should be the output of the previous effect in the effects list. We know the
|
|
1488
|
+
// output track of the previous effect must exist because it must have been loaded (and all
|
|
1489
|
+
// loaded effects have an output track).
|
|
1490
|
+
const inputTrack = existingEffectIndex === 0
|
|
1491
|
+
? this.inputTrack
|
|
1492
|
+
: this.effects[existingEffectIndex - 1].getOutputTrack();
|
|
1493
|
+
yield effect.replaceInputTrack(inputTrack);
|
|
1494
|
+
// Enabling the new effect will trigger the track-updated event, which will handle the new
|
|
1495
|
+
// effect's updated output track.
|
|
1496
|
+
yield effect.enable();
|
|
1497
|
+
}
|
|
1498
|
+
yield existingEffect.dispose();
|
|
1499
|
+
}
|
|
1500
|
+
else {
|
|
1501
|
+
this.effects.push(effect);
|
|
1502
|
+
}
|
|
1503
|
+
// Emit an event with the effect so others can listen to the effect events.
|
|
1504
|
+
this[exports.LocalStreamEventNames.EffectAdded].emit(effect);
|
|
1505
|
+
});
|
|
1506
|
+
}
|
|
1507
|
+
/**
|
|
1508
|
+
* Get an effect from the effects list by ID.
|
|
1509
|
+
*
|
|
1510
|
+
* @param id - The id of the effect you want to get.
|
|
1511
|
+
* @returns The effect or undefined.
|
|
1512
|
+
*/
|
|
1513
|
+
getEffectById(id) {
|
|
1514
|
+
return this.effects.find((effect) => effect.id === id);
|
|
1515
|
+
}
|
|
1516
|
+
/**
|
|
1517
|
+
* Get an effect from the effects list by kind.
|
|
1518
|
+
*
|
|
1519
|
+
* @param kind - The kind of the effect you want to get.
|
|
1520
|
+
* @returns The effect or undefined.
|
|
1521
|
+
*/
|
|
1522
|
+
getEffectByKind(kind) {
|
|
1523
|
+
return this.effects.find((effect) => effect.kind === kind);
|
|
1524
|
+
}
|
|
1525
|
+
/**
|
|
1526
|
+
* Get all the effects from the effects list.
|
|
1527
|
+
*
|
|
1528
|
+
* @returns A list of effects.
|
|
1529
|
+
*/
|
|
1530
|
+
getEffects() {
|
|
1531
|
+
return this.effects;
|
|
1532
|
+
}
|
|
1533
|
+
/**
|
|
1534
|
+
* Method to serialize data about input, output streams
|
|
1535
|
+
* and also effects from LocalStream.
|
|
1536
|
+
*
|
|
1537
|
+
* @returns - A JSON-compatible object representation with data from LocalStream.
|
|
1538
|
+
*/
|
|
1539
|
+
toJSON() {
|
|
1540
|
+
return {
|
|
1541
|
+
muted: this.muted,
|
|
1542
|
+
label: this.label,
|
|
1543
|
+
readyState: this.readyState,
|
|
1544
|
+
inputStream: {
|
|
1545
|
+
active: this.inputStream.active,
|
|
1546
|
+
id: this.inputStream.id,
|
|
1547
|
+
enabled: this.inputTrack.enabled,
|
|
1548
|
+
muted: this.inputTrack.muted,
|
|
1549
|
+
},
|
|
1550
|
+
outputStream: {
|
|
1551
|
+
active: this.outputStream.active,
|
|
1552
|
+
id: this.outputStream.id,
|
|
1553
|
+
},
|
|
1554
|
+
effects: this.effects.map((effect) => {
|
|
1555
|
+
return {
|
|
1556
|
+
id: effect.id,
|
|
1557
|
+
kind: effect.kind,
|
|
1558
|
+
isEnabled: effect.isEnabled,
|
|
1559
|
+
};
|
|
1560
|
+
}),
|
|
1561
|
+
};
|
|
1562
|
+
}
|
|
1563
|
+
/**
|
|
1564
|
+
* Cleanup the local effects.
|
|
1565
|
+
*/
|
|
1566
|
+
disposeEffects() {
|
|
1567
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
1568
|
+
this.loadingEffects.clear();
|
|
1569
|
+
// Dispose of any effects currently in use
|
|
1570
|
+
if (this.effects.length > 0) {
|
|
1571
|
+
this.changeOutputTrack(this.inputTrack);
|
|
1572
|
+
yield Promise.all(this.effects.map((effect) => effect.dispose()));
|
|
1573
|
+
this.effects = [];
|
|
1574
|
+
}
|
|
1575
|
+
});
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
_a$1$1 = exports.LocalStreamEventNames.UserMuteStateChange, _b = exports.LocalStreamEventNames.SystemMuteStateChange, _c = exports.LocalStreamEventNames.ConstraintsChange, _d = exports.LocalStreamEventNames.OutputTrackChange, _e = exports.LocalStreamEventNames.EffectAdded;
|
|
1579
1579
|
const LocalStream = AddEvents(_LocalStream);
|
|
1580
1580
|
|
|
1581
|
-
/**
|
|
1582
|
-
* An audio LocalStream.
|
|
1583
|
-
*/
|
|
1584
|
-
class LocalAudioStream extends LocalStream {
|
|
1585
|
-
/**
|
|
1586
|
-
* Apply constraints to the stream.
|
|
1587
|
-
*
|
|
1588
|
-
* @param constraints - The constraints to apply.
|
|
1589
|
-
* @returns A promise which resolves when the constraints have been successfully applied.
|
|
1590
|
-
*/
|
|
1591
|
-
applyConstraints(constraints) {
|
|
1592
|
-
return __awaiter$2(this, void 0, void 0, function* () {
|
|
1593
|
-
logger$3.log(`Applying constraints to local track:`, constraints);
|
|
1594
|
-
return this.inputTrack.applyConstraints(constraints).then(() => {
|
|
1595
|
-
this[exports.LocalStreamEventNames.ConstraintsChange].emit();
|
|
1596
|
-
});
|
|
1597
|
-
});
|
|
1598
|
-
}
|
|
1581
|
+
/**
|
|
1582
|
+
* An audio LocalStream.
|
|
1583
|
+
*/
|
|
1584
|
+
class LocalAudioStream extends LocalStream {
|
|
1585
|
+
/**
|
|
1586
|
+
* Apply constraints to the stream.
|
|
1587
|
+
*
|
|
1588
|
+
* @param constraints - The constraints to apply.
|
|
1589
|
+
* @returns A promise which resolves when the constraints have been successfully applied.
|
|
1590
|
+
*/
|
|
1591
|
+
applyConstraints(constraints) {
|
|
1592
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
1593
|
+
logger$3.log(`Applying constraints to local track:`, constraints);
|
|
1594
|
+
return this.inputTrack.applyConstraints(constraints).then(() => {
|
|
1595
|
+
this[exports.LocalStreamEventNames.ConstraintsChange].emit();
|
|
1596
|
+
});
|
|
1597
|
+
});
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
/**
|
|
1602
|
+
* A video LocalStream.
|
|
1603
|
+
*/
|
|
1604
|
+
class LocalVideoStream extends LocalStream {
|
|
1605
|
+
/**
|
|
1606
|
+
* Apply constraints to the stream.
|
|
1607
|
+
*
|
|
1608
|
+
* @param constraints - The constraints to apply.
|
|
1609
|
+
* @returns A promise which resolves when the constraints have been successfully applied.
|
|
1610
|
+
*/
|
|
1611
|
+
applyConstraints(constraints) {
|
|
1612
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
1613
|
+
logger$3.log(`Applying constraints to local track:`, constraints);
|
|
1614
|
+
return this.inputTrack.applyConstraints(constraints).then(() => {
|
|
1615
|
+
this[exports.LocalStreamEventNames.ConstraintsChange].emit();
|
|
1616
|
+
});
|
|
1617
|
+
});
|
|
1618
|
+
}
|
|
1619
|
+
/**
|
|
1620
|
+
* Get the content hint for this stream.
|
|
1621
|
+
*
|
|
1622
|
+
* @returns The content hint setting for this stream, or undefined if none has been set.
|
|
1623
|
+
*/
|
|
1624
|
+
get contentHint() {
|
|
1625
|
+
return this.inputTrack.contentHint;
|
|
1626
|
+
}
|
|
1627
|
+
/**
|
|
1628
|
+
* Set the content hint for this stream.
|
|
1629
|
+
*
|
|
1630
|
+
* @param hint - The content hint to set.
|
|
1631
|
+
*/
|
|
1632
|
+
set contentHint(hint) {
|
|
1633
|
+
this.inputTrack.contentHint = hint;
|
|
1634
|
+
}
|
|
1635
|
+
/**
|
|
1636
|
+
* Check the resolution and then return how many layers will be active.
|
|
1637
|
+
*
|
|
1638
|
+
* @returns The active layers count.
|
|
1639
|
+
*/
|
|
1640
|
+
getNumActiveSimulcastLayers() {
|
|
1641
|
+
let activeSimulcastLayersNumber = 0;
|
|
1642
|
+
const videoHeight = this.inputTrack.getSettings().height;
|
|
1643
|
+
if (videoHeight <= 180) {
|
|
1644
|
+
activeSimulcastLayersNumber = 1;
|
|
1645
|
+
}
|
|
1646
|
+
else if (videoHeight <= 360) {
|
|
1647
|
+
activeSimulcastLayersNumber = 2;
|
|
1648
|
+
}
|
|
1649
|
+
else {
|
|
1650
|
+
activeSimulcastLayersNumber = 3;
|
|
1651
|
+
}
|
|
1652
|
+
return activeSimulcastLayersNumber;
|
|
1653
|
+
}
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
/**
|
|
1657
|
+
* A local camera stream.
|
|
1658
|
+
*/
|
|
1659
|
+
class LocalCameraStream extends LocalVideoStream {
|
|
1660
|
+
}
|
|
1661
|
+
|
|
1662
|
+
/**
|
|
1663
|
+
* A local display stream.
|
|
1664
|
+
*/
|
|
1665
|
+
class LocalDisplayStream extends LocalVideoStream {
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1668
|
+
/**
|
|
1669
|
+
* A local microphone stream.
|
|
1670
|
+
*/
|
|
1671
|
+
class LocalMicrophoneStream extends LocalAudioStream {
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
/**
|
|
1675
|
+
* A local system audio stream.
|
|
1676
|
+
*/
|
|
1677
|
+
class LocalSystemAudioStream extends LocalAudioStream {
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1680
|
+
var _a$6;
|
|
1681
|
+
exports.RemoteMediaState = void 0;
|
|
1682
|
+
(function (RemoteMediaState) {
|
|
1683
|
+
RemoteMediaState["Started"] = "started";
|
|
1684
|
+
RemoteMediaState["Stopped"] = "stopped";
|
|
1685
|
+
})(exports.RemoteMediaState || (exports.RemoteMediaState = {}));
|
|
1686
|
+
exports.RemoteStreamEventNames = void 0;
|
|
1687
|
+
(function (RemoteStreamEventNames) {
|
|
1688
|
+
RemoteStreamEventNames["MediaStateChange"] = "media-state-change";
|
|
1689
|
+
})(exports.RemoteStreamEventNames || (exports.RemoteStreamEventNames = {}));
|
|
1690
|
+
/**
|
|
1691
|
+
* A stream originating from a remote peer.
|
|
1692
|
+
*/
|
|
1693
|
+
class _RemoteStream extends Stream {
|
|
1694
|
+
/**
|
|
1695
|
+
* Create a RemoteStream from the given values.
|
|
1696
|
+
*
|
|
1697
|
+
* @param stream - The initial output MediaStream for this Stream.
|
|
1698
|
+
*/
|
|
1699
|
+
constructor(stream) {
|
|
1700
|
+
super(stream);
|
|
1701
|
+
this[_a$6] = new TypedEvent$1();
|
|
1702
|
+
this.handleMediaStarted = this.handleMediaStarted.bind(this);
|
|
1703
|
+
this.handleMediaStopped = this.handleMediaStopped.bind(this);
|
|
1704
|
+
this.outputTrack.addEventListener('mute', this.handleMediaStopped);
|
|
1705
|
+
this.outputTrack.addEventListener('unmute', this.handleMediaStarted);
|
|
1706
|
+
}
|
|
1707
|
+
/**
|
|
1708
|
+
* @inheritdoc
|
|
1709
|
+
*/
|
|
1710
|
+
handleMediaStarted() {
|
|
1711
|
+
this[exports.RemoteStreamEventNames.MediaStateChange].emit(exports.RemoteMediaState.Started);
|
|
1712
|
+
}
|
|
1713
|
+
/**
|
|
1714
|
+
* @inheritdoc
|
|
1715
|
+
*/
|
|
1716
|
+
handleMediaStopped() {
|
|
1717
|
+
this[exports.RemoteStreamEventNames.MediaStateChange].emit(exports.RemoteMediaState.Stopped);
|
|
1718
|
+
}
|
|
1719
|
+
/**
|
|
1720
|
+
* Helper function to add event handlers to a MediaStreamTrack. See
|
|
1721
|
+
* {@link Stream.addTrackHandlersForStreamEvents} for why this is useful.
|
|
1722
|
+
*
|
|
1723
|
+
* @param track - The MediaStreamTrack.
|
|
1724
|
+
*/
|
|
1725
|
+
addTrackHandlersForRemoteStreamEvents(track) {
|
|
1726
|
+
track.addEventListener('mute', this.handleMediaStopped);
|
|
1727
|
+
track.addEventListener('unmute', this.handleMediaStarted);
|
|
1728
|
+
}
|
|
1729
|
+
/**
|
|
1730
|
+
* @inheritdoc
|
|
1731
|
+
*/
|
|
1732
|
+
addTrackHandlers(track) {
|
|
1733
|
+
super.addTrackHandlers(track);
|
|
1734
|
+
this.addTrackHandlersForRemoteStreamEvents(track);
|
|
1735
|
+
}
|
|
1736
|
+
/**
|
|
1737
|
+
* @inheritdoc
|
|
1738
|
+
*/
|
|
1739
|
+
removeTrackHandlers(track) {
|
|
1740
|
+
super.removeTrackHandlers(track);
|
|
1741
|
+
track.removeEventListener('mute', this.handleMediaStopped);
|
|
1742
|
+
track.removeEventListener('unmute', this.handleMediaStarted);
|
|
1743
|
+
}
|
|
1744
|
+
/**
|
|
1745
|
+
* Get whether the media on this stream has started or stopped.
|
|
1746
|
+
*
|
|
1747
|
+
* @returns The state of the media.
|
|
1748
|
+
*/
|
|
1749
|
+
get mediaState() {
|
|
1750
|
+
return this.outputTrack.muted ? exports.RemoteMediaState.Stopped : exports.RemoteMediaState.Started;
|
|
1751
|
+
}
|
|
1752
|
+
/**
|
|
1753
|
+
* @inheritdoc
|
|
1754
|
+
*/
|
|
1755
|
+
getSettings() {
|
|
1756
|
+
return this.outputTrack.getSettings();
|
|
1757
|
+
}
|
|
1758
|
+
/**
|
|
1759
|
+
* Replace the existing track on the output stream for a new track.
|
|
1760
|
+
*
|
|
1761
|
+
* @param newTrack - The track to add to the stream.
|
|
1762
|
+
*/
|
|
1763
|
+
replaceTrack(newTrack) {
|
|
1764
|
+
const oldTrack = this.outputTrack;
|
|
1765
|
+
this.removeTrackHandlers(oldTrack);
|
|
1766
|
+
this.outputStream.removeTrack(oldTrack);
|
|
1767
|
+
this.outputStream.addTrack(newTrack);
|
|
1768
|
+
this.addTrackHandlers(newTrack);
|
|
1769
|
+
if (oldTrack.muted !== newTrack.muted) {
|
|
1770
|
+
if (newTrack.muted) {
|
|
1771
|
+
this.handleMediaStopped();
|
|
1772
|
+
}
|
|
1773
|
+
else {
|
|
1774
|
+
this.handleMediaStarted();
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1777
|
+
// TODO: Chrome/React may not automatically refresh the media element with the new track when
|
|
1778
|
+
// the output track has changed, so we may need to emit an event here if this is the case.
|
|
1779
|
+
// this[StreamEventNames.OutputTrackChange].emit(newTrack);
|
|
1780
|
+
}
|
|
1781
|
+
/**
|
|
1782
|
+
* @inheritdoc
|
|
1783
|
+
*/
|
|
1784
|
+
stop() {
|
|
1785
|
+
this.outputTrack.stop();
|
|
1786
|
+
// calling stop() will not automatically emit Ended, so we emit it here
|
|
1787
|
+
this[exports.StreamEventNames.Ended].emit();
|
|
1788
|
+
}
|
|
1599
1789
|
}
|
|
1600
|
-
|
|
1601
|
-
/**
|
|
1602
|
-
* A video LocalStream.
|
|
1603
|
-
*/
|
|
1604
|
-
class LocalVideoStream extends LocalStream {
|
|
1605
|
-
/**
|
|
1606
|
-
* Apply constraints to the stream.
|
|
1607
|
-
*
|
|
1608
|
-
* @param constraints - The constraints to apply.
|
|
1609
|
-
* @returns A promise which resolves when the constraints have been successfully applied.
|
|
1610
|
-
*/
|
|
1611
|
-
applyConstraints(constraints) {
|
|
1612
|
-
return __awaiter$2(this, void 0, void 0, function* () {
|
|
1613
|
-
logger$3.log(`Applying constraints to local track:`, constraints);
|
|
1614
|
-
return this.inputTrack.applyConstraints(constraints).then(() => {
|
|
1615
|
-
this[exports.LocalStreamEventNames.ConstraintsChange].emit();
|
|
1616
|
-
});
|
|
1617
|
-
});
|
|
1618
|
-
}
|
|
1619
|
-
/**
|
|
1620
|
-
* Get the content hint for this stream.
|
|
1621
|
-
*
|
|
1622
|
-
* @returns The content hint setting for this stream, or undefined if none has been set.
|
|
1623
|
-
*/
|
|
1624
|
-
get contentHint() {
|
|
1625
|
-
return this.inputTrack.contentHint;
|
|
1626
|
-
}
|
|
1627
|
-
/**
|
|
1628
|
-
* Set the content hint for this stream.
|
|
1629
|
-
*
|
|
1630
|
-
* @param hint - The content hint to set.
|
|
1631
|
-
*/
|
|
1632
|
-
set contentHint(hint) {
|
|
1633
|
-
this.inputTrack.contentHint = hint;
|
|
1634
|
-
}
|
|
1635
|
-
/**
|
|
1636
|
-
* Check the resolution and then return how many layers will be active.
|
|
1637
|
-
*
|
|
1638
|
-
* @returns The active layers count.
|
|
1639
|
-
*/
|
|
1640
|
-
getNumActiveSimulcastLayers() {
|
|
1641
|
-
let activeSimulcastLayersNumber = 0;
|
|
1642
|
-
const videoHeight = this.inputTrack.getSettings().height;
|
|
1643
|
-
if (videoHeight <= 180) {
|
|
1644
|
-
activeSimulcastLayersNumber = 1;
|
|
1645
|
-
}
|
|
1646
|
-
else if (videoHeight <= 360) {
|
|
1647
|
-
activeSimulcastLayersNumber = 2;
|
|
1648
|
-
}
|
|
1649
|
-
else {
|
|
1650
|
-
activeSimulcastLayersNumber = 3;
|
|
1651
|
-
}
|
|
1652
|
-
return activeSimulcastLayersNumber;
|
|
1653
|
-
}
|
|
1654
|
-
}
|
|
1655
|
-
|
|
1656
|
-
/**
|
|
1657
|
-
* A local camera stream.
|
|
1658
|
-
*/
|
|
1659
|
-
class LocalCameraStream extends LocalVideoStream {
|
|
1660
|
-
}
|
|
1661
|
-
|
|
1662
|
-
/**
|
|
1663
|
-
* A local display stream.
|
|
1664
|
-
*/
|
|
1665
|
-
class LocalDisplayStream extends LocalVideoStream {
|
|
1666
|
-
}
|
|
1667
|
-
|
|
1668
|
-
/**
|
|
1669
|
-
* A local microphone stream.
|
|
1670
|
-
*/
|
|
1671
|
-
class LocalMicrophoneStream extends LocalAudioStream {
|
|
1672
|
-
}
|
|
1673
|
-
|
|
1674
|
-
/**
|
|
1675
|
-
* A local system audio stream.
|
|
1676
|
-
*/
|
|
1677
|
-
class LocalSystemAudioStream extends LocalAudioStream {
|
|
1678
|
-
}
|
|
1679
|
-
|
|
1680
|
-
var _a$6;
|
|
1681
|
-
exports.RemoteMediaState = void 0;
|
|
1682
|
-
(function (RemoteMediaState) {
|
|
1683
|
-
RemoteMediaState["Started"] = "started";
|
|
1684
|
-
RemoteMediaState["Stopped"] = "stopped";
|
|
1685
|
-
})(exports.RemoteMediaState || (exports.RemoteMediaState = {}));
|
|
1686
|
-
exports.RemoteStreamEventNames = void 0;
|
|
1687
|
-
(function (RemoteStreamEventNames) {
|
|
1688
|
-
RemoteStreamEventNames["MediaStateChange"] = "media-state-change";
|
|
1689
|
-
})(exports.RemoteStreamEventNames || (exports.RemoteStreamEventNames = {}));
|
|
1690
|
-
/**
|
|
1691
|
-
* A stream originating from a remote peer.
|
|
1692
|
-
*/
|
|
1693
|
-
class _RemoteStream extends Stream {
|
|
1694
|
-
/**
|
|
1695
|
-
* Create a RemoteStream from the given values.
|
|
1696
|
-
*
|
|
1697
|
-
* @param stream - The initial output MediaStream for this Stream.
|
|
1698
|
-
*/
|
|
1699
|
-
constructor(stream) {
|
|
1700
|
-
super(stream);
|
|
1701
|
-
this[_a$6] = new TypedEvent$1();
|
|
1702
|
-
this.handleMediaStarted = this.handleMediaStarted.bind(this);
|
|
1703
|
-
this.handleMediaStopped = this.handleMediaStopped.bind(this);
|
|
1704
|
-
this.outputTrack.addEventListener('mute', this.handleMediaStopped);
|
|
1705
|
-
this.outputTrack.addEventListener('unmute', this.handleMediaStarted);
|
|
1706
|
-
}
|
|
1707
|
-
/**
|
|
1708
|
-
* @inheritdoc
|
|
1709
|
-
*/
|
|
1710
|
-
handleMediaStarted() {
|
|
1711
|
-
this[exports.RemoteStreamEventNames.MediaStateChange].emit(exports.RemoteMediaState.Started);
|
|
1712
|
-
}
|
|
1713
|
-
/**
|
|
1714
|
-
* @inheritdoc
|
|
1715
|
-
*/
|
|
1716
|
-
handleMediaStopped() {
|
|
1717
|
-
this[exports.RemoteStreamEventNames.MediaStateChange].emit(exports.RemoteMediaState.Stopped);
|
|
1718
|
-
}
|
|
1719
|
-
/**
|
|
1720
|
-
* Helper function to add event handlers to a MediaStreamTrack. See
|
|
1721
|
-
* {@link Stream.addTrackHandlersForStreamEvents} for why this is useful.
|
|
1722
|
-
*
|
|
1723
|
-
* @param track - The MediaStreamTrack.
|
|
1724
|
-
*/
|
|
1725
|
-
addTrackHandlersForRemoteStreamEvents(track) {
|
|
1726
|
-
track.addEventListener('mute', this.handleMediaStopped);
|
|
1727
|
-
track.addEventListener('unmute', this.handleMediaStarted);
|
|
1728
|
-
}
|
|
1729
|
-
/**
|
|
1730
|
-
* @inheritdoc
|
|
1731
|
-
*/
|
|
1732
|
-
addTrackHandlers(track) {
|
|
1733
|
-
super.addTrackHandlers(track);
|
|
1734
|
-
this.addTrackHandlersForRemoteStreamEvents(track);
|
|
1735
|
-
}
|
|
1736
|
-
/**
|
|
1737
|
-
* @inheritdoc
|
|
1738
|
-
*/
|
|
1739
|
-
removeTrackHandlers(track) {
|
|
1740
|
-
super.removeTrackHandlers(track);
|
|
1741
|
-
track.removeEventListener('mute', this.handleMediaStopped);
|
|
1742
|
-
track.removeEventListener('unmute', this.handleMediaStarted);
|
|
1743
|
-
}
|
|
1744
|
-
/**
|
|
1745
|
-
* Get whether the media on this stream has started or stopped.
|
|
1746
|
-
*
|
|
1747
|
-
* @returns The state of the media.
|
|
1748
|
-
*/
|
|
1749
|
-
get mediaState() {
|
|
1750
|
-
return this.outputTrack.muted ? exports.RemoteMediaState.Stopped : exports.RemoteMediaState.Started;
|
|
1751
|
-
}
|
|
1752
|
-
/**
|
|
1753
|
-
* @inheritdoc
|
|
1754
|
-
*/
|
|
1755
|
-
getSettings() {
|
|
1756
|
-
return this.outputTrack.getSettings();
|
|
1757
|
-
}
|
|
1758
|
-
/**
|
|
1759
|
-
* Replace the existing track on the output stream for a new track.
|
|
1760
|
-
*
|
|
1761
|
-
* @param newTrack - The track to add to the stream.
|
|
1762
|
-
*/
|
|
1763
|
-
replaceTrack(newTrack) {
|
|
1764
|
-
const oldTrack = this.outputTrack;
|
|
1765
|
-
this.removeTrackHandlers(oldTrack);
|
|
1766
|
-
this.outputStream.removeTrack(oldTrack);
|
|
1767
|
-
this.outputStream.addTrack(newTrack);
|
|
1768
|
-
this.addTrackHandlers(newTrack);
|
|
1769
|
-
if (oldTrack.muted !== newTrack.muted) {
|
|
1770
|
-
if (newTrack.muted) {
|
|
1771
|
-
this.handleMediaStopped();
|
|
1772
|
-
}
|
|
1773
|
-
else {
|
|
1774
|
-
this.handleMediaStarted();
|
|
1775
|
-
}
|
|
1776
|
-
}
|
|
1777
|
-
// TODO: Chrome/React may not automatically refresh the media element with the new track when
|
|
1778
|
-
// the output track has changed, so we may need to emit an event here if this is the case.
|
|
1779
|
-
// this[StreamEventNames.OutputTrackChange].emit(newTrack);
|
|
1780
|
-
}
|
|
1781
|
-
/**
|
|
1782
|
-
* @inheritdoc
|
|
1783
|
-
*/
|
|
1784
|
-
stop() {
|
|
1785
|
-
this.outputTrack.stop();
|
|
1786
|
-
// calling stop() will not automatically emit Ended, so we emit it here
|
|
1787
|
-
this[exports.StreamEventNames.Ended].emit();
|
|
1788
|
-
}
|
|
1789
|
-
}
|
|
1790
|
-
_a$6 = exports.RemoteStreamEventNames.MediaStateChange;
|
|
1790
|
+
_a$6 = exports.RemoteStreamEventNames.MediaStateChange;
|
|
1791
1791
|
const RemoteStream = AddEvents(_RemoteStream);
|
|
1792
1792
|
|
|
1793
1793
|
var commonjsGlobal$3 = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
@@ -2347,104 +2347,114 @@ function eventTargetAgnosticAddListener$2(emitter, name, listener, flags) {
|
|
|
2347
2347
|
}
|
|
2348
2348
|
}
|
|
2349
2349
|
|
|
2350
|
-
/**
|
|
2351
|
-
* Typed event emitter class.
|
|
2352
|
-
*/
|
|
2353
|
-
class EventEmitter$4 extends events$2.exports.EventEmitter {
|
|
2354
|
-
}
|
|
2355
|
-
|
|
2356
|
-
// Overall connection state (based on the ICE and DTLS connection states)
|
|
2357
|
-
exports.ConnectionState = void 0;
|
|
2358
|
-
(function (ConnectionState) {
|
|
2359
|
-
ConnectionState["New"] = "New";
|
|
2360
|
-
ConnectionState["Closed"] = "Closed";
|
|
2361
|
-
ConnectionState["Connected"] = "Connected";
|
|
2362
|
-
ConnectionState["Connecting"] = "Connecting";
|
|
2363
|
-
ConnectionState["Disconnected"] = "Disconnected";
|
|
2364
|
-
ConnectionState["Failed"] = "Failed";
|
|
2365
|
-
})(exports.ConnectionState || (exports.ConnectionState = {}));
|
|
2366
|
-
var ConnectionStateEvents;
|
|
2367
|
-
(function (ConnectionStateEvents) {
|
|
2368
|
-
ConnectionStateEvents["
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
*
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
*
|
|
2378
|
-
*
|
|
2379
|
-
*
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
this.
|
|
2385
|
-
}
|
|
2386
|
-
/**
|
|
2387
|
-
* Handler for connection state change.
|
|
2388
|
-
*/
|
|
2389
|
-
|
|
2390
|
-
this.
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
*
|
|
2442
|
-
*
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2350
|
+
/**
|
|
2351
|
+
* Typed event emitter class.
|
|
2352
|
+
*/
|
|
2353
|
+
class EventEmitter$4 extends events$2.exports.EventEmitter {
|
|
2354
|
+
}
|
|
2355
|
+
|
|
2356
|
+
// Overall connection state (based on the ICE and DTLS connection states)
|
|
2357
|
+
exports.ConnectionState = void 0;
|
|
2358
|
+
(function (ConnectionState) {
|
|
2359
|
+
ConnectionState["New"] = "New";
|
|
2360
|
+
ConnectionState["Closed"] = "Closed";
|
|
2361
|
+
ConnectionState["Connected"] = "Connected";
|
|
2362
|
+
ConnectionState["Connecting"] = "Connecting";
|
|
2363
|
+
ConnectionState["Disconnected"] = "Disconnected";
|
|
2364
|
+
ConnectionState["Failed"] = "Failed";
|
|
2365
|
+
})(exports.ConnectionState || (exports.ConnectionState = {}));
|
|
2366
|
+
var ConnectionStateEvents;
|
|
2367
|
+
(function (ConnectionStateEvents) {
|
|
2368
|
+
ConnectionStateEvents["PeerConnectionStateChanged"] = "PeerConnectionStateChanged";
|
|
2369
|
+
ConnectionStateEvents["IceConnectionStateChanged"] = "IceConnectionStateChanged";
|
|
2370
|
+
})(ConnectionStateEvents || (ConnectionStateEvents = {}));
|
|
2371
|
+
/**
|
|
2372
|
+
* Listens on the connection's ICE and DTLS state changes and emits a single
|
|
2373
|
+
* event that summarizes all the internal states into a single overall connection state.
|
|
2374
|
+
*/
|
|
2375
|
+
class ConnectionStateHandler extends EventEmitter$4 {
|
|
2376
|
+
/**
|
|
2377
|
+
* Creates an instance of ConnectionStateHandler.
|
|
2378
|
+
*
|
|
2379
|
+
* @param getCurrentStatesCallback - Callback for getting the connection state information
|
|
2380
|
+
* from the peer connection.
|
|
2381
|
+
*/
|
|
2382
|
+
constructor(getCurrentStatesCallback) {
|
|
2383
|
+
super();
|
|
2384
|
+
this.getCurrentStatesCallback = getCurrentStatesCallback;
|
|
2385
|
+
}
|
|
2386
|
+
/**
|
|
2387
|
+
* Handler for connection state change.
|
|
2388
|
+
*/
|
|
2389
|
+
onPeerConnectionStateChange() {
|
|
2390
|
+
const state = this.getPeerConnectionState();
|
|
2391
|
+
this.emit(ConnectionStateEvents.PeerConnectionStateChanged, state);
|
|
2392
|
+
}
|
|
2393
|
+
/**
|
|
2394
|
+
* Handler for ice connection state change.
|
|
2395
|
+
*/
|
|
2396
|
+
onIceConnectionStateChange() {
|
|
2397
|
+
const state = this.getIceConnectionState();
|
|
2398
|
+
this.emit(ConnectionStateEvents.IceConnectionStateChanged, state);
|
|
2399
|
+
}
|
|
2400
|
+
/**
|
|
2401
|
+
* Evaluates the overall connection state based on peer connection's
|
|
2402
|
+
* connectionState and iceConnectionState.
|
|
2403
|
+
*
|
|
2404
|
+
* @returns Current overall connection state.
|
|
2405
|
+
*/
|
|
2406
|
+
evaluateMediaConnectionState() {
|
|
2407
|
+
const { connectionState, iceState } = this.getCurrentStatesCallback();
|
|
2408
|
+
const connectionStates = [connectionState, iceState];
|
|
2409
|
+
let mediaConnectionState;
|
|
2410
|
+
if (connectionStates.every((value) => value === 'new')) {
|
|
2411
|
+
mediaConnectionState = exports.ConnectionState.New;
|
|
2412
|
+
}
|
|
2413
|
+
else if (connectionStates.some((value) => value === 'closed')) {
|
|
2414
|
+
mediaConnectionState = exports.ConnectionState.Closed;
|
|
2415
|
+
}
|
|
2416
|
+
else if (connectionStates.some((value) => value === 'failed')) {
|
|
2417
|
+
mediaConnectionState = exports.ConnectionState.Failed;
|
|
2418
|
+
}
|
|
2419
|
+
else if (connectionStates.some((value) => value === 'disconnected')) {
|
|
2420
|
+
mediaConnectionState = exports.ConnectionState.Disconnected;
|
|
2421
|
+
}
|
|
2422
|
+
else if (connectionStates.every((value) => value === 'connected' || value === 'completed')) {
|
|
2423
|
+
mediaConnectionState = exports.ConnectionState.Connected;
|
|
2424
|
+
}
|
|
2425
|
+
else {
|
|
2426
|
+
mediaConnectionState = exports.ConnectionState.Connecting;
|
|
2427
|
+
}
|
|
2428
|
+
logger$3.log(`iceConnectionState=${iceState} connectionState=${connectionState} => ${mediaConnectionState}`);
|
|
2429
|
+
return mediaConnectionState;
|
|
2430
|
+
}
|
|
2431
|
+
/**
|
|
2432
|
+
* Gets current connection state.
|
|
2433
|
+
*
|
|
2434
|
+
* @returns Current connection state.
|
|
2435
|
+
*/
|
|
2436
|
+
getPeerConnectionState() {
|
|
2437
|
+
const { connectionState } = this.getCurrentStatesCallback();
|
|
2438
|
+
return connectionState;
|
|
2439
|
+
}
|
|
2440
|
+
/**
|
|
2441
|
+
* Gets current ice connection state.
|
|
2442
|
+
*
|
|
2443
|
+
* @returns Current ice connection state.
|
|
2444
|
+
*/
|
|
2445
|
+
getIceConnectionState() {
|
|
2446
|
+
const { iceState } = this.getCurrentStatesCallback();
|
|
2447
|
+
return iceState;
|
|
2448
|
+
}
|
|
2449
|
+
/**
|
|
2450
|
+
* Gets current overall connection state.
|
|
2451
|
+
*
|
|
2452
|
+
* @returns Current overall connection state.
|
|
2453
|
+
*/
|
|
2454
|
+
getConnectionState() {
|
|
2455
|
+
return this.evaluateMediaConnectionState();
|
|
2456
|
+
}
|
|
2457
|
+
}
|
|
2448
2458
|
ConnectionStateHandler.Events = ConnectionStateEvents;
|
|
2449
2459
|
|
|
2450
2460
|
/*
|
|
@@ -5802,320 +5812,345 @@ function adapterFactory({window} = {}, options = {
|
|
|
5802
5812
|
|
|
5803
5813
|
adapterFactory({window: typeof window === 'undefined' ? undefined : window});
|
|
5804
5814
|
|
|
5805
|
-
/**
|
|
5806
|
-
* Creates an RTCPeerConnection.
|
|
5807
|
-
*
|
|
5808
|
-
* @param configuration - Config to the RTCPeerConnection constructor.
|
|
5809
|
-
* @returns An RTCPeerConnection instance.
|
|
5810
|
-
*/
|
|
5811
|
-
function createRTCPeerConnection(configuration) {
|
|
5812
|
-
return new RTCPeerConnection(configuration);
|
|
5813
|
-
}
|
|
5814
|
-
|
|
5815
|
-
/**
|
|
5816
|
-
* A type-safe form of the DOMString used in the MediaStreamTrack.kind field.
|
|
5817
|
-
*/
|
|
5818
|
-
exports.MediaStreamTrackKind = void 0;
|
|
5819
|
-
(function (MediaStreamTrackKind) {
|
|
5820
|
-
MediaStreamTrackKind["Audio"] = "audio";
|
|
5821
|
-
MediaStreamTrackKind["Video"] = "video";
|
|
5822
|
-
})(exports.MediaStreamTrackKind || (exports.MediaStreamTrackKind = {}));
|
|
5823
|
-
var PeerConnectionEvents;
|
|
5824
|
-
(function (PeerConnectionEvents) {
|
|
5825
|
-
PeerConnectionEvents["IceGatheringStateChange"] = "icegatheringstatechange";
|
|
5826
|
-
PeerConnectionEvents["IceCandidate"] = "icecandidate";
|
|
5827
|
-
PeerConnectionEvents["
|
|
5828
|
-
PeerConnectionEvents["
|
|
5829
|
-
PeerConnectionEvents["
|
|
5830
|
-
PeerConnectionEvents["
|
|
5831
|
-
PeerConnectionEvents["
|
|
5832
|
-
|
|
5833
|
-
|
|
5834
|
-
|
|
5835
|
-
|
|
5836
|
-
|
|
5837
|
-
|
|
5838
|
-
|
|
5839
|
-
|
|
5840
|
-
*
|
|
5841
|
-
|
|
5842
|
-
|
|
5843
|
-
|
|
5844
|
-
|
|
5845
|
-
|
|
5846
|
-
|
|
5847
|
-
|
|
5848
|
-
|
|
5849
|
-
|
|
5850
|
-
|
|
5851
|
-
|
|
5852
|
-
|
|
5853
|
-
|
|
5854
|
-
|
|
5855
|
-
|
|
5856
|
-
|
|
5857
|
-
this.
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
//
|
|
5861
|
-
|
|
5862
|
-
this.pc.
|
|
5863
|
-
|
|
5864
|
-
|
|
5865
|
-
|
|
5866
|
-
|
|
5867
|
-
|
|
5868
|
-
|
|
5869
|
-
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
|
|
5876
|
-
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
*
|
|
5880
|
-
*
|
|
5881
|
-
|
|
5882
|
-
|
|
5883
|
-
|
|
5884
|
-
|
|
5885
|
-
|
|
5886
|
-
|
|
5887
|
-
*
|
|
5888
|
-
*
|
|
5889
|
-
* @
|
|
5890
|
-
|
|
5891
|
-
|
|
5892
|
-
|
|
5893
|
-
|
|
5894
|
-
|
|
5895
|
-
|
|
5896
|
-
|
|
5897
|
-
|
|
5898
|
-
|
|
5899
|
-
|
|
5900
|
-
|
|
5901
|
-
|
|
5902
|
-
|
|
5903
|
-
*
|
|
5904
|
-
*
|
|
5905
|
-
* @returns
|
|
5906
|
-
*/
|
|
5907
|
-
|
|
5908
|
-
return this.
|
|
5909
|
-
}
|
|
5910
|
-
/**
|
|
5911
|
-
*
|
|
5912
|
-
*
|
|
5913
|
-
*
|
|
5914
|
-
*
|
|
5915
|
-
*
|
|
5916
|
-
*
|
|
5917
|
-
*
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
|
|
5925
|
-
|
|
5926
|
-
|
|
5927
|
-
*
|
|
5928
|
-
*
|
|
5929
|
-
* @param
|
|
5930
|
-
* @
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
*
|
|
5938
|
-
*
|
|
5939
|
-
*
|
|
5940
|
-
*
|
|
5941
|
-
*
|
|
5942
|
-
*
|
|
5943
|
-
*
|
|
5944
|
-
*
|
|
5945
|
-
|
|
5946
|
-
|
|
5947
|
-
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
|
|
5951
|
-
|
|
5952
|
-
|
|
5953
|
-
|
|
5954
|
-
|
|
5955
|
-
*
|
|
5956
|
-
*
|
|
5957
|
-
|
|
5958
|
-
|
|
5959
|
-
|
|
5960
|
-
|
|
5961
|
-
|
|
5962
|
-
*
|
|
5963
|
-
|
|
5964
|
-
|
|
5965
|
-
|
|
5966
|
-
|
|
5967
|
-
|
|
5968
|
-
|
|
5969
|
-
|
|
5970
|
-
|
|
5971
|
-
|
|
5972
|
-
|
|
5973
|
-
|
|
5974
|
-
|
|
5975
|
-
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
5981
|
-
|
|
5982
|
-
|
|
5983
|
-
|
|
5984
|
-
|
|
5985
|
-
|
|
5986
|
-
|
|
5987
|
-
|
|
5988
|
-
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
|
|
5994
|
-
|
|
5995
|
-
|
|
5996
|
-
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
*
|
|
6003
|
-
*
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
|
|
6011
|
-
|
|
6012
|
-
|
|
6013
|
-
|
|
6014
|
-
|
|
6015
|
-
|
|
6016
|
-
|
|
6017
|
-
|
|
6018
|
-
|
|
6019
|
-
|
|
6020
|
-
|
|
6021
|
-
|
|
6022
|
-
|
|
6023
|
-
|
|
6024
|
-
|
|
6025
|
-
|
|
6026
|
-
|
|
6027
|
-
|
|
6028
|
-
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
*
|
|
6033
|
-
*
|
|
6034
|
-
|
|
6035
|
-
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
|
|
6039
|
-
|
|
6040
|
-
|
|
6041
|
-
|
|
6042
|
-
|
|
6043
|
-
*
|
|
6044
|
-
|
|
6045
|
-
|
|
6046
|
-
|
|
6047
|
-
|
|
6048
|
-
|
|
6049
|
-
|
|
6050
|
-
|
|
6051
|
-
*
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
|
|
6060
|
-
|
|
6061
|
-
|
|
6062
|
-
|
|
6063
|
-
|
|
6064
|
-
|
|
6065
|
-
*
|
|
6066
|
-
*
|
|
6067
|
-
*
|
|
6068
|
-
|
|
6069
|
-
|
|
6070
|
-
|
|
6071
|
-
|
|
6072
|
-
|
|
6073
|
-
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
|
|
6077
|
-
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
|
|
6081
|
-
*
|
|
6082
|
-
|
|
6083
|
-
|
|
6084
|
-
|
|
6085
|
-
|
|
6086
|
-
|
|
6087
|
-
|
|
6088
|
-
|
|
6089
|
-
|
|
6090
|
-
|
|
6091
|
-
|
|
6092
|
-
|
|
6093
|
-
|
|
6094
|
-
|
|
6095
|
-
|
|
6096
|
-
|
|
6097
|
-
|
|
6098
|
-
|
|
6099
|
-
|
|
6100
|
-
|
|
6101
|
-
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
|
|
6109
|
-
|
|
6110
|
-
|
|
6111
|
-
|
|
6112
|
-
|
|
6113
|
-
|
|
6114
|
-
|
|
6115
|
-
|
|
6116
|
-
|
|
6117
|
-
|
|
6118
|
-
|
|
5815
|
+
/**
|
|
5816
|
+
* Creates an RTCPeerConnection.
|
|
5817
|
+
*
|
|
5818
|
+
* @param configuration - Config to the RTCPeerConnection constructor.
|
|
5819
|
+
* @returns An RTCPeerConnection instance.
|
|
5820
|
+
*/
|
|
5821
|
+
function createRTCPeerConnection(configuration) {
|
|
5822
|
+
return new RTCPeerConnection(configuration);
|
|
5823
|
+
}
|
|
5824
|
+
|
|
5825
|
+
/**
|
|
5826
|
+
* A type-safe form of the DOMString used in the MediaStreamTrack.kind field.
|
|
5827
|
+
*/
|
|
5828
|
+
exports.MediaStreamTrackKind = void 0;
|
|
5829
|
+
(function (MediaStreamTrackKind) {
|
|
5830
|
+
MediaStreamTrackKind["Audio"] = "audio";
|
|
5831
|
+
MediaStreamTrackKind["Video"] = "video";
|
|
5832
|
+
})(exports.MediaStreamTrackKind || (exports.MediaStreamTrackKind = {}));
|
|
5833
|
+
var PeerConnectionEvents;
|
|
5834
|
+
(function (PeerConnectionEvents) {
|
|
5835
|
+
PeerConnectionEvents["IceGatheringStateChange"] = "icegatheringstatechange";
|
|
5836
|
+
PeerConnectionEvents["IceCandidate"] = "icecandidate";
|
|
5837
|
+
PeerConnectionEvents["IceCandidateError"] = "icecandidateerror";
|
|
5838
|
+
PeerConnectionEvents["PeerConnectionStateChange"] = "peerconnectionstatechange";
|
|
5839
|
+
PeerConnectionEvents["IceConnectionStateChange"] = "iceconnectionstatechange";
|
|
5840
|
+
PeerConnectionEvents["CreateOfferOnSuccess"] = "createofferonsuccess";
|
|
5841
|
+
PeerConnectionEvents["CreateAnswerOnSuccess"] = "createansweronsuccess";
|
|
5842
|
+
PeerConnectionEvents["SetLocalDescriptionOnSuccess"] = "setlocaldescriptiononsuccess";
|
|
5843
|
+
PeerConnectionEvents["SetRemoteDescriptionOnSuccess"] = "setremotedescriptiononsuccess";
|
|
5844
|
+
})(PeerConnectionEvents || (PeerConnectionEvents = {}));
|
|
5845
|
+
/**
|
|
5846
|
+
* Manages a single RTCPeerConnection with the server.
|
|
5847
|
+
*/
|
|
5848
|
+
class PeerConnection extends EventEmitter$4 {
|
|
5849
|
+
/**
|
|
5850
|
+
* Creates an instance of the RTCPeerConnection.
|
|
5851
|
+
*
|
|
5852
|
+
* @param configuration - Config to the RTCPeerConnection constructor.
|
|
5853
|
+
*/
|
|
5854
|
+
constructor(configuration) {
|
|
5855
|
+
super();
|
|
5856
|
+
logger$3.log('PeerConnection init');
|
|
5857
|
+
this.pc = createRTCPeerConnection(configuration);
|
|
5858
|
+
this.connectionStateHandler = new ConnectionStateHandler(() => {
|
|
5859
|
+
return {
|
|
5860
|
+
connectionState: this.pc.connectionState,
|
|
5861
|
+
iceState: this.pc.iceConnectionState,
|
|
5862
|
+
};
|
|
5863
|
+
});
|
|
5864
|
+
this.connectionStateHandler.on(ConnectionStateHandler.Events.PeerConnectionStateChanged, (state) => {
|
|
5865
|
+
this.emit(PeerConnection.Events.PeerConnectionStateChange, state);
|
|
5866
|
+
});
|
|
5867
|
+
this.connectionStateHandler.on(ConnectionStateHandler.Events.IceConnectionStateChanged, (state) => {
|
|
5868
|
+
this.emit(PeerConnection.Events.IceConnectionStateChange, state);
|
|
5869
|
+
});
|
|
5870
|
+
// Forward the connection state related events to connection state handler
|
|
5871
|
+
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
5872
|
+
this.pc.oniceconnectionstatechange = () => this.connectionStateHandler.onIceConnectionStateChange();
|
|
5873
|
+
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
5874
|
+
this.pc.onconnectionstatechange = () => this.connectionStateHandler.onPeerConnectionStateChange();
|
|
5875
|
+
// Subscribe to underlying PeerConnection events and emit them via the EventEmitter
|
|
5876
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
5877
|
+
this.pc.onicegatheringstatechange = (ev) => {
|
|
5878
|
+
this.emit(PeerConnection.Events.IceGatheringStateChange, ev);
|
|
5879
|
+
};
|
|
5880
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
5881
|
+
this.pc.onicecandidate = (ev) => {
|
|
5882
|
+
this.emit(PeerConnection.Events.IceCandidate, ev);
|
|
5883
|
+
};
|
|
5884
|
+
this.pc.onicecandidateerror = (ev) => {
|
|
5885
|
+
this.emit(PeerConnection.Events.IceCandidateError, ev);
|
|
5886
|
+
};
|
|
5887
|
+
}
|
|
5888
|
+
/**
|
|
5889
|
+
* Get the underlying RTCPeerConnection.
|
|
5890
|
+
*
|
|
5891
|
+
* @returns The underlying RTCPeerConnection.
|
|
5892
|
+
*/
|
|
5893
|
+
getUnderlyingRTCPeerConnection() {
|
|
5894
|
+
return this.pc;
|
|
5895
|
+
}
|
|
5896
|
+
/**
|
|
5897
|
+
* Gets the overall connection state of the underlying RTCPeerConnection.
|
|
5898
|
+
*
|
|
5899
|
+
* @returns The underlying connection's overall state.
|
|
5900
|
+
*/
|
|
5901
|
+
getConnectionState() {
|
|
5902
|
+
return this.connectionStateHandler.getConnectionState();
|
|
5903
|
+
}
|
|
5904
|
+
/**
|
|
5905
|
+
* Gets the connection state of the underlying RTCPeerConnection.
|
|
5906
|
+
*
|
|
5907
|
+
* @returns The underlying RTCPeerConnection connection state.
|
|
5908
|
+
*/
|
|
5909
|
+
getPeerConnectionState() {
|
|
5910
|
+
return this.connectionStateHandler.getPeerConnectionState();
|
|
5911
|
+
}
|
|
5912
|
+
/**
|
|
5913
|
+
* Gets the ICE connection state of the underlying RTCPeerConnection.
|
|
5914
|
+
*
|
|
5915
|
+
* @returns The underlying RTCPeerConnection ICE connection state.
|
|
5916
|
+
*/
|
|
5917
|
+
getIceConnectionState() {
|
|
5918
|
+
return this.connectionStateHandler.getIceConnectionState();
|
|
5919
|
+
}
|
|
5920
|
+
/**
|
|
5921
|
+
* Adds a new media track to the set of tracks which will be transmitted to the other peer.
|
|
5922
|
+
*
|
|
5923
|
+
* @param track - A MediaStreamTrack object representing the media track to add to the peer connection.
|
|
5924
|
+
* @param streams - (Optional) One or more local MediaStream objects to which the track should be
|
|
5925
|
+
* added.
|
|
5926
|
+
* @returns The RTCRtpSender object which will be used to transmit the media data, or null if
|
|
5927
|
+
* there is no underlying track when a track is added.
|
|
5928
|
+
*/
|
|
5929
|
+
addTrack(track, ...streams) {
|
|
5930
|
+
return this.pc.addTrack(track, ...streams);
|
|
5931
|
+
}
|
|
5932
|
+
/**
|
|
5933
|
+
* Creates a new RTCRtpTransceiver and adds it to the set of transceivers associated with the
|
|
5934
|
+
* PeerConnection. Each transceiver represents a bidirectional stream, with both an RTCRtpSender
|
|
5935
|
+
* and an RTCRtpReceiver associated with it.
|
|
5936
|
+
*
|
|
5937
|
+
* @param trackOrKind - A MediaStreamTrack to associate with the transceiver, or a string which is used
|
|
5938
|
+
* as the kind of the receiver's track, and by extension the RTCRtpReceiver itself.
|
|
5939
|
+
* @param init - Options that you may wish to specify when creating the new transceiver.
|
|
5940
|
+
* @returns - The created RTCRtpTransceiver object.
|
|
5941
|
+
*/
|
|
5942
|
+
addTransceiver(trackOrKind, init) {
|
|
5943
|
+
return this.pc.addTransceiver(trackOrKind, init);
|
|
5944
|
+
}
|
|
5945
|
+
/**
|
|
5946
|
+
* Tell the local end of the connection to stop sending media from the specified track, without
|
|
5947
|
+
* actually removing the corresponding RTCRtpSender from the list of senders as reported by
|
|
5948
|
+
* RTCPeerConnection.getSenders(). If the track is already stopped, or is not in the connection's
|
|
5949
|
+
* senders list, the method has no effect.
|
|
5950
|
+
*
|
|
5951
|
+
* If the connection has already been negotiated (signalingState is set to 'stable'), it is marked
|
|
5952
|
+
* as needing to be negotiated again; the remote peer won't experience the change until this
|
|
5953
|
+
* negotiation occurs. A negotiatedneeded event is sent to the RTCPeerConnection to let the local
|
|
5954
|
+
* end know this negotiation must occur.
|
|
5955
|
+
*
|
|
5956
|
+
* @param sender - An RTCRtpSender specifying the sender to remove from the connection.
|
|
5957
|
+
*/
|
|
5958
|
+
removeTrack(sender) {
|
|
5959
|
+
this.pc.removeTrack(sender);
|
|
5960
|
+
}
|
|
5961
|
+
/**
|
|
5962
|
+
* Creates a new data channel linked with the remote peer.
|
|
5963
|
+
*
|
|
5964
|
+
* @param label - A human-readable name for the channel. May not be longer than 65,535 bytes.
|
|
5965
|
+
* @param options - An object providing configuration options for the data channel.
|
|
5966
|
+
* @returns An RTCDataChannel object.
|
|
5967
|
+
*/
|
|
5968
|
+
createDataChannel(label, options) {
|
|
5969
|
+
return this.pc.createDataChannel(label, options);
|
|
5970
|
+
}
|
|
5971
|
+
/**
|
|
5972
|
+
* Creates an SDP answer to an offer received from a remote peer during the offer/answer
|
|
5973
|
+
* negotiation of a WebRTC connection.
|
|
5974
|
+
*
|
|
5975
|
+
* @param options - (Optional) An object which contains options which customize the answer; this
|
|
5976
|
+
* is based on the RTCAnswerOptions dictionary.
|
|
5977
|
+
* @returns A Promise whose fulfillment handler is called with an object conforming to the
|
|
5978
|
+
* RTCSessionDescriptionInit dictionary which contains the SDP answer to be delivered to the
|
|
5979
|
+
* other peer.
|
|
5980
|
+
*/
|
|
5981
|
+
createAnswer(options) {
|
|
5982
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
5983
|
+
return this.pc.createAnswer(options).then((answer) => {
|
|
5984
|
+
this.emit(PeerConnection.Events.CreateAnswerOnSuccess, answer);
|
|
5985
|
+
return answer;
|
|
5986
|
+
});
|
|
5987
|
+
});
|
|
5988
|
+
}
|
|
5989
|
+
/**
|
|
5990
|
+
* Initiates the creation of an SDP offer for the purpose of starting a new WebRTC connection to a
|
|
5991
|
+
* remote peer.
|
|
5992
|
+
*
|
|
5993
|
+
* @param options - (Optional) An RTCOfferOptions dictionary providing options requested for the
|
|
5994
|
+
* offer.
|
|
5995
|
+
* @returns A Promise whose fulfillment handler will receive an object conforming to the
|
|
5996
|
+
* RTCSessionDescriptionInit dictionary which contains the SDP describing the generated offer.
|
|
5997
|
+
* That received offer should be delivered through the signaling server to a remote peer.
|
|
5998
|
+
*/
|
|
5999
|
+
createOffer(options) {
|
|
6000
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
6001
|
+
return this.pc.createOffer(options).then((offer) => {
|
|
6002
|
+
this.emit(PeerConnection.Events.CreateOfferOnSuccess, offer);
|
|
6003
|
+
return offer;
|
|
6004
|
+
});
|
|
6005
|
+
});
|
|
6006
|
+
}
|
|
6007
|
+
/**
|
|
6008
|
+
* Changes the local description associated with the connection.
|
|
6009
|
+
*
|
|
6010
|
+
* @param description - An RTCSessionDescriptionInit or RTCSessionDescription which specifies the
|
|
6011
|
+
* configuration to be applied to the local end of the connection.
|
|
6012
|
+
* @returns A Promise which is fulfilled once the value of RTCPeerConnection.localDescription is
|
|
6013
|
+
* successfully changed or rejected if the change cannot be applied.
|
|
6014
|
+
*/
|
|
6015
|
+
setLocalDescription(description) {
|
|
6016
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
6017
|
+
var _a;
|
|
6018
|
+
// In Firefox, setLocalDescription will not throw an error if an m-line has no codecs, even
|
|
6019
|
+
// though it violates https://datatracker.ietf.org/doc/html/rfc8866. See
|
|
6020
|
+
// https://bugzilla.mozilla.org/show_bug.cgi?id=1857612. So, we check the media lines here to
|
|
6021
|
+
// preemptively throw an error on Firefox.
|
|
6022
|
+
if (BrowserInfo$1.isFirefox()) {
|
|
6023
|
+
(_a = description === null || description === void 0 ? void 0 : description.sdp) === null || _a === void 0 ? void 0 : _a.split(/(\r\n|\r|\n)/).filter((line) => line.startsWith('m')).forEach((mediaLine) => {
|
|
6024
|
+
if (mediaLine.trim().split(' ').length < 4) {
|
|
6025
|
+
throw new Error(`Invalid media line ${mediaLine}, expected at least 4 fields`);
|
|
6026
|
+
}
|
|
6027
|
+
});
|
|
6028
|
+
}
|
|
6029
|
+
return this.pc.setLocalDescription(description).then(() => {
|
|
6030
|
+
if (description) {
|
|
6031
|
+
this.emit(PeerConnection.Events.SetLocalDescriptionOnSuccess, description);
|
|
6032
|
+
}
|
|
6033
|
+
});
|
|
6034
|
+
});
|
|
6035
|
+
}
|
|
6036
|
+
/**
|
|
6037
|
+
* Sets the specified session description as the remote peer's current offer or answer.
|
|
6038
|
+
*
|
|
6039
|
+
* @param description - An RTCSessionDescriptionInit or RTCSessionDescription which specifies the
|
|
6040
|
+
* remote peer's current offer or answer.
|
|
6041
|
+
* @returns A Promise which is fulfilled once the value of the connection's remoteDescription is
|
|
6042
|
+
* successfully changed or rejected if the change cannot be applied (for example, if the
|
|
6043
|
+
* specified description is incompatible with one or both of the peers on the connection).
|
|
6044
|
+
*/
|
|
6045
|
+
setRemoteDescription(description) {
|
|
6046
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
6047
|
+
return this.pc.setRemoteDescription(description).then(() => {
|
|
6048
|
+
this.emit(PeerConnection.Events.SetRemoteDescriptionOnSuccess, description);
|
|
6049
|
+
});
|
|
6050
|
+
});
|
|
6051
|
+
}
|
|
6052
|
+
/**
|
|
6053
|
+
* Closes the current peer connection.
|
|
6054
|
+
*/
|
|
6055
|
+
close() {
|
|
6056
|
+
this.pc.close();
|
|
6057
|
+
}
|
|
6058
|
+
/**
|
|
6059
|
+
* Get the local description from this PeerConnection.
|
|
6060
|
+
*
|
|
6061
|
+
* @returns An RTCSessionDescription representing the local description, or null if none has been set.
|
|
6062
|
+
*/
|
|
6063
|
+
getLocalDescription() {
|
|
6064
|
+
return this.pc.localDescription;
|
|
6065
|
+
}
|
|
6066
|
+
/**
|
|
6067
|
+
* Get the remote description from this PeerConnection.
|
|
6068
|
+
*
|
|
6069
|
+
* @returns An RTCSessionDescription representing the remote description, or null if none has been set.
|
|
6070
|
+
*/
|
|
6071
|
+
getRemoteDescription() {
|
|
6072
|
+
return this.pc.remoteDescription;
|
|
6073
|
+
}
|
|
6074
|
+
/**
|
|
6075
|
+
* Returns an array of RTCRtpSender objects, each of which represents the RTP sender responsible
|
|
6076
|
+
* for transmitting one track's data. A sender object provides methods and properties for
|
|
6077
|
+
* examining and controlling the encoding and transmission of the track's data.
|
|
6078
|
+
*
|
|
6079
|
+
* @returns An array of RTCRtpSender objects, one for each track on the connection. The array is
|
|
6080
|
+
* empty if there are no RTP senders on the connection.
|
|
6081
|
+
*/
|
|
6082
|
+
getSenders() {
|
|
6083
|
+
return this.pc.getSenders();
|
|
6084
|
+
}
|
|
6085
|
+
/**
|
|
6086
|
+
* Get the list of RTCRtpTransceiver objects being used to send and receive data on the
|
|
6087
|
+
* connection.
|
|
6088
|
+
*
|
|
6089
|
+
* @returns - An array of the RTCRtpTransceiver objects representing the transceivers handling
|
|
6090
|
+
* sending and receiving all media on the PeerConnection. The list is in the order in which the
|
|
6091
|
+
* transceivers were added to the connection.
|
|
6092
|
+
*/
|
|
6093
|
+
getTransceivers() {
|
|
6094
|
+
return this.pc.getTransceivers();
|
|
6095
|
+
}
|
|
6096
|
+
/**
|
|
6097
|
+
* Get statistics about either the overall connection or about the specified MediaStreamTrack.
|
|
6098
|
+
*
|
|
6099
|
+
* @param selector - An optional MediaStreamTrack for which to gather statistics. If not provided,
|
|
6100
|
+
* statistics will be gathered for the entire underlying RTCPeerConnection.
|
|
6101
|
+
* @returns - A Promise which resolves with an RTCStatsReport object providing connection
|
|
6102
|
+
* statistics.
|
|
6103
|
+
*/
|
|
6104
|
+
getStats(selector) {
|
|
6105
|
+
return this.pc.getStats(selector);
|
|
6106
|
+
}
|
|
6107
|
+
/**
|
|
6108
|
+
* Returns a string that describes the connections' ICE gathering state.
|
|
6109
|
+
*
|
|
6110
|
+
* @returns - The ICE gathering state.
|
|
6111
|
+
*/
|
|
6112
|
+
get iceGatheringState() {
|
|
6113
|
+
return this.pc.iceGatheringState;
|
|
6114
|
+
}
|
|
6115
|
+
/**
|
|
6116
|
+
* Returns the type of a connection that has been established.
|
|
6117
|
+
*
|
|
6118
|
+
* @returns The connection type which would be `ConnectionType`.
|
|
6119
|
+
*/
|
|
6120
|
+
getCurrentConnectionType() {
|
|
6121
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
6122
|
+
var _a;
|
|
6123
|
+
// make sure this method only can be called when the ice connection is established;
|
|
6124
|
+
const isIceConnected = this.pc.iceConnectionState === 'connected' || this.pc.iceConnectionState === 'completed';
|
|
6125
|
+
if (!isIceConnected) {
|
|
6126
|
+
throw new Error('Ice connection is not established');
|
|
6127
|
+
}
|
|
6128
|
+
const succeededLocalCandidateIds = new Set();
|
|
6129
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6130
|
+
const localCandidateStatsReports = [];
|
|
6131
|
+
(yield this.pc.getStats()).forEach((report) => {
|
|
6132
|
+
var _a;
|
|
6133
|
+
// collect all local candidate ids from `candidate-pair` stats reports with `succeeded` state.
|
|
6134
|
+
if (report.type === 'candidate-pair' && ((_a = report.state) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === 'succeeded') {
|
|
6135
|
+
succeededLocalCandidateIds.add(report.localCandidateId);
|
|
6136
|
+
}
|
|
6137
|
+
// collect all `local-candidate` stats.
|
|
6138
|
+
if (report.type === 'local-candidate') {
|
|
6139
|
+
localCandidateStatsReports.push(report);
|
|
6140
|
+
}
|
|
6141
|
+
});
|
|
6142
|
+
// find the `local-candidate` stats which report id contains in `succeededLocalCandidateIds`.
|
|
6143
|
+
const localCandidate = localCandidateStatsReports.find((report) => succeededLocalCandidateIds.has(report.id));
|
|
6144
|
+
if (!localCandidate) {
|
|
6145
|
+
return 'unknown';
|
|
6146
|
+
}
|
|
6147
|
+
if (localCandidate.relayProtocol) {
|
|
6148
|
+
return `TURN-${localCandidate.relayProtocol.toUpperCase()}`;
|
|
6149
|
+
}
|
|
6150
|
+
return (_a = localCandidate.protocol) === null || _a === void 0 ? void 0 : _a.toUpperCase();
|
|
6151
|
+
});
|
|
6152
|
+
}
|
|
6153
|
+
}
|
|
6119
6154
|
PeerConnection.Events = PeerConnectionEvents;
|
|
6120
6155
|
|
|
6121
6156
|
var commonjsGlobal$2 = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
@@ -9505,10 +9540,6 @@ const simulcastMaxFrameSizes = {
|
|
|
9505
9540
|
};
|
|
9506
9541
|
|
|
9507
9542
|
class JmpLine extends Line {
|
|
9508
|
-
constructor(versions) {
|
|
9509
|
-
super();
|
|
9510
|
-
this.versions = versions;
|
|
9511
|
-
}
|
|
9512
9543
|
static fromSdpLine(line) {
|
|
9513
9544
|
if (!JmpLine.regex.test(line)) {
|
|
9514
9545
|
return undefined;
|
|
@@ -9517,6 +9548,10 @@ class JmpLine extends Line {
|
|
|
9517
9548
|
const versions = tokens[1].split(',').filter((v) => v.length);
|
|
9518
9549
|
return new JmpLine(versions);
|
|
9519
9550
|
}
|
|
9551
|
+
constructor(versions) {
|
|
9552
|
+
super();
|
|
9553
|
+
this.versions = versions;
|
|
9554
|
+
}
|
|
9520
9555
|
toSdpLine() {
|
|
9521
9556
|
return `a=jmp:${this.versions.join(',')}`;
|
|
9522
9557
|
}
|
|
@@ -14702,13 +14737,15 @@ exports.MultistreamConnectionEventNames = void 0;
|
|
|
14702
14737
|
MultistreamConnectionEventNames["VideoSourceCountUpdate"] = "video-source-count-update";
|
|
14703
14738
|
MultistreamConnectionEventNames["AudioSourceCountUpdate"] = "audio-source-count-update";
|
|
14704
14739
|
MultistreamConnectionEventNames["ActiveSpeakerNotification"] = "active-speaker-notification";
|
|
14705
|
-
MultistreamConnectionEventNames["
|
|
14740
|
+
MultistreamConnectionEventNames["PeerConnectionStateUpdate"] = "peer-connection-state-update";
|
|
14741
|
+
MultistreamConnectionEventNames["IceConnectionStateUpdate"] = "ice-connection-state-update";
|
|
14706
14742
|
MultistreamConnectionEventNames["IceGatheringStateUpdate"] = "ice-gathering-state-update";
|
|
14707
14743
|
MultistreamConnectionEventNames["NegotiationNeeded"] = "negotiation-needed";
|
|
14708
14744
|
MultistreamConnectionEventNames["CreateOfferOnSuccess"] = "createofferonsuccess";
|
|
14709
14745
|
MultistreamConnectionEventNames["CreateAnswerOnSuccess"] = "createansweronsuccess";
|
|
14710
14746
|
MultistreamConnectionEventNames["SetLocalDescriptionOnSuccess"] = "setlocaldescriptiononsuccess";
|
|
14711
14747
|
MultistreamConnectionEventNames["SetRemoteDescriptionOnSuccess"] = "setremotedescriptiononsuccess";
|
|
14748
|
+
MultistreamConnectionEventNames["IceCandidateError"] = "icecandidateerror";
|
|
14712
14749
|
})(exports.MultistreamConnectionEventNames || (exports.MultistreamConnectionEventNames = {}));
|
|
14713
14750
|
const defaultMultistreamConnectionOptions = {
|
|
14714
14751
|
disableSimulcast: BrowserInfo.isFirefox(),
|
|
@@ -14756,8 +14793,11 @@ class MultistreamConnection extends EventEmitter$2 {
|
|
|
14756
14793
|
this.createDataChannel();
|
|
14757
14794
|
}
|
|
14758
14795
|
propagatePeerConnectionEvents() {
|
|
14759
|
-
this.pc.on(PeerConnection.Events.
|
|
14760
|
-
this.emit(exports.MultistreamConnectionEventNames.
|
|
14796
|
+
this.pc.on(PeerConnection.Events.PeerConnectionStateChange, (state) => {
|
|
14797
|
+
this.emit(exports.MultistreamConnectionEventNames.PeerConnectionStateUpdate, state);
|
|
14798
|
+
});
|
|
14799
|
+
this.pc.on(PeerConnection.Events.IceConnectionStateChange, (state) => {
|
|
14800
|
+
this.emit(exports.MultistreamConnectionEventNames.IceConnectionStateUpdate, state);
|
|
14761
14801
|
});
|
|
14762
14802
|
this.pc.on(PeerConnection.Events.CreateOfferOnSuccess, (description) => {
|
|
14763
14803
|
this.emit(exports.MultistreamConnectionEventNames.CreateOfferOnSuccess, description);
|
|
@@ -14774,10 +14814,22 @@ class MultistreamConnection extends EventEmitter$2 {
|
|
|
14774
14814
|
this.pc.on(PeerConnection.Events.IceGatheringStateChange, () => {
|
|
14775
14815
|
this.emit(exports.MultistreamConnectionEventNames.IceGatheringStateUpdate, this.getIceGatheringState());
|
|
14776
14816
|
});
|
|
14817
|
+
this.pc.on(PeerConnection.Events.IceCandidateError, (error) => {
|
|
14818
|
+
this.emit(exports.MultistreamConnectionEventNames.IceCandidateError, error);
|
|
14819
|
+
});
|
|
14777
14820
|
}
|
|
14778
14821
|
getConnectionState() {
|
|
14779
14822
|
return this.pc.getConnectionState();
|
|
14780
14823
|
}
|
|
14824
|
+
getPeerConnectionState() {
|
|
14825
|
+
return this.pc.getPeerConnectionState();
|
|
14826
|
+
}
|
|
14827
|
+
getIceConnectionState() {
|
|
14828
|
+
return this.pc.getIceConnectionState();
|
|
14829
|
+
}
|
|
14830
|
+
getCurrentConnectionType() {
|
|
14831
|
+
return this.pc.getCurrentConnectionType();
|
|
14832
|
+
}
|
|
14781
14833
|
getIceGatheringState() {
|
|
14782
14834
|
return this.pc.iceGatheringState;
|
|
14783
14835
|
}
|