@webex/internal-media-core 1.35.6 → 1.35.7

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
@@ -4748,14 +4748,15 @@ function createMicrophoneTrack(constructor, constraints) {
4748
4748
  * Creates a display video track.
4749
4749
  *
4750
4750
  * @param constructor - Constructor for the local display track.
4751
+ * @param videoContentHint - An optional parameters to give a hint for the content of the track.
4751
4752
  * @returns A Promise that resolves to a LocalDisplayTrack.
4752
4753
  */
4753
- function createDisplayTrack(constructor) {
4754
+ function createDisplayTrack(constructor, videoContentHint) {
4754
4755
  return __awaiter$1(this, void 0, void 0, function* () {
4755
4756
  var stream = yield getDisplayMedia({
4756
4757
  video: true
4757
4758
  });
4758
- return new constructor(stream);
4759
+ return new constructor(stream, videoContentHint);
4759
4760
  });
4760
4761
  }
4761
4762
  /**
@@ -5483,7 +5484,27 @@ class LocalCameraTrack extends LocalTrack {}
5483
5484
  /**
5484
5485
  * Represents a local track for a display source.
5485
5486
  */
5486
- class LocalDisplayTrack extends LocalTrack {}
5487
+ class LocalDisplayTrack extends LocalTrack {
5488
+ /**
5489
+ * Create a LocalDisplayTrack from the given values.
5490
+ *
5491
+ * @param stream - The MediaStream for this track.
5492
+ * @param videoContentHint - An optional content hint, describing the content of the track.
5493
+ */
5494
+ constructor(stream, videoContentHint) {
5495
+ super(stream);
5496
+ this._videoContentHint = videoContentHint;
5497
+ this.underlyingTrack.contentHint = videoContentHint || '';
5498
+ }
5499
+ /**
5500
+ * Get the VideoContentHint for this track.
5501
+ *
5502
+ * @returns The VideoContentHint for this track.
5503
+ */
5504
+ get videoContentHint() {
5505
+ return this._videoContentHint;
5506
+ }
5507
+ }
5487
5508
 
5488
5509
  /**
5489
5510
  * Represents a local track for a microphone source.
@@ -9483,11 +9504,12 @@ function compareStreamIds(id1, id2) {
9483
9504
  return keys1.every(key => id1[key] === id2[key]);
9484
9505
  }
9485
9506
  class SourceIndicationMsg {
9486
- constructor(seqNum, numTotalSources, numLiveSources, sources) {
9507
+ constructor(seqNum, numTotalSources, numLiveSources, sources, videoContentHint) {
9487
9508
  this.seqNum = seqNum;
9488
9509
  this.numTotalSources = numTotalSources;
9489
9510
  this.numLiveSources = numLiveSources;
9490
9511
  this.sources = sources;
9512
+ this.videoContentHint = videoContentHint;
9491
9513
  }
9492
9514
  sourcesToString() {
9493
9515
  return this.sources.map(source => "Source(id=".concat(source.id, " state=").concat(source.state, " ").concat(source.csi ? "csi=".concat(source.csi) : '', ")")).join(', ');
@@ -9574,13 +9596,13 @@ class JmpSession extends EventEmitter$4 {
9574
9596
  this.logger.warn("Retransmits for message expired: ".concat(expiredJmpMsg));
9575
9597
  });
9576
9598
  }
9577
- updateSourceIndication(numTotalSources, numLiveSources, sources) {
9599
+ updateSourceIndication(numTotalSources, numLiveSources, sources, videoContentHint) {
9578
9600
  var _a;
9579
9601
  var filteredSources = sources.filter(source => {
9580
9602
  var _a;
9581
9603
  return (_a = this.lastReceivedScr) === null || _a === void 0 ? void 0 : _a.requests.some(req => req.ids.find(streamId => compareStreamIds(streamId, source.id)));
9582
9604
  });
9583
- var sourceIndicationMsg = new SourceIndicationMsg(this.currSourceIndicationSeqNum++, numTotalSources, numLiveSources, filteredSources);
9605
+ var sourceIndicationMsg = new SourceIndicationMsg(this.currSourceIndicationSeqNum++, numTotalSources, numLiveSources, filteredSources, videoContentHint);
9584
9606
  var jmpMsg = new JmpMsg(this.mediaFamily, this.mediaContent, {
9585
9607
  msgType: JmpMsgType$1.SourceIndication,
9586
9608
  payload: sourceIndicationMsg
@@ -12725,7 +12747,9 @@ class SsrcIngressStreamSignaler {
12725
12747
  mLine.addLine(new SsrcLine(this.ssrc, 'cname', "".concat(this.ssrc, "-cname")));
12726
12748
  mLine.addLine(new SsrcLine(this.ssrc, 'msid', '-', '1'));
12727
12749
  if (hasCodec('rtx', mLine)) {
12728
- this.rtxSsrc = generateSsrc();
12750
+ if (!this.rtxSsrc) {
12751
+ this.rtxSsrc = generateSsrc();
12752
+ }
12729
12753
  mLine.addLine(new SsrcLine(this.rtxSsrc, 'cname', "".concat(this.ssrc, "-cname")));
12730
12754
  mLine.addLine(new SsrcLine(this.rtxSsrc, 'msid', '-', '1'));
12731
12755
  mLine.addLine(new SsrcGroupLine('FID', [this.ssrc, this.rtxSsrc]));
@@ -12737,23 +12761,57 @@ class SsrcEgressStreamSignaler {
12737
12761
  this.streamIds = [];
12738
12762
  }
12739
12763
  signalStreams(simulcastEnabled, rtxEnabled, mLine) {
12764
+ var _a;
12740
12765
  mLine.rids = [];
12741
12766
  mLine.simulcast = undefined;
12742
- mLine.ssrcs = [];
12743
- mLine.ssrcGroups = [];
12744
12767
  mLine.extMaps = mLine.extMaps.filter(extMapLine => !/^urn:ietf:params:rtp-hdrext:sdes:(?:mid|rtp-stream-id|repaired-rtp-stream-id)$/.test(extMapLine.uri));
12745
- if (this.streamIds.length === 0) {
12746
- var numStreams = simulcastEnabled ? 3 : 1;
12747
- [...Array(numStreams).keys()].forEach(() => {
12748
- var newStreamId = {
12749
- ssrc: generateSsrc()
12750
- };
12751
- if (rtxEnabled) {
12752
- newStreamId.rtxSsrc = generateSsrc();
12768
+ var numStreams = simulcastEnabled ? 3 : 1;
12769
+ if (!this.streamIds.length) {
12770
+ if (mLine.ssrcs.length) {
12771
+ var ssrcs = [...new Set(mLine.ssrcs.map(ssrcLine => ssrcLine.ssrcId))];
12772
+ mLine.ssrcGroups.forEach(sg => {
12773
+ if (!sg.ssrcs.every(ssrc => ssrcs.includes(ssrc))) {
12774
+ throw new Error('SSRC present in SSRC groups is missing from SSRC lines');
12775
+ }
12776
+ });
12777
+ var rtxSsrcGroups = mLine.ssrcGroups.filter(sg => sg.semantics === 'FID');
12778
+ if (rtxSsrcGroups.length && rtxSsrcGroups.length !== numStreams) {
12779
+ throw new Error("Expect ".concat(numStreams, " RTX SSRC groups, got ").concat(rtxSsrcGroups.length));
12753
12780
  }
12754
- this.streamIds.push(newStreamId);
12755
- });
12781
+ rtxSsrcGroups.forEach(sg => {
12782
+ this.streamIds.push({
12783
+ ssrc: sg.ssrcs[0],
12784
+ rtxSsrc: sg.ssrcs[1]
12785
+ });
12786
+ });
12787
+ var simulcastSsrcs = (_a = mLine.ssrcGroups.find(sg => sg.semantics === 'SIM')) === null || _a === void 0 ? void 0 : _a.ssrcs;
12788
+ if (simulcastSsrcs) {
12789
+ if (simulcastSsrcs.length !== numStreams || !this.streamIds.every(streamId => simulcastSsrcs.includes(streamId.ssrc))) {
12790
+ throw new Error('SSRCs in simulcast SSRC group do not match primary SSRCs in RTX SSRC groups');
12791
+ }
12792
+ this.streamIds.sort((a, b) => simulcastSsrcs.indexOf(a.ssrc) - simulcastSsrcs.indexOf(b.ssrc));
12793
+ } else if (rtxSsrcGroups.length > 1) {
12794
+ throw new Error('Multiple RTX SSRC groups but no simulcast SSRC group found');
12795
+ }
12796
+ if (!this.streamIds.length) {
12797
+ this.streamIds.push({
12798
+ ssrc: ssrcs[0]
12799
+ });
12800
+ }
12801
+ } else {
12802
+ [...Array(numStreams).keys()].forEach(() => {
12803
+ var newStreamId = {
12804
+ ssrc: generateSsrc()
12805
+ };
12806
+ if (rtxEnabled) {
12807
+ newStreamId.rtxSsrc = generateSsrc();
12808
+ }
12809
+ this.streamIds.push(newStreamId);
12810
+ });
12811
+ }
12756
12812
  }
12813
+ mLine.ssrcs = [];
12814
+ mLine.ssrcGroups = [];
12757
12815
  this.streamIds.forEach(streamId => {
12758
12816
  var rtpSsrc = streamId.ssrc;
12759
12817
  mLine.addLine(new SsrcLine(rtpSsrc, 'cname', "".concat(rtpSsrc, "-cname")));
@@ -14508,6 +14566,15 @@ function setLogHandler(logHandler) {
14508
14566
  function toMediaStreamTrackKind(mediaType) {
14509
14567
  return [MediaType.VideoMain, MediaType.VideoSlides].includes(mediaType) ? exports.MediaStreamTrackKind.Video : exports.MediaStreamTrackKind.Audio;
14510
14568
  }
14569
+ function webRtcVideoContentHintToJmpVideoContentHint(hint) {
14570
+ if (hint === 'motion') {
14571
+ return 'motion';
14572
+ }
14573
+ if (hint === 'detail') {
14574
+ return 'sharpness';
14575
+ }
14576
+ return undefined;
14577
+ }
14511
14578
  function toMediaFamily(kind) {
14512
14579
  if (kind === exports.MediaStreamTrackKind.Video) {
14513
14580
  return MediaFamily.Video;
@@ -14773,24 +14840,8 @@ class MultistreamConnection extends EventEmitter {
14773
14840
  var dataChannel = this.pc.createDataChannel('datachannel', {});
14774
14841
  dataChannel.onopen = e => {
14775
14842
  logger$4.info('DataChannel opened: ', e);
14776
- this.sendTransceivers.forEach((transceiver, mediaType) => {
14777
- var track = transceiver.publishedTrack;
14778
- if (track) {
14779
- if (getMediaFamily$1(mediaType) === MediaFamily.Audio) {
14780
- this.sendSourceIndication(mediaType, +!track.muted);
14781
- } else {
14782
- var signaler = this.streamSignalerManager.getEgressStreamSignalerOrThrow(transceiver.mid);
14783
- var state = track.muted ? 'avatar' : 'live';
14784
- var sources = signaler.getSenderIds().map(id => ({
14785
- id,
14786
- state,
14787
- csi: transceiver.csi
14788
- }));
14789
- this.sendSourceIndication(mediaType, +!track.muted, sources);
14790
- }
14791
- } else {
14792
- this.sendSourceIndication(mediaType, 0);
14793
- }
14843
+ [...this.sendTransceivers.keys()].forEach(mediaType => {
14844
+ this.maybeSendSourceIndication(mediaType);
14794
14845
  });
14795
14846
  logger$4.info("Flushing pending JMP task queue");
14796
14847
  this.pendingJmpTasks.forEach(t => t());
@@ -14838,12 +14889,31 @@ class MultistreamConnection extends EventEmitter {
14838
14889
  });
14839
14890
  this.pc.close();
14840
14891
  }
14892
+ maybeSendSourceIndication(mediaType) {
14893
+ var _a;
14894
+ var transceiver = this.getSendTransceiverOrThrow(mediaType);
14895
+ var numLiveSources = ((_a = transceiver.publishedTrack) === null || _a === void 0 ? void 0 : _a.muted) === false ? 1 : 0;
14896
+ if (getMediaFamily$1(mediaType) === MediaFamily.Video) {
14897
+ var sources = this.getVideoSources(mediaType);
14898
+ if (sources === null) {
14899
+ return;
14900
+ }
14901
+ var webRtcVideoContentHint;
14902
+ if (transceiver.publishedTrack instanceof LocalDisplayTrack) {
14903
+ webRtcVideoContentHint = transceiver.publishedTrack.videoContentHint;
14904
+ }
14905
+ this.sendSourceIndication(mediaType, numLiveSources, sources, webRtcVideoContentHintToJmpVideoContentHint(webRtcVideoContentHint));
14906
+ } else {
14907
+ this.sendSourceIndication(mediaType, numLiveSources);
14908
+ }
14909
+ }
14841
14910
  sendSourceIndication(mediaType, numLiveSources) {
14842
14911
  var sources = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
14912
+ var videoContentHint = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : undefined;
14843
14913
  var _a;
14844
14914
  var task = () => {
14845
14915
  var _a;
14846
- (_a = this.jmpSessions.get(mediaType)) === null || _a === void 0 ? void 0 : _a.updateSourceIndication(1, numLiveSources, sources);
14916
+ (_a = this.jmpSessions.get(mediaType)) === null || _a === void 0 ? void 0 : _a.updateSourceIndication(1, numLiveSources, sources, videoContentHint);
14847
14917
  };
14848
14918
  if (((_a = this.dataChannel) === null || _a === void 0 ? void 0 : _a.readyState) === 'open') {
14849
14919
  task();
@@ -14885,23 +14955,9 @@ class MultistreamConnection extends EventEmitter {
14885
14955
  });
14886
14956
  }
14887
14957
  addTrackListeners(mediaType, track) {
14888
- var onTrackResolutionChange = () => {
14889
- var sources = this.getVideoSources(mediaType);
14890
- if (sources != null) {
14891
- this.sendSourceIndication(mediaType, 1, sources);
14892
- }
14893
- };
14958
+ var onTrackResolutionChange = () => this.maybeSendSourceIndication(mediaType);
14894
14959
  track.on(LocalTrack.Events.TrackConstraintsChange, onTrackResolutionChange);
14895
- var onTrackMute = event => {
14896
- if (getMediaFamily$1(mediaType) === MediaFamily.Audio) {
14897
- this.sendSourceIndication(mediaType, +!event.trackState.muted);
14898
- } else {
14899
- var sources = this.getVideoSources(mediaType);
14900
- if (sources != null) {
14901
- this.sendSourceIndication(mediaType, +!event.trackState.muted, sources);
14902
- }
14903
- }
14904
- };
14960
+ var onTrackMute = () => this.maybeSendSourceIndication(mediaType);
14905
14961
  track.on(LocalTrack.Events.Muted, onTrackMute);
14906
14962
  var onTrackPublish = event => {
14907
14963
  if (!event.isPublished) {
@@ -14909,13 +14965,8 @@ class MultistreamConnection extends EventEmitter {
14909
14965
  track.off(LocalTrack.Events.PublishedStateUpdate, onTrackPublish);
14910
14966
  track.off(LocalTrack.Events.TrackConstraintsChange, onTrackResolutionChange);
14911
14967
  }
14912
- if (getMediaFamily$1(mediaType) === MediaFamily.Audio) {
14913
- this.sendSourceIndication(mediaType, +event.isPublished);
14914
- } else {
14915
- var sources = this.getVideoSources(mediaType);
14916
- if (sources != null) {
14917
- this.sendSourceIndication(mediaType, +event.isPublished, sources);
14918
- }
14968
+ if (!track.muted) {
14969
+ this.maybeSendSourceIndication(mediaType);
14919
14970
  }
14920
14971
  };
14921
14972
  track.on(LocalTrack.Events.PublishedStateUpdate, onTrackPublish);
package/dist/esm/index.js CHANGED
@@ -4737,14 +4737,15 @@ function createMicrophoneTrack(constructor, constraints) {
4737
4737
  * Creates a display video track.
4738
4738
  *
4739
4739
  * @param constructor - Constructor for the local display track.
4740
+ * @param videoContentHint - An optional parameters to give a hint for the content of the track.
4740
4741
  * @returns A Promise that resolves to a LocalDisplayTrack.
4741
4742
  */
4742
- function createDisplayTrack(constructor) {
4743
+ function createDisplayTrack(constructor, videoContentHint) {
4743
4744
  return __awaiter$1(this, void 0, void 0, function* () {
4744
4745
  var stream = yield getDisplayMedia({
4745
4746
  video: true
4746
4747
  });
4747
- return new constructor(stream);
4748
+ return new constructor(stream, videoContentHint);
4748
4749
  });
4749
4750
  }
4750
4751
  /**
@@ -5472,7 +5473,27 @@ class LocalCameraTrack extends LocalTrack {}
5472
5473
  /**
5473
5474
  * Represents a local track for a display source.
5474
5475
  */
5475
- class LocalDisplayTrack extends LocalTrack {}
5476
+ class LocalDisplayTrack extends LocalTrack {
5477
+ /**
5478
+ * Create a LocalDisplayTrack from the given values.
5479
+ *
5480
+ * @param stream - The MediaStream for this track.
5481
+ * @param videoContentHint - An optional content hint, describing the content of the track.
5482
+ */
5483
+ constructor(stream, videoContentHint) {
5484
+ super(stream);
5485
+ this._videoContentHint = videoContentHint;
5486
+ this.underlyingTrack.contentHint = videoContentHint || '';
5487
+ }
5488
+ /**
5489
+ * Get the VideoContentHint for this track.
5490
+ *
5491
+ * @returns The VideoContentHint for this track.
5492
+ */
5493
+ get videoContentHint() {
5494
+ return this._videoContentHint;
5495
+ }
5496
+ }
5476
5497
 
5477
5498
  /**
5478
5499
  * Represents a local track for a microphone source.
@@ -9472,11 +9493,12 @@ function compareStreamIds(id1, id2) {
9472
9493
  return keys1.every(key => id1[key] === id2[key]);
9473
9494
  }
9474
9495
  class SourceIndicationMsg {
9475
- constructor(seqNum, numTotalSources, numLiveSources, sources) {
9496
+ constructor(seqNum, numTotalSources, numLiveSources, sources, videoContentHint) {
9476
9497
  this.seqNum = seqNum;
9477
9498
  this.numTotalSources = numTotalSources;
9478
9499
  this.numLiveSources = numLiveSources;
9479
9500
  this.sources = sources;
9501
+ this.videoContentHint = videoContentHint;
9480
9502
  }
9481
9503
  sourcesToString() {
9482
9504
  return this.sources.map(source => "Source(id=".concat(source.id, " state=").concat(source.state, " ").concat(source.csi ? "csi=".concat(source.csi) : '', ")")).join(', ');
@@ -9563,13 +9585,13 @@ class JmpSession extends EventEmitter$4 {
9563
9585
  this.logger.warn("Retransmits for message expired: ".concat(expiredJmpMsg));
9564
9586
  });
9565
9587
  }
9566
- updateSourceIndication(numTotalSources, numLiveSources, sources) {
9588
+ updateSourceIndication(numTotalSources, numLiveSources, sources, videoContentHint) {
9567
9589
  var _a;
9568
9590
  var filteredSources = sources.filter(source => {
9569
9591
  var _a;
9570
9592
  return (_a = this.lastReceivedScr) === null || _a === void 0 ? void 0 : _a.requests.some(req => req.ids.find(streamId => compareStreamIds(streamId, source.id)));
9571
9593
  });
9572
- var sourceIndicationMsg = new SourceIndicationMsg(this.currSourceIndicationSeqNum++, numTotalSources, numLiveSources, filteredSources);
9594
+ var sourceIndicationMsg = new SourceIndicationMsg(this.currSourceIndicationSeqNum++, numTotalSources, numLiveSources, filteredSources, videoContentHint);
9573
9595
  var jmpMsg = new JmpMsg(this.mediaFamily, this.mediaContent, {
9574
9596
  msgType: JmpMsgType$1.SourceIndication,
9575
9597
  payload: sourceIndicationMsg
@@ -12714,7 +12736,9 @@ class SsrcIngressStreamSignaler {
12714
12736
  mLine.addLine(new SsrcLine(this.ssrc, 'cname', "".concat(this.ssrc, "-cname")));
12715
12737
  mLine.addLine(new SsrcLine(this.ssrc, 'msid', '-', '1'));
12716
12738
  if (hasCodec('rtx', mLine)) {
12717
- this.rtxSsrc = generateSsrc();
12739
+ if (!this.rtxSsrc) {
12740
+ this.rtxSsrc = generateSsrc();
12741
+ }
12718
12742
  mLine.addLine(new SsrcLine(this.rtxSsrc, 'cname', "".concat(this.ssrc, "-cname")));
12719
12743
  mLine.addLine(new SsrcLine(this.rtxSsrc, 'msid', '-', '1'));
12720
12744
  mLine.addLine(new SsrcGroupLine('FID', [this.ssrc, this.rtxSsrc]));
@@ -12726,23 +12750,57 @@ class SsrcEgressStreamSignaler {
12726
12750
  this.streamIds = [];
12727
12751
  }
12728
12752
  signalStreams(simulcastEnabled, rtxEnabled, mLine) {
12753
+ var _a;
12729
12754
  mLine.rids = [];
12730
12755
  mLine.simulcast = undefined;
12731
- mLine.ssrcs = [];
12732
- mLine.ssrcGroups = [];
12733
12756
  mLine.extMaps = mLine.extMaps.filter(extMapLine => !/^urn:ietf:params:rtp-hdrext:sdes:(?:mid|rtp-stream-id|repaired-rtp-stream-id)$/.test(extMapLine.uri));
12734
- if (this.streamIds.length === 0) {
12735
- var numStreams = simulcastEnabled ? 3 : 1;
12736
- [...Array(numStreams).keys()].forEach(() => {
12737
- var newStreamId = {
12738
- ssrc: generateSsrc()
12739
- };
12740
- if (rtxEnabled) {
12741
- newStreamId.rtxSsrc = generateSsrc();
12757
+ var numStreams = simulcastEnabled ? 3 : 1;
12758
+ if (!this.streamIds.length) {
12759
+ if (mLine.ssrcs.length) {
12760
+ var ssrcs = [...new Set(mLine.ssrcs.map(ssrcLine => ssrcLine.ssrcId))];
12761
+ mLine.ssrcGroups.forEach(sg => {
12762
+ if (!sg.ssrcs.every(ssrc => ssrcs.includes(ssrc))) {
12763
+ throw new Error('SSRC present in SSRC groups is missing from SSRC lines');
12764
+ }
12765
+ });
12766
+ var rtxSsrcGroups = mLine.ssrcGroups.filter(sg => sg.semantics === 'FID');
12767
+ if (rtxSsrcGroups.length && rtxSsrcGroups.length !== numStreams) {
12768
+ throw new Error("Expect ".concat(numStreams, " RTX SSRC groups, got ").concat(rtxSsrcGroups.length));
12742
12769
  }
12743
- this.streamIds.push(newStreamId);
12744
- });
12770
+ rtxSsrcGroups.forEach(sg => {
12771
+ this.streamIds.push({
12772
+ ssrc: sg.ssrcs[0],
12773
+ rtxSsrc: sg.ssrcs[1]
12774
+ });
12775
+ });
12776
+ var simulcastSsrcs = (_a = mLine.ssrcGroups.find(sg => sg.semantics === 'SIM')) === null || _a === void 0 ? void 0 : _a.ssrcs;
12777
+ if (simulcastSsrcs) {
12778
+ if (simulcastSsrcs.length !== numStreams || !this.streamIds.every(streamId => simulcastSsrcs.includes(streamId.ssrc))) {
12779
+ throw new Error('SSRCs in simulcast SSRC group do not match primary SSRCs in RTX SSRC groups');
12780
+ }
12781
+ this.streamIds.sort((a, b) => simulcastSsrcs.indexOf(a.ssrc) - simulcastSsrcs.indexOf(b.ssrc));
12782
+ } else if (rtxSsrcGroups.length > 1) {
12783
+ throw new Error('Multiple RTX SSRC groups but no simulcast SSRC group found');
12784
+ }
12785
+ if (!this.streamIds.length) {
12786
+ this.streamIds.push({
12787
+ ssrc: ssrcs[0]
12788
+ });
12789
+ }
12790
+ } else {
12791
+ [...Array(numStreams).keys()].forEach(() => {
12792
+ var newStreamId = {
12793
+ ssrc: generateSsrc()
12794
+ };
12795
+ if (rtxEnabled) {
12796
+ newStreamId.rtxSsrc = generateSsrc();
12797
+ }
12798
+ this.streamIds.push(newStreamId);
12799
+ });
12800
+ }
12745
12801
  }
12802
+ mLine.ssrcs = [];
12803
+ mLine.ssrcGroups = [];
12746
12804
  this.streamIds.forEach(streamId => {
12747
12805
  var rtpSsrc = streamId.ssrc;
12748
12806
  mLine.addLine(new SsrcLine(rtpSsrc, 'cname', "".concat(rtpSsrc, "-cname")));
@@ -14497,6 +14555,15 @@ function setLogHandler(logHandler) {
14497
14555
  function toMediaStreamTrackKind(mediaType) {
14498
14556
  return [MediaType$1.VideoMain, MediaType$1.VideoSlides].includes(mediaType) ? MediaStreamTrackKind.Video : MediaStreamTrackKind.Audio;
14499
14557
  }
14558
+ function webRtcVideoContentHintToJmpVideoContentHint(hint) {
14559
+ if (hint === 'motion') {
14560
+ return 'motion';
14561
+ }
14562
+ if (hint === 'detail') {
14563
+ return 'sharpness';
14564
+ }
14565
+ return undefined;
14566
+ }
14500
14567
  function toMediaFamily(kind) {
14501
14568
  if (kind === MediaStreamTrackKind.Video) {
14502
14569
  return MediaFamily$1.Video;
@@ -14762,24 +14829,8 @@ class MultistreamConnection extends EventEmitter {
14762
14829
  var dataChannel = this.pc.createDataChannel('datachannel', {});
14763
14830
  dataChannel.onopen = e => {
14764
14831
  logger$4.info('DataChannel opened: ', e);
14765
- this.sendTransceivers.forEach((transceiver, mediaType) => {
14766
- var track = transceiver.publishedTrack;
14767
- if (track) {
14768
- if (getMediaFamily$1(mediaType) === MediaFamily$1.Audio) {
14769
- this.sendSourceIndication(mediaType, +!track.muted);
14770
- } else {
14771
- var signaler = this.streamSignalerManager.getEgressStreamSignalerOrThrow(transceiver.mid);
14772
- var state = track.muted ? 'avatar' : 'live';
14773
- var sources = signaler.getSenderIds().map(id => ({
14774
- id,
14775
- state,
14776
- csi: transceiver.csi
14777
- }));
14778
- this.sendSourceIndication(mediaType, +!track.muted, sources);
14779
- }
14780
- } else {
14781
- this.sendSourceIndication(mediaType, 0);
14782
- }
14832
+ [...this.sendTransceivers.keys()].forEach(mediaType => {
14833
+ this.maybeSendSourceIndication(mediaType);
14783
14834
  });
14784
14835
  logger$4.info("Flushing pending JMP task queue");
14785
14836
  this.pendingJmpTasks.forEach(t => t());
@@ -14827,12 +14878,31 @@ class MultistreamConnection extends EventEmitter {
14827
14878
  });
14828
14879
  this.pc.close();
14829
14880
  }
14881
+ maybeSendSourceIndication(mediaType) {
14882
+ var _a;
14883
+ var transceiver = this.getSendTransceiverOrThrow(mediaType);
14884
+ var numLiveSources = ((_a = transceiver.publishedTrack) === null || _a === void 0 ? void 0 : _a.muted) === false ? 1 : 0;
14885
+ if (getMediaFamily$1(mediaType) === MediaFamily$1.Video) {
14886
+ var sources = this.getVideoSources(mediaType);
14887
+ if (sources === null) {
14888
+ return;
14889
+ }
14890
+ var webRtcVideoContentHint;
14891
+ if (transceiver.publishedTrack instanceof LocalDisplayTrack) {
14892
+ webRtcVideoContentHint = transceiver.publishedTrack.videoContentHint;
14893
+ }
14894
+ this.sendSourceIndication(mediaType, numLiveSources, sources, webRtcVideoContentHintToJmpVideoContentHint(webRtcVideoContentHint));
14895
+ } else {
14896
+ this.sendSourceIndication(mediaType, numLiveSources);
14897
+ }
14898
+ }
14830
14899
  sendSourceIndication(mediaType, numLiveSources) {
14831
14900
  var sources = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
14901
+ var videoContentHint = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : undefined;
14832
14902
  var _a;
14833
14903
  var task = () => {
14834
14904
  var _a;
14835
- (_a = this.jmpSessions.get(mediaType)) === null || _a === void 0 ? void 0 : _a.updateSourceIndication(1, numLiveSources, sources);
14905
+ (_a = this.jmpSessions.get(mediaType)) === null || _a === void 0 ? void 0 : _a.updateSourceIndication(1, numLiveSources, sources, videoContentHint);
14836
14906
  };
14837
14907
  if (((_a = this.dataChannel) === null || _a === void 0 ? void 0 : _a.readyState) === 'open') {
14838
14908
  task();
@@ -14874,23 +14944,9 @@ class MultistreamConnection extends EventEmitter {
14874
14944
  });
14875
14945
  }
14876
14946
  addTrackListeners(mediaType, track) {
14877
- var onTrackResolutionChange = () => {
14878
- var sources = this.getVideoSources(mediaType);
14879
- if (sources != null) {
14880
- this.sendSourceIndication(mediaType, 1, sources);
14881
- }
14882
- };
14947
+ var onTrackResolutionChange = () => this.maybeSendSourceIndication(mediaType);
14883
14948
  track.on(LocalTrack.Events.TrackConstraintsChange, onTrackResolutionChange);
14884
- var onTrackMute = event => {
14885
- if (getMediaFamily$1(mediaType) === MediaFamily$1.Audio) {
14886
- this.sendSourceIndication(mediaType, +!event.trackState.muted);
14887
- } else {
14888
- var sources = this.getVideoSources(mediaType);
14889
- if (sources != null) {
14890
- this.sendSourceIndication(mediaType, +!event.trackState.muted, sources);
14891
- }
14892
- }
14893
- };
14949
+ var onTrackMute = () => this.maybeSendSourceIndication(mediaType);
14894
14950
  track.on(LocalTrack.Events.Muted, onTrackMute);
14895
14951
  var onTrackPublish = event => {
14896
14952
  if (!event.isPublished) {
@@ -14898,13 +14954,8 @@ class MultistreamConnection extends EventEmitter {
14898
14954
  track.off(LocalTrack.Events.PublishedStateUpdate, onTrackPublish);
14899
14955
  track.off(LocalTrack.Events.TrackConstraintsChange, onTrackResolutionChange);
14900
14956
  }
14901
- if (getMediaFamily$1(mediaType) === MediaFamily$1.Audio) {
14902
- this.sendSourceIndication(mediaType, +event.isPublished);
14903
- } else {
14904
- var sources = this.getVideoSources(mediaType);
14905
- if (sources != null) {
14906
- this.sendSourceIndication(mediaType, +event.isPublished, sources);
14907
- }
14957
+ if (!track.muted) {
14958
+ this.maybeSendSourceIndication(mediaType);
14908
14959
  }
14909
14960
  };
14910
14961
  track.on(LocalTrack.Events.PublishedStateUpdate, onTrackPublish);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webex/internal-media-core",
3
- "version": "1.35.6",
3
+ "version": "1.35.7",
4
4
  "files": [
5
5
  "dist/cjs",
6
6
  "dist/esm",
@@ -45,9 +45,9 @@
45
45
  },
46
46
  "dependencies": {
47
47
  "@babel/runtime": "^7.18.9",
48
- "@webex/json-multistream": "1.20.2",
48
+ "@webex/json-multistream": "1.22.0",
49
49
  "@webex/ts-sdp": "1.3.2",
50
- "@webex/web-client-media-engine": "1.40.4",
50
+ "@webex/web-client-media-engine": "1.40.6",
51
51
  "detectrtc": "^1.4.1",
52
52
  "events": "^3.3.0",
53
53
  "typed-emitter": "^2.1.0",