@webex/web-client-media-engine 3.27.0 → 3.28.1

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 CHANGED
@@ -362,10 +362,11 @@ function getUserMedia(constraints) {
362
362
  }
363
363
  /**
364
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.
365
+ * absent from the constraints argument, one will still be provided. Includes experimental options
366
+ * found in https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia#options.
366
367
  *
367
368
  * @param constraints - A MediaStreamConstraints object specifying the types of media to request,
368
- * along with any requirements for each type.
369
+ * along with any requirements for each type, as well as experimental options.
369
370
  * @returns A Promise whose fulfillment handler receives a MediaStream object when the requested
370
371
  * media has successfully been obtained.
371
372
  */
@@ -514,11 +515,11 @@ class WebrtcCoreError {
514
515
  * 1. Previous captured video stream from the same device is not stopped.
515
516
  * 2. Previous createCameraStream() call for the same device is in progress.
516
517
  *
517
- * @param constructor - Constructor for the local camera stream.
518
+ * @param cameraStreamConstructor - Constructor for the local camera stream.
518
519
  * @param constraints - Video device constraints.
519
520
  * @returns A LocalCameraStream object or an error.
520
521
  */
521
- function createCameraStream(constructor, constraints) {
522
+ function createCameraStream(cameraStreamConstructor, constraints) {
522
523
  return __awaiter$2(this, void 0, void 0, function* () {
523
524
  let stream;
524
525
  try {
@@ -527,17 +528,18 @@ function createCameraStream(constructor, constraints) {
527
528
  catch (error) {
528
529
  throw new WebrtcCoreError(exports.WebrtcCoreErrorType.CREATE_STREAM_FAILED, `Failed to create camera stream: ${error}`);
529
530
  }
530
- return new constructor(stream);
531
+ // eslint-disable-next-line new-cap
532
+ return new cameraStreamConstructor(stream);
531
533
  });
532
534
  }
533
535
  /**
534
536
  * Creates a LocalMicrophoneStream with the given constraints.
535
537
  *
536
- * @param constructor - Constructor for the local microphone stream.
538
+ * @param microphoneStreamConstructor - Constructor for the local microphone stream.
537
539
  * @param constraints - Audio device constraints.
538
540
  * @returns A LocalMicrophoneStream object or an error.
539
541
  */
540
- function createMicrophoneStream(constructor, constraints) {
542
+ function createMicrophoneStream(microphoneStreamConstructor, constraints) {
541
543
  return __awaiter$2(this, void 0, void 0, function* () {
542
544
  let stream;
543
545
  try {
@@ -546,64 +548,132 @@ function createMicrophoneStream(constructor, constraints) {
546
548
  catch (error) {
547
549
  throw new WebrtcCoreError(exports.WebrtcCoreErrorType.CREATE_STREAM_FAILED, `Failed to create microphone stream: ${error}`);
548
550
  }
549
- return new constructor(stream);
551
+ // eslint-disable-next-line new-cap
552
+ return new microphoneStreamConstructor(stream);
550
553
  });
551
554
  }
552
555
  /**
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.
556
+ * Creates a LocalCameraStream and a LocalMicrophoneStream with the given constraints.
557
+ *
558
+ * @param cameraStreamConstructor - Constructor for the local camera stream.
559
+ * @param microphoneStreamConstructor - Constructor for the local microphone stream.
560
+ * @param constraints - Object containing video and audio device constraints.
561
+ * @param constraints.video - Video device constraints.
562
+ * @param constraints.audio - Audio device constraints.
563
+ * @returns A Promise that resolves to a LocalCameraStream and a LocalMicrophoneStream or an error.
558
564
  */
559
- function createDisplayStream(constructor, videoContentHint) {
565
+ function createCameraAndMicrophoneStreams(cameraStreamConstructor, microphoneStreamConstructor, constraints) {
560
566
  return __awaiter$2(this, void 0, void 0, function* () {
561
567
  let stream;
562
568
  try {
563
- stream = yield getDisplayMedia({ video: true });
569
+ stream = yield getUserMedia({
570
+ video: Object.assign({}, constraints === null || constraints === void 0 ? void 0 : constraints.video),
571
+ audio: Object.assign({}, constraints === null || constraints === void 0 ? void 0 : constraints.audio),
572
+ });
564
573
  }
565
574
  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;
575
+ throw new WebrtcCoreError(exports.WebrtcCoreErrorType.CREATE_STREAM_FAILED, `Failed to create camera and microphone streams: ${error}`);
571
576
  }
572
- return localDisplayStream;
577
+ // eslint-disable-next-line new-cap
578
+ const localCameraStream = new cameraStreamConstructor(new MediaStream(stream.getVideoTracks()));
579
+ // eslint-disable-next-line new-cap
580
+ const localMicrophoneStream = new microphoneStreamConstructor(new MediaStream(stream.getAudioTracks()));
581
+ return [localCameraStream, localMicrophoneStream];
573
582
  });
574
583
  }
575
584
  /**
576
585
  * Creates a LocalDisplayStream and a LocalSystemAudioStream with the given parameters.
577
586
  *
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.
587
+ * This is a more advanced version of createDisplayStreamWithAudio that allows the user to specify
588
+ * additional display media options and constraints.
589
+ *
590
+ * See https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia#options.
591
+ *
592
+ * @param options - An object containing the options for creating the display and system audio streams.
593
+ * @param options.video - An object containing the video stream options.
594
+ * @param options.video.displayStreamConstructor - Constructor for the local display stream.
595
+ * @param options.video.constraints - Video device constraints.
596
+ * @param options.video.videoContentHint - A hint for the content of the stream.
597
+ * @param options.video.preferCurrentTab - Whether to offer the current tab as the most prominent capture source.
598
+ * @param options.video.selfBrowserSurface - Whether to allow the user to select the current tab for capture.
599
+ * @param options.video.surfaceSwitching - Whether to allow the user to dynamically switch the shared tab during screen-sharing.
600
+ * @param options.video.monitorTypeSurfaces - Whether to offer the user the option to choose display surfaces whose type is monitor.
601
+ * @param options.audio - An object containing the audio stream options. If present, a system audio stream will be created.
602
+ * @param options.audio.systemAudioStreamConstructor - Constructor for the local system audio stream.
603
+ * @param options.audio.constraints - Audio device constraints.
604
+ * @param options.audio.systemAudio - Whether to include the system audio among the possible audio sources offered to the user.
605
+ * @param options.controller - CaptureController to further manipulate the capture session.
581
606
  * @returns A Promise that resolves to a LocalDisplayStream and a LocalSystemAudioStream or an
582
607
  * error. If no system audio is available, the LocalSystemAudioStream will be resolved as null
583
608
  * instead.
584
609
  */
585
- function createDisplayStreamWithAudio(displayStreamConstructor, systemAudioStreamConstructor, videoContentHint) {
610
+ function createDisplayMedia(options) {
586
611
  return __awaiter$2(this, void 0, void 0, function* () {
612
+ var _a, _b;
587
613
  let stream;
614
+ const videoConstraints = options.video.constraints || true;
615
+ const audioConstraints = ((_a = options.audio) === null || _a === void 0 ? void 0 : _a.constraints) || !!options.audio;
588
616
  try {
589
- stream = yield getDisplayMedia({ video: true, audio: true });
617
+ stream = yield getDisplayMedia({
618
+ video: videoConstraints,
619
+ audio: audioConstraints,
620
+ controller: options.controller,
621
+ preferCurrentTab: options.video.preferCurrentTab,
622
+ selfBrowserSurface: options.video.selfBrowserSurface,
623
+ surfaceSwitching: options.video.surfaceSwitching,
624
+ systemAudio: (_b = options.audio) === null || _b === void 0 ? void 0 : _b.systemAudio,
625
+ monitorTypeSurfaces: options.video.monitorTypeSurfaces,
626
+ });
590
627
  }
591
628
  catch (error) {
592
- throw new WebrtcCoreError(exports.WebrtcCoreErrorType.CREATE_STREAM_FAILED, `Failed to create display and system audio streams: ${error}`);
629
+ throw new WebrtcCoreError(exports.WebrtcCoreErrorType.CREATE_STREAM_FAILED, `Failed to create display and/or system audio streams: ${error}`);
593
630
  }
594
631
  // eslint-disable-next-line new-cap
595
- const localDisplayStream = new displayStreamConstructor(new MediaStream(stream.getVideoTracks()));
596
- if (videoContentHint) {
597
- localDisplayStream.contentHint = videoContentHint;
632
+ const localDisplayStream = new options.video.displayStreamConstructor(new MediaStream(stream.getVideoTracks()));
633
+ if (options.video.videoContentHint) {
634
+ localDisplayStream.contentHint = options.video.videoContentHint;
598
635
  }
599
636
  let localSystemAudioStream = null;
600
- if (stream.getAudioTracks().length > 0) {
637
+ if (options.audio && stream.getAudioTracks().length > 0) {
601
638
  // eslint-disable-next-line new-cap
602
- localSystemAudioStream = new systemAudioStreamConstructor(new MediaStream(stream.getAudioTracks()));
639
+ localSystemAudioStream = new options.audio.systemAudioStreamConstructor(new MediaStream(stream.getAudioTracks()));
603
640
  }
604
641
  return [localDisplayStream, localSystemAudioStream];
605
642
  });
606
643
  }
644
+ /**
645
+ * Creates a LocalDisplayStream with the given parameters.
646
+ *
647
+ * @param displayStreamConstructor - Constructor for the local display stream.
648
+ * @param videoContentHint - An optional parameter to give a hint for the content of the stream.
649
+ * @returns A Promise that resolves to a LocalDisplayStream or an error.
650
+ */
651
+ function createDisplayStream(displayStreamConstructor, videoContentHint) {
652
+ return __awaiter$2(this, void 0, void 0, function* () {
653
+ const [localDisplayStream] = yield createDisplayMedia({
654
+ video: { displayStreamConstructor, videoContentHint },
655
+ });
656
+ return localDisplayStream;
657
+ });
658
+ }
659
+ /**
660
+ * Creates a LocalDisplayStream and a LocalSystemAudioStream with the given parameters.
661
+ *
662
+ * @param displayStreamConstructor - Constructor for the local display stream.
663
+ * @param systemAudioStreamConstructor - Constructor for the local system audio stream.
664
+ * @param videoContentHint - An optional parameter to give a hint for the content of the stream.
665
+ * @returns A Promise that resolves to a LocalDisplayStream and a LocalSystemAudioStream or an
666
+ * error. If no system audio is available, the LocalSystemAudioStream will be resolved as null
667
+ * instead.
668
+ */
669
+ function createDisplayStreamWithAudio(displayStreamConstructor, systemAudioStreamConstructor, videoContentHint) {
670
+ return __awaiter$2(this, void 0, void 0, function* () {
671
+ return createDisplayMedia({
672
+ video: { displayStreamConstructor, videoContentHint },
673
+ audio: { systemAudioStreamConstructor },
674
+ });
675
+ });
676
+ }
607
677
  /**
608
678
  * Enumerates the media input and output devices available.
609
679
  *
@@ -7496,6 +7566,8 @@ const maxFrameSizeToMaxBitrateMap = new Map([
7496
7566
  [3600, 2500000],
7497
7567
  [8160, 4000000],
7498
7568
  ]);
7569
+ const defaultVideoMainRtxTime = '300';
7570
+ const defaultVideoSlidesRtxTime = '1000';
7499
7571
  function areProfileLevelIdsCompatible(senderProfileLevelId, receiverProfileLevelId, levelAsymmetryAllowed) {
7500
7572
  const senderProfile = Number.parseInt(`0x${senderProfileLevelId}`, 16);
7501
7573
  const recvProfile = Number.parseInt(`0x${receiverProfileLevelId}`, 16);
@@ -9734,10 +9806,10 @@ function addVlaExtension(mediaDescription) {
9734
9806
  mediaDescription.addExtension({ uri: vlaExtensionUri });
9735
9807
  }
9736
9808
  }
9737
- function applyFormatParameters(mediaDescription, paramsMap) {
9809
+ function applyFormatParameters(mediaDescription, codecs, paramsMap) {
9738
9810
  paramsMap.forEach((value, param) => {
9739
9811
  [...mediaDescription.codecs.values()]
9740
- .filter((ci) => ci.name === 'H264' || ci.name === 'opus')
9812
+ .filter((ci) => ci.name && codecs.includes(ci.name))
9741
9813
  .forEach((ci) => {
9742
9814
  if (value === null) {
9743
9815
  ci.fmtParams.delete(param);
@@ -9858,7 +9930,7 @@ class EgressSdpMunger {
9858
9930
  if (options.simulcastEnabled) {
9859
9931
  mediaDescription.addLine(new SsrcGroupLine('SIM', this.streamIds.map((streamId) => streamId.ssrc)));
9860
9932
  }
9861
- applyFormatParameters(mediaDescription, this.customCodecParameters);
9933
+ applyFormatParameters(mediaDescription, ['H264', 'opus'], this.customCodecParameters);
9862
9934
  if (options.twccDisabled) {
9863
9935
  disableTwcc(mediaDescription);
9864
9936
  }
@@ -10386,6 +10458,7 @@ class EventEmitter$2 extends events$1.exports.EventEmitter {
10386
10458
 
10387
10459
  class IngressSdpMunger {
10388
10460
  constructor() {
10461
+ this.customRtxCodecParameters = new Map();
10389
10462
  this.ssrc = generateSsrc();
10390
10463
  }
10391
10464
  getReceiverId() {
@@ -10397,6 +10470,7 @@ class IngressSdpMunger {
10397
10470
  logErrorAndThrow(exports.WcmeErrorType.SDP_MUNGE_MISSING_CODECS, `No codecs present in m-line with MID ${mediaDescription.mid} after filtering.`);
10398
10471
  }
10399
10472
  removeMidRidExtensions(mediaDescription);
10473
+ applyFormatParameters(mediaDescription, ['rtx'], this.customRtxCodecParameters);
10400
10474
  if (options.twccDisabled) {
10401
10475
  disableTwcc(mediaDescription);
10402
10476
  }
@@ -10420,6 +10494,12 @@ class IngressSdpMunger {
10420
10494
  [...mediaDescription.codecs.values()].forEach((ci) => {
10421
10495
  ci.fmtParams.set('x-google-start-bitrate', '60000');
10422
10496
  });
10497
+ applyFormatParameters(mediaDescription, ['rtx'], this.customRtxCodecParameters);
10498
+ }
10499
+ setRtxCodecParameters(parameters) {
10500
+ Object.entries(parameters).forEach(([param, value]) => {
10501
+ this.customRtxCodecParameters.set(param, value);
10502
+ });
10423
10503
  }
10424
10504
  reset() {
10425
10505
  this.ssrc = generateSsrc();
@@ -10638,7 +10718,9 @@ class ReceiveOnlyTransceiver extends Transceiver {
10638
10718
  });
10639
10719
  }
10640
10720
  mungeLocalDescription(mediaDescription) {
10641
- this.munger.mungeLocalDescription(mediaDescription, { twccDisabled: this.twccDisabled });
10721
+ this.munger.mungeLocalDescription(mediaDescription, {
10722
+ twccDisabled: this.twccDisabled,
10723
+ });
10642
10724
  }
10643
10725
  mungeRemoteDescription(mediaDescription) {
10644
10726
  this.munger.mungeRemoteDescription(mediaDescription);
@@ -10675,6 +10757,9 @@ class ReceiveOnlyTransceiver extends Transceiver {
10675
10757
  this.metadata.lastActiveSpeakerUpdateTimestamp = getCurrentTimestamp();
10676
10758
  }
10677
10759
  }
10760
+ setRtxCodecParameters(parameters) {
10761
+ this.munger.setRtxCodecParameters(parameters);
10762
+ }
10678
10763
  }
10679
10764
  ReceiveOnlyTransceiver.rid = '1';
10680
10765
 
@@ -15231,6 +15316,11 @@ SCTP Max Message Size: ${maxMessageSize}`);
15231
15316
  mediaType,
15232
15317
  munger,
15233
15318
  });
15319
+ if (getMediaFamily(mediaType) === exports.MediaFamily.Video) {
15320
+ recvOnlyTransceiver.setRtxCodecParameters({
15321
+ 'rtx-time': mediaType === exports.MediaType.VideoMain ? defaultVideoMainRtxTime : defaultVideoSlidesRtxTime,
15322
+ });
15323
+ }
15234
15324
  recvOnlyTransceiver.twccDisabled =
15235
15325
  getMediaFamily(mediaType) === exports.MediaFamily.Audio ? this.options.disableAudioTwcc : false;
15236
15326
  this.recvTransceivers.set(mediaType, [
@@ -15710,7 +15800,9 @@ exports.WcmeError = WcmeError;
15710
15800
  exports.WebRtcCoreLogger = Logger$2;
15711
15801
  exports.WebrtcCoreError = WebrtcCoreError;
15712
15802
  exports.areReceiveSlotIdsEqual = areReceiveSlotIdsEqual;
15803
+ exports.createCameraAndMicrophoneStreams = createCameraAndMicrophoneStreams;
15713
15804
  exports.createCameraStream = createCameraStream;
15805
+ exports.createDisplayMedia = createDisplayMedia;
15714
15806
  exports.createDisplayStream = createDisplayStream;
15715
15807
  exports.createDisplayStreamWithAudio = createDisplayStreamWithAudio;
15716
15808
  exports.createMicrophoneStream = createMicrophoneStream;