@webex/web-client-media-engine 3.36.1 → 3.37.1

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
@@ -8206,6 +8206,24 @@ function getRecommendedMaxBitrateForFrameSize(requestedMaxFs) {
8206
8206
  .sort((a, b) => b - a)
8207
8207
  .find((h) => requestedMaxFs >= h);
8208
8208
  return maxFrameSizeToMaxBitrateMap.get(expectedHeight);
8209
+ }
8210
+ function setCodecParameters(allCodecParameters, codecMimeType, newParameters) {
8211
+ if (!allCodecParameters.has(codecMimeType)) {
8212
+ allCodecParameters.set(codecMimeType, {});
8213
+ }
8214
+ const currentParameters = allCodecParameters.get(codecMimeType);
8215
+ Object.entries(newParameters).forEach(([param, value]) => {
8216
+ currentParameters[param] = value;
8217
+ });
8218
+ }
8219
+ function markCodecParametersForDeletion(allCodecParameters, codecMimeTypeToUpdate, codecParameters) {
8220
+ if (!allCodecParameters.has(codecMimeTypeToUpdate)) {
8221
+ allCodecParameters.set(codecMimeTypeToUpdate, {});
8222
+ }
8223
+ const currentParameters = allCodecParameters.get(codecMimeTypeToUpdate);
8224
+ codecParameters.forEach((param) => {
8225
+ currentParameters[param] = undefined;
8226
+ });
8209
8227
  }
8210
8228
 
8211
8229
  /******************************************************************************
@@ -10439,16 +10457,17 @@ function addVlaExtension(mediaDescription) {
10439
10457
  mediaDescription.addExtension({ uri: vlaExtensionUri });
10440
10458
  }
10441
10459
  }
10442
- function applyFormatParameters(mediaDescription, codecs, paramsMap) {
10443
- paramsMap.forEach((value, param) => {
10460
+ function setFormatParameters(mediaDescription, codecMimeType, paramsMap) {
10461
+ const codecName = codecMimeType.split('/')[1].toLowerCase();
10462
+ Object.entries(paramsMap).forEach(([param, value]) => {
10444
10463
  [...mediaDescription.codecs.values()]
10445
- .filter((ci) => ci.name && codecs.includes(ci.name))
10464
+ .filter((ci) => ci.name && codecName === ci.name.toLowerCase())
10446
10465
  .forEach((ci) => {
10447
- if (value === null) {
10466
+ if (value === undefined) {
10448
10467
  ci.fmtParams.delete(param);
10449
10468
  }
10450
10469
  else {
10451
- ci.fmtParams.set(param, `${value}`);
10470
+ ci.fmtParams.set(param, value);
10452
10471
  }
10453
10472
  });
10454
10473
  });
@@ -10563,7 +10582,9 @@ class EgressSdpMunger {
10563
10582
  if (options.simulcastEnabled) {
10564
10583
  mediaDescription.addLine(new SsrcGroupLine('SIM', this.streamIds.map((streamId) => streamId.ssrc)));
10565
10584
  }
10566
- applyFormatParameters(mediaDescription, ['H264', 'opus'], this.customCodecParameters);
10585
+ this.customCodecParameters.forEach((codecParams, codecMimeType) => {
10586
+ setFormatParameters(mediaDescription, codecMimeType, codecParams);
10587
+ });
10567
10588
  if (options.twccDisabled) {
10568
10589
  disableTwcc(mediaDescription);
10569
10590
  }
@@ -10593,7 +10614,9 @@ class EgressSdpMunger {
10593
10614
  ci.fmtParams.set('usedtx', mungeOptions.dtxDisabled ? '0' : '1');
10594
10615
  });
10595
10616
  }
10596
- applyFormatParameters(mediaDescription, ['H264', 'opus'], this.customCodecParameters);
10617
+ this.customCodecParameters.forEach((codecParams, codecMimeType) => {
10618
+ setFormatParameters(mediaDescription, codecMimeType, codecParams);
10619
+ });
10597
10620
  }
10598
10621
  getSenderIds() {
10599
10622
  return this.streamIds;
@@ -10601,15 +10624,11 @@ class EgressSdpMunger {
10601
10624
  getEncodingIndexForStreamId(streamId) {
10602
10625
  return this.streamIds.findIndex((currStreamId) => areStreamIdsEqual(currStreamId, streamId));
10603
10626
  }
10604
- setCodecParameters(parameters) {
10605
- Object.entries(parameters).forEach(([param, value]) => {
10606
- this.customCodecParameters.set(param, value);
10607
- });
10627
+ setCustomCodecParameters(codecMimeType, parameters) {
10628
+ setCodecParameters(this.customCodecParameters, codecMimeType, parameters);
10608
10629
  }
10609
- deleteCodecParameters(parameters) {
10610
- parameters.forEach((param) => {
10611
- this.customCodecParameters.set(param, null);
10612
- });
10630
+ markCustomCodecParametersForDeletion(codecMimeType, parameters) {
10631
+ markCodecParametersForDeletion(this.customCodecParameters, codecMimeType, parameters);
10613
10632
  }
10614
10633
  }
10615
10634
 
@@ -11095,7 +11114,6 @@ class EventEmitter$2 extends events$1.exports.EventEmitter {
11095
11114
  class IngressSdpMunger {
11096
11115
  constructor() {
11097
11116
  this.customCodecParameters = new Map();
11098
- this.customRtxCodecParameters = new Map();
11099
11117
  this.ssrc = generateSsrc();
11100
11118
  }
11101
11119
  getReceiverId() {
@@ -11107,8 +11125,9 @@ class IngressSdpMunger {
11107
11125
  logErrorAndThrow(WcmeErrorType.SDP_MUNGE_MISSING_CODECS, `No codecs present in m-line with MID ${mediaDescription.mid} after filtering.`);
11108
11126
  }
11109
11127
  removeMidRidExtensions(mediaDescription);
11110
- applyFormatParameters(mediaDescription, ['H264', 'opus'], this.customCodecParameters);
11111
- applyFormatParameters(mediaDescription, ['rtx'], this.customRtxCodecParameters);
11128
+ this.customCodecParameters.forEach((codecParams, codecMimeType) => {
11129
+ setFormatParameters(mediaDescription, codecMimeType, codecParams);
11130
+ });
11112
11131
  if (options.twccDisabled) {
11113
11132
  disableTwcc(mediaDescription);
11114
11133
  }
@@ -11129,17 +11148,16 @@ class IngressSdpMunger {
11129
11148
  if (retainCandidatesByTransportType(mediaDescription, ['udp', 'tcp'])) {
11130
11149
  logger.log(`Some unsupported remote candidates have been removed from mid ${mediaDescription.mid}`);
11131
11150
  }
11132
- applyFormatParameters(mediaDescription, ['rtx'], this.customRtxCodecParameters);
11151
+ const rtxParams = this.customCodecParameters.get(MediaCodecMimeType.RTX);
11152
+ if (rtxParams) {
11153
+ setFormatParameters(mediaDescription, MediaCodecMimeType.RTX, rtxParams);
11154
+ }
11133
11155
  }
11134
- setCodecParameters(parameters) {
11135
- Object.entries(parameters).forEach(([param, value]) => {
11136
- this.customCodecParameters.set(param, value);
11137
- });
11156
+ setCustomCodecParameters(codecMimeType, parameters) {
11157
+ setCodecParameters(this.customCodecParameters, codecMimeType, parameters);
11138
11158
  }
11139
- setRtxCodecParameters(parameters) {
11140
- Object.entries(parameters).forEach(([param, value]) => {
11141
- this.customRtxCodecParameters.set(param, value);
11142
- });
11159
+ markCustomCodecParametersForDeletion(codecMimeType, parameters) {
11160
+ markCodecParametersForDeletion(this.customCodecParameters, codecMimeType, parameters);
11143
11161
  }
11144
11162
  reset() {
11145
11163
  this.ssrc = generateSsrc();
@@ -11452,11 +11470,8 @@ class ReceiveOnlyTransceiver extends Transceiver {
11452
11470
  this.metadata.lastActiveSpeakerUpdateTimestamp = getCurrentTimestamp();
11453
11471
  }
11454
11472
  }
11455
- setCodecParameters(parameters) {
11456
- this.munger.setCodecParameters(parameters);
11457
- }
11458
- setRtxCodecParameters(parameters) {
11459
- this.munger.setRtxCodecParameters(parameters);
11473
+ setCustomCodecParameters(codecMimeType, parameters) {
11474
+ this.munger.setCustomCodecParameters(codecMimeType, parameters);
11460
11475
  }
11461
11476
  }
11462
11477
  ReceiveOnlyTransceiver.rid = '1';
@@ -15432,12 +15447,12 @@ class SendOnlyTransceiver extends Transceiver {
15432
15447
  resetSdpMunger() {
15433
15448
  this.munger.reset();
15434
15449
  }
15435
- setCodecParameters(parameters) {
15436
- this.munger.setCodecParameters(parameters);
15450
+ setCustomCodecParameters(codecMimeType, codecParams) {
15451
+ this.munger.setCustomCodecParameters(codecMimeType, codecParams);
15437
15452
  this.negotiationNeeded.emit(OfferAnswerType.LocalOnly);
15438
15453
  }
15439
- deleteCodecParameters(parameters) {
15440
- this.munger.deleteCodecParameters(parameters);
15454
+ markCustomCodecParametersForDeletion(codecMimeType, parameters) {
15455
+ this.munger.markCustomCodecParametersForDeletion(codecMimeType, parameters);
15441
15456
  this.negotiationNeeded.emit(OfferAnswerType.LocalOnly);
15442
15457
  }
15443
15458
  setSourceStateOverride(state) {
@@ -15498,12 +15513,26 @@ class SendSlot {
15498
15513
  }
15499
15514
  setCodecParameters(parameters) {
15500
15515
  return __awaiter(this, void 0, void 0, function* () {
15501
- this.sendTransceiver.setCodecParameters(parameters);
15516
+ [MediaCodecMimeType.H264, MediaCodecMimeType.OPUS].forEach((codecMimeType) => {
15517
+ this.setCustomCodecParameters(codecMimeType, parameters);
15518
+ });
15502
15519
  });
15503
15520
  }
15504
15521
  deleteCodecParameters(parameters) {
15505
15522
  return __awaiter(this, void 0, void 0, function* () {
15506
- this.sendTransceiver.deleteCodecParameters(parameters);
15523
+ [MediaCodecMimeType.H264, MediaCodecMimeType.OPUS].forEach((codecMimeType) => {
15524
+ this.markCustomCodecParametersForDeletion(codecMimeType, parameters);
15525
+ });
15526
+ });
15527
+ }
15528
+ setCustomCodecParameters(codecMimeType, parameters) {
15529
+ return __awaiter(this, void 0, void 0, function* () {
15530
+ this.sendTransceiver.setCustomCodecParameters(codecMimeType, parameters);
15531
+ });
15532
+ }
15533
+ markCustomCodecParametersForDeletion(codecMimeType, parameters) {
15534
+ return __awaiter(this, void 0, void 0, function* () {
15535
+ this.sendTransceiver.markCustomCodecParametersForDeletion(codecMimeType, parameters);
15507
15536
  });
15508
15537
  }
15509
15538
  setSourceStateOverride(state) {
@@ -15697,7 +15726,7 @@ function getWorkerManager() {
15697
15726
  return WorkerManager.workerManagerInstance;
15698
15727
  }
15699
15728
 
15700
- function toMediaStreamTrackKind(mediaType) {
15729
+ function mediaTypeToTrackKind(mediaType) {
15701
15730
  return [MediaType.VideoMain, MediaType.VideoSlides].includes(mediaType)
15702
15731
  ? MediaStreamTrackKind.Video
15703
15732
  : MediaStreamTrackKind.Audio;
@@ -15767,9 +15796,10 @@ class MultistreamConnection extends EventEmitter$2 {
15767
15796
  const slidesSceneId = generateSceneId();
15768
15797
  const videoMainEncodingOptions = this.getVideoEncodingOptions(MediaContent.Main);
15769
15798
  const videoSlidesEncodingOptions = this.getVideoEncodingOptions(MediaContent.Slides);
15770
- this.createSendTransceiver(MediaType.VideoMain, mainSceneId, videoMainEncodingOptions);
15799
+ const sendVideoCodecParams = this.getCustomSendVideoCodecParams();
15800
+ this.createSendTransceiver(MediaType.VideoMain, mainSceneId, videoMainEncodingOptions, sendVideoCodecParams);
15771
15801
  this.createSendTransceiver(MediaType.AudioMain, mainSceneId);
15772
- this.createSendTransceiver(MediaType.VideoSlides, slidesSceneId, videoSlidesEncodingOptions);
15802
+ this.createSendTransceiver(MediaType.VideoSlides, slidesSceneId, videoSlidesEncodingOptions, sendVideoCodecParams);
15773
15803
  this.createSendTransceiver(MediaType.AudioSlides, slidesSceneId);
15774
15804
  }
15775
15805
  startWorkerIfNeeded() {
@@ -15847,10 +15877,29 @@ class MultistreamConnection extends EventEmitter$2 {
15847
15877
  ]
15848
15878
  : [{ active: false }];
15849
15879
  }
15850
- createSendTransceiver(mediaType, sceneId, sendEncodingsOptions) {
15880
+ getCustomSendVideoCodecParams() {
15881
+ return {
15882
+ [MediaCodecMimeType.H264]: {
15883
+ 'x-google-start-bitrate': `${this.options.preferredStartingBitrateKbps}`,
15884
+ 'max-mbps': `${defaultMaxVideoEncodeMbps}`,
15885
+ 'max-fs': `${defaultMaxVideoEncodeFrameSize}`,
15886
+ },
15887
+ };
15888
+ }
15889
+ getCustomReceiveVideoCodecParams(mediaType) {
15890
+ return {
15891
+ [MediaCodecMimeType.H264]: {
15892
+ 'sps-pps-idr-in-keyframe': '1',
15893
+ },
15894
+ [MediaCodecMimeType.RTX]: {
15895
+ 'rtx-time': mediaType === MediaType.VideoMain ? defaultVideoMainRtxTime : defaultVideoSlidesRtxTime,
15896
+ },
15897
+ };
15898
+ }
15899
+ createSendTransceiver(mediaType, sceneId, sendEncodingsOptions, codecParams) {
15851
15900
  let rtcRtpTransceiver;
15852
15901
  try {
15853
- rtcRtpTransceiver = this.pc.addTransceiver(toMediaStreamTrackKind(mediaType), {
15902
+ rtcRtpTransceiver = this.pc.addTransceiver(mediaTypeToTrackKind(mediaType), {
15854
15903
  direction: 'sendrecv',
15855
15904
  sendEncodings: sendEncodingsOptions,
15856
15905
  });
@@ -15869,14 +15918,12 @@ class MultistreamConnection extends EventEmitter$2 {
15869
15918
  munger,
15870
15919
  csi,
15871
15920
  });
15872
- let codecParameters = {
15873
- 'x-google-start-bitrate': `${this.options.preferredStartingBitrateKbps}`,
15874
- };
15875
15921
  if (getMediaFamily(mediaType) === MediaFamily.Video) {
15876
15922
  transceiver.rtxEnabled = true;
15877
- codecParameters = Object.assign(Object.assign({}, codecParameters), { 'max-mbps': `${defaultMaxVideoEncodeMbps}`, 'max-fs': `${defaultMaxVideoEncodeFrameSize}` });
15878
15923
  }
15879
- transceiver.setCodecParameters(codecParameters);
15924
+ Object.entries(codecParams !== null && codecParams !== void 0 ? codecParams : {}).forEach(([codec, params]) => {
15925
+ transceiver.setCustomCodecParameters(codec, params);
15926
+ });
15880
15927
  transceiver.twccDisabled =
15881
15928
  getMediaFamily(mediaType) === MediaFamily.Audio ? this.options.disableAudioTwcc : false;
15882
15929
  transceiver.dtxDisabled = mediaType !== MediaType.AudioMain || this.options.disableAudioMainDtx;
@@ -16177,8 +16224,8 @@ SCTP Max Message Size: ${maxMessageSize}`);
16177
16224
  static getEncodedTransformId(mediaType, mid) {
16178
16225
  return `INBOUND-${mediaType}-${mid}`;
16179
16226
  }
16180
- createReceiveTransceiver(mediaType) {
16181
- const rtcRtpTransceiver = this.pc.addTransceiver(toMediaStreamTrackKind(mediaType), {
16227
+ createReceiveTransceiver(mediaType, codecParams) {
16228
+ const rtcRtpTransceiver = this.pc.addTransceiver(mediaTypeToTrackKind(mediaType), {
16182
16229
  direction: 'recvonly',
16183
16230
  });
16184
16231
  const mid = this.midPredictor.getNextMid(mediaType);
@@ -16206,14 +16253,9 @@ SCTP Max Message Size: ${maxMessageSize}`);
16206
16253
  logger.warn(`Failed to setup encoded transform for audio level monitoring of mid=${mid}: ${e}`);
16207
16254
  }
16208
16255
  }
16209
- if (getMediaFamily(mediaType) === MediaFamily.Video) {
16210
- recvOnlyTransceiver.setCodecParameters({
16211
- 'sps-pps-idr-in-keyframe': '1',
16212
- });
16213
- recvOnlyTransceiver.setRtxCodecParameters({
16214
- 'rtx-time': mediaType === MediaType.VideoMain ? defaultVideoMainRtxTime : defaultVideoSlidesRtxTime,
16215
- });
16216
- }
16256
+ Object.entries(codecParams !== null && codecParams !== void 0 ? codecParams : {}).forEach(([codec, params]) => {
16257
+ recvOnlyTransceiver.setCustomCodecParameters(codec, params);
16258
+ });
16217
16259
  recvOnlyTransceiver.twccDisabled =
16218
16260
  getMediaFamily(mediaType) === MediaFamily.Audio ? this.options.disableAudioTwcc : false;
16219
16261
  this.recvTransceivers.set(mediaType, [
@@ -16232,8 +16274,11 @@ SCTP Max Message Size: ${maxMessageSize}`);
16232
16274
  return new Promise((createReceiveSlotsResolve) => {
16233
16275
  this.offerAnswerQueue.push(() => __awaiter(this, void 0, void 0, function* () {
16234
16276
  const createdReceiveOnlyTransceivers = [];
16277
+ const codecParams = mediaTypeToTrackKind(mediaType) === MediaStreamTrackKind.Video
16278
+ ? this.getCustomReceiveVideoCodecParams(mediaType)
16279
+ : undefined;
16235
16280
  for (let i = 0; i < count; i++) {
16236
- const recvOnlyTransceiver = this.createReceiveTransceiver(mediaType);
16281
+ const recvOnlyTransceiver = this.createReceiveTransceiver(mediaType, codecParams);
16237
16282
  createdReceiveOnlyTransceivers.push(recvOnlyTransceiver);
16238
16283
  }
16239
16284
  if (this.pc.getRemoteDescription()) {
@@ -16610,7 +16655,7 @@ SCTP Max Message Size: ${maxMessageSize}`);
16610
16655
  const mediaContent = getMediaContent(mediaType);
16611
16656
  const sceneId = mediaContent === MediaContent.Main ? mainSceneId : slidesSceneId;
16612
16657
  const mid = this.midPredictor.getNextMid(mediaType);
16613
- transceiver.replaceTransceiver(this.pc.addTransceiver(toMediaStreamTrackKind(mediaType), {
16658
+ transceiver.replaceTransceiver(this.pc.addTransceiver(mediaTypeToTrackKind(mediaType), {
16614
16659
  direction: 'sendrecv',
16615
16660
  sendEncodings: getMediaFamily(mediaType) === MediaFamily.Video
16616
16661
  ? this.getVideoEncodingOptions(mediaContent)
@@ -16625,7 +16670,7 @@ SCTP Max Message Size: ${maxMessageSize}`);
16625
16670
  this.recvTransceivers.forEach((transceivers, mediaType) => {
16626
16671
  transceivers.forEach((t) => {
16627
16672
  const mid = this.midPredictor.getNextMid(mediaType);
16628
- const rtcRtpTransceiver = this.pc.addTransceiver(toMediaStreamTrackKind(mediaType), {
16673
+ const rtcRtpTransceiver = this.pc.addTransceiver(mediaTypeToTrackKind(mediaType), {
16629
16674
  direction: 'recvonly',
16630
16675
  });
16631
16676
  t.replaceTransceiver(rtcRtpTransceiver);