@webex/web-client-media-engine 1.42.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/index.js CHANGED
@@ -5270,6 +5270,31 @@ function getRecommendedMaxBitrateForFrameSize(requestedMaxFs) {
5270
5270
  return maxFrameSizeToMaxBitrateMap.get(expectedHeight);
5271
5271
  }
5272
5272
 
5273
+ /******************************************************************************
5274
+ Copyright (c) Microsoft Corporation.
5275
+
5276
+ Permission to use, copy, modify, and/or distribute this software for any
5277
+ purpose with or without fee is hereby granted.
5278
+
5279
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
5280
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
5281
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
5282
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
5283
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
5284
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
5285
+ PERFORMANCE OF THIS SOFTWARE.
5286
+ ***************************************************************************** */
5287
+
5288
+ function __awaiter(thisArg, _arguments, P, generator) {
5289
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
5290
+ return new (P || (P = Promise))(function (resolve, reject) {
5291
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5292
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
5293
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
5294
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
5295
+ });
5296
+ }
5297
+
5273
5298
  var commonjsGlobal$1 = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
5274
5299
 
5275
5300
  var logger$2 = {exports: {}};
@@ -5562,6 +5587,34 @@ Logger$1.useDefaults({
5562
5587
  messages.unshift(`[${context.name}] `);
5563
5588
  },
5564
5589
  });
5590
+ function isValidActiveSpeakerInfo(msg) {
5591
+ const maybeActiveSpeakerInfo = msg;
5592
+ return Boolean('priority' in maybeActiveSpeakerInfo &&
5593
+ 'crossPriorityDuplication' in maybeActiveSpeakerInfo &&
5594
+ 'crossPolicyDuplication' in maybeActiveSpeakerInfo &&
5595
+ 'preferLiveVideo' in maybeActiveSpeakerInfo);
5596
+ }
5597
+ function areNamedMediaGroupArraysEqual(left, right) {
5598
+ if (left === undefined || right === undefined) {
5599
+ return left === right;
5600
+ }
5601
+ if (left.length !== right.length) {
5602
+ return false;
5603
+ }
5604
+ for (let i = 0; i < left.length; i += 1) {
5605
+ if (left[i] !== right[i]) {
5606
+ return false;
5607
+ }
5608
+ }
5609
+ return true;
5610
+ }
5611
+ function areActiveSpeakerInfosEqual(left, right) {
5612
+ return (left.priority === right.priority &&
5613
+ left.crossPriorityDuplication === right.crossPriorityDuplication &&
5614
+ left.crossPolicyDuplication === right.crossPolicyDuplication &&
5615
+ left.preferLiveVideo === right.preferLiveVideo &&
5616
+ areNamedMediaGroupArraysEqual(left.namedMediaGroups, right.namedMediaGroups));
5617
+ }
5565
5618
  function isValidActiveSpeakerNotificationMsg(msg) {
5566
5619
  const maybeActiveSpeakerNotificationMsg = msg;
5567
5620
  return Boolean(maybeActiveSpeakerNotificationMsg.seqNum && maybeActiveSpeakerNotificationMsg.csis);
@@ -5586,11 +5639,13 @@ class HomerMsg {
5586
5639
 
5587
5640
  var JmpMsgType;
5588
5641
  (function (JmpMsgType) {
5589
- JmpMsgType["Scr"] = "scr";
5590
- JmpMsgType["ScrAck"] = "scrAck";
5642
+ JmpMsgType["MediaRequest"] = "mediaRequest";
5643
+ JmpMsgType["MediaRequestAck"] = "mediaRequestAck";
5644
+ JmpMsgType["MediaRequestStatus"] = "mediaRequestStatus";
5645
+ JmpMsgType["MediaRequestStatusAck"] = "mediaRequestStatusAck";
5646
+ JmpMsgType["SourceAdvertisement"] = "sourceAdvertisement";
5647
+ JmpMsgType["SourceAdvertisementAck"] = "sourceAdvertisementAck";
5591
5648
  JmpMsgType["ActiveSpeakerNotification"] = "activeSpeakerNotification";
5592
- JmpMsgType["SourceIndication"] = "sourceIndication";
5593
- JmpMsgType["SourceIndicationAck"] = "sourceIndicationAck";
5594
5649
  })(JmpMsgType || (JmpMsgType = {}));
5595
5650
  class JmpMsg {
5596
5651
  constructor(mediaFamily, mediaContent, payload) {
@@ -5614,61 +5669,117 @@ function isValidJmpMsg(msg) {
5614
5669
  isValidJmpMsgPayload(maybeJmpMsg.payload));
5615
5670
  }
5616
5671
 
5617
- class JmpScrAckMsg {
5618
- constructor(scrSeqNum) {
5619
- this.scrSeqNum = scrSeqNum;
5672
+ class MediaRequestMsg {
5673
+ constructor(seqNum, requests) {
5674
+ this.seqNum = seqNum;
5675
+ this.requests = requests;
5620
5676
  }
5621
5677
  toString() {
5622
- return `JmpScrAckMsg(seqNum=${this.scrSeqNum})`;
5678
+ return `JmpMediaMsg(seqNum=${this.seqNum}, requests=[${this.requests}])`;
5623
5679
  }
5624
5680
  }
5625
- function isValidJmpScrAckMsg(msg) {
5626
- const maybeJmpScrAckMsg = msg;
5627
- return Boolean(maybeJmpScrAckMsg.scrSeqNum);
5681
+ function isValidMediaRequestMsg(msg) {
5682
+ const maybeMediaRequestMsg = msg;
5683
+ return Boolean(maybeMediaRequestMsg.seqNum && maybeMediaRequestMsg.requests);
5628
5684
  }
5629
5685
 
5630
- class JmpScrMsg {
5631
- constructor(seqNum, requests) {
5632
- this.seqNum = seqNum;
5633
- this.requests = requests;
5686
+ class MediaRequestAckMsg {
5687
+ constructor(mediaRequestSeqNum) {
5688
+ this.mediaRequestSeqNum = mediaRequestSeqNum;
5634
5689
  }
5635
5690
  toString() {
5636
- return `JmpScrMsg(seqNum=${this.seqNum}, requests=[${this.requests}])`;
5691
+ return `MediaRequestAckMsg(seqNum=${this.mediaRequestSeqNum})`;
5637
5692
  }
5638
5693
  }
5639
- function isValidJmpScrMsg(msg) {
5640
- const maybeJmpScrMsg = msg;
5641
- return Boolean(maybeJmpScrMsg.seqNum && maybeJmpScrMsg.requests);
5694
+ function isValidMediaRequestAckMsg(msg) {
5695
+ const maybeMediaRequestAckMsg = msg;
5696
+ return Boolean(maybeMediaRequestAckMsg.mediaRequestSeqNum);
5642
5697
  }
5643
5698
 
5644
- class JmpScrRequest {
5645
- constructor(policy, policySpecificInfo, ids, maxPayloadBitsPerSecond, codecInfos = []) {
5646
- this.policy = policy;
5647
- this.policySpecificInfo = policySpecificInfo;
5648
- this.ids = ids;
5649
- this.maxPayloadBitsPerSecond = maxPayloadBitsPerSecond;
5650
- this.codecInfos = codecInfos;
5699
+ function isValidStreamId(obj) {
5700
+ const maybeStreamId = obj;
5701
+ if (maybeStreamId.mid && maybeStreamId.ssrc) {
5702
+ return false;
5651
5703
  }
5652
- toString() {
5653
- return `Request(policy=${this.policy}, info=${this.policySpecificInfo}, ids=[${this.ids}], maxPayloadBitsPerSecond=[${this.maxPayloadBitsPerSecond}], codecInfos=[${this.codecInfos}])`;
5704
+ return Boolean(maybeStreamId.mid) || Boolean(maybeStreamId.ssrc);
5705
+ }
5706
+ function compareStreamIds(id1, id2) {
5707
+ const keys1 = Object.keys(id1);
5708
+ const keys2 = Object.keys(id2);
5709
+ if (keys1.length !== keys2.length) {
5710
+ return false;
5711
+ }
5712
+ return keys1.every((key) => id1[key] === id2[key]);
5713
+ }
5714
+
5715
+ function isValidStreamInfo(obj) {
5716
+ const maybeStreamInfo = obj;
5717
+ return Boolean(maybeStreamInfo.id &&
5718
+ isValidStreamId(maybeStreamInfo.id) &&
5719
+ ['no source', 'invalid source', 'live', 'avatar', 'bandwidth disabled'].includes(maybeStreamInfo.state));
5720
+ }
5721
+ class MediaRequestStatusMsg {
5722
+ constructor(seqNum, streamStates) {
5723
+ this.seqNum = seqNum;
5724
+ this.streamStates = streamStates;
5654
5725
  }
5655
5726
  }
5656
- function isValidReceiverSelectedInfo(msg) {
5657
- const maybeReceiverSelectedInfo = msg;
5658
- return Boolean(maybeReceiverSelectedInfo.csi);
5727
+ function isValidMediaRequestStatusMsg(msg) {
5728
+ const maybeMediaRequestStatusMsg = msg;
5729
+ return (Boolean(maybeMediaRequestStatusMsg.seqNum) &&
5730
+ maybeMediaRequestStatusMsg.streamStates &&
5731
+ maybeMediaRequestStatusMsg.streamStates.every((streamInfo) => isValidStreamInfo(streamInfo)));
5732
+ }
5733
+ function compareStreamStateArrays(streamStates1, streamStates2) {
5734
+ var _a, _b;
5735
+ if (streamStates1.length !== streamStates2.length) {
5736
+ return false;
5737
+ }
5738
+ for (let i = 0; i < streamStates1.length; i += 1) {
5739
+ if (!compareStreamIds(streamStates1[i].id, streamStates2[i].id)) {
5740
+ return false;
5741
+ }
5742
+ if (streamStates1[i].state !== streamStates2[i].state) {
5743
+ return false;
5744
+ }
5745
+ if (((_a = streamStates1[i]) === null || _a === void 0 ? void 0 : _a.csi) !== ((_b = streamStates2[i]) === null || _b === void 0 ? void 0 : _b.csi)) {
5746
+ return false;
5747
+ }
5748
+ }
5749
+ return true;
5659
5750
  }
5660
5751
 
5661
- class SourceIndicationAckMsg {
5662
- constructor(sourceIndicationSeqNum) {
5663
- this.sourceIndicationSeqNum = sourceIndicationSeqNum;
5752
+ class MediaRequestStatusAckMsg {
5753
+ constructor(mediaRequestStatusSeqNum) {
5754
+ this.mediaRequestStatusSeqNum = mediaRequestStatusSeqNum;
5664
5755
  }
5665
5756
  toString() {
5666
- return `SourceIndicationAckMsg(sourceIndicationSeqNum=${this.sourceIndicationSeqNum})`;
5757
+ return `MediaRequestStatusAckMsg(seqNum=${this.mediaRequestStatusSeqNum})`;
5667
5758
  }
5668
5759
  }
5669
- function isValidSourceIndicationAckMsg(msg) {
5670
- const maybeSourceIndicationAckMsg = msg;
5671
- return Boolean(maybeSourceIndicationAckMsg.sourceIndicationSeqNum);
5760
+ function isValidMediaRequestStatusAckMsg(msg) {
5761
+ const maybeMediaRequestStatusAckMsg = msg;
5762
+ return Boolean(maybeMediaRequestStatusAckMsg.mediaRequestStatusSeqNum);
5763
+ }
5764
+ function areH264CodecsEqual(left, right) {
5765
+ if (left === undefined || right === undefined) {
5766
+ return left === right;
5767
+ }
5768
+ return (left.maxFs === right.maxFs &&
5769
+ left.maxFps === right.maxFps &&
5770
+ left.maxMbps === right.maxMbps &&
5771
+ left.maxWidth === right.maxWidth &&
5772
+ left.maxHeight === right.maxHeight);
5773
+ }
5774
+ function areCodecInfosEqual(left, right) {
5775
+ return left.payloadType === right.payloadType && areH264CodecsEqual(left.h264, right.h264);
5776
+ }
5777
+ function isValidReceiverSelectedInfo(msg) {
5778
+ const maybeReceiverSelectedInfo = msg;
5779
+ return Boolean(maybeReceiverSelectedInfo.csi);
5780
+ }
5781
+ function areReceiverSelectedInfosEqual(left, right) {
5782
+ return left.csi === right.csi;
5672
5783
  }
5673
5784
 
5674
5785
  var MediaFamily;
@@ -5734,53 +5845,104 @@ function getMediaContent(mediaType) {
5734
5845
  }
5735
5846
  const truthyOrZero = (value) => value === 0 || value;
5736
5847
 
5737
- function isValidStreamId(obj) {
5738
- const maybeSourceId = obj;
5739
- if (maybeSourceId.mid && maybeSourceId.ssrc) {
5740
- return false;
5741
- }
5742
- return Boolean(maybeSourceId.mid) || Boolean(maybeSourceId.ssrc);
5743
- }
5744
- function compareStreamIds(id1, id2) {
5745
- const keys1 = Object.keys(id1);
5746
- const keys2 = Object.keys(id2);
5747
- if (keys1.length !== keys2.length) {
5748
- return false;
5749
- }
5750
- return keys1.every((key) => id1[key] === id2[key]);
5751
- }
5752
-
5753
- class SourceIndicationMsg {
5754
- constructor(seqNum, numTotalSources, numLiveSources, sources, videoContentHint) {
5848
+ class SourceAdvertisementMsg {
5849
+ constructor(seqNum, numTotalSources, numLiveSources, namedMediaGroups, videoContentHint) {
5755
5850
  this.seqNum = seqNum;
5756
5851
  this.numTotalSources = numTotalSources;
5757
5852
  this.numLiveSources = numLiveSources;
5758
- this.sources = sources;
5853
+ this.namedMediaGroups = namedMediaGroups;
5759
5854
  this.videoContentHint = videoContentHint;
5760
5855
  }
5761
- sourcesToString() {
5762
- return this.sources
5763
- .map((source) => `Source(id=${source.id} state=${source.state} ${source.csi ? `csi=${source.csi}` : ''})`)
5764
- .join(', ');
5856
+ toString() {
5857
+ return `SourceAdvertisement(seqNum=${this.seqNum}, numTotalSources=${this.numTotalSources}, numLiveSources=${this.numLiveSources}, namedMediaGroups=${this.namedMediaGroups}, videoContentHint=${this.videoContentHint}`;
5858
+ }
5859
+ }
5860
+ function isValidSourceAdvertisementMsg(msg) {
5861
+ const maybeSourceAdvertisementMsg = msg;
5862
+ return Boolean(maybeSourceAdvertisementMsg.seqNum &&
5863
+ truthyOrZero(maybeSourceAdvertisementMsg.numTotalSources) &&
5864
+ truthyOrZero(maybeSourceAdvertisementMsg.numLiveSources));
5865
+ }
5866
+
5867
+ class SourceAdvertisementAckMsg {
5868
+ constructor(sourceAdvertisementSeqNum) {
5869
+ this.sourceAdvertisementSeqNum = sourceAdvertisementSeqNum;
5765
5870
  }
5766
5871
  toString() {
5767
- return `SourceIndication(seqNum=${this.seqNum} numTotalSources=${this.numTotalSources} numLiveSources=${this.numLiveSources} sources=[${this.sourcesToString()}])`;
5872
+ return `SourceAdvertisementAckMsg(sourceAdvertisementSeqNum=${this.sourceAdvertisementSeqNum})`;
5768
5873
  }
5769
5874
  }
5770
- function isValidSource(obj) {
5771
- const maybeSource = obj;
5772
- return Boolean(maybeSource.id &&
5773
- isValidStreamId(maybeSource.id) &&
5774
- ['no source', 'invalid source', 'live', 'avatar', 'bandwidth disabled'].includes(maybeSource.state));
5875
+ function isValidSourceAdvertisementAckMsg(msg) {
5876
+ const maybeSourceAdvertisementAckMsg = msg;
5877
+ return Boolean(maybeSourceAdvertisementAckMsg.sourceAdvertisementSeqNum);
5878
+ }
5879
+
5880
+ class StreamRequest {
5881
+ constructor(policy, policySpecificInfo, ids, maxPayloadBitsPerSecond, codecInfos = []) {
5882
+ this.policy = policy;
5883
+ this.policySpecificInfo = policySpecificInfo;
5884
+ this.ids = ids;
5885
+ this.maxPayloadBitsPerSecond = maxPayloadBitsPerSecond;
5886
+ this.codecInfos = codecInfos;
5887
+ }
5888
+ toString() {
5889
+ return `Request(policy=${this.policy}, info=${this.policySpecificInfo}, ids=[${this.ids}], maxPayloadBitsPerSecond=[${this.maxPayloadBitsPerSecond}], codecInfos=[${this.codecInfos}])`;
5890
+ }
5775
5891
  }
5776
- function isValidSourceIndicationMsg(msg) {
5777
- var _a;
5778
- const maybeSourceIndicationMsg = msg;
5779
- return Boolean(maybeSourceIndicationMsg.seqNum &&
5780
- truthyOrZero(maybeSourceIndicationMsg.numTotalSources) &&
5781
- truthyOrZero(maybeSourceIndicationMsg.numLiveSources) &&
5782
- maybeSourceIndicationMsg.sources &&
5783
- ((_a = maybeSourceIndicationMsg.sources) === null || _a === void 0 ? void 0 : _a.every((source) => isValidSource(source))));
5892
+ function arePolicySpecificInfosEqual(left, right) {
5893
+ if (isValidActiveSpeakerInfo(left)) {
5894
+ if (!isValidActiveSpeakerInfo(right)) {
5895
+ return false;
5896
+ }
5897
+ return areActiveSpeakerInfosEqual(left, right);
5898
+ }
5899
+ if (isValidReceiverSelectedInfo(left)) {
5900
+ if (!isValidReceiverSelectedInfo(right)) {
5901
+ return false;
5902
+ }
5903
+ return areReceiverSelectedInfosEqual(left, right);
5904
+ }
5905
+ throw new Error('Invalid PolicySpecificInfo');
5906
+ }
5907
+ function areCodecInfoArraysEqual(left, right) {
5908
+ if (left.length !== right.length) {
5909
+ return false;
5910
+ }
5911
+ for (let i = 0; i < left.length; i += 1) {
5912
+ if (!areCodecInfosEqual(left[i], right[i])) {
5913
+ return false;
5914
+ }
5915
+ }
5916
+ return true;
5917
+ }
5918
+ function areStreamIdArraysEqual(left, right) {
5919
+ if (left.length !== right.length) {
5920
+ return false;
5921
+ }
5922
+ for (let i = 0; i < left.length; i += 1) {
5923
+ if (!compareStreamIds(left[i], right[i])) {
5924
+ return false;
5925
+ }
5926
+ }
5927
+ return true;
5928
+ }
5929
+ function areStreamRequestsEqual(left, right) {
5930
+ if (left.policy !== right.policy) {
5931
+ return false;
5932
+ }
5933
+ if (!arePolicySpecificInfosEqual(left.policySpecificInfo, right.policySpecificInfo)) {
5934
+ return false;
5935
+ }
5936
+ if (!areStreamIdArraysEqual(left.ids, right.ids)) {
5937
+ return false;
5938
+ }
5939
+ if (left.maxPayloadBitsPerSecond !== right.maxPayloadBitsPerSecond) {
5940
+ return false;
5941
+ }
5942
+ if (!areCodecInfoArraysEqual(left.codecInfos, right.codecInfos)) {
5943
+ return false;
5944
+ }
5945
+ return true;
5784
5946
  }
5785
5947
 
5786
5948
  class RetransmitHandler {
@@ -5817,19 +5979,32 @@ class RetransmitHandler {
5817
5979
 
5818
5980
  var JmpSessionEvents;
5819
5981
  (function (JmpSessionEvents) {
5820
- JmpSessionEvents["SourceIndication"] = "source-indication";
5821
5982
  JmpSessionEvents["ActiveSpeaker"] = "active-speaker";
5822
- JmpSessionEvents["ScrRequestReceived"] = "scr-request-received";
5983
+ JmpSessionEvents["MediaRequestReceived"] = "media-request-received";
5984
+ JmpSessionEvents["MediaRequestStatusReceived"] = "media-request-status-received";
5985
+ JmpSessionEvents["SourceAdvertisementReceived"] = "source-advertisement-received";
5823
5986
  })(JmpSessionEvents || (JmpSessionEvents = {}));
5987
+ function areStreamRequestArraysEqual(left, right) {
5988
+ if (left.length !== right.length) {
5989
+ return false;
5990
+ }
5991
+ for (let i = 0; i < left.length; i += 1) {
5992
+ if (!areStreamRequestsEqual(left[i], right[i])) {
5993
+ return false;
5994
+ }
5995
+ }
5996
+ return true;
5997
+ }
5824
5998
  class JmpSession extends events$2.EventEmitter {
5825
5999
  constructor(mediaFamily, mediaContent, maxNumRetransmits = 3, retransmitIntervalMs = 250) {
5826
6000
  super();
5827
- this.currScrSeqNum = 1;
5828
- this.currSourceIndicationSeqNum = 1;
6001
+ this.currMediaRequestSeqNum = 1;
6002
+ this.currSourceAdvertisementSeqNum = 1;
6003
+ this.currMediaRequestStatusSeqNum = 1;
5829
6004
  this.txCallback = undefined;
5830
- this.lastSentScr = undefined;
5831
- this.lastSentScrAck = undefined;
5832
- this.lastReceivedScr = undefined;
6005
+ this.lastSentMediaRequest = undefined;
6006
+ this.lastSentMediaRequestAck = undefined;
6007
+ this.lastReceivedMediaRequest = undefined;
5833
6008
  this.mediaFamily = mediaFamily;
5834
6009
  this.mediaContent = mediaContent;
5835
6010
  this.logger = Logger$1.get(`JmpSession ${this.mediaFamily}-${this.mediaContent}`);
@@ -5841,82 +6016,63 @@ class JmpSession extends events$2.EventEmitter {
5841
6016
  }
5842
6017
  sendRequests(requests) {
5843
6018
  var _a;
5844
- const jmpScr = new JmpScrMsg(this.currScrSeqNum++, requests);
5845
- const jmpMsg = new JmpMsg(this.mediaFamily, this.mediaContent, {
5846
- msgType: JmpMsgType.Scr,
5847
- payload: jmpScr,
5848
- });
5849
- this.sendJmpMsg(jmpMsg);
5850
- (_a = this.lastSentScr) === null || _a === void 0 ? void 0 : _a.cancel();
5851
- this.lastSentScr = new RetransmitHandler(jmpScr, this.maxNumRetransmits, this.retransmitIntervalMs, (msg) => this.sendJmpScr(msg), (expiredJmpMsg) => {
5852
- this.logger.warn(`Retransmits for message expired: ${expiredJmpMsg}`);
6019
+ const mediaRequestMsg = new MediaRequestMsg(this.currMediaRequestSeqNum, requests);
6020
+ if (!this.lastSentMediaRequest ||
6021
+ !areStreamRequestArraysEqual(this.lastSentMediaRequest.msg.requests, requests)) {
6022
+ this.sendJmpMsg(JmpMsgType.MediaRequest, mediaRequestMsg);
6023
+ (_a = this.lastSentMediaRequest) === null || _a === void 0 ? void 0 : _a.cancel();
6024
+ this.lastSentMediaRequest = new RetransmitHandler(mediaRequestMsg, this.maxNumRetransmits, this.retransmitIntervalMs, () => this.sendJmpMsg(JmpMsgType.MediaRequest, mediaRequestMsg), (expiredJmpMsg) => {
6025
+ this.logger.warn(`Retransmits for message expired: ${expiredJmpMsg}`);
6026
+ });
6027
+ this.currMediaRequestSeqNum++;
6028
+ }
6029
+ }
6030
+ sendSourceAdvertisement(numTotalSources, numLiveSources, namedMediaGroups, videoContentHint) {
6031
+ const sourceAdvertisementMsg = new SourceAdvertisementMsg(this.currSourceAdvertisementSeqNum++, numTotalSources, numLiveSources, namedMediaGroups, videoContentHint);
6032
+ this.sendJmpMsg(JmpMsgType.SourceAdvertisement, sourceAdvertisementMsg);
6033
+ this.lastSentSourceAdvertisement = new RetransmitHandler(sourceAdvertisementMsg, this.maxNumRetransmits, this.retransmitIntervalMs, () => this.sendJmpMsg(JmpMsgType.SourceAdvertisement, sourceAdvertisementMsg), (expiredMsg) => {
6034
+ this.logger.warn(`Retransmits for message expired: `, expiredMsg);
5853
6035
  });
5854
6036
  }
5855
- updateSourceIndication(numTotalSources, numLiveSources, sources, videoContentHint) {
5856
- var _a;
5857
- const filteredSources = sources.filter((source) => {
6037
+ sendMediaRequestStatus(streamStates) {
6038
+ var _a, _b;
6039
+ const filteredStreamStates = streamStates.filter((streamState) => {
5858
6040
  var _a;
5859
- return (_a = this.lastReceivedScr) === null || _a === void 0 ? void 0 : _a.requests.some((req) => req.ids.find((streamId) => compareStreamIds(streamId, source.id)));
5860
- });
5861
- const sourceIndicationMsg = new SourceIndicationMsg(this.currSourceIndicationSeqNum++, numTotalSources, numLiveSources, filteredSources, videoContentHint);
5862
- const jmpMsg = new JmpMsg(this.mediaFamily, this.mediaContent, {
5863
- msgType: JmpMsgType.SourceIndication,
5864
- payload: sourceIndicationMsg,
5865
- });
5866
- this.sendJmpMsg(jmpMsg);
5867
- (_a = this.lastSentSourceIndication) === null || _a === void 0 ? void 0 : _a.cancel();
5868
- this.lastSentSourceIndication = new RetransmitHandler(sourceIndicationMsg, this.maxNumRetransmits, this.retransmitIntervalMs, (msg) => this.sendSourceIndication(msg), (expiredMsg) => {
5869
- this.logger.warn(`Retransmits for message expired:`, expiredMsg);
6041
+ return (_a = this.lastReceivedMediaRequest) === null || _a === void 0 ? void 0 : _a.requests.some((req) => req.ids.find((streamId) => compareStreamIds(streamId, streamState.id)));
5870
6042
  });
6043
+ const mediaRequestStatus = new MediaRequestStatusMsg(this.currMediaRequestStatusSeqNum, filteredStreamStates);
6044
+ if (!((_a = this.lastSentMediaRequestStatus) === null || _a === void 0 ? void 0 : _a.msg.streamStates) ||
6045
+ !compareStreamStateArrays(filteredStreamStates, this.lastSentMediaRequestStatus.msg.streamStates)) {
6046
+ this.sendJmpMsg(JmpMsgType.MediaRequestStatus, mediaRequestStatus);
6047
+ (_b = this.lastSentMediaRequestStatus) === null || _b === void 0 ? void 0 : _b.cancel();
6048
+ this.lastSentMediaRequestStatus = new RetransmitHandler(mediaRequestStatus, this.maxNumRetransmits, this.retransmitIntervalMs, () => this.sendJmpMsg(JmpMsgType.MediaRequestStatus, mediaRequestStatus), (expiredMsg) => {
6049
+ this.logger.warn(`Retransmits for message expired: `, expiredMsg);
6050
+ });
6051
+ this.currMediaRequestStatusSeqNum++;
6052
+ }
5871
6053
  }
5872
6054
  receive(jmpMsg) {
5873
- var _a, _b, _c, _d, _e, _f, _g, _h;
5874
6055
  if (jmpMsg.mediaContent !== this.mediaContent || jmpMsg.mediaFamily !== this.mediaFamily) {
5875
6056
  this.logger.error(`JmpMsg ${jmpMsg} sent to incorrect JmpSession`);
5876
6057
  return;
5877
6058
  }
5878
6059
  this.logger.debug(`Received JmpMsg`, jmpMsg);
5879
6060
  const { payload } = jmpMsg;
5880
- if (payload.msgType === JmpMsgType.Scr) {
5881
- const jmpScr = payload.payload;
5882
- if (!isValidJmpScrMsg(jmpScr)) {
5883
- this.logger.error(`Received invalid SCR:`, jmpScr);
6061
+ if (payload.msgType === JmpMsgType.MediaRequest) {
6062
+ const mediaRequestMsg = payload.payload;
6063
+ if (!isValidMediaRequestMsg(mediaRequestMsg)) {
6064
+ this.logger.error(`Received invalid MediaRequest:`, mediaRequestMsg);
5884
6065
  return;
5885
6066
  }
5886
- if (this.lastReceivedScr && jmpScr.seqNum < ((_a = this.lastReceivedScr) === null || _a === void 0 ? void 0 : _a.seqNum)) {
5887
- this.logger.info(`Received old SCR, ignoring`);
5888
- }
5889
- else if (this.lastReceivedScr && jmpScr.seqNum === this.lastReceivedScr.seqNum) {
5890
- if (this.lastSentScrAck) {
5891
- this.logger.info(`Received duplicate SCR, re-sending ACK`);
5892
- this.sendJmpScrAck(this.lastSentScrAck);
5893
- }
5894
- else {
5895
- this.logger.warn(`Received duplicate SCR, but there was no ACK previously sent`);
5896
- }
5897
- }
5898
- else {
5899
- this.logger.info(`Received new SCR, sending ACK`);
5900
- const jmpScrAck = new JmpScrAckMsg(jmpScr.seqNum);
5901
- this.lastReceivedScr = jmpScr;
5902
- this.lastSentScrAck = jmpScrAck;
5903
- this.sendJmpScrAck(jmpScrAck);
5904
- this.emit(JmpSessionEvents.ScrRequestReceived, jmpScr);
5905
- }
6067
+ this.handleIncomingMediaRequest(mediaRequestMsg);
5906
6068
  }
5907
- else if (payload.msgType === JmpMsgType.ScrAck) {
5908
- const jmpScrAck = payload.payload;
5909
- if (!isValidJmpScrAckMsg(jmpScrAck)) {
5910
- this.logger.error(`Received invalid SCR ACK:`, jmpScrAck);
6069
+ else if (payload.msgType === JmpMsgType.MediaRequestAck) {
6070
+ const mediaRequestAckMsg = payload.payload;
6071
+ if (!isValidMediaRequestAckMsg(mediaRequestAckMsg)) {
6072
+ this.logger.error(`Received invalid MediaRequest ACK:`, mediaRequestAckMsg);
5911
6073
  return;
5912
6074
  }
5913
- if (jmpScrAck.scrSeqNum === ((_c = (_b = this.lastSentScr) === null || _b === void 0 ? void 0 : _b.msg) === null || _c === void 0 ? void 0 : _c.seqNum)) {
5914
- this.logger.info(`Received ACK for last sent SCR`);
5915
- (_d = this.lastSentScr) === null || _d === void 0 ? void 0 : _d.cancel();
5916
- }
5917
- else {
5918
- this.logger.info(`Received ACK for old SCR`);
5919
- }
6075
+ this.handleIncomingMediaRequestAck(mediaRequestAckMsg);
5920
6076
  }
5921
6077
  else if (payload.msgType === JmpMsgType.ActiveSpeakerNotification) {
5922
6078
  const activeSpeakerNotification = payload.payload;
@@ -5924,51 +6080,39 @@ class JmpSession extends events$2.EventEmitter {
5924
6080
  this.logger.info(`Received invalid Active Speaker Notification:`, activeSpeakerNotification);
5925
6081
  return;
5926
6082
  }
5927
- this.logger.debug(`Received Active Speaker Notification:`, activeSpeakerNotification);
5928
- this.emit(JmpSessionEvents.ActiveSpeaker, activeSpeakerNotification);
6083
+ this.handleIncomingActiveSpeakerNotification(activeSpeakerNotification);
5929
6084
  }
5930
- else if (payload.msgType === JmpMsgType.SourceIndication) {
5931
- const sourceIndication = payload.payload;
5932
- if (!isValidSourceIndicationMsg(sourceIndication)) {
5933
- this.logger.error(`Received invalid Source Indication:`, sourceIndication);
6085
+ else if (payload.msgType === JmpMsgType.SourceAdvertisement) {
6086
+ const sourceAdvertisement = payload.payload;
6087
+ if (!isValidSourceAdvertisementMsg(sourceAdvertisement)) {
6088
+ this.logger.error(`Received invalid SourceAdvertisementMsg: `, sourceAdvertisement);
5934
6089
  return;
5935
6090
  }
5936
- if (this.lastReceivedSourceIndication &&
5937
- sourceIndication.seqNum < ((_e = this.lastReceivedSourceIndication) === null || _e === void 0 ? void 0 : _e.seqNum)) {
5938
- this.logger.info(`Received old Source Indication, ignoring`);
5939
- }
5940
- else if (this.lastReceivedSourceIndication &&
5941
- sourceIndication.seqNum === this.lastReceivedSourceIndication.seqNum) {
5942
- if (this.lastSentSourceIndicationAck) {
5943
- this.logger.info(`Received duplicate Source Indication, re-sending ACK`);
5944
- this.sendSourceIndicationAck(this.lastSentSourceIndicationAck);
5945
- }
5946
- else {
5947
- this.logger.warn(`Received duplicate Source Indication, but there was no ACK previously sent`);
5948
- }
5949
- }
5950
- else {
5951
- this.logger.info(`Received new Source Indication, sending ACK`);
5952
- const sourceIndicationAck = new SourceIndicationAckMsg(sourceIndication.seqNum);
5953
- this.lastReceivedSourceIndication = sourceIndication;
5954
- this.lastSentSourceIndicationAck = sourceIndicationAck;
5955
- this.sendSourceIndicationAck(sourceIndicationAck);
5956
- this.emit(JmpSessionEvents.SourceIndication, sourceIndication);
5957
- }
6091
+ this.handleIncomingSourceAdvertisement(sourceAdvertisement);
5958
6092
  }
5959
- else if (payload.msgType === JmpMsgType.SourceIndicationAck) {
5960
- const sourceIndicationAck = payload.payload;
5961
- if (!isValidSourceIndicationAckMsg(sourceIndicationAck)) {
5962
- this.logger.error(`Received invalid SCR ACK:`, sourceIndicationAck);
6093
+ else if (payload.msgType === JmpMsgType.SourceAdvertisementAck) {
6094
+ const sourceAdvertisementAck = payload.payload;
6095
+ if (!isValidSourceAdvertisementAckMsg(sourceAdvertisementAck)) {
6096
+ this.logger.error(`Received invalid SourceAdvertisementAckMsg: `, sourceAdvertisementAck);
5963
6097
  return;
5964
6098
  }
5965
- if (sourceIndicationAck.sourceIndicationSeqNum === ((_g = (_f = this.lastSentSourceIndication) === null || _f === void 0 ? void 0 : _f.msg) === null || _g === void 0 ? void 0 : _g.seqNum)) {
5966
- this.logger.info(`Received ACK for last sent SCR`);
5967
- (_h = this.lastSentSourceIndication) === null || _h === void 0 ? void 0 : _h.cancel();
6099
+ this.handleIncomingSourceAdvertisementAck(sourceAdvertisementAck);
6100
+ }
6101
+ else if (payload.msgType === JmpMsgType.MediaRequestStatus) {
6102
+ const mediaRequestStatus = payload.payload;
6103
+ if (!isValidMediaRequestStatusMsg(mediaRequestStatus)) {
6104
+ this.logger.error(`Received invalid MediaRequestStatusMsg: `, mediaRequestStatus);
6105
+ return;
5968
6106
  }
5969
- else {
5970
- this.logger.info(`Received ACK for old SCR`);
6107
+ this.handleIncomingMediaRequestStatus(mediaRequestStatus);
6108
+ }
6109
+ else if (payload.msgType === JmpMsgType.MediaRequestStatusAck) {
6110
+ const mediaRequestStatusAck = payload.payload;
6111
+ if (!isValidMediaRequestStatusAckMsg(mediaRequestStatusAck)) {
6112
+ this.logger.error(`Received invalid MediaRequestStatusAckMsg: `, mediaRequestStatusAck);
6113
+ return;
5971
6114
  }
6115
+ this.handleIncomingMediaRequestStatusAck(mediaRequestStatusAck);
5972
6116
  }
5973
6117
  else {
5974
6118
  this.logger.error(`Received unknown JmpMsg`);
@@ -5980,79 +6124,126 @@ class JmpSession extends events$2.EventEmitter {
5980
6124
  close() {
5981
6125
  var _a;
5982
6126
  this.logger.info(`closing`);
5983
- (_a = this.lastSentScr) === null || _a === void 0 ? void 0 : _a.cancel();
6127
+ (_a = this.lastSentMediaRequest) === null || _a === void 0 ? void 0 : _a.cancel();
5984
6128
  }
5985
- sendSourceIndicationAck(sourceIndicationAck) {
6129
+ sendJmpMsg(msgType, payload) {
6130
+ var _a;
5986
6131
  const jmpMsg = new JmpMsg(this.mediaFamily, this.mediaContent, {
5987
- msgType: JmpMsgType.SourceIndicationAck,
5988
- payload: sourceIndicationAck,
6132
+ msgType,
6133
+ payload,
5989
6134
  });
5990
- this.sendJmpMsg(jmpMsg);
6135
+ const homerMsg = new HomerMsg(HomerMsgType.Multistream, jmpMsg);
6136
+ (_a = this.txCallback) === null || _a === void 0 ? void 0 : _a.call(this, JSON.stringify(homerMsg));
5991
6137
  }
5992
- sendSourceIndication(sourceIndication) {
5993
- const jmpMsg = new JmpMsg(this.mediaFamily, this.mediaContent, {
5994
- msgType: JmpMsgType.SourceIndication,
5995
- payload: sourceIndication,
5996
- });
5997
- this.sendJmpMsg(jmpMsg);
6138
+ handleIncomingMediaRequest(mediaRequestMsg) {
6139
+ var _a;
6140
+ if (this.lastReceivedMediaRequest &&
6141
+ mediaRequestMsg.seqNum < ((_a = this.lastReceivedMediaRequest) === null || _a === void 0 ? void 0 : _a.seqNum)) {
6142
+ this.logger.info(`Received old MediaRequest, ignoring`);
6143
+ }
6144
+ else if (this.lastReceivedMediaRequest &&
6145
+ mediaRequestMsg.seqNum === this.lastReceivedMediaRequest.seqNum) {
6146
+ if (this.lastSentMediaRequestAck) {
6147
+ this.logger.info(`Received duplicate MediaRequest, re-sending ACK`);
6148
+ this.sendJmpMsg(JmpMsgType.MediaRequestAck, this.lastSentMediaRequestAck);
6149
+ }
6150
+ else {
6151
+ this.logger.warn(`Received duplicate MediaRequest, but there was no ACK previously sent`);
6152
+ }
6153
+ }
6154
+ else {
6155
+ this.logger.info(`Received new MediaRequest, sending ACK`);
6156
+ const mediaRequestAck = new MediaRequestAckMsg(mediaRequestMsg.seqNum);
6157
+ this.lastReceivedMediaRequest = mediaRequestMsg;
6158
+ this.lastSentMediaRequestAck = mediaRequestAck;
6159
+ this.sendJmpMsg(JmpMsgType.MediaRequestAck, mediaRequestAck);
6160
+ this.emit(JmpSessionEvents.MediaRequestReceived, mediaRequestMsg);
6161
+ }
5998
6162
  }
5999
- sendJmpScrAck(jmpScrAck) {
6000
- const jmpMsg = new JmpMsg(this.mediaFamily, this.mediaContent, {
6001
- msgType: JmpMsgType.ScrAck,
6002
- payload: jmpScrAck,
6003
- });
6004
- this.sendJmpMsg(jmpMsg);
6163
+ handleIncomingMediaRequestAck(mediaRequestAckMsg) {
6164
+ var _a, _b, _c;
6165
+ if (mediaRequestAckMsg.mediaRequestSeqNum === ((_b = (_a = this.lastSentMediaRequest) === null || _a === void 0 ? void 0 : _a.msg) === null || _b === void 0 ? void 0 : _b.seqNum)) {
6166
+ this.logger.info(`Received ACK for last sent MediaRequest`);
6167
+ (_c = this.lastSentMediaRequest) === null || _c === void 0 ? void 0 : _c.cancel();
6168
+ }
6169
+ else {
6170
+ this.logger.info(`Received ACK for old MediaRequest`);
6171
+ }
6005
6172
  }
6006
- sendJmpScr(jmpScr) {
6007
- const jmpMsg = new JmpMsg(this.mediaFamily, this.mediaContent, {
6008
- msgType: JmpMsgType.Scr,
6009
- payload: jmpScr,
6010
- });
6011
- this.sendJmpMsg(jmpMsg);
6173
+ handleIncomingActiveSpeakerNotification(activeSpeakerNotification) {
6174
+ this.logger.debug(`Received Active Speaker Notification:`, activeSpeakerNotification);
6175
+ this.emit(JmpSessionEvents.ActiveSpeaker, activeSpeakerNotification);
6012
6176
  }
6013
- sendJmpMsg(msg) {
6014
- var _a;
6015
- const homerMsg = new HomerMsg(HomerMsgType.Multistream, msg);
6016
- (_a = this.txCallback) === null || _a === void 0 ? void 0 : _a.call(this, JSON.stringify(homerMsg));
6177
+ handleIncomingSourceAdvertisement(sourceAdvertisement) {
6178
+ if (this.lastReceivedSourceAdvertisement &&
6179
+ sourceAdvertisement.seqNum < this.lastReceivedSourceAdvertisement.seqNum) {
6180
+ this.logger.info(`Received old SourceAdvertisement, ignoring`);
6181
+ }
6182
+ else if (this.lastReceivedSourceAdvertisement &&
6183
+ sourceAdvertisement.seqNum === this.lastReceivedSourceAdvertisement.seqNum) {
6184
+ if (this.lastSentSourceAdvertisementAck) {
6185
+ this.logger.info(`Received duplicate SourceAdvertisement, re-sending ACK`);
6186
+ this.sendJmpMsg(JmpMsgType.SourceAdvertisementAck, this.lastSentSourceAdvertisementAck);
6187
+ }
6188
+ else {
6189
+ this.logger.warn(`Received duplicate SourceAdvertisement, but there was no ACK previously sent`);
6190
+ }
6191
+ }
6192
+ else {
6193
+ this.logger.info(`Received new SourceAdvertisement, sending ACK`);
6194
+ const sourceAdvertisementAck = new SourceAdvertisementAckMsg(sourceAdvertisement.seqNum);
6195
+ this.lastReceivedSourceAdvertisement = sourceAdvertisement;
6196
+ this.lastSentSourceAdvertisementAck = sourceAdvertisementAck;
6197
+ this.sendJmpMsg(JmpMsgType.SourceAdvertisementAck, sourceAdvertisementAck);
6198
+ this.emit(JmpSessionEvents.SourceAdvertisementReceived, sourceAdvertisement);
6199
+ }
6017
6200
  }
6018
- }
6019
-
6020
- class MediaRequest {
6021
- constructor(policy, policySpecificInfo, receiveSlots, maxPayloadBitsPerSecond, codecInfos = []) {
6022
- this.policy = policy;
6023
- this.policySpecificInfo = policySpecificInfo;
6024
- this.receiveSlots = receiveSlots;
6025
- this.maxPayloadBitsPerSecond = maxPayloadBitsPerSecond;
6026
- this.codecInfos = codecInfos;
6201
+ handleIncomingSourceAdvertisementAck(sourceAdvertisementAck) {
6202
+ var _a, _b, _c;
6203
+ if (sourceAdvertisementAck.sourceAdvertisementSeqNum ===
6204
+ ((_b = (_a = this.lastSentSourceAdvertisement) === null || _a === void 0 ? void 0 : _a.msg) === null || _b === void 0 ? void 0 : _b.seqNum)) {
6205
+ this.logger.info(`Received ACK for last sent SourceAdvertisement`);
6206
+ (_c = this.lastSentSourceAdvertisement) === null || _c === void 0 ? void 0 : _c.cancel();
6207
+ }
6208
+ else {
6209
+ this.logger.info(`Received ACK for old SourceAdvertisement`);
6210
+ }
6027
6211
  }
6028
- _toJmpScrRequest() {
6029
- return new JmpScrRequest(this.policy, this.policySpecificInfo, this.receiveSlots.map((rs) => rs.id), this.maxPayloadBitsPerSecond, this.codecInfos);
6212
+ handleIncomingMediaRequestStatus(mediaRequestStatus) {
6213
+ if (this.lastReceivedMediaRequestStatus &&
6214
+ mediaRequestStatus.seqNum < this.lastReceivedMediaRequestStatus.seqNum) {
6215
+ this.logger.info(`Received old MediaRequestStatus, ignoring`);
6216
+ }
6217
+ else if (this.lastReceivedMediaRequestStatus &&
6218
+ mediaRequestStatus.seqNum === this.lastReceivedMediaRequestStatus.seqNum) {
6219
+ if (this.lastSentMediaRequestStatusAck) {
6220
+ this.logger.info(`Received duplicate MediaRequestStatus, re-sending ACK`);
6221
+ this.sendJmpMsg(JmpMsgType.MediaRequestStatusAck, this.lastSentMediaRequestStatusAck);
6222
+ }
6223
+ else {
6224
+ this.logger.warn(`Received duplicate MediaRequestStatus, but there was no ACK previously sent`);
6225
+ }
6226
+ }
6227
+ else {
6228
+ this.logger.info(`Received new MediaRequestStatus, sending ACK`);
6229
+ const mediaRequestStatusAck = new MediaRequestStatusAckMsg(mediaRequestStatus.seqNum);
6230
+ this.lastReceivedMediaRequestStatus = mediaRequestStatus;
6231
+ this.lastSentMediaRequestStatusAck = mediaRequestStatusAck;
6232
+ this.sendJmpMsg(JmpMsgType.MediaRequestStatusAck, mediaRequestStatusAck);
6233
+ this.emit(JmpSessionEvents.MediaRequestStatusReceived, mediaRequestStatus);
6234
+ }
6235
+ }
6236
+ handleIncomingMediaRequestStatusAck(mediaRequestStatusAck) {
6237
+ var _a, _b, _c;
6238
+ if (mediaRequestStatusAck.mediaRequestStatusSeqNum ===
6239
+ ((_b = (_a = this.lastSentMediaRequestStatus) === null || _a === void 0 ? void 0 : _a.msg) === null || _b === void 0 ? void 0 : _b.seqNum)) {
6240
+ this.logger.info(`Received ACK for last sent MediaRequestStatus`);
6241
+ (_c = this.lastSentMediaRequestStatus) === null || _c === void 0 ? void 0 : _c.cancel();
6242
+ }
6243
+ else {
6244
+ this.logger.info(`Received ACK for old MediaRequestStatus`);
6245
+ }
6030
6246
  }
6031
- }
6032
-
6033
- /******************************************************************************
6034
- Copyright (c) Microsoft Corporation.
6035
-
6036
- Permission to use, copy, modify, and/or distribute this software for any
6037
- purpose with or without fee is hereby granted.
6038
-
6039
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
6040
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
6041
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
6042
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
6043
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
6044
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
6045
- PERFORMANCE OF THIS SOFTWARE.
6046
- ***************************************************************************** */
6047
-
6048
- function __awaiter(thisArg, _arguments, P, generator) {
6049
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
6050
- return new (P || (P = Promise))(function (resolve, reject) {
6051
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6052
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6053
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
6054
- step((generator = generator.apply(thisArg, _arguments || [])).next());
6055
- });
6056
6247
  }
6057
6248
 
6058
6249
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
@@ -12021,17 +12212,23 @@ class ReceiveOnlyTransceiver extends Transceiver {
12021
12212
  ReceiveOnlyTransceiver.rid = '1';
12022
12213
 
12023
12214
  class JmpLine extends Line {
12215
+ constructor(versions) {
12216
+ super();
12217
+ this.versions = versions;
12218
+ }
12024
12219
  static fromSdpLine(line) {
12025
12220
  if (!JmpLine.regex.test(line)) {
12026
12221
  return undefined;
12027
12222
  }
12028
- return new JmpLine();
12223
+ const tokens = line.match(JmpLine.regex);
12224
+ const versions = tokens[1].split(',').filter((v) => v.length);
12225
+ return new JmpLine(versions);
12029
12226
  }
12030
12227
  toSdpLine() {
12031
- return `a=jmp`;
12228
+ return `a=jmp:${this.versions.join(',')}`;
12032
12229
  }
12033
12230
  }
12034
- JmpLine.regex = /^jmp$/;
12231
+ JmpLine.regex = /^jmp:((?:v\d+,?)+)/;
12035
12232
  class JmpStreamIdModeLine extends Line {
12036
12233
  constructor(streamIdMode) {
12037
12234
  super();
@@ -12215,7 +12412,7 @@ function injectJmpAttributes(parsedSdp, csiMap, streamSignalingMode) {
12215
12412
  .filter((mLine) => mLine.direction === 'sendrecv' || mLine.direction === 'inactive')
12216
12413
  .forEach((mLine) => {
12217
12414
  if (!mLine.otherLines.find((line) => line instanceof JmpLine)) {
12218
- mLine.addLine(new JmpLine());
12415
+ mLine.addLine(new JmpLine(['v1']));
12219
12416
  }
12220
12417
  if (!mLine.otherLines.find((line) => line instanceof JmpSourceLine)) {
12221
12418
  const mediaType = getMediaTypeForMline(mLine);
@@ -13085,83 +13282,37 @@ class MultistreamConnection extends EventEmitter {
13085
13282
  logger.info(`Sending JMP message: ${msg}`);
13086
13283
  this.dataChannel.send(msg);
13087
13284
  });
13088
- if (getMediaFamily(mediaType) === MediaFamily.Video) {
13089
- let prevNumTotalSources = 0;
13090
- let prevNumLiveSources = 0;
13091
- jmpSession.on(JmpSessionEvents.SourceIndication, (data) => {
13092
- data.sources.forEach((s) => {
13093
- const receiveSlot = this.getReceiveSlotById(s.id);
13094
- if (!receiveSlot) {
13095
- logger.warn(`Got source indication for unknown receive slot: ${s.id}`);
13096
- return;
13097
- }
13098
- receiveSlot._updateSource(s.state, s.csi);
13099
- });
13100
- if (data.numTotalSources !== prevNumTotalSources ||
13101
- data.numLiveSources !== prevNumLiveSources) {
13102
- prevNumTotalSources = data.numTotalSources;
13103
- prevNumLiveSources = data.numLiveSources;
13104
- this.emit(exports.MultistreamConnectionEventNames.VideoSourceCountUpdate, data.numTotalSources, data.numLiveSources, getMediaContent(mediaType));
13105
- }
13106
- });
13107
- jmpSession.on(JmpSessionEvents.ScrRequestReceived, (data) => {
13108
- this.sendSourceWarnings(mediaType, data.requests);
13109
- this.updateRequestedStreams(mediaType, data.requests);
13110
- });
13111
- }
13112
- if (getMediaFamily(mediaType) === MediaFamily.Audio) {
13113
- let prevNumTotalSources = 0;
13114
- let prevNumLiveSources = 0;
13115
- jmpSession.on(JmpSessionEvents.SourceIndication, (data) => {
13116
- data.sources.forEach((s) => {
13117
- const receiveSlot = this.getReceiveSlotById(s.id);
13118
- if (!receiveSlot) {
13119
- logger.warn(`Got source indication for unknown receive slot: ${s.id}`);
13120
- return;
13121
- }
13122
- receiveSlot._updateSource(s.state, s.csi);
13123
- });
13124
- if (data.numTotalSources !== prevNumTotalSources ||
13125
- data.numLiveSources !== prevNumLiveSources) {
13126
- prevNumTotalSources = data.numTotalSources;
13127
- prevNumLiveSources = data.numLiveSources;
13128
- this.emit(exports.MultistreamConnectionEventNames.AudioSourceCountUpdate, data.numTotalSources, data.numLiveSources, getMediaContent(mediaType));
13285
+ let prevNumTotalSources = 0;
13286
+ let prevNumLiveSources = 0;
13287
+ jmpSession.on(JmpSessionEvents.SourceAdvertisementReceived, (data) => {
13288
+ if (data.numTotalSources !== prevNumTotalSources ||
13289
+ data.numLiveSources !== prevNumLiveSources) {
13290
+ prevNumTotalSources = data.numTotalSources;
13291
+ prevNumLiveSources = data.numLiveSources;
13292
+ const eventName = getMediaFamily(mediaType) === MediaFamily.Video
13293
+ ? exports.MultistreamConnectionEventNames.VideoSourceCountUpdate
13294
+ : exports.MultistreamConnectionEventNames.AudioSourceCountUpdate;
13295
+ this.emit(eventName, data.numTotalSources, data.numLiveSources, getMediaContent(mediaType));
13296
+ }
13297
+ });
13298
+ jmpSession.on(JmpSessionEvents.MediaRequestStatusReceived, (data) => {
13299
+ data.streamStates.forEach((s) => {
13300
+ const receiveSlot = this.getReceiveSlotById(s.id);
13301
+ if (!receiveSlot) {
13302
+ logger.warn(`Got MediaRequestStatus for unknown receive slot: ${s.id}`);
13303
+ return;
13129
13304
  }
13305
+ receiveSlot._updateSource(s.state, s.csi);
13130
13306
  });
13131
- jmpSession.on(JmpSessionEvents.ActiveSpeaker, (data) => this.emit(exports.MultistreamConnectionEventNames.ActiveSpeakerNotification, data));
13132
- jmpSession.on(JmpSessionEvents.ScrRequestReceived, (data) => {
13133
- this.updateRequestedStreams(mediaType, data.requests);
13134
- });
13135
- }
13136
- this.jmpSessions.set(mediaType, jmpSession);
13137
- }
13138
- sendSourceWarnings(mediaType, requests) {
13139
- var _a;
13140
- if (getMediaFamily(mediaType) === MediaFamily.Video) {
13141
- const sendTransceiver = this.getSendTransceiverOrThrow(mediaType);
13142
- const signaler = this.streamSignalerManager.getEgressStreamSignalerOrThrow(sendTransceiver.mid);
13143
- const activeSimulcastLayerNumber = ((_a = sendTransceiver.publishedTrack) === null || _a === void 0 ? void 0 : _a.getNumActiveSimulcastLayers()) || 0;
13144
- const sourceWarnings = [];
13145
- requests.forEach(({ ids, policySpecificInfo }) => {
13146
- ids.forEach((id) => {
13147
- if (isValidReceiverSelectedInfo(policySpecificInfo) &&
13148
- sendTransceiver.csi !== policySpecificInfo.csi) {
13149
- sourceWarnings.push({ id, state: 'invalid source', csi: policySpecificInfo.csi });
13150
- }
13151
- else if (!signaler.getSenderIds().some((validId) => compareStreamIds(id, validId))) {
13152
- sourceWarnings.push({ id, state: 'invalid source', csi: sendTransceiver.csi });
13153
- }
13154
- else if (signaler.getEncodingIndexForStreamId(id) >= activeSimulcastLayerNumber) {
13155
- sourceWarnings.push({ id, state: 'no source', csi: sendTransceiver.csi });
13156
- }
13157
- });
13158
- });
13159
- if (sourceWarnings.length > 0) {
13160
- const { publishedTrack } = sendTransceiver;
13161
- const live = !!publishedTrack && publishedTrack.published && !publishedTrack.muted;
13162
- this.sendSourceIndication(mediaType, +live, sourceWarnings);
13307
+ });
13308
+ jmpSession.on(JmpSessionEvents.MediaRequestReceived, (data) => {
13309
+ if (getMediaFamily(mediaType) === MediaFamily.Video) {
13310
+ this.sendMediaRequestStatus(mediaType);
13163
13311
  }
13164
- }
13312
+ this.updateRequestedStreams(mediaType, data.requests);
13313
+ });
13314
+ jmpSession.on(JmpSessionEvents.ActiveSpeaker, (data) => this.emit(exports.MultistreamConnectionEventNames.ActiveSpeakerNotification, data));
13315
+ this.jmpSessions.set(mediaType, jmpSession);
13165
13316
  }
13166
13317
  updateRequestedStreams(mediaType, requests) {
13167
13318
  const sendTransceiver = this.getSendTransceiverOrThrow(mediaType);
@@ -13181,7 +13332,7 @@ class MultistreamConnection extends EventEmitter {
13181
13332
  return;
13182
13333
  }
13183
13334
  if (sendTransceiver.csi !== policySpecificInfo.csi) {
13184
- logger.warn('csi in the scr request does not match');
13335
+ logger.warn('csi in the StreamRequest does not match');
13185
13336
  return;
13186
13337
  }
13187
13338
  const id = ids[0];
@@ -13217,7 +13368,7 @@ class MultistreamConnection extends EventEmitter {
13217
13368
  dataChannel.onopen = (e) => {
13218
13369
  logger.info('DataChannel opened: ', e);
13219
13370
  [...this.sendTransceivers.keys()].forEach((mediaType) => {
13220
- this.maybeSendSourceIndication(mediaType);
13371
+ this.sendSourceAdvertisement(mediaType);
13221
13372
  });
13222
13373
  logger.info(`Flushing pending JMP task queue`);
13223
13374
  this.pendingJmpTasks.forEach((t) => t());
@@ -13266,33 +13417,51 @@ class MultistreamConnection extends EventEmitter {
13266
13417
  });
13267
13418
  this.pc.close();
13268
13419
  }
13269
- maybeSendSourceIndication(mediaType) {
13420
+ sendMediaRequestStatus(mediaType) {
13270
13421
  var _a;
13422
+ if (getMediaFamily(mediaType) !== MediaFamily.Video) {
13423
+ return;
13424
+ }
13425
+ const streamStates = this.getVideoStreamStates(mediaType);
13426
+ if (streamStates === null) {
13427
+ logger.debug(`Empty streamStates, not sending MediaRequestStatus`);
13428
+ return;
13429
+ }
13430
+ const task = () => {
13431
+ var _a;
13432
+ (_a = this.jmpSessions.get(mediaType)) === null || _a === void 0 ? void 0 : _a.sendMediaRequestStatus(streamStates);
13433
+ };
13434
+ if (((_a = this.dataChannel) === null || _a === void 0 ? void 0 : _a.readyState) === 'open') {
13435
+ task();
13436
+ }
13437
+ else {
13438
+ this.pendingJmpTasks.push(task);
13439
+ }
13440
+ }
13441
+ sendSourceAdvertisement(mediaType) {
13442
+ var _a, _b;
13271
13443
  const transceiver = this.getSendTransceiverOrThrow(mediaType);
13272
13444
  const numLiveSources = ((_a = transceiver.publishedTrack) === null || _a === void 0 ? void 0 : _a.muted) === false ? 1 : 0;
13445
+ let task;
13273
13446
  if (getMediaFamily(mediaType) === MediaFamily.Video) {
13274
- const sources = this.getVideoSources(mediaType);
13447
+ const sources = this.getVideoStreamStates(mediaType);
13275
13448
  if (sources === null) {
13276
13449
  return;
13277
13450
  }
13278
- let webRtcVideoContentHint;
13451
+ let contentHint;
13279
13452
  if (transceiver.publishedTrack instanceof LocalDisplayTrack) {
13280
- webRtcVideoContentHint = transceiver.publishedTrack.videoContentHint;
13453
+ contentHint = transceiver.publishedTrack.videoContentHint;
13281
13454
  }
13282
- this.sendSourceIndication(mediaType, numLiveSources, sources, webRtcVideoContentHintToJmpVideoContentHint(webRtcVideoContentHint));
13455
+ task = () => {
13456
+ var _a;
13457
+ (_a = this.jmpSessions
13458
+ .get(mediaType)) === null || _a === void 0 ? void 0 : _a.sendSourceAdvertisement(1, numLiveSources, [], webRtcVideoContentHintToJmpVideoContentHint(contentHint));
13459
+ };
13283
13460
  }
13284
13461
  else {
13285
- this.sendSourceIndication(mediaType, numLiveSources);
13462
+ task = () => { var _a; return (_a = this.jmpSessions.get(mediaType)) === null || _a === void 0 ? void 0 : _a.sendSourceAdvertisement(1, numLiveSources); };
13286
13463
  }
13287
- }
13288
- sendSourceIndication(mediaType, numLiveSources, sources = [], videoContentHint = undefined) {
13289
- var _a;
13290
- const task = () => {
13291
- var _a;
13292
- (_a = this.jmpSessions
13293
- .get(mediaType)) === null || _a === void 0 ? void 0 : _a.updateSourceIndication(1, numLiveSources, sources, videoContentHint);
13294
- };
13295
- if (((_a = this.dataChannel) === null || _a === void 0 ? void 0 : _a.readyState) === 'open') {
13464
+ if (((_b = this.dataChannel) === null || _b === void 0 ? void 0 : _b.readyState) === 'open') {
13296
13465
  task();
13297
13466
  }
13298
13467
  else {
@@ -13335,23 +13504,32 @@ class MultistreamConnection extends EventEmitter {
13335
13504
  });
13336
13505
  }
13337
13506
  addTrackListeners(mediaType, track) {
13338
- const onTrackResolutionChange = () => this.maybeSendSourceIndication(mediaType);
13507
+ const onTrackResolutionChange = () => {
13508
+ this.sendMediaRequestStatus(mediaType);
13509
+ };
13339
13510
  track.on(LocalTrack.Events.TrackConstraintsChange, onTrackResolutionChange);
13340
- const onTrackMute = () => this.maybeSendSourceIndication(mediaType);
13511
+ const onTrackMute = () => {
13512
+ this.sendSourceAdvertisement(mediaType);
13513
+ this.sendMediaRequestStatus(mediaType);
13514
+ };
13341
13515
  track.on(LocalTrack.Events.Muted, onTrackMute);
13342
13516
  const onTrackPublish = (event) => {
13343
13517
  if (!event.isPublished) {
13344
13518
  track.off(LocalTrack.Events.Muted, onTrackMute);
13345
13519
  track.off(LocalTrack.Events.PublishedStateUpdate, onTrackPublish);
13346
13520
  track.off(LocalTrack.Events.TrackConstraintsChange, onTrackResolutionChange);
13521
+ if (!track.muted) {
13522
+ this.sendSourceAdvertisement(mediaType);
13523
+ this.sendMediaRequestStatus(mediaType);
13524
+ }
13347
13525
  }
13348
- if (!track.muted) {
13349
- this.maybeSendSourceIndication(mediaType);
13526
+ else if (!track.muted) {
13527
+ this.sendSourceAdvertisement(mediaType);
13350
13528
  }
13351
13529
  };
13352
13530
  track.on(LocalTrack.Events.PublishedStateUpdate, onTrackPublish);
13353
13531
  }
13354
- getVideoSources(mediaType) {
13532
+ getVideoStreamStates(mediaType) {
13355
13533
  var _a, _b, _c;
13356
13534
  const sendTransceiver = this.getSendTransceiverOrThrow(mediaType);
13357
13535
  const signaler = this.streamSignalerManager.getEgressStreamSignaler(sendTransceiver.mid);
@@ -13369,7 +13547,7 @@ class MultistreamConnection extends EventEmitter {
13369
13547
  else if (muted) {
13370
13548
  state = 'avatar';
13371
13549
  }
13372
- else if (activeSimulcastLayerNumber <= signaler.getEncodingIndexForStreamId(id)) {
13550
+ else if (activeSimulcastLayerNumber < signaler.getEncodingIndexForStreamId(id)) {
13373
13551
  state = 'no source';
13374
13552
  }
13375
13553
  else {
@@ -13623,7 +13801,7 @@ class MultistreamConnection extends EventEmitter {
13623
13801
  }
13624
13802
  });
13625
13803
  }
13626
- requestMedia(mediaType, mediaRequests) {
13804
+ requestMedia(mediaType, streamRequests) {
13627
13805
  var _a;
13628
13806
  const task = () => {
13629
13807
  var _a;
@@ -13632,20 +13810,13 @@ class MultistreamConnection extends EventEmitter {
13632
13810
  logger.error(`Unable to find jmp session for ${mediaType}`);
13633
13811
  return;
13634
13812
  }
13635
- const requestedReceiveSlotIds = [];
13636
- mediaRequests.forEach((mr) => mr.receiveSlots.forEach((rs) => {
13637
- if (!rs.id) {
13638
- logger.error(`Running subscribe task, but ReceiveSlot ID is missing!`);
13639
- return;
13640
- }
13641
- requestedReceiveSlotIds.push(rs.id);
13642
- }));
13813
+ const requestedReceiveSlotIds = streamRequests.flatMap((sr) => sr.ids);
13643
13814
  (_a = this.recvTransceivers.get(mediaType)) === null || _a === void 0 ? void 0 : _a.forEach((transceiver) => {
13644
13815
  if (!requestedReceiveSlotIds.some((id) => compareStreamIds(id, transceiver.receiveSlot.id))) {
13645
13816
  transceiver.receiveSlot._updateSource('no source', undefined);
13646
13817
  }
13647
13818
  });
13648
- jmpSession.sendRequests(mediaRequests.map((mr) => mr._toJmpScrRequest()));
13819
+ jmpSession.sendRequests(streamRequests);
13649
13820
  };
13650
13821
  if (((_a = this.dataChannel) === null || _a === void 0 ? void 0 : _a.readyState) === 'open') {
13651
13822
  task();
@@ -13770,11 +13941,11 @@ exports.LocalDisplayTrack = LocalDisplayTrack;
13770
13941
  exports.LocalMicrophoneTrack = LocalMicrophoneTrack;
13771
13942
  exports.LocalTrack = LocalTrack;
13772
13943
  exports.Logger = Logger;
13773
- exports.MediaRequest = MediaRequest;
13774
13944
  exports.MultistreamConnection = MultistreamConnection;
13775
13945
  exports.PeerConnection = PeerConnection;
13776
13946
  exports.ReceiveSlot = ReceiveSlot;
13777
13947
  exports.SendOnlyTransceiver = SendOnlyTransceiver;
13948
+ exports.StreamRequest = StreamRequest;
13778
13949
  exports.WcmeError = WcmeError;
13779
13950
  exports.compareReceiveSlotIds = compareReceiveSlotIds;
13780
13951
  exports.createCameraTrack = createCameraTrack;