@webex/web-client-media-engine 1.37.1 → 1.37.3

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
@@ -8769,17 +8769,25 @@ function setMaxBandwidth(parsedSdp, maxBandwidth) {
8769
8769
  mline.bandwidth = new BandwidthLine('TIAS', maxBandwidth);
8770
8770
  });
8771
8771
  }
8772
- function setupBundle(parsedSdp, bundlePolicy) {
8772
+ function setupBundle(parsedSdp, bundlePolicy, midMap) {
8773
8773
  if (bundlePolicy === 'max-compat') {
8774
- const audioMids = parsedSdp.avMedia
8775
- .filter((m) => m.type === 'audio')
8776
- .map((m) => m.mid);
8777
- const videoMids = parsedSdp.avMedia
8778
- .filter((m) => m.type === 'video')
8779
- .map((m) => m.mid);
8774
+ const audioMainMids = midMap.get(MediaType.AudioMain);
8775
+ const videoMainMids = midMap.get(MediaType.VideoMain);
8776
+ const audioContentMids = midMap.get(MediaType.AudioSlides);
8777
+ const videoContentMids = midMap.get(MediaType.VideoSlides);
8780
8778
  parsedSdp.session.groups.splice(0, parsedSdp.session.groups.length);
8781
- parsedSdp.session.groups.push(new BundleGroupLine(audioMids));
8782
- parsedSdp.session.groups.push(new BundleGroupLine(videoMids));
8779
+ if (audioMainMids) {
8780
+ parsedSdp.session.groups.push(new BundleGroupLine(audioMainMids));
8781
+ }
8782
+ if (videoMainMids) {
8783
+ parsedSdp.session.groups.push(new BundleGroupLine(videoMainMids));
8784
+ }
8785
+ if (audioContentMids) {
8786
+ parsedSdp.session.groups.push(new BundleGroupLine(audioContentMids));
8787
+ }
8788
+ if (videoContentMids) {
8789
+ parsedSdp.session.groups.push(new BundleGroupLine(videoContentMids));
8790
+ }
8783
8791
  }
8784
8792
  }
8785
8793
  function filterRecvOnlyMlines(parsedSdp) {
@@ -8879,6 +8887,18 @@ class SendOnlyTransceiver extends Transceiver {
8879
8887
  }
8880
8888
  });
8881
8889
  }
8890
+ replaceTransceiver(newRtcRtpTransceiver) {
8891
+ const _super = Object.create(null, {
8892
+ replaceTransceiver: { get: () => super.replaceTransceiver }
8893
+ });
8894
+ var _a;
8895
+ return __awaiter(this, void 0, void 0, function* () {
8896
+ _super.replaceTransceiver.call(this, newRtcRtpTransceiver);
8897
+ if (this.requested) {
8898
+ yield this.sender.replaceTrack(((_a = this.publishedTrack) === null || _a === void 0 ? void 0 : _a.underlyingTrack) || null);
8899
+ }
8900
+ });
8901
+ }
8882
8902
  replacePublishedTrack(newTrack) {
8883
8903
  var _a, _b;
8884
8904
  return __awaiter(this, void 0, void 0, function* () {
@@ -9571,6 +9591,8 @@ class MultistreamConnection extends EventEmitter {
9571
9591
  this.pendingJmpTasks = [];
9572
9592
  this.metricsCallback = () => { };
9573
9593
  this.overuseUpdateCallback = () => { };
9594
+ this.midMap = new Map();
9595
+ this.currentMid = 0;
9574
9596
  this.options = Object.assign(Object.assign({}, defaultMultistreamConnectionOptions), userOptions);
9575
9597
  logger.info(`Creating multistream connection with options ${JSON.stringify(this.options)}`);
9576
9598
  this.initializePeerConnection();
@@ -9589,6 +9611,16 @@ class MultistreamConnection extends EventEmitter {
9589
9611
  this.createSendTransceiver(MediaType.AudioSlides, contentSceneId);
9590
9612
  }
9591
9613
  }
9614
+ addMid(mediaType) {
9615
+ const mid = this.currentMid++;
9616
+ const mids = this.midMap.get(mediaType) || [];
9617
+ mids.push(`${mid}`);
9618
+ this.midMap.set(mediaType, mids);
9619
+ }
9620
+ clearMids() {
9621
+ this.midMap = new Map();
9622
+ this.currentMid = 0;
9623
+ }
9592
9624
  initializePeerConnection() {
9593
9625
  var _a;
9594
9626
  (_a = this.pc) === null || _a === void 0 ? void 0 : _a.close();
@@ -9617,6 +9649,7 @@ class MultistreamConnection extends EventEmitter {
9617
9649
  direction: 'sendrecv',
9618
9650
  sendEncodings: sendEncodingsOptions,
9619
9651
  });
9652
+ this.addMid(mediaType);
9620
9653
  const csi = generateCsi(getMediaFamily(mediaType), sceneId);
9621
9654
  this.sendTransceivers.set(mediaType, new SendOnlyTransceiver(rtcTransceiver, csi));
9622
9655
  this.createJmpSession(mediaType);
@@ -9821,29 +9854,39 @@ class MultistreamConnection extends EventEmitter {
9821
9854
  }
9822
9855
  }
9823
9856
  publishTrack(track) {
9824
- let mediaContent;
9825
- if (track instanceof LocalDisplayTrack && this.options.floorControlledPresentation) {
9826
- mediaContent = MediaContent.Slides;
9827
- }
9828
- else {
9829
- mediaContent = MediaContent.Main;
9830
- }
9831
- const mediaFamily = toMediaFamily(track.kind);
9832
- const mediaType = getMediaType(mediaFamily, mediaContent);
9833
- this.addTrackListeners(mediaType, track);
9834
- return this.getSendTransceiverOrThrow(mediaType).publishTrack(track);
9857
+ return __awaiter(this, void 0, void 0, function* () {
9858
+ let mediaContent;
9859
+ if (track instanceof LocalDisplayTrack && this.options.floorControlledPresentation) {
9860
+ mediaContent = MediaContent.Slides;
9861
+ }
9862
+ else {
9863
+ mediaContent = MediaContent.Main;
9864
+ }
9865
+ const mediaFamily = toMediaFamily(track.kind);
9866
+ const mediaType = getMediaType(mediaFamily, mediaContent);
9867
+ const sendTransceiver = this.getSendTransceiverOrThrow(mediaType);
9868
+ if (track === sendTransceiver.publishedTrack) {
9869
+ logger.warn(`This track has already been published on the transceiver.`);
9870
+ return Promise.resolve();
9871
+ }
9872
+ this.addTrackListeners(mediaType, track);
9873
+ return sendTransceiver.publishTrack(track);
9874
+ });
9835
9875
  }
9836
9876
  unpublishTrack(track) {
9837
- let mediaContent;
9838
- if (track instanceof LocalDisplayTrack && this.options.floorControlledPresentation) {
9839
- mediaContent = MediaContent.Slides;
9840
- }
9841
- else {
9842
- mediaContent = MediaContent.Main;
9843
- }
9844
- const mediaFamily = toMediaFamily(track.kind);
9845
- const mediaType = getMediaType(mediaFamily, mediaContent);
9846
- return this.getSendTransceiverOrThrow(mediaType).unpublishTrack();
9877
+ return __awaiter(this, void 0, void 0, function* () {
9878
+ let mediaContent;
9879
+ if (track instanceof LocalDisplayTrack && this.options.floorControlledPresentation) {
9880
+ mediaContent = MediaContent.Slides;
9881
+ }
9882
+ else {
9883
+ mediaContent = MediaContent.Main;
9884
+ }
9885
+ const mediaFamily = toMediaFamily(track.kind);
9886
+ const mediaType = getMediaType(mediaFamily, mediaContent);
9887
+ const sendTransceiver = this.getSendTransceiverOrThrow(mediaType);
9888
+ return sendTransceiver.unpublishTrack();
9889
+ });
9847
9890
  }
9848
9891
  addTrackListeners(mediaType, track) {
9849
9892
  const onTrackMute = (event) => {
@@ -9896,6 +9939,7 @@ class MultistreamConnection extends EventEmitter {
9896
9939
  const rtcRtpTransceiver = this.pc.addTransceiver(toMediaStreamTrackKind(mediaType), {
9897
9940
  direction: 'recvonly',
9898
9941
  });
9942
+ this.addMid(mediaType);
9899
9943
  const recvOnlyTransceiver = new ReceiveOnlyTransceiver(rtcRtpTransceiver, (mid) => {
9900
9944
  const ingressSignaler = this.streamSignalerManager.getIngressStreamSignaler(mid);
9901
9945
  if (!ingressSignaler) {
@@ -9959,6 +10003,9 @@ class MultistreamConnection extends EventEmitter {
9959
10003
  }
9960
10004
  createOffer() {
9961
10005
  return __awaiter(this, void 0, void 0, function* () {
10006
+ if (!this.pc.getLocalDescription()) {
10007
+ this.currentMid++;
10008
+ }
9962
10009
  return (this.pc
9963
10010
  .createOffer()
9964
10011
  .then((offer) => {
@@ -10018,7 +10065,7 @@ class MultistreamConnection extends EventEmitter {
10018
10065
  }
10019
10066
  });
10020
10067
  if (getBrowserDetails().name !== 'Firefox') {
10021
- setupBundle(parsed, this.options.bundlePolicy);
10068
+ setupBundle(parsed, this.options.bundlePolicy, this.midMap);
10022
10069
  }
10023
10070
  return parsed.toString();
10024
10071
  }
@@ -10053,7 +10100,7 @@ class MultistreamConnection extends EventEmitter {
10053
10100
  const parsedOffer = parse((_a = this.pc.getLocalDescription()) === null || _a === void 0 ? void 0 : _a.sdp);
10054
10101
  matchMlinesInAnswer(parsedOffer, parsedAnswer, this.streamSignalerManager);
10055
10102
  if (getBrowserDetails().name === 'Firefox') {
10056
- setupBundle(parsedAnswer, this.options.bundlePolicy);
10103
+ setupBundle(parsedAnswer, this.options.bundlePolicy, this.midMap);
10057
10104
  }
10058
10105
  return parsedAnswer.toString();
10059
10106
  }
@@ -10095,26 +10142,26 @@ class MultistreamConnection extends EventEmitter {
10095
10142
  this.options = Object.assign(Object.assign({}, defaultMultistreamConnectionOptions), userOptions);
10096
10143
  }
10097
10144
  logger.info(`Renewing multistream connection with options ${JSON.stringify(this.options)}`);
10145
+ this.clearMids();
10098
10146
  this.initializePeerConnection();
10099
10147
  this.streamSignalerManager = new StreamSignalerManager(this.options.streamSignalingMode);
10100
10148
  const mainSceneId = generateSceneId();
10101
10149
  this.sendTransceivers.forEach((transceiver, mediaType) => {
10102
10150
  var _a;
10151
+ this.addMid(mediaType);
10103
10152
  transceiver.replaceTransceiver(this.pc.addTransceiver(toMediaStreamTrackKind(mediaType), {
10104
10153
  direction: 'sendrecv',
10105
10154
  sendEncodings: getMediaFamily(mediaType) === MediaFamily.Video
10106
10155
  ? this.getVideoEncodingOptions()
10107
10156
  : undefined,
10108
10157
  }));
10109
- if (transceiver.publishedTrack) {
10110
- transceiver.publishTrack(transceiver.publishedTrack);
10111
- }
10112
10158
  transceiver.csi = generateCsi(getMediaFamily(mediaType), mainSceneId);
10113
10159
  (_a = this.jmpSessions.get(mediaType)) === null || _a === void 0 ? void 0 : _a.close();
10114
10160
  this.createJmpSession(mediaType);
10115
10161
  });
10116
10162
  this.recvTransceivers.forEach((transceivers, mediaType) => {
10117
10163
  transceivers.forEach((t) => {
10164
+ this.addMid(mediaType);
10118
10165
  t.replaceTransceiver(this.pc.addTransceiver(toMediaStreamTrackKind(mediaType), {
10119
10166
  direction: 'recvonly',
10120
10167
  }));