@webex/web-client-media-engine 1.40.0 → 1.40.2

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
@@ -8979,6 +8979,9 @@ function injectJmpAttributes(parsedSdp, csiMap, streamSignalingMode) {
8979
8979
  mLine.addLine(new JmpStreamIdModeLine(streamSignalingMode));
8980
8980
  }
8981
8981
  });
8982
+ }
8983
+ function hasSimulcast(av) {
8984
+ return !!av.simulcast || av.ssrcGroups.map((sg) => sg.semantics).some((sem) => sem === 'SIM');
8982
8985
  }
8983
8986
 
8984
8987
  class SendOnlyTransceiver extends Transceiver {
@@ -9702,10 +9705,6 @@ const defaultMultistreamConnectionOptions = {
9702
9705
  enableMainAudio: true,
9703
9706
  enableMainVideo: true,
9704
9707
  };
9705
- const defaultVideoCodecParameters = {
9706
- 'max-mbps': `${defaultMaxVideoEncodeMbps}`,
9707
- 'max-fs': `${defaultMaxVideoEncodeFrameSize}`,
9708
- };
9709
9708
  class MultistreamConnection extends EventEmitter {
9710
9709
  constructor(userOptions = {}) {
9711
9710
  var _a, _b;
@@ -9729,7 +9728,6 @@ class MultistreamConnection extends EventEmitter {
9729
9728
  const mainSceneId = generateSceneId();
9730
9729
  const videoMainEncodingOptions = this.getVideoEncodingOptions(MediaContent.Main);
9731
9730
  this.createSendTransceiver(MediaType.VideoMain, mainSceneId, videoMainEncodingOptions);
9732
- this.setCodecParameters(MediaType.VideoMain, defaultVideoCodecParameters);
9733
9731
  this.createSendTransceiver(MediaType.AudioMain, mainSceneId);
9734
9732
  (_a = this.sendTransceivers.get(MediaType.VideoMain)) === null || _a === void 0 ? void 0 : _a.setActive(this.options.enableMainVideo);
9735
9733
  (_b = this.sendTransceivers.get(MediaType.AudioMain)) === null || _b === void 0 ? void 0 : _b.setActive(this.options.enableMainAudio);
@@ -9737,7 +9735,6 @@ class MultistreamConnection extends EventEmitter {
9737
9735
  const videoPresentationEncodingOptions = this.getVideoEncodingOptions(MediaContent.Slides);
9738
9736
  const contentSceneId = generateSceneId();
9739
9737
  this.createSendTransceiver(MediaType.VideoSlides, contentSceneId, videoPresentationEncodingOptions);
9740
- this.setCodecParameters(MediaType.VideoSlides, defaultVideoCodecParameters);
9741
9738
  this.createSendTransceiver(MediaType.AudioSlides, contentSceneId);
9742
9739
  }
9743
9740
  }
@@ -9856,9 +9853,11 @@ class MultistreamConnection extends EventEmitter {
9856
9853
  this.jmpSessions.set(mediaType, jmpSession);
9857
9854
  }
9858
9855
  sendSourceWarnings(mediaType, requests) {
9856
+ var _a;
9859
9857
  if (getMediaFamily(mediaType) === MediaFamily.Video) {
9860
9858
  const sendTransceiver = this.getSendTransceiverOrThrow(mediaType);
9861
9859
  const signaler = this.streamSignalerManager.getEgressStreamSignalerOrThrow(sendTransceiver.mid);
9860
+ const activeSimulcastLayerNumber = ((_a = sendTransceiver.publishedTrack) === null || _a === void 0 ? void 0 : _a.getNumActiveSimulcastLayers()) || 0;
9862
9861
  const sourceWarnings = [];
9863
9862
  requests.forEach(({ ids, policySpecificInfo }) => {
9864
9863
  ids.forEach((id) => {
@@ -9869,6 +9868,9 @@ class MultistreamConnection extends EventEmitter {
9869
9868
  else if (!signaler.getSenderIds().some((validId) => compareStreamIds(id, validId))) {
9870
9869
  sourceWarnings.push({ id, state: 'invalid source', csi: sendTransceiver.csi });
9871
9870
  }
9871
+ else if (signaler.getEncodingIndexForStreamId(id) > activeSimulcastLayerNumber) {
9872
+ sourceWarnings.push({ id, state: 'no source', csi: sendTransceiver.csi });
9873
+ }
9872
9874
  });
9873
9875
  });
9874
9876
  if (sourceWarnings.length > 0) {
@@ -10043,21 +10045,20 @@ class MultistreamConnection extends EventEmitter {
10043
10045
  });
10044
10046
  }
10045
10047
  addTrackListeners(mediaType, track) {
10048
+ const onTrackResolutionChange = () => {
10049
+ const sources = this.getVideoSources(mediaType);
10050
+ if (sources != null) {
10051
+ this.sendSourceIndication(mediaType, 1, sources);
10052
+ }
10053
+ };
10054
+ track.on(LocalTrack.Events.TrackConstraintsChange, onTrackResolutionChange);
10046
10055
  const onTrackMute = (event) => {
10047
- const sendTransceiver = this.getSendTransceiverOrThrow(mediaType);
10048
- const signaler = this.streamSignalerManager.getEgressStreamSignaler(sendTransceiver.mid);
10049
- if (!signaler) {
10050
- return;
10056
+ if (getMediaFamily(mediaType) === MediaFamily.Audio) {
10057
+ this.sendSourceIndication(mediaType, +!event.trackState.muted);
10051
10058
  }
10052
- if (this.getPublishedTracks().includes(track)) {
10053
- if (getMediaFamily(mediaType) === MediaFamily.Audio) {
10054
- this.sendSourceIndication(mediaType, +!event.trackState.muted);
10055
- }
10056
- else {
10057
- const state = event.trackState.muted ? 'avatar' : 'live';
10058
- const sources = signaler
10059
- .getSenderIds()
10060
- .map((id) => ({ id, state, csi: sendTransceiver.csi }));
10059
+ else {
10060
+ const sources = this.getVideoSources(mediaType);
10061
+ if (sources != null) {
10061
10062
  this.sendSourceIndication(mediaType, +!event.trackState.muted, sources);
10062
10063
  }
10063
10064
  }
@@ -10067,27 +10068,47 @@ class MultistreamConnection extends EventEmitter {
10067
10068
  if (!event.isPublished) {
10068
10069
  track.off(LocalTrack.Events.Muted, onTrackMute);
10069
10070
  track.off(LocalTrack.Events.PublishedStateUpdate, onTrackPublish);
10071
+ track.off(LocalTrack.Events.TrackConstraintsChange, onTrackResolutionChange);
10070
10072
  }
10071
- const sendTransceiver = this.getSendTransceiverOrThrow(mediaType);
10072
- const signaler = this.streamSignalerManager.getEgressStreamSignaler(sendTransceiver.mid);
10073
- if (!signaler) {
10074
- return;
10073
+ if (getMediaFamily(mediaType) === MediaFamily.Audio) {
10074
+ this.sendSourceIndication(mediaType, +event.isPublished);
10075
10075
  }
10076
- if (!event.trackState.muted) {
10077
- if (getMediaFamily(mediaType) === MediaFamily.Audio) {
10078
- this.sendSourceIndication(mediaType, +event.isPublished);
10079
- }
10080
- else {
10081
- const state = event.isPublished ? 'live' : 'no source';
10082
- const sources = signaler
10083
- .getSenderIds()
10084
- .map((id) => ({ id, state, csi: sendTransceiver.csi }));
10076
+ else {
10077
+ const sources = this.getVideoSources(mediaType);
10078
+ if (sources != null) {
10085
10079
  this.sendSourceIndication(mediaType, +event.isPublished, sources);
10086
10080
  }
10087
10081
  }
10088
10082
  };
10089
10083
  track.on(LocalTrack.Events.PublishedStateUpdate, onTrackPublish);
10090
10084
  }
10085
+ getVideoSources(mediaType) {
10086
+ var _a, _b, _c;
10087
+ const sendTransceiver = this.getSendTransceiverOrThrow(mediaType);
10088
+ const signaler = this.streamSignalerManager.getEgressStreamSignaler(sendTransceiver.mid);
10089
+ if (!signaler) {
10090
+ return null;
10091
+ }
10092
+ const activeSimulcastLayerNumber = ((_a = sendTransceiver.publishedTrack) === null || _a === void 0 ? void 0 : _a.getNumActiveSimulcastLayers()) || 0;
10093
+ const published = (_b = sendTransceiver.publishedTrack) === null || _b === void 0 ? void 0 : _b.published;
10094
+ const muted = ((_c = sendTransceiver.publishedTrack) === null || _c === void 0 ? void 0 : _c.muted) === true;
10095
+ return signaler.getSenderIds().map((id) => {
10096
+ let state;
10097
+ if (!published) {
10098
+ state = 'no source';
10099
+ }
10100
+ else if (muted) {
10101
+ state = 'avatar';
10102
+ }
10103
+ else if (activeSimulcastLayerNumber <= signaler.getEncodingIndexForStreamId(id)) {
10104
+ state = 'no source';
10105
+ }
10106
+ else {
10107
+ state = 'live';
10108
+ }
10109
+ return { id, state, csi: sendTransceiver.csi };
10110
+ });
10111
+ }
10091
10112
  createReceiveSlot(mediaType) {
10092
10113
  return __awaiter(this, void 0, void 0, function* () {
10093
10114
  const rtcRtpTransceiver = this.pc.addTransceiver(toMediaStreamTrackKind(mediaType), {
@@ -10211,9 +10232,17 @@ class MultistreamConnection extends EventEmitter {
10211
10232
  .filter((av) => av.direction === 'sendrecv')
10212
10233
  .forEach((av) => {
10213
10234
  const egressSignaler = this.streamSignalerManager.getOrCreateEgressStreamSignaler(av.mid);
10214
- const simulcastEnabled = !!av.simulcast;
10235
+ const simulcastEnabled = hasSimulcast(av);
10215
10236
  const rtxEnabled = av.type === 'video';
10216
10237
  egressSignaler.signalStreams(simulcastEnabled, rtxEnabled, av);
10238
+ if (av.type === 'video') {
10239
+ [...av.codecs.values()]
10240
+ .filter((ci) => ci.name === 'H264')
10241
+ .forEach((ci) => {
10242
+ ci.fmtParams.set('max-mbps', `${defaultMaxVideoEncodeMbps}`);
10243
+ ci.fmtParams.set('max-fs', `${defaultMaxVideoEncodeFrameSize}`);
10244
+ });
10245
+ }
10217
10246
  const mediaType = [...this.sendTransceivers.keys()].find((key) => { var _a; return ((_a = this.sendTransceivers.get(key)) === null || _a === void 0 ? void 0 : _a.mid) === av.mid; });
10218
10247
  if (mediaType && this.customCodecParameters.has(mediaType)) {
10219
10248
  [...av.codecs.values()]