@opentok/client 2.27.6 → 2.28.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.
@@ -277,6 +277,10 @@ declare namespace OT {
277
277
  track: MediaStreamTrack | undefined
278
278
  };
279
279
 
280
+ mediaStreamAvailable: Event<'mediaStreamAvailable', Publisher> & {
281
+ mediaStream: MediaStream;
282
+ };
283
+
280
284
  streamCreated: Event<'streamCreated', Publisher> & {
281
285
  stream: Stream;
282
286
  };
@@ -549,6 +553,10 @@ declare namespace OT {
549
553
 
550
554
  encryptionSecretMatch: Event<'encryptionSecretMatch', Subscriber>;
551
555
 
556
+ mediaStreamAvailable: Event<'mediaStreamAvailable', Subscriber> & {
557
+ mediaStream: MediaStream;
558
+ };
559
+
552
560
  videoDimensionsChanged: VideoDimensionsChangedEvent<Subscriber>;
553
561
 
554
562
  videoDisabled: Event<'videoDisabled', Subscriber> & {
@@ -1,11 +1,11 @@
1
1
  /**
2
- * @license OpenTok.js 2.27.6 cf306f8
2
+ * @license OpenTok.js 2.28.0 1ea3fa6
3
3
  *
4
4
  * Copyright (c) 2010-2024 TokBox, Inc.
5
5
  * Subject to the applicable Software Development Kit (SDK) License Agreement:
6
6
  * https://www.vonage.com/legal/communications-apis/terms-of-use/
7
7
  *
8
- * Date: Wed, 05 Jun 2024 14:03:04 GMT
8
+ * Date: Wed, 26 Jun 2024 15:49:08 GMT
9
9
  */
10
10
 
11
11
  (function webpackUniversalModuleDefinition(root, factory) {
@@ -6753,6 +6753,29 @@ function EventsFactory(deps) {
6753
6753
  captionsEnabled
6754
6754
  });
6755
6755
  };
6756
+
6757
+ /**
6758
+ * This is a <b>beta</b> feature.
6759
+ * Defines an event object for the <code>mediaStreamAvailable</code> event dispatched by both
6760
+ * the Publisher and Subscriber objects. The Publisher and Subscriber objects both dispatch a <code>mediaStreamAvailable</code>
6761
+ * event when the MediaStream is available to be used in custom video elements. The Publisher and Subscriber objects should still be used to
6762
+ * control all other aspects of the video API such as muting, disconnecting, and more.
6763
+ *
6764
+ * <p>Note that the audio will play through both the custom element and the Publisher or Subscriber widget.
6765
+ * The custom elements should be muted to avoid echo.</p>
6766
+ *
6767
+ * @property {MediaStream} mediaStream The MediaStream object.
6768
+ * @see <a href="Publisher.html#event:mediaStreamAvailable">Publisher mediaStreamAvailable
6769
+ * event</a>
6770
+ * @see <a href="Subscriber.html#event:mediaStreamAvailable">Subscriber mediaStreamAvailable
6771
+ * event</a>
6772
+ * @augments Event
6773
+ */
6774
+ Events.MediaStreamAvailable = function MediaStreamAvailable(mediaStream) {
6775
+ return new _Event4.default('mediaStreamAvailable', false, {
6776
+ mediaStream
6777
+ });
6778
+ };
6756
6779
  Events.StreamUpdatedEvent = function StreamUpdatedEvent(stream, key, oldValue, newValue) {
6757
6780
  return new _Event4.default('updated', false, {
6758
6781
  target: stream,
@@ -7922,7 +7945,7 @@ const logging = (0, _log.default)('StaticConfig');
7922
7945
  */
7923
7946
 
7924
7947
  /** @type builtInConfig */
7925
- const builtInConfig = (0, _cloneDeep.default)({"version":"v2.27.6","buildHash":"cf306f8","minimumVersion":{"firefox":52,"chrome":49},"debug":false,"websiteURL":"http://www.tokbox.com","configURL":"https://config.opentok.com","ipWhitelistConfigURL":"","cdnURL":"","loggingURL":"https://hlg.tokbox.com/prod","apiURL":"https://anvil.opentok.com"});
7948
+ const builtInConfig = (0, _cloneDeep.default)({"version":"v2.28.0","buildHash":"1ea3fa6","minimumVersion":{"firefox":52,"chrome":49},"debug":false,"websiteURL":"http://www.tokbox.com","configURL":"https://config.opentok.com","ipWhitelistConfigURL":"","cdnURL":"","loggingURL":"https://hlg.tokbox.com/prod","apiURL":"https://anvil.opentok.com"});
7926
7949
  const whitelistAllowedRuntimeProperties = (0, _pick.default)(['apiURL', 'assetURL', 'cdnURL', 'sessionInfoOverrides', 'loggingURL']);
7927
7950
  const liveConfigMap = {
7928
7951
  apiUrl: 'apiURL',
@@ -18472,6 +18495,7 @@ function PublisherFactory(_ref) {
18472
18495
  }
18473
18496
  });
18474
18497
  widgetView.on('videoElementCreated', element => {
18498
+ this.dispatchEvent(new Events.MediaStreamAvailable(webRTCStream));
18475
18499
  const event = new Events.VideoElementCreatedEvent(element);
18476
18500
  this.dispatchEvent(event);
18477
18501
  });
@@ -22210,6 +22234,15 @@ function PublisherFactory(_ref) {
22210
22234
  * @memberof Publisher
22211
22235
  */
22212
22236
 
22237
+ /**
22238
+ * This is a <b>beta</b> feature.
22239
+ * Dispatched when the MediaStream is available.
22240
+ * @see Event
22241
+ * @name mediaStreamAvailable
22242
+ * @event
22243
+ * @memberof Publisher
22244
+ */
22245
+
22213
22246
  /**
22214
22247
  * Dispatched when the Allow/Deny box is closed. (This is the dialog box in which the
22215
22248
  * user can grant the app access to the camera and microphone.)
@@ -33380,7 +33413,7 @@ var _amrVideoBufferError = __webpack_require__(322);
33380
33413
  var _updateTrackOnStream = _interopRequireDefault(__webpack_require__(331));
33381
33414
  var _time = _interopRequireDefault(__webpack_require__(110));
33382
33415
  var _amrStates = _interopRequireDefault(__webpack_require__(325));
33383
- const _excluded = ["AudioLevelMeter", "AudioLevelTransformer", "BackingBar", "Chrome", "env", "Errors", "Events", "ExceptionCodes", "audioLevelSamplerFactory", "getStatsHelpers", "hasAudioOutputLevelStatCapability", "hasRemoteStreamsWithWebAudio", "interpretPeerConnectionError", "logging", "MuteButton", "NamePanel", "otError", "OTErrorClass", "OTHelpers", "StylableComponent", "SubscriberPeerConnection", "SubscribingState", "VideoDisabledIndicator", "AudioBlockedIndicator", "VideoUnsupportedIndicator", "watchFrameRate", "createSendMethod", "parseIceServers", "document", "WidgetView", "createAudioConnector", "ResizeObserverPolyfill", "AMRStateDurations"];
33416
+ const _excluded = ["AudioLevelMeter", "AudioLevelTransformer", "BackingBar", "Chrome", "env", "Errors", "Events", "ExceptionCodes", "audioLevelSamplerFactory", "getStatsHelpers", "hasAudioOutputLevelStatCapability", "hasRemoteStreamsWithWebAudio", "interpretPeerConnectionError", "logging", "MuteButton", "NamePanel", "otError", "OTErrorClass", "OTHelpers", "StylableComponent", "SubscriberPeerConnection", "SubscribingState", "VideoDisabledIndicator", "AudioBlockedIndicator", "VideoUnsupportedIndicator", "watchFrameRate", "createSendMethod", "parseIceServers", "document", "WidgetView", "createAudioConnector", "ResizeObserverPolyfill", "MediaStream", "AMRStateDurations"];
33384
33417
  const defaultWidgetView = (0, _widget_view.default)();
33385
33418
  const EventsDefault = (0, _events2.default)();
33386
33419
  const errorsDefault = _Errors.default;
@@ -33485,6 +33518,8 @@ function SubscriberFactory(_ref2) {
33485
33518
  createAudioConnector = _ref3$createAudioConn === void 0 ? _audioConnector2.default : _ref3$createAudioConn,
33486
33519
  _ref3$ResizeObserverP = _ref3.ResizeObserverPolyfill,
33487
33520
  ResizeObserverPolyfill = _ref3$ResizeObserverP === void 0 ? _resizeObserverPolyfill.default : _ref3$ResizeObserverP,
33521
+ _ref3$MediaStream = _ref3.MediaStream,
33522
+ MediaStream = _ref3$MediaStream === void 0 ? (typeof window !== undefined ? window : global).MediaStream : _ref3$MediaStream,
33488
33523
  AMRStateDurations = _ref3.AMRStateDurations,
33489
33524
  deps = (0, _objectWithoutPropertiesLoose2.default)(_ref3, _excluded);
33490
33525
  const BIND_VIDEO_DELAY_MAX = 30000;
@@ -33530,7 +33565,15 @@ function SubscriberFactory(_ref2) {
33530
33565
  const webRTCStreams = {};
33531
33566
  const hybridSessionTransitionStartTimes = {};
33532
33567
  const _peerConnectionEvents = {};
33533
- const _audioConnector = createAudioConnector(webRTCStreams);
33568
+ const updateTrackOnStream = (mediaStream, oldTrack, newTrack) => {
33569
+ if (_exposedWebRTCStream) {
33570
+ (0, _updateTrackOnStream.default)(_exposedWebRTCStream, oldTrack, newTrack);
33571
+ }
33572
+ (0, _updateTrackOnStream.default)(mediaStream, oldTrack, newTrack);
33573
+ };
33574
+ const _audioConnector = createAudioConnector(webRTCStreams, {
33575
+ updateTrackOnStream
33576
+ });
33534
33577
 
33535
33578
  /** @type {defaultWidgetView|null} */
33536
33579
  let _widgetView;
@@ -33582,6 +33625,7 @@ function SubscriberFactory(_ref2) {
33582
33625
  let _originalVideoTrack;
33583
33626
  let _senderStats;
33584
33627
  let _resizeObserver;
33628
+ let _exposedWebRTCStream;
33585
33629
 
33586
33630
  // The audio stats watcher is only supported on chromium-based browsers that supports
33587
33631
  // the standard version of the getStats API.
@@ -33655,6 +33699,10 @@ function SubscriberFactory(_ref2) {
33655
33699
  isSubscriber: true
33656
33700
  }));
33657
33701
  };
33702
+ const syncUpMediaStreams = (targetStream, originalStream) => {
33703
+ (0, _updateTrackOnStream.default)(targetStream, targetStream.getAudioTracks()[0], originalStream.getAudioTracks()[0]);
33704
+ (0, _updateTrackOnStream.default)(targetStream, targetStream.getVideoTracks()[0], originalStream.getVideoTracks()[0]);
33705
+ };
33658
33706
  const bindWebRTCStream = /*#__PURE__*/function () {
33659
33707
  var _ref6 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(webRTCStream) {
33660
33708
  var _stream2;
@@ -33668,6 +33716,10 @@ function SubscriberFactory(_ref2) {
33668
33716
  }
33669
33717
  return _context3.abrupt("return");
33670
33718
  case 2:
33719
+ // Sync the track state of the exposed stream with our current stream
33720
+ if (_exposedWebRTCStream) {
33721
+ syncUpMediaStreams(_exposedWebRTCStream, webRTCStream);
33722
+ }
33671
33723
  videoContainerOptions = {
33672
33724
  error: onVideoError,
33673
33725
  audioVolume: _audioVolume,
@@ -33675,28 +33727,28 @@ function SubscriberFactory(_ref2) {
33675
33727
  }; // We want to catch any error in the prebuffering when transition to P2P.
33676
33728
  // Otherwise, we ignore it.
33677
33729
  throwIfBufferFails = _isAdaptiveEnabled && _activeSourceStreamId === 'P2P';
33678
- _context3.prev = 4;
33679
- _context3.next = 7;
33730
+ _context3.prev = 5;
33731
+ _context3.next = 8;
33680
33732
  return _widgetView.bindVideo(webRTCStream, videoContainerOptions, throwIfBufferFails);
33681
- case 7:
33682
- _context3.next = 15;
33733
+ case 8:
33734
+ _context3.next = 16;
33683
33735
  break;
33684
- case 9:
33685
- _context3.prev = 9;
33686
- _context3.t0 = _context3["catch"](4);
33736
+ case 10:
33737
+ _context3.prev = 10;
33738
+ _context3.t0 = _context3["catch"](5);
33687
33739
  if (!(_context3.t0 instanceof _cancel.CancellationError || _state.isDestroyed())) {
33688
- _context3.next = 13;
33740
+ _context3.next = 14;
33689
33741
  break;
33690
33742
  }
33691
33743
  return _context3.abrupt("return");
33692
- case 13:
33744
+ case 14:
33693
33745
  onVideoError(_context3.t0);
33694
33746
  throw _context3.t0;
33695
- case 15:
33747
+ case 16:
33696
33748
  case "end":
33697
33749
  return _context3.stop();
33698
33750
  }
33699
- }, _callee3, null, [[4, 9]]);
33751
+ }, _callee3, null, [[5, 10]]);
33700
33752
  }));
33701
33753
  return function bindWebRTCStream(_x3) {
33702
33754
  return _ref6.apply(this, arguments);
@@ -34296,6 +34348,10 @@ function SubscriberFactory(_ref2) {
34296
34348
  isSwappingStreams = Object.keys(webRTCStreams).length === 1;
34297
34349
  sourceStreamId = peerConnection == null ? void 0 : peerConnection.getSourceStreamId();
34298
34350
  _session2 = _session, sessionInfo = _session2.sessionInfo;
34351
+ if (!_exposedWebRTCStream) {
34352
+ _exposedWebRTCStream = new MediaStream(webRTCStream);
34353
+ _this.dispatchEvent(new Events.MediaStreamAvailable(_exposedWebRTCStream));
34354
+ }
34299
34355
  _webRTCStream = webRTCStream;
34300
34356
 
34301
34357
  // save a copy of the WebRTCStream
@@ -34305,21 +34361,21 @@ function SubscriberFactory(_ref2) {
34305
34361
  logging.debug('OT.Subscriber.onRemoteStreamAdded with sourceStreamId', sourceStreamId);
34306
34362
  _state.set('BindingRemoteStream');
34307
34363
  if (!_videoMediaProcessorConnector) {
34308
- _context7.next = 14;
34364
+ _context7.next = 15;
34309
34365
  break;
34310
34366
  }
34311
34367
  if (!_videoEnabled) {
34312
- _context7.next = 13;
34368
+ _context7.next = 14;
34313
34369
  break;
34314
34370
  }
34315
- _context7.next = 11;
34371
+ _context7.next = 12;
34316
34372
  return applyVideoConnectorOnStream(sourceStreamId);
34317
- case 11:
34318
- _context7.next = 14;
34373
+ case 12:
34374
+ _context7.next = 15;
34319
34375
  break;
34320
- case 13:
34321
- _videoMediaProcessorConnector.destroy();
34322
34376
  case 14:
34377
+ _videoMediaProcessorConnector.destroy();
34378
+ case 15:
34323
34379
  // Disable the audio/video, if needed
34324
34380
  _this.subscribeToAudio(_isSubscribingToAudio);
34325
34381
  if (!(_lastSubscribeToVideoReason === 'auto' && !_properties.subscribeToVideo)) {
@@ -34351,17 +34407,17 @@ function SubscriberFactory(_ref2) {
34351
34407
  }
34352
34408
  });
34353
34409
  }
34354
- _context7.prev = 18;
34355
- _context7.next = 21;
34410
+ _context7.prev = 19;
34411
+ _context7.next = 22;
34356
34412
  return bindWebRTCStream(_webRTCStream);
34357
- case 21:
34358
- _context7.next = 32;
34413
+ case 22:
34414
+ _context7.next = 33;
34359
34415
  break;
34360
- case 23:
34361
- _context7.prev = 23;
34362
- _context7.t0 = _context7["catch"](18);
34416
+ case 24:
34417
+ _context7.prev = 24;
34418
+ _context7.t0 = _context7["catch"](19);
34363
34419
  if (!(0, _amrVideoBufferError.isAmrVideoBufferError)(_context7.t0)) {
34364
- _context7.next = 31;
34420
+ _context7.next = 32;
34365
34421
  break;
34366
34422
  }
34367
34423
  logging.error(`OT.Subscriber: ${_context7.t0.message}`);
@@ -34374,17 +34430,17 @@ function SubscriberFactory(_ref2) {
34374
34430
  socket.subscriberDestroy(_stream.id, _this.widgetId, _activeSourceStreamId);
34375
34431
  }
34376
34432
  return _context7.abrupt("return");
34377
- case 31:
34378
- throw _context7.t0;
34379
34433
  case 32:
34434
+ throw _context7.t0;
34435
+ case 33:
34380
34436
  startAudioStatsWatcher();
34381
34437
  if (!_state.isDestroyed()) {
34382
- _context7.next = 36;
34438
+ _context7.next = 37;
34383
34439
  break;
34384
34440
  }
34385
34441
  logging.error('Subscriber destroyed');
34386
34442
  return _context7.abrupt("return");
34387
- case 36:
34443
+ case 37:
34388
34444
  if (peerConnection && (typeof window !== undefined ? window : global).webkitMediaStream) {
34389
34445
  // Enable any video streams that we previously disabled for OPENTOK-27112
34390
34446
  peerConnection._getVideoTracks().forEach(track => {
@@ -34412,12 +34468,12 @@ function SubscriberFactory(_ref2) {
34412
34468
  _widgetView.once('videoElementCreated', resolve);
34413
34469
  _subscriber.once('destroyed', reject);
34414
34470
  });
34415
- _context7.next = 44;
34471
+ _context7.next = 45;
34416
34472
  return videoElementCreated;
34417
- case 44:
34418
- _context7.next = 46;
34473
+ case 45:
34474
+ _context7.next = 47;
34419
34475
  return _pcConnected.promise;
34420
- case 46:
34476
+ case 47:
34421
34477
  if (!isSwappingStreams) {
34422
34478
  onLoaded();
34423
34479
  } else {
@@ -34453,34 +34509,34 @@ function SubscriberFactory(_ref2) {
34453
34509
  // Given an AMR transition, and an audio connector, we apply the connector for the new
34454
34510
  // relayed stream and clear it for the routed stream.
34455
34511
  if (!_isAdaptiveEnabled) {
34456
- _context7.next = 62;
34512
+ _context7.next = 63;
34457
34513
  break;
34458
34514
  }
34459
34515
  amrState.completeTransitionTo(_activeSourceStreamId);
34460
34516
  if (!(_isSubscribingToAudio && _audioConnector.audioMediaProcessorConnector)) {
34461
- _context7.next = 62;
34517
+ _context7.next = 63;
34462
34518
  break;
34463
34519
  }
34464
- _context7.prev = 53;
34465
- _context7.next = 56;
34520
+ _context7.prev = 54;
34521
+ _context7.next = 57;
34466
34522
  return _audioConnector.applyAudioConnectorOnRoutedToRelayedTransition();
34467
- case 56:
34523
+ case 57:
34468
34524
  logAnalyticsEvent('setAudioMediaProcessorConnector', 'Success', {
34469
34525
  message: 'Audio connector applied on routed to relayed transition.'
34470
34526
  });
34471
- _context7.next = 62;
34527
+ _context7.next = 63;
34472
34528
  break;
34473
- case 59:
34474
- _context7.prev = 59;
34475
- _context7.t1 = _context7["catch"](53);
34529
+ case 60:
34530
+ _context7.prev = 60;
34531
+ _context7.t1 = _context7["catch"](54);
34476
34532
  logAnalyticsEvent('setAudioMediaProcessorConnector', 'Failure', {
34477
34533
  message: _context7.t1.message
34478
34534
  });
34479
- case 62:
34535
+ case 63:
34480
34536
  case "end":
34481
34537
  return _context7.stop();
34482
34538
  }
34483
- }, _callee7, null, [[18, 23], [53, 59]]);
34539
+ }, _callee7, null, [[19, 24], [54, 60]]);
34484
34540
  }));
34485
34541
  return function onRemoteStreamAdded(_x9, _x10) {
34486
34542
  return _ref15.apply(this, arguments);
@@ -35046,8 +35102,9 @@ function SubscriberFactory(_ref2) {
35046
35102
  _context15.next = 29;
35047
35103
  return createAudioLevelSampler(peerConnection);
35048
35104
  case 29:
35105
+ _audioLevelSampler.webRTCStream(_webRTCStream);
35049
35106
  logRelayedToRoutedTransition('Success');
35050
- case 30:
35107
+ case 31:
35051
35108
  case "end":
35052
35109
  return _context15.stop();
35053
35110
  }
@@ -36661,7 +36718,7 @@ function SubscriberFactory(_ref2) {
36661
36718
  return _videoMediaProcessorConnector.setTrack(_originalVideoTrack);
36662
36719
  case 10:
36663
36720
  filteredVideoTrack = _context27.sent;
36664
- (0, _updateTrackOnStream.default)(_webRTCStream, _originalVideoTrack, filteredVideoTrack);
36721
+ updateTrackOnStream(_webRTCStream, _originalVideoTrack, filteredVideoTrack);
36665
36722
  logAnalyticsEvent('setVideoMediaProcessorConnector', 'Success');
36666
36723
  _context27.next = 20;
36667
36724
  break;
@@ -36691,7 +36748,7 @@ function SubscriberFactory(_ref2) {
36691
36748
  // We need to switch to the original track so we can transform it later when resetting the connector.
36692
36749
  const _webRTCStream$getVide2 = _webRTCStream.getVideoTracks(),
36693
36750
  filteredVideoTrack = _webRTCStream$getVide2[0];
36694
- (0, _updateTrackOnStream.default)(_webRTCStream, filteredVideoTrack, _originalVideoTrack);
36751
+ updateTrackOnStream(_webRTCStream, filteredVideoTrack, _originalVideoTrack);
36695
36752
  logAnalyticsEvent('setVideoMediaProcessorConnector', 'Success', {
36696
36753
  message: 'reset the video track'
36697
36754
  });
@@ -37056,6 +37113,15 @@ function SubscriberFactory(_ref2) {
37056
37113
  * @memberof Subscriber
37057
37114
  */
37058
37115
 
37116
+ /**
37117
+ * This is a <b>beta</b> feature.
37118
+ * Dispatched when the MediaStream is available.
37119
+ * @see Event
37120
+ * @name mediaStreamAvailable
37121
+ * @event
37122
+ * @memberof Subscriber
37123
+ */
37124
+
37059
37125
  /**
37060
37126
  * Dispatched when the subscriber receives a caption from the transcription service.
37061
37127
  * You must first call the <a href="Subscriber.html#subscribeToCaptions">Subscriber.subscribeToCaptions()</a>
@@ -66861,7 +66927,7 @@ function SessionFactory(deps) {
66861
66927
  /**
66862
66928
  * The client has disconnected from the session. This event may be dispatched asynchronously
66863
66929
  * in response to a successful call to the <code>disconnect()</code> method of the Session object.
66864
- * The event may also be disptached if a session connection is lost inadvertantly, as in the case
66930
+ * The event may also be dispatched if a session connection is lost inadvertantly, as in the case
66865
66931
  * of a lost network connection.
66866
66932
  * <p>
66867
66933
  * The default behavior is that all Subscriber objects are unsubscribed and removed from the
@@ -94223,6 +94289,16 @@ var _default = _ref => {
94223
94289
  subscriber.dispatchEvent(new Events.AudioLevelUpdatedEvent(loudness));
94224
94290
  }
94225
94291
  });
94292
+ const audioLevelUpdatedAdded = () => audioLevelRunner.start();
94293
+ const subscriberDestroyed = () => audioLevelRunner.stop();
94294
+ const addListeners = () => {
94295
+ subscriber.on('audioLevelUpdated:added', audioLevelUpdatedAdded);
94296
+ subscriber.once(_eventNames.default.SUBSCRIBER_DESTROYED, subscriberDestroyed);
94297
+ };
94298
+ const removeListeners = () => {
94299
+ subscriber.off('audioLevelUpdated:added', audioLevelUpdatedAdded);
94300
+ subscriber.off(_eventNames.default.SUBSCRIBER_DESTROYED, subscriberDestroyed);
94301
+ };
94226
94302
  Object.defineProperty(subscriber, 'loudness', {
94227
94303
  get() {
94228
94304
  audioLevelRunner.start();
@@ -94237,16 +94313,14 @@ var _default = _ref => {
94237
94313
  if (subscriber.listenerCount(_eventNames.default.AUDIO_LEVEL_UPDATED)) {
94238
94314
  audioLevelRunner.start();
94239
94315
  }
94240
- subscriber.on('audioLevelUpdated:added', () => {
94241
- audioLevelRunner.start();
94242
- });
94243
- subscriber.once(_eventNames.default.SUBSCRIBER_DESTROYED, () => {
94244
- audioLevelRunner.stop();
94245
- });
94316
+ addListeners();
94246
94317
  return {
94247
94318
  destroy() {
94248
94319
  audioLevelSampler.destroy();
94249
94320
  audioLevelRunner.stop();
94321
+ removeListeners();
94322
+ // eslint-disable-next-line no-param-reassign
94323
+ subscriber = undefined;
94250
94324
  }
94251
94325
  };
94252
94326
  };
@@ -103310,6 +103384,8 @@ let SinglePeerConnectionController = /*#__PURE__*/function () {
103310
103384
  };
103311
103385
  _proto._parseOptions = function _parseOptions(options) {
103312
103386
  return Object.assign({}, options, {
103387
+ // Create only one RTCDtlsTransport
103388
+ bundlePolicy: 'max-bundle',
103313
103389
  // We always remove unused codecs after iceRestart in SPC
103314
103390
  removeUnusedCodecs: true,
103315
103391
  sendMessage: (type, payload) => {
@@ -103461,7 +103537,7 @@ let SinglePeerConnectionController = /*#__PURE__*/function () {
103461
103537
 
103462
103538
  // Singleton to make sure we are using only one PC when SPC. If SPC, we will add Subscriber
103463
103539
  // specific options to handle analytics and negotiation per Subscriber. This will take care
103464
- // to send the answer back to Rumor by its respective Subcriber and not multiple answers.
103540
+ // to send the answer back to Rumor by its respective Subscriber and not multiple answers.
103465
103541
  // It will instantiate a new regular PC for all other cases.
103466
103542
  ;
103467
103543
  _proto.getPeerConnection = function getPeerConnection(opt, subscriberPc) {