@webex/plugin-meetings 3.0.0-beta.37 → 3.0.0-beta.38

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.
@@ -130,7 +130,7 @@ var Breakout = _webexCore.WebexPlugin.extend({
130
130
  sessionId: this.sessionId
131
131
  });
132
132
  },
133
- version: "3.0.0-beta.37"
133
+ version: "3.0.0-beta.38"
134
134
  });
135
135
  var _default = Breakout;
136
136
  exports.default = _default;
@@ -451,7 +451,7 @@ var Breakouts = _webexCore.WebexPlugin.extend({
451
451
  }, _callee3);
452
452
  }))();
453
453
  },
454
- version: "3.0.0-beta.37"
454
+ version: "3.0.0-beta.38"
455
455
  });
456
456
  var _default = Breakouts;
457
457
  exports.default = _default;
@@ -6,8 +6,8 @@ _Object$defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
8
  exports.MediaRequestManager = void 0;
9
- var _values = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/values"));
10
9
  var _entries = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/entries"));
10
+ var _values = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/values"));
11
11
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
12
12
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
13
13
  var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
@@ -32,43 +32,15 @@ var MediaRequestManager = /*#__PURE__*/function () {
32
32
  (0, _defineProperty2.default)(this, "sendMediaRequestsCallback", void 0);
33
33
  (0, _defineProperty2.default)(this, "counter", void 0);
34
34
  (0, _defineProperty2.default)(this, "clientRequests", void 0);
35
- (0, _defineProperty2.default)(this, "slotsActiveInLastMediaRequest", void 0);
36
35
  (0, _defineProperty2.default)(this, "degradationPreferences", void 0);
37
36
  (0, _defineProperty2.default)(this, "sourceUpdateListener", void 0);
38
37
  this.sendMediaRequestsCallback = sendMediaRequestsCallback;
39
38
  this.counter = 0;
40
39
  this.clientRequests = {};
41
- this.slotsActiveInLastMediaRequest = {};
42
40
  this.degradationPreferences = degradationPreferences;
43
41
  this.sourceUpdateListener = this.commit.bind(this);
44
42
  }
45
43
  (0, _createClass2.default)(MediaRequestManager, [{
46
- key: "resetInactiveReceiveSlots",
47
- value: function resetInactiveReceiveSlots() {
48
- var activeSlots = {};
49
-
50
- // create a map of all currently used slot ids
51
- (0, _values.default)(this.clientRequests).forEach(function (request) {
52
- return request.receiveSlots.forEach(function (slot) {
53
- activeSlots[slot.id] = slot;
54
- });
55
- });
56
-
57
- // when we stop using some receive slots and they are not included in the new media request,
58
- // we will never get a 'no source' notification for them, so we reset their state,
59
- // so that the client doesn't try to display their video anymore
60
- for (var _i = 0, _Object$entries = (0, _entries.default)(this.slotsActiveInLastMediaRequest); _i < _Object$entries.length; _i++) {
61
- var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i], 2),
62
- slotId = _Object$entries$_i[0],
63
- slot = _Object$entries$_i[1];
64
- if (!(slotId in activeSlots)) {
65
- _loggerProxy.default.logger.info("multistream:mediaRequestManager --> resetting sourceState to \"no source\" for slot ".concat(slot.id));
66
- slot.resetSourceState();
67
- }
68
- }
69
- this.slotsActiveInLastMediaRequest = activeSlots;
70
- }
71
- }, {
72
44
  key: "setDegradationPreferences",
73
45
  value: function setDegradationPreferences(degradationPreferences) {
74
46
  this.degradationPreferences = degradationPreferences;
@@ -126,7 +98,6 @@ var MediaRequestManager = /*#__PURE__*/function () {
126
98
  }), maxPayloadBitsPerSecond, mr.codecInfo && [new _internalMediaCore.CodecInfo(0x80, new _internalMediaCore.H264Codec(mr.codecInfo.maxFs, mr.codecInfo.maxFps || CODEC_DEFAULTS.h264.maxFps, mr.codecInfo.maxMbps || CODEC_DEFAULTS.h264.maxMbps, mr.codecInfo.maxWidth, mr.codecInfo.maxHeight))]));
127
99
  });
128
100
  this.sendMediaRequestsCallback(wcmeMediaRequests);
129
- this.resetInactiveReceiveSlots();
130
101
  }
131
102
  }, {
132
103
  key: "addRequest",
@@ -167,7 +138,6 @@ var MediaRequestManager = /*#__PURE__*/function () {
167
138
  key: "reset",
168
139
  value: function reset() {
169
140
  this.clientRequests = {};
170
- this.slotsActiveInLastMediaRequest = {};
171
141
  }
172
142
  }]);
173
143
  return MediaRequestManager;
@@ -1 +1 @@
1
- {"version":3,"names":["CODEC_DEFAULTS","h264","maxFs","maxFps","maxMbps","MediaRequestManager","degradationPreferences","sendMediaRequestsCallback","counter","clientRequests","slotsActiveInLastMediaRequest","sourceUpdateListener","commit","bind","activeSlots","forEach","request","receiveSlots","slot","id","slotId","LoggerProxy","logger","info","resetSourceState","sendRequests","maxFsLimits","getMaxFs","totalMacroblocksRequested","mr","codecInfo","Math","min","i","slotsWithLiveSource","filter","rs","sourceState","length","maxMacroblocksLimit","warn","wcmeMediaRequests","getDegradedClientRequests","maxPayloadBitsPerSecond","push","WcmeMediaRequest","policyInfo","policy","Policy","ActiveSpeaker","ReceiverSelected","ActiveSpeakerInfo","priority","crossPriorityDuplication","crossPolicyDuplication","preferLiveVideo","ReceiverSelectedInfo","csi","map","receiveSlot","wcmeReceiveSlot","WcmeCodecInfo","H264Codec","maxWidth","maxHeight","resetInactiveReceiveSlots","mediaRequest","newId","on","ReceiveSlotEvents","SourceUpdate","requestId","off"],"sources":["mediaRequestManager.ts"],"sourcesContent":["/* eslint-disable require-jsdoc */\nimport {\n MediaRequest as WcmeMediaRequest,\n Policy,\n ActiveSpeakerInfo,\n ReceiverSelectedInfo,\n CodecInfo as WcmeCodecInfo,\n H264Codec,\n} from '@webex/internal-media-core';\nimport {cloneDeep} from 'lodash';\n\nimport LoggerProxy from '../common/logs/logger-proxy';\n\nimport {ReceiveSlot, ReceiveSlotEvents, ReceiveSlotId} from './receiveSlot';\nimport {getMaxFs} from './remoteMedia';\n\nexport interface ActiveSpeakerPolicyInfo {\n policy: 'active-speaker';\n priority: number;\n crossPriorityDuplication: boolean;\n crossPolicyDuplication: boolean;\n preferLiveVideo: boolean;\n}\n\nexport interface ReceiverSelectedPolicyInfo {\n policy: 'receiver-selected';\n csi: number;\n}\n\nexport type PolicyInfo = ActiveSpeakerPolicyInfo | ReceiverSelectedPolicyInfo;\n\nexport interface H264CodecInfo {\n codec: 'h264';\n maxFs?: number;\n maxFps?: number;\n maxMbps?: number;\n maxWidth?: number;\n maxHeight?: number;\n}\n\nexport type CodecInfo = H264CodecInfo; // we'll add AV1 here in the future when it's available\n\nexport interface MediaRequest {\n policyInfo: PolicyInfo;\n receiveSlots: Array<ReceiveSlot>;\n codecInfo?: CodecInfo;\n}\n\nexport type MediaRequestId = string;\n\nconst CODEC_DEFAULTS = {\n h264: {\n maxFs: 8192,\n maxFps: 3000,\n maxMbps: 245760,\n },\n};\n\ntype DegradationPreferences = {\n maxMacroblocksLimit: number;\n};\n\ntype SendMediaRequestsCallback = (mediaRequests: WcmeMediaRequest[]) => void;\n\nexport class MediaRequestManager {\n private sendMediaRequestsCallback: SendMediaRequestsCallback;\n\n private counter: number;\n\n private clientRequests: {[key: MediaRequestId]: MediaRequest};\n\n private slotsActiveInLastMediaRequest: {[key: ReceiveSlotId]: ReceiveSlot};\n\n private degradationPreferences: DegradationPreferences;\n\n private sourceUpdateListener: () => void;\n\n constructor(\n degradationPreferences: DegradationPreferences,\n sendMediaRequestsCallback: SendMediaRequestsCallback\n ) {\n this.sendMediaRequestsCallback = sendMediaRequestsCallback;\n this.counter = 0;\n this.clientRequests = {};\n this.slotsActiveInLastMediaRequest = {};\n this.degradationPreferences = degradationPreferences;\n this.sourceUpdateListener = this.commit.bind(this);\n }\n\n private resetInactiveReceiveSlots() {\n const activeSlots: {[key: ReceiveSlotId]: ReceiveSlot} = {};\n\n // create a map of all currently used slot ids\n Object.values(this.clientRequests).forEach((request) =>\n request.receiveSlots.forEach((slot) => {\n activeSlots[slot.id] = slot;\n })\n );\n\n // when we stop using some receive slots and they are not included in the new media request,\n // we will never get a 'no source' notification for them, so we reset their state,\n // so that the client doesn't try to display their video anymore\n for (const [slotId, slot] of Object.entries(this.slotsActiveInLastMediaRequest)) {\n if (!(slotId in activeSlots)) {\n LoggerProxy.logger.info(\n `multistream:mediaRequestManager --> resetting sourceState to \"no source\" for slot ${slot.id}`\n );\n slot.resetSourceState();\n }\n }\n\n this.slotsActiveInLastMediaRequest = activeSlots;\n }\n\n public setDegradationPreferences(degradationPreferences: DegradationPreferences) {\n this.degradationPreferences = degradationPreferences;\n this.sendRequests(); // re-send requests after preferences are set\n }\n\n private getDegradedClientRequests() {\n const clientRequests = cloneDeep(this.clientRequests);\n const maxFsLimits = [\n getMaxFs('best'),\n getMaxFs('large'),\n getMaxFs('medium'),\n getMaxFs('small'),\n getMaxFs('very small'),\n getMaxFs('thumbnail'),\n ];\n\n // reduce max-fs until total macroblocks is below limit\n for (let i = 0; i < maxFsLimits.length; i += 1) {\n let totalMacroblocksRequested = 0;\n Object.entries(clientRequests).forEach(([id, mr]) => {\n if (mr.codecInfo) {\n mr.codecInfo.maxFs = Math.min(\n mr.codecInfo.maxFs || CODEC_DEFAULTS.h264.maxFs,\n maxFsLimits[i]\n );\n // we only consider sources with \"live\" state\n const slotsWithLiveSource = this.clientRequests[id].receiveSlots.filter(\n (rs) => rs.sourceState === 'live'\n );\n totalMacroblocksRequested += mr.codecInfo.maxFs * slotsWithLiveSource.length;\n }\n });\n if (totalMacroblocksRequested <= this.degradationPreferences.maxMacroblocksLimit) {\n if (i !== 0) {\n LoggerProxy.logger.warn(\n `multistream:mediaRequestManager --> too many streams with high max-fs, frame size will be limited to ${maxFsLimits[i]}`\n );\n }\n break;\n } else if (i === maxFsLimits.length - 1) {\n LoggerProxy.logger.warn(\n `multistream:mediaRequestManager --> even with frame size limited to ${maxFsLimits[i]} you are still requesting too many streams, consider reducing the number of requests`\n );\n }\n }\n\n return clientRequests;\n }\n\n private sendRequests() {\n const wcmeMediaRequests: WcmeMediaRequest[] = [];\n\n const clientRequests = this.getDegradedClientRequests();\n const maxPayloadBitsPerSecond = 10 * 1000 * 1000;\n\n // map all the client media requests to wcme media requests\n Object.values(clientRequests).forEach((mr) => {\n wcmeMediaRequests.push(\n new WcmeMediaRequest(\n mr.policyInfo.policy === 'active-speaker'\n ? Policy.ActiveSpeaker\n : Policy.ReceiverSelected,\n mr.policyInfo.policy === 'active-speaker'\n ? new ActiveSpeakerInfo(\n mr.policyInfo.priority,\n mr.policyInfo.crossPriorityDuplication,\n mr.policyInfo.crossPolicyDuplication,\n mr.policyInfo.preferLiveVideo\n )\n : new ReceiverSelectedInfo(mr.policyInfo.csi),\n mr.receiveSlots.map((receiveSlot) => receiveSlot.wcmeReceiveSlot),\n maxPayloadBitsPerSecond,\n mr.codecInfo && [\n new WcmeCodecInfo(\n 0x80,\n new H264Codec(\n mr.codecInfo.maxFs,\n mr.codecInfo.maxFps || CODEC_DEFAULTS.h264.maxFps,\n mr.codecInfo.maxMbps || CODEC_DEFAULTS.h264.maxMbps,\n mr.codecInfo.maxWidth,\n mr.codecInfo.maxHeight\n )\n ),\n ]\n )\n );\n });\n\n this.sendMediaRequestsCallback(wcmeMediaRequests);\n\n this.resetInactiveReceiveSlots();\n }\n\n public addRequest(mediaRequest: MediaRequest, commit = true): MediaRequestId {\n // eslint-disable-next-line no-plusplus\n const newId = `${this.counter++}`;\n\n this.clientRequests[newId] = mediaRequest;\n\n mediaRequest.receiveSlots.forEach((rs) => {\n rs.on(ReceiveSlotEvents.SourceUpdate, this.sourceUpdateListener);\n });\n\n if (commit) {\n this.commit();\n }\n\n return newId;\n }\n\n public cancelRequest(requestId: MediaRequestId, commit = true) {\n this.clientRequests[requestId]?.receiveSlots.forEach((rs) => {\n rs.off(ReceiveSlotEvents.SourceUpdate, this.sourceUpdateListener);\n });\n\n delete this.clientRequests[requestId];\n\n if (commit) {\n this.commit();\n }\n }\n\n public commit() {\n return this.sendRequests();\n }\n\n public reset() {\n this.clientRequests = {};\n this.slotsActiveInLastMediaRequest = {};\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["CODEC_DEFAULTS","h264","maxFs","maxFps","maxMbps","MediaRequestManager","degradationPreferences","sendMediaRequestsCallback","counter","clientRequests","sourceUpdateListener","commit","bind","sendRequests","maxFsLimits","getMaxFs","totalMacroblocksRequested","forEach","id","mr","codecInfo","Math","min","i","slotsWithLiveSource","receiveSlots","filter","rs","sourceState","length","maxMacroblocksLimit","LoggerProxy","logger","warn","wcmeMediaRequests","getDegradedClientRequests","maxPayloadBitsPerSecond","push","WcmeMediaRequest","policyInfo","policy","Policy","ActiveSpeaker","ReceiverSelected","ActiveSpeakerInfo","priority","crossPriorityDuplication","crossPolicyDuplication","preferLiveVideo","ReceiverSelectedInfo","csi","map","receiveSlot","wcmeReceiveSlot","WcmeCodecInfo","H264Codec","maxWidth","maxHeight","mediaRequest","newId","on","ReceiveSlotEvents","SourceUpdate","requestId","off"],"sources":["mediaRequestManager.ts"],"sourcesContent":["/* eslint-disable require-jsdoc */\nimport {\n MediaRequest as WcmeMediaRequest,\n Policy,\n ActiveSpeakerInfo,\n ReceiverSelectedInfo,\n CodecInfo as WcmeCodecInfo,\n H264Codec,\n} from '@webex/internal-media-core';\nimport {cloneDeep} from 'lodash';\n\nimport LoggerProxy from '../common/logs/logger-proxy';\n\nimport {ReceiveSlot, ReceiveSlotEvents, ReceiveSlotId} from './receiveSlot';\nimport {getMaxFs} from './remoteMedia';\n\nexport interface ActiveSpeakerPolicyInfo {\n policy: 'active-speaker';\n priority: number;\n crossPriorityDuplication: boolean;\n crossPolicyDuplication: boolean;\n preferLiveVideo: boolean;\n}\n\nexport interface ReceiverSelectedPolicyInfo {\n policy: 'receiver-selected';\n csi: number;\n}\n\nexport type PolicyInfo = ActiveSpeakerPolicyInfo | ReceiverSelectedPolicyInfo;\n\nexport interface H264CodecInfo {\n codec: 'h264';\n maxFs?: number;\n maxFps?: number;\n maxMbps?: number;\n maxWidth?: number;\n maxHeight?: number;\n}\n\nexport type CodecInfo = H264CodecInfo; // we'll add AV1 here in the future when it's available\n\nexport interface MediaRequest {\n policyInfo: PolicyInfo;\n receiveSlots: Array<ReceiveSlot>;\n codecInfo?: CodecInfo;\n}\n\nexport type MediaRequestId = string;\n\nconst CODEC_DEFAULTS = {\n h264: {\n maxFs: 8192,\n maxFps: 3000,\n maxMbps: 245760,\n },\n};\n\ntype DegradationPreferences = {\n maxMacroblocksLimit: number;\n};\n\ntype SendMediaRequestsCallback = (mediaRequests: WcmeMediaRequest[]) => void;\n\nexport class MediaRequestManager {\n private sendMediaRequestsCallback: SendMediaRequestsCallback;\n\n private counter: number;\n\n private clientRequests: {[key: MediaRequestId]: MediaRequest};\n\n private degradationPreferences: DegradationPreferences;\n\n private sourceUpdateListener: () => void;\n\n constructor(\n degradationPreferences: DegradationPreferences,\n sendMediaRequestsCallback: SendMediaRequestsCallback\n ) {\n this.sendMediaRequestsCallback = sendMediaRequestsCallback;\n this.counter = 0;\n this.clientRequests = {};\n this.degradationPreferences = degradationPreferences;\n this.sourceUpdateListener = this.commit.bind(this);\n }\n\n public setDegradationPreferences(degradationPreferences: DegradationPreferences) {\n this.degradationPreferences = degradationPreferences;\n this.sendRequests(); // re-send requests after preferences are set\n }\n\n private getDegradedClientRequests() {\n const clientRequests = cloneDeep(this.clientRequests);\n const maxFsLimits = [\n getMaxFs('best'),\n getMaxFs('large'),\n getMaxFs('medium'),\n getMaxFs('small'),\n getMaxFs('very small'),\n getMaxFs('thumbnail'),\n ];\n\n // reduce max-fs until total macroblocks is below limit\n for (let i = 0; i < maxFsLimits.length; i += 1) {\n let totalMacroblocksRequested = 0;\n Object.entries(clientRequests).forEach(([id, mr]) => {\n if (mr.codecInfo) {\n mr.codecInfo.maxFs = Math.min(\n mr.codecInfo.maxFs || CODEC_DEFAULTS.h264.maxFs,\n maxFsLimits[i]\n );\n // we only consider sources with \"live\" state\n const slotsWithLiveSource = this.clientRequests[id].receiveSlots.filter(\n (rs) => rs.sourceState === 'live'\n );\n totalMacroblocksRequested += mr.codecInfo.maxFs * slotsWithLiveSource.length;\n }\n });\n if (totalMacroblocksRequested <= this.degradationPreferences.maxMacroblocksLimit) {\n if (i !== 0) {\n LoggerProxy.logger.warn(\n `multistream:mediaRequestManager --> too many streams with high max-fs, frame size will be limited to ${maxFsLimits[i]}`\n );\n }\n break;\n } else if (i === maxFsLimits.length - 1) {\n LoggerProxy.logger.warn(\n `multistream:mediaRequestManager --> even with frame size limited to ${maxFsLimits[i]} you are still requesting too many streams, consider reducing the number of requests`\n );\n }\n }\n\n return clientRequests;\n }\n\n private sendRequests() {\n const wcmeMediaRequests: WcmeMediaRequest[] = [];\n\n const clientRequests = this.getDegradedClientRequests();\n const maxPayloadBitsPerSecond = 10 * 1000 * 1000;\n\n // map all the client media requests to wcme media requests\n Object.values(clientRequests).forEach((mr) => {\n wcmeMediaRequests.push(\n new WcmeMediaRequest(\n mr.policyInfo.policy === 'active-speaker'\n ? Policy.ActiveSpeaker\n : Policy.ReceiverSelected,\n mr.policyInfo.policy === 'active-speaker'\n ? new ActiveSpeakerInfo(\n mr.policyInfo.priority,\n mr.policyInfo.crossPriorityDuplication,\n mr.policyInfo.crossPolicyDuplication,\n mr.policyInfo.preferLiveVideo\n )\n : new ReceiverSelectedInfo(mr.policyInfo.csi),\n mr.receiveSlots.map((receiveSlot) => receiveSlot.wcmeReceiveSlot),\n maxPayloadBitsPerSecond,\n mr.codecInfo && [\n new WcmeCodecInfo(\n 0x80,\n new H264Codec(\n mr.codecInfo.maxFs,\n mr.codecInfo.maxFps || CODEC_DEFAULTS.h264.maxFps,\n mr.codecInfo.maxMbps || CODEC_DEFAULTS.h264.maxMbps,\n mr.codecInfo.maxWidth,\n mr.codecInfo.maxHeight\n )\n ),\n ]\n )\n );\n });\n\n this.sendMediaRequestsCallback(wcmeMediaRequests);\n }\n\n public addRequest(mediaRequest: MediaRequest, commit = true): MediaRequestId {\n // eslint-disable-next-line no-plusplus\n const newId = `${this.counter++}`;\n\n this.clientRequests[newId] = mediaRequest;\n\n mediaRequest.receiveSlots.forEach((rs) => {\n rs.on(ReceiveSlotEvents.SourceUpdate, this.sourceUpdateListener);\n });\n\n if (commit) {\n this.commit();\n }\n\n return newId;\n }\n\n public cancelRequest(requestId: MediaRequestId, commit = true) {\n this.clientRequests[requestId]?.receiveSlots.forEach((rs) => {\n rs.off(ReceiveSlotEvents.SourceUpdate, this.sourceUpdateListener);\n });\n\n delete this.clientRequests[requestId];\n\n if (commit) {\n this.commit();\n }\n }\n\n public commit() {\n return this.sendRequests();\n }\n\n public reset() {\n this.clientRequests = {};\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AACA;AAUA;AAEA;AACA;AAdA;;AAkDA,IAAMA,cAAc,GAAG;EACrBC,IAAI,EAAE;IACJC,KAAK,EAAE,IAAI;IACXC,MAAM,EAAE,IAAI;IACZC,OAAO,EAAE;EACX;AACF,CAAC;AAAC,IAQWC,mBAAmB;EAW9B,6BACEC,sBAA8C,EAC9CC,yBAAoD,EACpD;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IACA,IAAI,CAACA,yBAAyB,GAAGA,yBAAyB;IAC1D,IAAI,CAACC,OAAO,GAAG,CAAC;IAChB,IAAI,CAACC,cAAc,GAAG,CAAC,CAAC;IACxB,IAAI,CAACH,sBAAsB,GAAGA,sBAAsB;IACpD,IAAI,CAACI,oBAAoB,GAAG,IAAI,CAACC,MAAM,CAACC,IAAI,CAAC,IAAI,CAAC;EACpD;EAAC;IAAA;IAAA,OAED,mCAAiCN,sBAA8C,EAAE;MAC/E,IAAI,CAACA,sBAAsB,GAAGA,sBAAsB;MACpD,IAAI,CAACO,YAAY,EAAE,CAAC,CAAC;IACvB;EAAC;IAAA;IAAA,OAED,qCAAoC;MAAA;MAClC,IAAMJ,cAAc,GAAG,yBAAU,IAAI,CAACA,cAAc,CAAC;MACrD,IAAMK,WAAW,GAAG,CAClB,IAAAC,qBAAQ,EAAC,MAAM,CAAC,EAChB,IAAAA,qBAAQ,EAAC,OAAO,CAAC,EACjB,IAAAA,qBAAQ,EAAC,QAAQ,CAAC,EAClB,IAAAA,qBAAQ,EAAC,OAAO,CAAC,EACjB,IAAAA,qBAAQ,EAAC,YAAY,CAAC,EACtB,IAAAA,qBAAQ,EAAC,WAAW,CAAC,CACtB;;MAED;MAAA,8BACgD;QAC9C,IAAIC,yBAAyB,GAAG,CAAC;QACjC,sBAAeP,cAAc,CAAC,CAACQ,OAAO,CAAC,gBAAc;UAAA;YAAZC,EAAE;YAAEC,EAAE;UAC7C,IAAIA,EAAE,CAACC,SAAS,EAAE;YAChBD,EAAE,CAACC,SAAS,CAAClB,KAAK,GAAGmB,IAAI,CAACC,GAAG,CAC3BH,EAAE,CAACC,SAAS,CAAClB,KAAK,IAAIF,cAAc,CAACC,IAAI,CAACC,KAAK,EAC/CY,WAAW,CAACS,CAAC,CAAC,CACf;YACD;YACA,IAAMC,mBAAmB,GAAG,KAAI,CAACf,cAAc,CAACS,EAAE,CAAC,CAACO,YAAY,CAACC,MAAM,CACrE,UAACC,EAAE;cAAA,OAAKA,EAAE,CAACC,WAAW,KAAK,MAAM;YAAA,EAClC;YACDZ,yBAAyB,IAAIG,EAAE,CAACC,SAAS,CAAClB,KAAK,GAAGsB,mBAAmB,CAACK,MAAM;UAC9E;QACF,CAAC,CAAC;QACF,IAAIb,yBAAyB,IAAI,KAAI,CAACV,sBAAsB,CAACwB,mBAAmB,EAAE;UAChF,IAAIP,CAAC,KAAK,CAAC,EAAE;YACXQ,oBAAW,CAACC,MAAM,CAACC,IAAI,gHACmFnB,WAAW,CAACS,CAAC,CAAC,EACvH;UACH;UAAC;QAEH,CAAC,MAAM,IAAIA,CAAC,KAAKT,WAAW,CAACe,MAAM,GAAG,CAAC,EAAE;UACvCE,oBAAW,CAACC,MAAM,CAACC,IAAI,+EACkDnB,WAAW,CAACS,CAAC,CAAC,0FACtF;QACH;MACF,CAAC;MA3BD,KAAK,IAAIA,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGT,WAAW,CAACe,MAAM,EAAEN,CAAC,IAAI,CAAC;QAAA;QAAA,sBAqB1C;MAAM;MAQV,OAAOd,cAAc;IACvB;EAAC;IAAA;IAAA,OAED,wBAAuB;MACrB,IAAMyB,iBAAqC,GAAG,EAAE;MAEhD,IAAMzB,cAAc,GAAG,IAAI,CAAC0B,yBAAyB,EAAE;MACvD,IAAMC,uBAAuB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI;;MAEhD;MACA,qBAAc3B,cAAc,CAAC,CAACQ,OAAO,CAAC,UAACE,EAAE,EAAK;QAC5Ce,iBAAiB,CAACG,IAAI,CACpB,IAAIC,+BAAgB,CAClBnB,EAAE,CAACoB,UAAU,CAACC,MAAM,KAAK,gBAAgB,GACrCC,yBAAM,CAACC,aAAa,GACpBD,yBAAM,CAACE,gBAAgB,EAC3BxB,EAAE,CAACoB,UAAU,CAACC,MAAM,KAAK,gBAAgB,GACrC,IAAII,oCAAiB,CACnBzB,EAAE,CAACoB,UAAU,CAACM,QAAQ,EACtB1B,EAAE,CAACoB,UAAU,CAACO,wBAAwB,EACtC3B,EAAE,CAACoB,UAAU,CAACQ,sBAAsB,EACpC5B,EAAE,CAACoB,UAAU,CAACS,eAAe,CAC9B,GACD,IAAIC,uCAAoB,CAAC9B,EAAE,CAACoB,UAAU,CAACW,GAAG,CAAC,EAC/C/B,EAAE,CAACM,YAAY,CAAC0B,GAAG,CAAC,UAACC,WAAW;UAAA,OAAKA,WAAW,CAACC,eAAe;QAAA,EAAC,EACjEjB,uBAAuB,EACvBjB,EAAE,CAACC,SAAS,IAAI,CACd,IAAIkC,4BAAa,CACf,IAAI,EACJ,IAAIC,4BAAS,CACXpC,EAAE,CAACC,SAAS,CAAClB,KAAK,EAClBiB,EAAE,CAACC,SAAS,CAACjB,MAAM,IAAIH,cAAc,CAACC,IAAI,CAACE,MAAM,EACjDgB,EAAE,CAACC,SAAS,CAAChB,OAAO,IAAIJ,cAAc,CAACC,IAAI,CAACG,OAAO,EACnDe,EAAE,CAACC,SAAS,CAACoC,QAAQ,EACrBrC,EAAE,CAACC,SAAS,CAACqC,SAAS,CACvB,CACF,CACF,CACF,CACF;MACH,CAAC,CAAC;MAEF,IAAI,CAAClD,yBAAyB,CAAC2B,iBAAiB,CAAC;IACnD;EAAC;IAAA;IAAA,OAED,oBAAkBwB,YAA0B,EAAiC;MAAA;MAAA,IAA/B/C,MAAM,uEAAG,IAAI;MACzD;MACA,IAAMgD,KAAK,aAAM,IAAI,CAACnD,OAAO,EAAE,CAAE;MAEjC,IAAI,CAACC,cAAc,CAACkD,KAAK,CAAC,GAAGD,YAAY;MAEzCA,YAAY,CAACjC,YAAY,CAACR,OAAO,CAAC,UAACU,EAAE,EAAK;QACxCA,EAAE,CAACiC,EAAE,CAACC,8BAAiB,CAACC,YAAY,EAAE,MAAI,CAACpD,oBAAoB,CAAC;MAClE,CAAC,CAAC;MAEF,IAAIC,MAAM,EAAE;QACV,IAAI,CAACA,MAAM,EAAE;MACf;MAEA,OAAOgD,KAAK;IACd;EAAC;IAAA;IAAA,OAED,uBAAqBI,SAAyB,EAAiB;MAAA;QAAA;MAAA,IAAfpD,MAAM,uEAAG,IAAI;MAC3D,6BAAI,CAACF,cAAc,CAACsD,SAAS,CAAC,0DAA9B,sBAAgCtC,YAAY,CAACR,OAAO,CAAC,UAACU,EAAE,EAAK;QAC3DA,EAAE,CAACqC,GAAG,CAACH,8BAAiB,CAACC,YAAY,EAAE,MAAI,CAACpD,oBAAoB,CAAC;MACnE,CAAC,CAAC;MAEF,OAAO,IAAI,CAACD,cAAc,CAACsD,SAAS,CAAC;MAErC,IAAIpD,MAAM,EAAE;QACV,IAAI,CAACA,MAAM,EAAE;MACf;IACF;EAAC;IAAA;IAAA,OAED,kBAAgB;MACd,OAAO,IAAI,CAACE,YAAY,EAAE;IAC5B;EAAC;IAAA;IAAA,OAED,iBAAe;MACb,IAAI,CAACJ,cAAc,GAAG,CAAC,CAAC;IAC1B;EAAC;EAAA;AAAA;AAAA"}
@@ -167,21 +167,6 @@ var ReceiveSlot = /*#__PURE__*/function (_EventsScope) {
167
167
  get: function get() {
168
168
  return this.mcReceiveSlot;
169
169
  }
170
-
171
- /**
172
- * Resets the source state to the default 'no source' value.
173
- * This function should be called on receive slots that are
174
- * no longer part of a media request. It's needed because WCME
175
- * does not send any more events on such slots, so the sourceState
176
- * value would not represent the truth anymore.
177
- */
178
- }, {
179
- key: "resetSourceState",
180
- value: function resetSourceState() {
181
- (0, _classPrivateFieldSet2.default)(this, _sourceState, 'no source');
182
- (0, _classPrivateFieldSet2.default)(this, _csi, undefined);
183
- (0, _classPrivateFieldSet2.default)(this, _memberId, undefined);
184
- }
185
170
  }]);
186
171
  return ReceiveSlot;
187
172
  }(_eventsScope.default);
@@ -1 +1 @@
1
- {"version":3,"names":["ReceiveSlotEvents","SourceUpdate","receiveSlotCounter","ReceiveSlot","mediaType","mcReceiveSlot","findMemberIdCallback","id","setupEventListeners","scope","file","function","on","WcmeReceiveSlotEvents","state","csi","LoggerProxy","logger","log","undefined","emit","memberId","stream","EventsScope"],"sources":["receiveSlot.ts"],"sourcesContent":["/* eslint-disable valid-jsdoc */\nimport {\n MediaType,\n ReceiveSlot as WcmeReceiveSlot,\n ReceiveSlotEvents as WcmeReceiveSlotEvents,\n SourceState,\n} from '@webex/internal-media-core';\n\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport EventsScope from '../common/events/events-scope';\n\nexport const ReceiveSlotEvents = {\n SourceUpdate: 'sourceUpdate',\n};\n\nexport type {SourceState} from '@webex/internal-media-core';\nexport type CSI = number;\nexport type MemberId = string;\nexport type ReceiveSlotId = string;\n\nlet receiveSlotCounter = 0;\n\nexport type FindMemberIdCallback = (csi: CSI) => MemberId | undefined;\n\n/**\n * Class representing a receive slot. A single receive slot is able to receive a single track\n * for example some participant's main video or audio\n */\nexport class ReceiveSlot extends EventsScope {\n private readonly mcReceiveSlot: WcmeReceiveSlot;\n\n private readonly findMemberIdCallback: FindMemberIdCallback;\n\n public readonly id: ReceiveSlotId;\n\n public readonly mediaType: MediaType;\n\n #memberId?: MemberId;\n\n #csi?: CSI;\n\n #sourceState: SourceState;\n\n /**\n * constructor - don't use it directly, you should always use meeting.receiveSlotManager.allocateSlot()\n * to create any receive slots\n *\n * @param {MediaType} mediaType\n * @param {ReceiveSlot} mcReceiveSlot\n * @param {FindMemberIdCallback} findMemberIdCallback callback for finding memberId for given CSI\n */\n constructor(\n mediaType: MediaType,\n mcReceiveSlot: WcmeReceiveSlot,\n findMemberIdCallback: FindMemberIdCallback\n ) {\n super();\n\n receiveSlotCounter += 1;\n\n this.findMemberIdCallback = findMemberIdCallback;\n this.mediaType = mediaType;\n this.mcReceiveSlot = mcReceiveSlot;\n this.#sourceState = 'no source';\n this.id = `r${receiveSlotCounter}`;\n\n this.setupEventListeners();\n }\n\n /**\n * Getter for memberId\n */\n public get memberId() {\n return this.#memberId;\n }\n\n /**\n * Getter for csi\n */\n public get csi() {\n return this.#csi;\n }\n\n /**\n * Getter for sourceState\n */\n public get sourceState() {\n return this.#sourceState;\n }\n\n /**\n * registers event handlers with the underlying ReceiveSlot\n */\n private setupEventListeners() {\n const scope = {\n file: 'meeting/receiveSlot',\n function: 'setupEventListeners',\n };\n\n this.mcReceiveSlot.on(\n WcmeReceiveSlotEvents.SourceUpdate,\n (state: SourceState, csi?: number) => {\n LoggerProxy.logger.log(\n `ReceiveSlot#setupEventListeners --> got source update on receive slot ${this.id}, mediaType=${this.mediaType}, csi=${csi}, state=${state}`\n );\n this.#memberId = csi ? this.findMemberIdCallback(csi) : undefined;\n this.#csi = csi;\n this.#sourceState = state;\n\n this.emit(scope, ReceiveSlotEvents.SourceUpdate, {\n state: this.#sourceState,\n csi: this.#csi,\n memberId: this.#memberId,\n });\n }\n );\n }\n\n /** Tries to find the member id for this receive slot if it hasn't got one */\n public findMemberId() {\n if (this.#memberId === undefined && this.#csi) {\n this.#memberId = this.findMemberIdCallback(this.#csi);\n\n if (this.#memberId) {\n // if we found the memberId, simulate source update so that the client app knows that something's changed\n this.emit(\n {\n file: 'meeting/receiveSlot',\n function: 'findMemberId',\n },\n ReceiveSlotEvents.SourceUpdate,\n {\n state: this.#sourceState,\n csi: this.#csi,\n memberId: this.#memberId,\n }\n );\n }\n }\n }\n\n /**\n * The MediaStream object associated with this slot.\n *\n * @returns {MediaStream} The MediaStreamTrack.\n */\n get stream(): MediaStream {\n return this.mcReceiveSlot.stream;\n }\n\n /**\n * The underlying WCME receive slot\n */\n get wcmeReceiveSlot(): WcmeReceiveSlot {\n return this.mcReceiveSlot;\n }\n\n /**\n * Resets the source state to the default 'no source' value.\n * This function should be called on receive slots that are\n * no longer part of a media request. It's needed because WCME\n * does not send any more events on such slots, so the sourceState\n * value would not represent the truth anymore.\n */\n public resetSourceState() {\n this.#sourceState = 'no source';\n this.#csi = undefined;\n this.#memberId = undefined;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["ReceiveSlotEvents","SourceUpdate","receiveSlotCounter","ReceiveSlot","mediaType","mcReceiveSlot","findMemberIdCallback","id","setupEventListeners","scope","file","function","on","WcmeReceiveSlotEvents","state","csi","LoggerProxy","logger","log","undefined","emit","memberId","stream","EventsScope"],"sources":["receiveSlot.ts"],"sourcesContent":["/* eslint-disable valid-jsdoc */\nimport {\n MediaType,\n ReceiveSlot as WcmeReceiveSlot,\n ReceiveSlotEvents as WcmeReceiveSlotEvents,\n SourceState,\n} from '@webex/internal-media-core';\n\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport EventsScope from '../common/events/events-scope';\n\nexport const ReceiveSlotEvents = {\n SourceUpdate: 'sourceUpdate',\n};\n\nexport type {SourceState} from '@webex/internal-media-core';\nexport type CSI = number;\nexport type MemberId = string;\nexport type ReceiveSlotId = string;\n\nlet receiveSlotCounter = 0;\n\nexport type FindMemberIdCallback = (csi: CSI) => MemberId | undefined;\n\n/**\n * Class representing a receive slot. A single receive slot is able to receive a single track\n * for example some participant's main video or audio\n */\nexport class ReceiveSlot extends EventsScope {\n private readonly mcReceiveSlot: WcmeReceiveSlot;\n\n private readonly findMemberIdCallback: FindMemberIdCallback;\n\n public readonly id: ReceiveSlotId;\n\n public readonly mediaType: MediaType;\n\n #memberId?: MemberId;\n\n #csi?: CSI;\n\n #sourceState: SourceState;\n\n /**\n * constructor - don't use it directly, you should always use meeting.receiveSlotManager.allocateSlot()\n * to create any receive slots\n *\n * @param {MediaType} mediaType\n * @param {ReceiveSlot} mcReceiveSlot\n * @param {FindMemberIdCallback} findMemberIdCallback callback for finding memberId for given CSI\n */\n constructor(\n mediaType: MediaType,\n mcReceiveSlot: WcmeReceiveSlot,\n findMemberIdCallback: FindMemberIdCallback\n ) {\n super();\n\n receiveSlotCounter += 1;\n\n this.findMemberIdCallback = findMemberIdCallback;\n this.mediaType = mediaType;\n this.mcReceiveSlot = mcReceiveSlot;\n this.#sourceState = 'no source';\n this.id = `r${receiveSlotCounter}`;\n\n this.setupEventListeners();\n }\n\n /**\n * Getter for memberId\n */\n public get memberId() {\n return this.#memberId;\n }\n\n /**\n * Getter for csi\n */\n public get csi() {\n return this.#csi;\n }\n\n /**\n * Getter for sourceState\n */\n public get sourceState() {\n return this.#sourceState;\n }\n\n /**\n * registers event handlers with the underlying ReceiveSlot\n */\n private setupEventListeners() {\n const scope = {\n file: 'meeting/receiveSlot',\n function: 'setupEventListeners',\n };\n\n this.mcReceiveSlot.on(\n WcmeReceiveSlotEvents.SourceUpdate,\n (state: SourceState, csi?: number) => {\n LoggerProxy.logger.log(\n `ReceiveSlot#setupEventListeners --> got source update on receive slot ${this.id}, mediaType=${this.mediaType}, csi=${csi}, state=${state}`\n );\n this.#memberId = csi ? this.findMemberIdCallback(csi) : undefined;\n this.#csi = csi;\n this.#sourceState = state;\n\n this.emit(scope, ReceiveSlotEvents.SourceUpdate, {\n state: this.#sourceState,\n csi: this.#csi,\n memberId: this.#memberId,\n });\n }\n );\n }\n\n /** Tries to find the member id for this receive slot if it hasn't got one */\n public findMemberId() {\n if (this.#memberId === undefined && this.#csi) {\n this.#memberId = this.findMemberIdCallback(this.#csi);\n\n if (this.#memberId) {\n // if we found the memberId, simulate source update so that the client app knows that something's changed\n this.emit(\n {\n file: 'meeting/receiveSlot',\n function: 'findMemberId',\n },\n ReceiveSlotEvents.SourceUpdate,\n {\n state: this.#sourceState,\n csi: this.#csi,\n memberId: this.#memberId,\n }\n );\n }\n }\n }\n\n /**\n * The MediaStream object associated with this slot.\n *\n * @returns {MediaStream} The MediaStreamTrack.\n */\n get stream(): MediaStream {\n return this.mcReceiveSlot.stream;\n }\n\n /**\n * The underlying WCME receive slot\n */\n get wcmeReceiveSlot(): WcmeReceiveSlot {\n return this.mcReceiveSlot;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AACA;AAOA;AACA;AAAwD;AAAA;AAAA;AAAA;AAEjD,IAAMA,iBAAiB,GAAG;EAC/BC,YAAY,EAAE;AAChB,CAAC;AAAC;AAOF,IAAIC,kBAAkB,GAAG,CAAC;AAAC;AAAA;AAAA;AAI3B;AACA;AACA;AACA;AAHA,IAIaC,WAAW;EAAA;EAAA;EAetB;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACE,qBACEC,SAAoB,EACpBC,aAA8B,EAC9BC,oBAA0C,EAC1C;IAAA;IAAA;IACA;IAAQ;IAAA;IAAA;IAAA;IAAA;MAAA;MAAA;IAAA;IAAA;MAAA;MAAA;IAAA;IAAA;MAAA;MAAA;IAAA;IAERJ,kBAAkB,IAAI,CAAC;IAEvB,MAAKI,oBAAoB,GAAGA,oBAAoB;IAChD,MAAKF,SAAS,GAAGA,SAAS;IAC1B,MAAKC,aAAa,GAAGA,aAAa;IAClC,+FAAoB,WAAW;IAC/B,MAAKE,EAAE,cAAOL,kBAAkB,CAAE;IAElC,MAAKM,mBAAmB,EAAE;IAAC;EAC7B;;EAEA;AACF;AACA;EAFE;IAAA;IAAA,KAGA,eAAsB;MACpB,2CAAO,IAAI;IACb;;IAEA;AACF;AACA;EAFE;IAAA;IAAA,KAGA,eAAiB;MACf,2CAAO,IAAI;IACb;;IAEA;AACF;AACA;EAFE;IAAA;IAAA,KAGA,eAAyB;MACvB,2CAAO,IAAI;IACb;;IAEA;AACF;AACA;EAFE;IAAA;IAAA,OAGA,+BAA8B;MAAA;MAC5B,IAAMC,KAAK,GAAG;QACZC,IAAI,EAAE,qBAAqB;QAC3BC,QAAQ,EAAE;MACZ,CAAC;MAED,IAAI,CAACN,aAAa,CAACO,EAAE,CACnBC,oCAAqB,CAACZ,YAAY,EAClC,UAACa,KAAkB,EAAEC,GAAY,EAAK;QACpCC,oBAAW,CAACC,MAAM,CAACC,GAAG,iFACqD,MAAI,CAACX,EAAE,yBAAe,MAAI,CAACH,SAAS,mBAASW,GAAG,qBAAWD,KAAK,EAC1I;QACD,0CAAI,aAAaC,GAAG,GAAG,MAAI,CAACT,oBAAoB,CAACS,GAAG,CAAC,GAAGI,SAAS;QACjE,0CAAI,QAAQJ,GAAG;QACf,0CAAI,gBAAgBD,KAAK;QAEzB,MAAI,CAACM,IAAI,CAACX,KAAK,EAAET,iBAAiB,CAACC,YAAY,EAAE;UAC/Ca,KAAK,sCAAE,MAAI,eAAa;UACxBC,GAAG,sCAAE,MAAI,OAAK;UACdM,QAAQ,sCAAE,MAAI;QAChB,CAAC,CAAC;MACJ,CAAC,CACF;IACH;;IAEA;EAAA;IAAA;IAAA,OACA,wBAAsB;MACpB,IAAI,wCAAI,iBAAeF,SAAS,wCAAI,IAAI,OAAK,EAAE;QAC7C,wCAAI,aAAa,IAAI,CAACb,oBAAoB,qCAAC,IAAI,QAAM;QAErD,wCAAI,IAAI,cAAY;UAClB;UACA,IAAI,CAACc,IAAI,CACP;YACEV,IAAI,EAAE,qBAAqB;YAC3BC,QAAQ,EAAE;UACZ,CAAC,EACDX,iBAAiB,CAACC,YAAY,EAC9B;YACEa,KAAK,sCAAE,IAAI,eAAa;YACxBC,GAAG,sCAAE,IAAI,OAAK;YACdM,QAAQ,sCAAE,IAAI;UAChB,CAAC,CACF;QACH;MACF;IACF;;IAEA;AACF;AACA;AACA;AACA;EAJE;IAAA;IAAA,KAKA,eAA0B;MACxB,OAAO,IAAI,CAAChB,aAAa,CAACiB,MAAM;IAClC;;IAEA;AACF;AACA;EAFE;IAAA;IAAA,KAGA,eAAuC;MACrC,OAAO,IAAI,CAACjB,aAAa;IAC3B;EAAC;EAAA;AAAA,EA/H8BkB,oBAAW;AAAA"}
@@ -35,11 +35,9 @@ export declare class MediaRequestManager {
35
35
  private sendMediaRequestsCallback;
36
36
  private counter;
37
37
  private clientRequests;
38
- private slotsActiveInLastMediaRequest;
39
38
  private degradationPreferences;
40
39
  private sourceUpdateListener;
41
40
  constructor(degradationPreferences: DegradationPreferences, sendMediaRequestsCallback: SendMediaRequestsCallback);
42
- private resetInactiveReceiveSlots;
43
41
  setDegradationPreferences(degradationPreferences: DegradationPreferences): void;
44
42
  private getDegradedClientRequests;
45
43
  private sendRequests;
@@ -55,12 +55,4 @@ export declare class ReceiveSlot extends EventsScope {
55
55
  * The underlying WCME receive slot
56
56
  */
57
57
  get wcmeReceiveSlot(): WcmeReceiveSlot;
58
- /**
59
- * Resets the source state to the default 'no source' value.
60
- * This function should be called on receive slots that are
61
- * no longer part of a media request. It's needed because WCME
62
- * does not send any more events on such slots, so the sourceState
63
- * value would not represent the truth anymore.
64
- */
65
- resetSourceState(): void;
66
58
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webex/plugin-meetings",
3
- "version": "3.0.0-beta.37",
3
+ "version": "3.0.0-beta.38",
4
4
  "description": "",
5
5
  "license": "Cisco EULA (https://www.cisco.com/c/en/us/products/end-user-license-agreement.html)",
6
6
  "contributors": [
@@ -32,12 +32,12 @@
32
32
  "build": "yarn run -T tsc --declaration true --declarationDir ./dist/types"
33
33
  },
34
34
  "devDependencies": {
35
- "@webex/plugin-meetings": "3.0.0-beta.37",
36
- "@webex/test-helper-chai": "3.0.0-beta.37",
37
- "@webex/test-helper-mocha": "3.0.0-beta.37",
38
- "@webex/test-helper-mock-webex": "3.0.0-beta.37",
39
- "@webex/test-helper-retry": "3.0.0-beta.37",
40
- "@webex/test-helper-test-users": "3.0.0-beta.37",
35
+ "@webex/plugin-meetings": "3.0.0-beta.38",
36
+ "@webex/test-helper-chai": "3.0.0-beta.38",
37
+ "@webex/test-helper-mocha": "3.0.0-beta.38",
38
+ "@webex/test-helper-mock-webex": "3.0.0-beta.38",
39
+ "@webex/test-helper-retry": "3.0.0-beta.38",
40
+ "@webex/test-helper-test-users": "3.0.0-beta.38",
41
41
  "chai": "^4.3.4",
42
42
  "chai-as-promised": "^7.1.1",
43
43
  "jsdom-global": "3.0.2",
@@ -46,18 +46,18 @@
46
46
  "typescript": "^4.7.4"
47
47
  },
48
48
  "dependencies": {
49
- "@webex/common": "3.0.0-beta.37",
50
- "@webex/internal-media-core": "1.35.1",
51
- "@webex/internal-plugin-conversation": "3.0.0-beta.37",
52
- "@webex/internal-plugin-device": "3.0.0-beta.37",
53
- "@webex/internal-plugin-llm": "3.0.0-beta.37",
54
- "@webex/internal-plugin-mercury": "3.0.0-beta.37",
55
- "@webex/internal-plugin-metrics": "3.0.0-beta.37",
56
- "@webex/internal-plugin-support": "3.0.0-beta.37",
57
- "@webex/internal-plugin-user": "3.0.0-beta.37",
58
- "@webex/plugin-people": "3.0.0-beta.37",
59
- "@webex/plugin-rooms": "3.0.0-beta.37",
60
- "@webex/webex-core": "3.0.0-beta.37",
49
+ "@webex/common": "3.0.0-beta.38",
50
+ "@webex/internal-media-core": "1.35.2",
51
+ "@webex/internal-plugin-conversation": "3.0.0-beta.38",
52
+ "@webex/internal-plugin-device": "3.0.0-beta.38",
53
+ "@webex/internal-plugin-llm": "3.0.0-beta.38",
54
+ "@webex/internal-plugin-mercury": "3.0.0-beta.38",
55
+ "@webex/internal-plugin-metrics": "3.0.0-beta.38",
56
+ "@webex/internal-plugin-support": "3.0.0-beta.38",
57
+ "@webex/internal-plugin-user": "3.0.0-beta.38",
58
+ "@webex/plugin-people": "3.0.0-beta.38",
59
+ "@webex/plugin-rooms": "3.0.0-beta.38",
60
+ "@webex/webex-core": "3.0.0-beta.38",
61
61
  "ampersand-collection": "^2.0.2",
62
62
  "bowser": "^2.11.0",
63
63
  "btoa": "^1.2.1",
@@ -69,8 +69,6 @@ export class MediaRequestManager {
69
69
 
70
70
  private clientRequests: {[key: MediaRequestId]: MediaRequest};
71
71
 
72
- private slotsActiveInLastMediaRequest: {[key: ReceiveSlotId]: ReceiveSlot};
73
-
74
72
  private degradationPreferences: DegradationPreferences;
75
73
 
76
74
  private sourceUpdateListener: () => void;
@@ -82,36 +80,10 @@ export class MediaRequestManager {
82
80
  this.sendMediaRequestsCallback = sendMediaRequestsCallback;
83
81
  this.counter = 0;
84
82
  this.clientRequests = {};
85
- this.slotsActiveInLastMediaRequest = {};
86
83
  this.degradationPreferences = degradationPreferences;
87
84
  this.sourceUpdateListener = this.commit.bind(this);
88
85
  }
89
86
 
90
- private resetInactiveReceiveSlots() {
91
- const activeSlots: {[key: ReceiveSlotId]: ReceiveSlot} = {};
92
-
93
- // create a map of all currently used slot ids
94
- Object.values(this.clientRequests).forEach((request) =>
95
- request.receiveSlots.forEach((slot) => {
96
- activeSlots[slot.id] = slot;
97
- })
98
- );
99
-
100
- // when we stop using some receive slots and they are not included in the new media request,
101
- // we will never get a 'no source' notification for them, so we reset their state,
102
- // so that the client doesn't try to display their video anymore
103
- for (const [slotId, slot] of Object.entries(this.slotsActiveInLastMediaRequest)) {
104
- if (!(slotId in activeSlots)) {
105
- LoggerProxy.logger.info(
106
- `multistream:mediaRequestManager --> resetting sourceState to "no source" for slot ${slot.id}`
107
- );
108
- slot.resetSourceState();
109
- }
110
- }
111
-
112
- this.slotsActiveInLastMediaRequest = activeSlots;
113
- }
114
-
115
87
  public setDegradationPreferences(degradationPreferences: DegradationPreferences) {
116
88
  this.degradationPreferences = degradationPreferences;
117
89
  this.sendRequests(); // re-send requests after preferences are set
@@ -201,8 +173,6 @@ export class MediaRequestManager {
201
173
  });
202
174
 
203
175
  this.sendMediaRequestsCallback(wcmeMediaRequests);
204
-
205
- this.resetInactiveReceiveSlots();
206
176
  }
207
177
 
208
178
  public addRequest(mediaRequest: MediaRequest, commit = true): MediaRequestId {
@@ -240,6 +210,5 @@ export class MediaRequestManager {
240
210
 
241
211
  public reset() {
242
212
  this.clientRequests = {};
243
- this.slotsActiveInLastMediaRequest = {};
244
213
  }
245
214
  }
@@ -154,17 +154,4 @@ export class ReceiveSlot extends EventsScope {
154
154
  get wcmeReceiveSlot(): WcmeReceiveSlot {
155
155
  return this.mcReceiveSlot;
156
156
  }
157
-
158
- /**
159
- * Resets the source state to the default 'no source' value.
160
- * This function should be called on receive slots that are
161
- * no longer part of a media request. It's needed because WCME
162
- * does not send any more events on such slots, so the sourceState
163
- * value would not represent the truth anymore.
164
- */
165
- public resetSourceState() {
166
- this.#sourceState = 'no source';
167
- this.#csi = undefined;
168
- this.#memberId = undefined;
169
- }
170
157
  }
@@ -62,7 +62,6 @@ describe('MediaRequestManager', () => {
62
62
  off: sinon.stub(),
63
63
  sourceState: 'live',
64
64
  wcmeReceiveSlot: fakeWcmeSlots[index],
65
- resetSourceState: sinon.stub(),
66
65
  } as unknown as ReceiveSlot)
67
66
  );
68
67
  });
@@ -609,78 +608,6 @@ describe('MediaRequestManager', () => {
609
608
  checkMediaRequestsSent([]);
610
609
  });
611
610
 
612
- it('calls resetSourceState() on slots that are stopped being used', () => {
613
- const requestIds = [
614
- addActiveSpeakerRequest(
615
- 255,
616
- [fakeReceiveSlots[0], fakeReceiveSlots[1]],
617
- ACTIVE_SPEAKER_MAX_FS
618
- ),
619
- addActiveSpeakerRequest(
620
- 255,
621
- [fakeReceiveSlots[2], fakeReceiveSlots[3]],
622
- ACTIVE_SPEAKER_MAX_FS
623
- ),
624
- addReceiverSelectedRequest(100, fakeReceiveSlots[4], RECEIVER_SELECTED_MAX_FS),
625
- addReceiverSelectedRequest(200, fakeReceiveSlots[5], RECEIVER_SELECTED_MAX_FS),
626
- ];
627
-
628
- mediaRequestManager.commit();
629
- checkMediaRequestsSent([
630
- {
631
- policy: 'active-speaker',
632
- priority: 255,
633
- receiveSlots: [fakeWcmeSlots[0], fakeWcmeSlots[1]],
634
- maxFs: ACTIVE_SPEAKER_MAX_FS,
635
- },
636
- {
637
- policy: 'active-speaker',
638
- priority: 255,
639
- receiveSlots: [fakeWcmeSlots[2], fakeWcmeSlots[3]],
640
- maxFs: ACTIVE_SPEAKER_MAX_FS,
641
- },
642
- {
643
- policy: 'receiver-selected',
644
- csi: 100,
645
- receiveSlot: fakeWcmeSlots[4],
646
- maxFs: RECEIVER_SELECTED_MAX_FS,
647
- },
648
- {
649
- policy: 'receiver-selected',
650
- csi: 200,
651
- receiveSlot: fakeWcmeSlots[5],
652
- maxFs: RECEIVER_SELECTED_MAX_FS,
653
- },
654
- ]);
655
-
656
- // cancel 2 of the requests
657
- mediaRequestManager.cancelRequest(requestIds[1], false);
658
- mediaRequestManager.cancelRequest(requestIds[3], false);
659
-
660
- mediaRequestManager.commit();
661
-
662
- // expect only the 2 remaining requests to be sent out
663
- checkMediaRequestsSent([
664
- {
665
- policy: 'active-speaker',
666
- priority: 255,
667
- receiveSlots: [fakeWcmeSlots[0], fakeWcmeSlots[1]],
668
- maxFs: ACTIVE_SPEAKER_MAX_FS,
669
- },
670
- {
671
- policy: 'receiver-selected',
672
- csi: 100,
673
- receiveSlot: fakeWcmeSlots[4],
674
- maxFs: RECEIVER_SELECTED_MAX_FS,
675
- },
676
- ]);
677
-
678
- // and that the receive slots of the 2 cancelled ones had resetSourceState() called
679
- assert.calledOnce(fakeReceiveSlots[2].resetSourceState);
680
- assert.calledOnce(fakeReceiveSlots[3].resetSourceState);
681
- assert.calledOnce(fakeReceiveSlots[5].resetSourceState);
682
- });
683
-
684
611
  it('re-sends media requests after degradation preferences are set', () => {
685
612
  // set max macroblocks limit
686
613
  mediaRequestManager.setDegradationPreferences({maxMacroblocksLimit: 32400});
@@ -83,25 +83,6 @@ describe('ReceiveSlot', () => {
83
83
  assert.strictEqual(receiveSlot.sourceState, 'live');
84
84
  });
85
85
 
86
- it('resets source related properties when resetSourceState() is called', () => {
87
- const csi = 123456;
88
- const fakeMemberId = '00000001-5555-6666-9012-345678901234';
89
-
90
- findMemberIdCallbackStub.returns(fakeMemberId);
91
-
92
- fakeWcmeSlot.emit(WcmeReceiveSlotEvents.SourceUpdate, 'live', csi);
93
-
94
- assert.strictEqual(receiveSlot.memberId, fakeMemberId);
95
- assert.strictEqual(receiveSlot.csi, csi);
96
- assert.strictEqual(receiveSlot.sourceState, 'live');
97
-
98
- receiveSlot.resetSourceState();
99
-
100
- assert.strictEqual(receiveSlot.memberId, undefined);
101
- assert.strictEqual(receiveSlot.csi, undefined);
102
- assert.strictEqual(receiveSlot.sourceState, 'no source');
103
- });
104
-
105
86
  describe('findMemberId()', () => {
106
87
  it('doesn\'t do anything if csi is not set', () => {
107
88
  // by default the receiveSlot does not have any csi or member id