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