@webex/plugin-meetings 3.0.0-beta.86 → 3.0.0-beta.87

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.
Files changed (36) hide show
  1. package/dist/breakouts/breakout.js +1 -1
  2. package/dist/breakouts/index.js +1 -1
  3. package/dist/index.js +63 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/media/index.js.map +1 -1
  6. package/dist/media/properties.js.map +1 -1
  7. package/dist/meeting/index.js +139 -88
  8. package/dist/meeting/index.js.map +1 -1
  9. package/dist/meeting/muteState.js +169 -26
  10. package/dist/meeting/muteState.js.map +1 -1
  11. package/dist/meeting/util.js.map +1 -1
  12. package/dist/meetings/index.js +20 -2
  13. package/dist/meetings/index.js.map +1 -1
  14. package/dist/types/controls-options-manager/util.d.ts +0 -102
  15. package/dist/types/index.d.ts +6 -5
  16. package/dist/types/media/properties.d.ts +1 -1
  17. package/dist/types/meeting/index.d.ts +8 -5
  18. package/dist/types/meeting/muteState.d.ts +58 -5
  19. package/dist/types/meetings/index.d.ts +1 -0
  20. package/dist/types/multistream/remoteMedia.d.ts +1 -29
  21. package/dist/types/multistream/remoteMediaGroup.d.ts +0 -9
  22. package/package.json +19 -18
  23. package/src/{index.js → index.ts} +15 -0
  24. package/src/media/index.ts +2 -7
  25. package/src/media/properties.ts +3 -7
  26. package/src/meeting/index.ts +108 -51
  27. package/src/meeting/muteState.ts +158 -15
  28. package/src/meeting/util.ts +1 -1
  29. package/src/meetings/index.ts +14 -0
  30. package/test/integration/spec/converged-space-meetings.js +4 -3
  31. package/test/integration/spec/journey.js +4 -3
  32. package/test/integration/spec/space-meeting.js +4 -3
  33. package/test/unit/spec/meeting/index.js +24 -28
  34. package/test/unit/spec/meeting/muteState.js +226 -13
  35. package/test/utils/integrationTestUtils.js +64 -0
  36. package/test/utils/testUtils.js +0 -57
@@ -40,6 +40,7 @@ var _cloneDeep2 = _interopRequireDefault(require("lodash/cloneDeep"));
40
40
  var _uuid = _interopRequireDefault(require("uuid"));
41
41
  var _webexCore = require("@webex/webex-core");
42
42
  var _internalMediaCore = require("@webex/internal-media-core");
43
+ var _mediaHelpers = require("@webex/media-helpers");
43
44
  var _webexErrors = require("../common/errors/webex-errors");
44
45
  var _statsAnalyzer = require("../statsAnalyzer");
45
46
  var _networkQualityMonitor = _interopRequireDefault(require("../networkQualityMonitor"));
@@ -503,6 +504,8 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
503
504
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "resourceUrl", void 0);
504
505
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "selfId", void 0);
505
506
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "state", void 0);
507
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "localAudioTrackMuteStateHandler", void 0);
508
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "localVideoTrackMuteStateHandler", void 0);
506
509
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "webexMeetingId", void 0);
507
510
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "namespace", _constants.MEETINGS);
508
511
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "processRelayEvent", function (e) {
@@ -999,6 +1002,7 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
999
1002
  }
1000
1003
  });
1001
1004
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleShareTrackEnded", /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
1005
+ var _this$mediaProperties;
1002
1006
  return _regenerator.default.wrap(function _callee$(_context) {
1003
1007
  while (1) switch (_context.prev = _context.next) {
1004
1008
  case 0:
@@ -1009,11 +1013,11 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
1009
1013
  _this.leave({
1010
1014
  reason: _constants.MEETING_REMOVED_REASON.USER_ENDED_SHARE_STREAMS
1011
1015
  });
1012
- _context.next = 21;
1016
+ _context.next = 22;
1013
1017
  break;
1014
1018
  case 4:
1015
1019
  if (!_this.isMultistream) {
1016
- _context.next = 20;
1020
+ _context.next = 21;
1017
1021
  break;
1018
1022
  }
1019
1023
  _context.prev = 5;
@@ -1032,13 +1036,15 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
1032
1036
  _loggerProxy.default.logger.log('Meeting:index#handleShareTrackEnded --> Error stopping share: ', _context.t0);
1033
1037
  case 14:
1034
1038
  _context.prev = 14;
1035
- _this.setLocalShareTrack(null);
1039
+ // todo: once SPARK-399695 is done, we will be able to just call this.setLocalShareTrack(null); here instead of the next 2 lines:
1040
+ (_this$mediaProperties = _this.mediaProperties.shareTrack) === null || _this$mediaProperties === void 0 ? void 0 : _this$mediaProperties.off(_mediaHelpers.LocalTrackEvents.Ended, _this.handleShareTrackEnded);
1041
+ _this.mediaProperties.setLocalShareTrack(null);
1036
1042
  _this.mediaProperties.mediaDirection.sendShare = false;
1037
1043
  return _context.finish(14);
1038
- case 18:
1039
- _context.next = 21;
1044
+ case 19:
1045
+ _context.next = 22;
1040
1046
  break;
1041
- case 20:
1047
+ case 21:
1042
1048
  // Skip checking for a stable peerConnection
1043
1049
  // to allow immediately stopping screenshare
1044
1050
  _this.stopShare({
@@ -1046,18 +1052,18 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
1046
1052
  }).catch(function (error) {
1047
1053
  _loggerProxy.default.logger.log('Meeting:index#handleShareTrackEnded --> Error stopping share: ', error);
1048
1054
  });
1049
- case 21:
1055
+ case 22:
1050
1056
  _triggerProxy.default.trigger((0, _assertThisInitialized2.default)(_this), {
1051
1057
  file: 'meeting/index',
1052
1058
  function: 'handleShareTrackEnded'
1053
1059
  }, _constants.EVENT_TRIGGERS.MEETING_STOPPED_SHARING_LOCAL, {
1054
1060
  type: _constants.EVENT_TYPES.LOCAL_SHARE
1055
1061
  });
1056
- case 22:
1062
+ case 23:
1057
1063
  case "end":
1058
1064
  return _context.stop();
1059
1065
  }
1060
- }, _callee, null, [[5, 11, 14, 18]]);
1066
+ }, _callee, null, [[5, 11, 14, 19]]);
1061
1067
  })));
1062
1068
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "clearMeetingData", function () {
1063
1069
  _this.audio = null;
@@ -1194,8 +1200,8 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
1194
1200
  * helper class for managing receive slots (for multistream media connections)
1195
1201
  */
1196
1202
  _this.receiveSlotManager = new _receiveSlotManager.ReceiveSlotManager(function (mediaType) {
1197
- var _this$mediaProperties;
1198
- if (!((_this$mediaProperties = _this.mediaProperties) !== null && _this$mediaProperties !== void 0 && _this$mediaProperties.webrtcMediaConnection)) {
1203
+ var _this$mediaProperties2;
1204
+ if (!((_this$mediaProperties2 = _this.mediaProperties) !== null && _this$mediaProperties2 !== void 0 && _this$mediaProperties2.webrtcMediaConnection)) {
1199
1205
  return _promise.default.reject(new Error('Webrtc media connection is missing'));
1200
1206
  }
1201
1207
  return _this.mediaProperties.webrtcMediaConnection.createReceiveSlot(mediaType);
@@ -1708,6 +1714,12 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
1708
1714
  * helper class for managing remote streams
1709
1715
  */
1710
1716
  _this.remoteMediaManager = null;
1717
+ _this.localAudioTrackMuteStateHandler = function (event) {
1718
+ _this.audio.handleLocalTrackMuteStateChange((0, _assertThisInitialized2.default)(_this), event.trackState.muted);
1719
+ };
1720
+ _this.localVideoTrackMuteStateHandler = function (event) {
1721
+ _this.video.handleLocalTrackMuteStateChange((0, _assertThisInitialized2.default)(_this), event.trackState.muted);
1722
+ };
1711
1723
  return _this;
1712
1724
  }
1713
1725
 
@@ -2064,11 +2076,11 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
2064
2076
  key: "getAnalyzerMetricsPrePayload",
2065
2077
  value: function getAnalyzerMetricsPrePayload(options) {
2066
2078
  if (options) {
2067
- var event = options.event,
2079
+ var _event = options.event,
2068
2080
  trackingId = options.trackingId,
2069
2081
  _mediaConnections = options.mediaConnections;
2070
- if (!event) {
2071
- _loggerProxy.default.logger.error('Meeting:index#getAnalyzerMetricsPrePayload --> Error [Call Analyzer Event', event || '', "]: invalid identifers or event type! ".concat(this.correlationId));
2082
+ if (!_event) {
2083
+ _loggerProxy.default.logger.error('Meeting:index#getAnalyzerMetricsPrePayload --> Error [Call Analyzer Event', _event || '', "]: invalid identifers or event type! ".concat(this.correlationId));
2072
2084
  return null;
2073
2085
  }
2074
2086
  var identifiers = {
@@ -2462,7 +2474,7 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
2462
2474
  this.locusInfo.on(_constants.EVENTS.LOCUS_INFO_UPDATE_MEDIA_SHARES, /*#__PURE__*/function () {
2463
2475
  var _ref12 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(payload) {
2464
2476
  var _payload$previous, _payload$previous2;
2465
- var _payload$current, contentShare, whiteboardShare, previousContentShare, previousWhiteboardShare, newShareStatus, _this13$mediaProperti, localShareTrack, oldShareStatus, sendStartedSharingRemote, _this13$mediaProperti2, _this13$mediaProperti3;
2477
+ var _payload$current, contentShare, whiteboardShare, previousContentShare, previousWhiteboardShare, newShareStatus, _this13$mediaProperti, localShareTrack, oldShareStatus, sendStartedSharingRemote, _this13$mediaProperti2;
2466
2478
  return _regenerator.default.wrap(function _callee3$(_context3) {
2467
2479
  while (1) switch (_context3.prev = _context3.next) {
2468
2480
  case 0:
@@ -2489,7 +2501,7 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
2489
2501
  _context3.next = 31;
2490
2502
  break;
2491
2503
  }
2492
- // @ts-ignore originalTrack is private - this will be fixed when SPARK-399694 are SPARK-399695 done
2504
+ // @ts-ignore originalTrack is private - this will be fixed when SPARK-399695 is done
2493
2505
  localShareTrack = (_this13$mediaProperti = _this13.mediaProperties.shareTrack) === null || _this13$mediaProperti === void 0 ? void 0 : _this13$mediaProperti.originalTrack; // todo: remove this block of code and instead make sure we have LocalTrackEvents.Ended listener always registered (SPARK-399695)
2494
2506
  if (!((localShareTrack === null || localShareTrack === void 0 ? void 0 : localShareTrack.readyState) === 'ended')) {
2495
2507
  _context3.next = 28;
@@ -2501,7 +2513,7 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
2501
2513
  break;
2502
2514
  }
2503
2515
  _context3.next = 17;
2504
- return _this13.unpublishTracks([localShareTrack]);
2516
+ return _this13.unpublishTracks([_this13.mediaProperties.shareTrack]);
2505
2517
  case 17:
2506
2518
  _context3.next = 21;
2507
2519
  break;
@@ -2594,7 +2606,7 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
2594
2606
  break;
2595
2607
  }
2596
2608
  _context3.next = 55;
2597
- return _this13.unpublishTracks([(_this13$mediaProperti3 = _this13.mediaProperties.shareTrack) === null || _this13$mediaProperti3 === void 0 ? void 0 : _this13$mediaProperti3.originalTrack]);
2609
+ return _this13.unpublishTracks([_this13.mediaProperties.shareTrack]);
2598
2610
  case 55:
2599
2611
  _context3.next = 59;
2600
2612
  break;
@@ -2872,7 +2884,7 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
2872
2884
  var _payload$muted, _payload$unmuteAllowe;
2873
2885
  payload.muted = (_payload$muted = payload.muted) !== null && _payload$muted !== void 0 ? _payload$muted : _this19.video.isRemotelyMuted();
2874
2886
  payload.unmuteAllowed = (_payload$unmuteAllowe = payload.unmuteAllowed) !== null && _payload$unmuteAllowe !== void 0 ? _payload$unmuteAllowe : _this19.video.isUnmuteAllowed();
2875
- _this19.video.handleServerRemoteMuteUpdate(payload.muted, payload.unmuteAllowed);
2887
+ _this19.video.handleServerRemoteMuteUpdate(_this19, payload.muted, payload.unmuteAllowed);
2876
2888
  }
2877
2889
  _triggerProxy.default.trigger(_this19, {
2878
2890
  file: 'meeting/index',
@@ -2886,7 +2898,7 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
2886
2898
  if (payload) {
2887
2899
  var _this19$audio;
2888
2900
  if (_this19.audio) {
2889
- _this19.audio.handleServerRemoteMuteUpdate(payload.muted, payload.unmuteAllowed);
2901
+ _this19.audio.handleServerRemoteMuteUpdate(_this19, payload.muted, payload.unmuteAllowed);
2890
2902
  }
2891
2903
  // with "mute on entry" server will send us remote mute even if we don't have media configured,
2892
2904
  // so if being muted by others, always send the notification,
@@ -3466,10 +3478,10 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
3466
3478
  key: "closeRemoteTracks",
3467
3479
  value: function closeRemoteTracks() {
3468
3480
  var _this22 = this;
3469
- var _this$mediaProperties2 = this.mediaProperties,
3470
- remoteAudioTrack = _this$mediaProperties2.remoteAudioTrack,
3471
- remoteVideoTrack = _this$mediaProperties2.remoteVideoTrack,
3472
- remoteShare = _this$mediaProperties2.remoteShare;
3481
+ var _this$mediaProperties3 = this.mediaProperties,
3482
+ remoteAudioTrack = _this$mediaProperties3.remoteAudioTrack,
3483
+ remoteVideoTrack = _this$mediaProperties3.remoteVideoTrack,
3484
+ remoteShare = _this$mediaProperties3.remoteShare;
3473
3485
 
3474
3486
  /**
3475
3487
  * Triggers an event to the developer
@@ -3518,13 +3530,13 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
3518
3530
  }, {
3519
3531
  key: "sendLocalMediaReadyEvent",
3520
3532
  value: function sendLocalMediaReadyEvent() {
3521
- var _this$mediaProperties3, _this$mediaProperties4;
3533
+ var _this$mediaProperties4, _this$mediaProperties5;
3522
3534
  _triggerProxy.default.trigger(this, {
3523
3535
  file: 'meeting/index',
3524
3536
  function: 'sendLocalMediaReadyEvent'
3525
3537
  }, _constants.EVENT_TRIGGERS.MEDIA_READY, {
3526
3538
  type: _constants.EVENT_TYPES.LOCAL,
3527
- stream: _util4.default.createMediaStream([(_this$mediaProperties3 = this.mediaProperties.audioTrack) === null || _this$mediaProperties3 === void 0 ? void 0 : _this$mediaProperties3.underlyingTrack, (_this$mediaProperties4 = this.mediaProperties.videoTrack) === null || _this$mediaProperties4 === void 0 ? void 0 : _this$mediaProperties4.underlyingTrack])
3539
+ stream: _util4.default.createMediaStream([(_this$mediaProperties4 = this.mediaProperties.audioTrack) === null || _this$mediaProperties4 === void 0 ? void 0 : _this$mediaProperties4.underlyingTrack, (_this$mediaProperties5 = this.mediaProperties.videoTrack) === null || _this$mediaProperties5 === void 0 ? void 0 : _this$mediaProperties5.underlyingTrack])
3528
3540
  });
3529
3541
  }
3530
3542
 
@@ -3540,9 +3552,12 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
3540
3552
  key: "setLocalAudioTrack",
3541
3553
  value: function setLocalAudioTrack(rawAudioTrack) {
3542
3554
  var emitEvent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
3555
+ if (this.isMultistream) {
3556
+ throw new Error('this method is only supposed to be used for transcoded meetings');
3557
+ }
3543
3558
  if (rawAudioTrack) {
3544
3559
  var settings = rawAudioTrack.getSettings();
3545
- var localMicrophoneTrack = new _internalMediaCore.LocalMicrophoneTrack(_util4.default.createMediaStream([rawAudioTrack]));
3560
+ var localMicrophoneTrack = new _mediaHelpers.LocalMicrophoneTrack(_util4.default.createMediaStream([rawAudioTrack]));
3546
3561
  this.mediaProperties.setMediaSettings('audio', {
3547
3562
  echoCancellation: settings.echoCancellation,
3548
3563
  noiseSuppression: settings.noiseSuppression
@@ -3570,6 +3585,9 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
3570
3585
  key: "setLocalVideoTrack",
3571
3586
  value: function setLocalVideoTrack(rawVideoTrack) {
3572
3587
  var emitEvent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
3588
+ if (this.isMultistream) {
3589
+ throw new Error('this method is only supposed to be used for transcoded meetings');
3590
+ }
3573
3591
  if (rawVideoTrack) {
3574
3592
  var _rawVideoTrack$getSet = rawVideoTrack.getSettings(),
3575
3593
  aspectRatio = _rawVideoTrack$getSet.aspectRatio,
@@ -3578,7 +3596,7 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
3578
3596
  width = _rawVideoTrack$getSet.width,
3579
3597
  deviceId = _rawVideoTrack$getSet.deviceId;
3580
3598
  var localQualityLevel = this.mediaProperties.localQualityLevel;
3581
- var localCameraTrack = new _internalMediaCore.LocalCameraTrack(_util4.default.createMediaStream([rawVideoTrack]));
3599
+ var localCameraTrack = new _mediaHelpers.LocalCameraTrack(_util4.default.createMediaStream([rawVideoTrack]));
3582
3600
  if (Number(localQualityLevel.slice(0, -1)) > height) {
3583
3601
  _loggerProxy.default.logger.warn("Meeting:index#setLocalVideoTrack --> Local video quality of ".concat(localQualityLevel, " not supported,\n downscaling to highest possible resolution of ").concat(height, "p"));
3584
3602
  this.mediaProperties.setLocalQualityLevel("".concat(height, "p"));
@@ -3639,7 +3657,7 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
3639
3657
  value: function setLocalShareTrack(rawLocalShareTrack) {
3640
3658
  if (rawLocalShareTrack) {
3641
3659
  var settings = rawLocalShareTrack.getSettings();
3642
- var localDisplayTrack = new _internalMediaCore.LocalDisplayTrack(_util4.default.createMediaStream([rawLocalShareTrack]));
3660
+ var localDisplayTrack = new _mediaHelpers.LocalDisplayTrack(_util4.default.createMediaStream([rawLocalShareTrack]));
3643
3661
  this.mediaProperties.setLocalShareTrack(localDisplayTrack);
3644
3662
  this.mediaProperties.setMediaSettings('screen', {
3645
3663
  aspectRatio: settings.aspectRatio,
@@ -3652,7 +3670,7 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
3652
3670
  cursor: settings.cursor
3653
3671
  });
3654
3672
  _loggerProxy.default.logger.log('Meeting:index#setLocalShareTrack --> Screen settings.', (0, _stringify.default)(this.mediaProperties.mediaSettings.screen));
3655
- localDisplayTrack.on(_internalMediaCore.LocalTrackEvents.Ended, this.handleShareTrackEnded);
3673
+ localDisplayTrack.on(_mediaHelpers.LocalTrackEvents.Ended, this.handleShareTrackEnded);
3656
3674
  _triggerProxy.default.trigger(this, {
3657
3675
  file: 'meeting/index',
3658
3676
  function: 'setLocalShareTrack'
@@ -3661,8 +3679,8 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
3661
3679
  track: rawLocalShareTrack
3662
3680
  });
3663
3681
  } else if (this.mediaProperties.shareTrack) {
3664
- this.mediaProperties.shareTrack.off(_internalMediaCore.LocalTrackEvents.Ended, this.handleShareTrackEnded);
3665
- this.mediaProperties.shareTrack.stop(); // todo: this line should be removed once SPARK-399694 are SPARK-399695 are done
3682
+ this.mediaProperties.shareTrack.off(_mediaHelpers.LocalTrackEvents.Ended, this.handleShareTrackEnded);
3683
+ this.mediaProperties.shareTrack.stop(); // todo: this line should be removed once SPARK-399695 is done
3666
3684
  this.mediaProperties.setLocalShareTrack(null);
3667
3685
  }
3668
3686
  }
@@ -3678,9 +3696,9 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
3678
3696
  key: "closeLocalStream",
3679
3697
  value: function closeLocalStream() {
3680
3698
  var _this23 = this;
3681
- var _this$mediaProperties5 = this.mediaProperties,
3682
- audioTrack = _this$mediaProperties5.audioTrack,
3683
- videoTrack = _this$mediaProperties5.videoTrack;
3699
+ var _this$mediaProperties6 = this.mediaProperties,
3700
+ audioTrack = _this$mediaProperties6.audioTrack,
3701
+ videoTrack = _this$mediaProperties6.videoTrack;
3684
3702
  return _media.default.stopTracks(audioTrack).then(function () {
3685
3703
  return _media.default.stopTracks(videoTrack);
3686
3704
  }).then(function () {
@@ -5307,7 +5325,7 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
5307
5325
  _this43.mediaProperties.mediaDirection.receiveAudio = receiveAudio;
5308
5326
 
5309
5327
  // audio state could be undefined if you have not sent audio before
5310
- _this43.audio = _this43.audio || (0, _muteState.createMuteState)(_constants.AUDIO, _this43, _this43.mediaProperties.mediaDirection);
5328
+ _this43.audio = _this43.audio || (0, _muteState.createMuteState)(_constants.AUDIO, _this43, _this43.mediaProperties.mediaDirection, true);
5311
5329
  }));
5312
5330
  case 11:
5313
5331
  case "end":
@@ -5374,7 +5392,7 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
5374
5392
  _this44.mediaProperties.mediaDirection.receiveVideo = receiveVideo;
5375
5393
 
5376
5394
  // video state could be undefined if you have not sent video before
5377
- _this44.video = _this44.video || (0, _muteState.createMuteState)(_constants.VIDEO, _this44, _this44.mediaProperties.mediaDirection);
5395
+ _this44.video = _this44.video || (0, _muteState.createMuteState)(_constants.VIDEO, _this44, _this44.mediaProperties.mediaDirection, true);
5378
5396
  });
5379
5397
  }
5380
5398
 
@@ -5504,10 +5522,12 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
5504
5522
  // TODO wire into default config. There's currently an issue with the stateless plugin or how we register
5505
5523
  // @ts-ignore - config coming from registerPlugin
5506
5524
  this.mediaProperties.setMediaDirection((0, _assign.default)(this.config.mediaSettings, mediaSettings));
5507
- // add a setup a function move the create and setup media in future
5508
- // TODO: delete old audio and video if stale
5509
- this.audio = this.audio || (0, _muteState.createMuteState)(_constants.AUDIO, this, this.mediaProperties.mediaDirection);
5510
- this.video = this.video || (0, _muteState.createMuteState)(_constants.VIDEO, this, this.mediaProperties.mediaDirection);
5525
+
5526
+ // for multistream, this.audio and this.video are created when publishTracks() is called
5527
+ if (!this.isMultistream) {
5528
+ this.audio = this.audio || (0, _muteState.createMuteState)(_constants.AUDIO, this, this.mediaProperties.mediaDirection, true);
5529
+ this.video = this.video || (0, _muteState.createMuteState)(_constants.VIDEO, this, this.mediaProperties.mediaDirection, true);
5530
+ }
5511
5531
  // Validation is already done in addMedia so no need to check if the lenght is greater then 0
5512
5532
  this.setLocalTracks(localStream);
5513
5533
  if (this.isMultistream && localShare) {
@@ -6011,10 +6031,10 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
6011
6031
  var renderInfo = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
6012
6032
  var main = renderInfo.main,
6013
6033
  content = renderInfo.content;
6014
- var _this$mediaProperties6 = this.mediaProperties,
6015
- mediaDirection = _this$mediaProperties6.mediaDirection,
6016
- remoteShare = _this$mediaProperties6.remoteShare,
6017
- remoteVideoTrack = _this$mediaProperties6.remoteVideoTrack;
6034
+ var _this$mediaProperties7 = this.mediaProperties,
6035
+ mediaDirection = _this$mediaProperties7.mediaDirection,
6036
+ remoteShare = _this$mediaProperties7.remoteShare,
6037
+ remoteVideoTrack = _this$mediaProperties7.remoteVideoTrack;
6018
6038
  var layoutInfo = (0, _cloneDeep2.default)(this.lastVideoLayoutInfo);
6019
6039
 
6020
6040
  // TODO: We need a real time value for Audio, Video and Share send indicator
@@ -6202,10 +6222,10 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
6202
6222
  }
6203
6223
 
6204
6224
  // Determine the direction of our current media
6205
- var _this$mediaProperties7 = this.mediaProperties.mediaDirection,
6206
- receiveAudio = _this$mediaProperties7.receiveAudio,
6207
- receiveVideo = _this$mediaProperties7.receiveVideo,
6208
- sendVideo = _this$mediaProperties7.sendVideo;
6225
+ var _this$mediaProperties8 = this.mediaProperties.mediaDirection,
6226
+ receiveAudio = _this$mediaProperties8.receiveAudio,
6227
+ receiveVideo = _this$mediaProperties8.receiveVideo,
6228
+ sendVideo = _this$mediaProperties8.sendVideo;
6209
6229
  return (sendVideo ? this.setLocalVideoQuality(level) : _promise.default.resolve()).then(function () {
6210
6230
  return receiveAudio || receiveVideo ? _this55.setRemoteQualityLevel(level) : _promise.default.resolve();
6211
6231
  }).catch(function (error) {
@@ -6638,8 +6658,8 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
6638
6658
  }, {
6639
6659
  key: "checkMediaConnection",
6640
6660
  value: function checkMediaConnection() {
6641
- var _this$mediaProperties8;
6642
- if ((_this$mediaProperties8 = this.mediaProperties) !== null && _this$mediaProperties8 !== void 0 && _this$mediaProperties8.webrtcMediaConnection) {
6661
+ var _this$mediaProperties9;
6662
+ if ((_this$mediaProperties9 = this.mediaProperties) !== null && _this$mediaProperties9 !== void 0 && _this$mediaProperties9.webrtcMediaConnection) {
6643
6663
  return;
6644
6664
  }
6645
6665
  throw new Error('Webrtc media connection is missing, call addMedia() first');
@@ -6656,47 +6676,75 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
6656
6676
  value: function () {
6657
6677
  var _publishTracks = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee12(tracks) {
6658
6678
  var _tracks$screenShare;
6679
+ var _tracks$screenShare2, oldTrack, localDisplayTrack, _oldTrack, localTrack, _oldTrack2, _localTrack;
6659
6680
  return _regenerator.default.wrap(function _callee12$(_context12) {
6660
6681
  while (1) switch (_context12.prev = _context12.next) {
6661
6682
  case 0:
6662
6683
  this.checkMediaConnection();
6684
+ if (this.isMultistream) {
6685
+ _context12.next = 3;
6686
+ break;
6687
+ }
6688
+ throw new Error('publishTracks() only supported with multistream');
6689
+ case 3:
6663
6690
  if (!((_tracks$screenShare = tracks.screenShare) !== null && _tracks$screenShare !== void 0 && _tracks$screenShare.video)) {
6664
- _context12.next = 8;
6691
+ _context12.next = 14;
6665
6692
  break;
6666
6693
  }
6694
+ oldTrack = this.mediaProperties.shareTrack;
6695
+ localDisplayTrack = (_tracks$screenShare2 = tracks.screenShare) === null || _tracks$screenShare2 === void 0 ? void 0 : _tracks$screenShare2.video;
6696
+ oldTrack === null || oldTrack === void 0 ? void 0 : oldTrack.off(_mediaHelpers.LocalTrackEvents.Ended, this.handleShareTrackEnded);
6697
+
6667
6698
  // we are starting a screen share
6668
- this.setLocalShareTrack(tracks.screenShare.video);
6669
- _context12.next = 5;
6699
+ this.mediaProperties.setLocalShareTrack(localDisplayTrack);
6700
+ localDisplayTrack.on(_mediaHelpers.LocalTrackEvents.Ended, this.handleShareTrackEnded);
6701
+ _context12.next = 11;
6670
6702
  return this.requestScreenShareFloor();
6671
- case 5:
6703
+ case 11:
6672
6704
  this.mediaProperties.mediaDirection.sendShare = true;
6673
- _context12.next = 8;
6705
+ _context12.next = 14;
6674
6706
  return this.mediaProperties.webrtcMediaConnection.publishTrack(this.mediaProperties.shareTrack);
6675
- case 8:
6707
+ case 14:
6676
6708
  if (!tracks.microphone) {
6677
- _context12.next = 14;
6709
+ _context12.next = 24;
6678
6710
  break;
6679
6711
  }
6680
- this.setLocalAudioTrack(tracks.microphone);
6712
+ _oldTrack = this.mediaProperties.audioTrack;
6713
+ localTrack = tracks.microphone;
6714
+ _oldTrack === null || _oldTrack === void 0 ? void 0 : _oldTrack.off(_mediaHelpers.LocalTrackEvents.Muted, this.localAudioTrackMuteStateHandler);
6715
+ this.mediaProperties.setLocalAudioTrack(localTrack);
6681
6716
  this.mediaProperties.mediaDirection.sendAudio = true;
6682
6717
 
6683
6718
  // audio mute state could be undefined if you have not sent audio before
6684
- this.audio = this.audio || (0, _muteState.createMuteState)(_constants.AUDIO, this, this.mediaProperties.mediaDirection);
6685
- _context12.next = 14;
6719
+ if (!this.audio) {
6720
+ this.audio = (0, _muteState.createMuteState)(_constants.AUDIO, this, this.mediaProperties.mediaDirection, false);
6721
+ } else {
6722
+ this.audio.handleLocalTrackChange(this);
6723
+ }
6724
+ localTrack.on(_mediaHelpers.LocalTrackEvents.Muted, this.localAudioTrackMuteStateHandler);
6725
+ _context12.next = 24;
6686
6726
  return this.mediaProperties.webrtcMediaConnection.publishTrack(this.mediaProperties.audioTrack);
6687
- case 14:
6727
+ case 24:
6688
6728
  if (!tracks.camera) {
6689
- _context12.next = 20;
6729
+ _context12.next = 34;
6690
6730
  break;
6691
6731
  }
6692
- this.setLocalVideoTrack(tracks.camera);
6732
+ _oldTrack2 = this.mediaProperties.videoTrack;
6733
+ _localTrack = tracks.camera;
6734
+ _oldTrack2 === null || _oldTrack2 === void 0 ? void 0 : _oldTrack2.off(_mediaHelpers.LocalTrackEvents.Muted, this.localVideoTrackMuteStateHandler);
6735
+ this.mediaProperties.setLocalVideoTrack(_localTrack);
6693
6736
  this.mediaProperties.mediaDirection.sendVideo = true;
6694
6737
 
6695
6738
  // video state could be undefined if you have not sent video before
6696
- this.video = this.video || (0, _muteState.createMuteState)(_constants.VIDEO, this, this.mediaProperties.mediaDirection);
6697
- _context12.next = 20;
6739
+ if (!this.video) {
6740
+ this.video = (0, _muteState.createMuteState)(_constants.VIDEO, this, this.mediaProperties.mediaDirection, false);
6741
+ } else {
6742
+ this.video.handleLocalTrackChange(this);
6743
+ }
6744
+ _localTrack.on(_mediaHelpers.LocalTrackEvents.Muted, this.localVideoTrackMuteStateHandler);
6745
+ _context12.next = 34;
6698
6746
  return this.mediaProperties.webrtcMediaConnection.publishTrack(this.mediaProperties.videoTrack);
6699
- case 20:
6747
+ case 34:
6700
6748
  case "end":
6701
6749
  return _context12.stop();
6702
6750
  }
@@ -6717,39 +6765,42 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
6717
6765
  key: "unpublishTracks",
6718
6766
  value: function () {
6719
6767
  var _unpublishTracks = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee13(tracks) {
6720
- var unpublishPromises, _iterator, _step, _this$mediaProperties9, _this$mediaProperties10, _this$mediaProperties11, track, localTrackToUnpublish, _localTrackToUnpublish, _localTrackToUnpublish2;
6768
+ var unpublishPromises, _iterator, _step, track;
6721
6769
  return _regenerator.default.wrap(function _callee13$(_context13) {
6722
6770
  while (1) switch (_context13.prev = _context13.next) {
6723
6771
  case 0:
6724
6772
  this.checkMediaConnection();
6773
+ if (this.isMultistream) {
6774
+ _context13.next = 3;
6775
+ break;
6776
+ }
6777
+ throw new Error('unpublishTracks() is only supported with multistream');
6778
+ case 3:
6725
6779
  unpublishPromises = [];
6726
- _iterator = _createForOfIteratorHelper(tracks);
6780
+ _iterator = _createForOfIteratorHelper(tracks.filter(function (t) {
6781
+ return !!t;
6782
+ }));
6727
6783
  try {
6728
6784
  for (_iterator.s(); !(_step = _iterator.n()).done;) {
6729
6785
  track = _step.value;
6730
- // @ts-ignore originalTrack is private - this will be fixed in SPARK-399694
6731
- if (track === ((_this$mediaProperties9 = this.mediaProperties.shareTrack) === null || _this$mediaProperties9 === void 0 ? void 0 : _this$mediaProperties9.originalTrack)) {
6732
- localTrackToUnpublish = this.mediaProperties.shareTrack;
6733
- this.setLocalShareTrack(null);
6786
+ if (track === this.mediaProperties.shareTrack) {
6787
+ this.mediaProperties.setLocalShareTrack(null);
6788
+ track.off(_mediaHelpers.LocalTrackEvents.Ended, this.handleShareTrackEnded);
6734
6789
  this.releaseScreenShareFloor(); // we ignore the returned promise here on purpose
6735
6790
  this.mediaProperties.mediaDirection.sendShare = false;
6736
- unpublishPromises.push(this.mediaProperties.webrtcMediaConnection.unpublishTrack(localTrackToUnpublish));
6791
+ unpublishPromises.push(this.mediaProperties.webrtcMediaConnection.unpublishTrack(track));
6737
6792
  }
6738
-
6739
- // @ts-ignore originalTrack is private - this will be fixed in SPARK-399694
6740
- if (track === ((_this$mediaProperties10 = this.mediaProperties.audioTrack) === null || _this$mediaProperties10 === void 0 ? void 0 : _this$mediaProperties10.originalTrack)) {
6741
- _localTrackToUnpublish = this.mediaProperties.audioTrack;
6742
- this.setLocalAudioTrack(null);
6793
+ if (track === this.mediaProperties.audioTrack) {
6794
+ this.mediaProperties.setLocalAudioTrack(null);
6743
6795
  this.mediaProperties.mediaDirection.sendAudio = false;
6744
- unpublishPromises.push(this.mediaProperties.webrtcMediaConnection.unpublishTrack(_localTrackToUnpublish));
6796
+ track.off(_mediaHelpers.LocalTrackEvents.Muted, this.localAudioTrackMuteStateHandler);
6797
+ unpublishPromises.push(this.mediaProperties.webrtcMediaConnection.unpublishTrack(track));
6745
6798
  }
6746
-
6747
- // @ts-ignore originalTrack is private - this will be fixed in SPARK-399694
6748
- if (track === ((_this$mediaProperties11 = this.mediaProperties.videoTrack) === null || _this$mediaProperties11 === void 0 ? void 0 : _this$mediaProperties11.originalTrack)) {
6749
- _localTrackToUnpublish2 = this.mediaProperties.videoTrack;
6750
- this.setLocalVideoTrack(null);
6799
+ if (track === this.mediaProperties.videoTrack) {
6800
+ this.mediaProperties.setLocalVideoTrack(null);
6751
6801
  this.mediaProperties.mediaDirection.sendVideo = false;
6752
- unpublishPromises.push(this.mediaProperties.webrtcMediaConnection.unpublishTrack(_localTrackToUnpublish2));
6802
+ track.off(_mediaHelpers.LocalTrackEvents.Muted, this.localVideoTrackMuteStateHandler);
6803
+ unpublishPromises.push(this.mediaProperties.webrtcMediaConnection.unpublishTrack(track));
6753
6804
  }
6754
6805
  }
6755
6806
  } catch (err) {
@@ -6757,9 +6808,9 @@ var Meeting = /*#__PURE__*/function (_StatelessWebexPlugin) {
6757
6808
  } finally {
6758
6809
  _iterator.f();
6759
6810
  }
6760
- _context13.next = 6;
6811
+ _context13.next = 8;
6761
6812
  return _promise.default.all(unpublishPromises);
6762
- case 6:
6813
+ case 8:
6763
6814
  case "end":
6764
6815
  return _context13.stop();
6765
6816
  }