@webex/web-client-media-engine 3.36.1 → 3.37.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/cjs/index.js CHANGED
@@ -8210,6 +8210,24 @@ function getRecommendedMaxBitrateForFrameSize(requestedMaxFs) {
8210
8210
  .sort((a, b) => b - a)
8211
8211
  .find((h) => requestedMaxFs >= h);
8212
8212
  return maxFrameSizeToMaxBitrateMap.get(expectedHeight);
8213
+ }
8214
+ function setCodecParameters(allCodecParameters, codecMimeType, newParameters) {
8215
+ if (!allCodecParameters.has(codecMimeType)) {
8216
+ allCodecParameters.set(codecMimeType, {});
8217
+ }
8218
+ const currentParameters = allCodecParameters.get(codecMimeType);
8219
+ Object.entries(newParameters).forEach(([param, value]) => {
8220
+ currentParameters[param] = value;
8221
+ });
8222
+ }
8223
+ function markCodecParametersForDeletion(allCodecParameters, codecMimeTypeToUpdate, codecParameters) {
8224
+ if (!allCodecParameters.has(codecMimeTypeToUpdate)) {
8225
+ allCodecParameters.set(codecMimeTypeToUpdate, {});
8226
+ }
8227
+ const currentParameters = allCodecParameters.get(codecMimeTypeToUpdate);
8228
+ codecParameters.forEach((param) => {
8229
+ currentParameters[param] = undefined;
8230
+ });
8213
8231
  }
8214
8232
 
8215
8233
  /******************************************************************************
@@ -10443,16 +10461,17 @@ function addVlaExtension(mediaDescription) {
10443
10461
  mediaDescription.addExtension({ uri: vlaExtensionUri });
10444
10462
  }
10445
10463
  }
10446
- function applyFormatParameters(mediaDescription, codecs, paramsMap) {
10447
- paramsMap.forEach((value, param) => {
10464
+ function setFormatParameters(mediaDescription, codecMimeType, paramsMap) {
10465
+ const codecName = codecMimeType.split('/')[1].toLowerCase();
10466
+ Object.entries(paramsMap).forEach(([param, value]) => {
10448
10467
  [...mediaDescription.codecs.values()]
10449
- .filter((ci) => ci.name && codecs.includes(ci.name))
10468
+ .filter((ci) => ci.name && codecName === ci.name.toLowerCase())
10450
10469
  .forEach((ci) => {
10451
- if (value === null) {
10470
+ if (value === undefined) {
10452
10471
  ci.fmtParams.delete(param);
10453
10472
  }
10454
10473
  else {
10455
- ci.fmtParams.set(param, `${value}`);
10474
+ ci.fmtParams.set(param, value);
10456
10475
  }
10457
10476
  });
10458
10477
  });
@@ -10567,7 +10586,9 @@ class EgressSdpMunger {
10567
10586
  if (options.simulcastEnabled) {
10568
10587
  mediaDescription.addLine(new SsrcGroupLine('SIM', this.streamIds.map((streamId) => streamId.ssrc)));
10569
10588
  }
10570
- applyFormatParameters(mediaDescription, ['H264', 'opus'], this.customCodecParameters);
10589
+ this.customCodecParameters.forEach((codecParams, codecMimeType) => {
10590
+ setFormatParameters(mediaDescription, codecMimeType, codecParams);
10591
+ });
10571
10592
  if (options.twccDisabled) {
10572
10593
  disableTwcc(mediaDescription);
10573
10594
  }
@@ -10597,7 +10618,9 @@ class EgressSdpMunger {
10597
10618
  ci.fmtParams.set('usedtx', mungeOptions.dtxDisabled ? '0' : '1');
10598
10619
  });
10599
10620
  }
10600
- applyFormatParameters(mediaDescription, ['H264', 'opus'], this.customCodecParameters);
10621
+ this.customCodecParameters.forEach((codecParams, codecMimeType) => {
10622
+ setFormatParameters(mediaDescription, codecMimeType, codecParams);
10623
+ });
10601
10624
  }
10602
10625
  getSenderIds() {
10603
10626
  return this.streamIds;
@@ -10605,15 +10628,11 @@ class EgressSdpMunger {
10605
10628
  getEncodingIndexForStreamId(streamId) {
10606
10629
  return this.streamIds.findIndex((currStreamId) => areStreamIdsEqual(currStreamId, streamId));
10607
10630
  }
10608
- setCodecParameters(parameters) {
10609
- Object.entries(parameters).forEach(([param, value]) => {
10610
- this.customCodecParameters.set(param, value);
10611
- });
10631
+ setCustomCodecParameters(codecMimeType, parameters) {
10632
+ setCodecParameters(this.customCodecParameters, codecMimeType, parameters);
10612
10633
  }
10613
- deleteCodecParameters(parameters) {
10614
- parameters.forEach((param) => {
10615
- this.customCodecParameters.set(param, null);
10616
- });
10634
+ markCustomCodecParametersForDeletion(codecMimeType, parameters) {
10635
+ markCodecParametersForDeletion(this.customCodecParameters, codecMimeType, parameters);
10617
10636
  }
10618
10637
  }
10619
10638
 
@@ -11099,7 +11118,6 @@ class EventEmitter$2 extends events$1.exports.EventEmitter {
11099
11118
  class IngressSdpMunger {
11100
11119
  constructor() {
11101
11120
  this.customCodecParameters = new Map();
11102
- this.customRtxCodecParameters = new Map();
11103
11121
  this.ssrc = generateSsrc();
11104
11122
  }
11105
11123
  getReceiverId() {
@@ -11111,8 +11129,9 @@ class IngressSdpMunger {
11111
11129
  logErrorAndThrow(exports.WcmeErrorType.SDP_MUNGE_MISSING_CODECS, `No codecs present in m-line with MID ${mediaDescription.mid} after filtering.`);
11112
11130
  }
11113
11131
  removeMidRidExtensions(mediaDescription);
11114
- applyFormatParameters(mediaDescription, ['H264', 'opus'], this.customCodecParameters);
11115
- applyFormatParameters(mediaDescription, ['rtx'], this.customRtxCodecParameters);
11132
+ this.customCodecParameters.forEach((codecParams, codecMimeType) => {
11133
+ setFormatParameters(mediaDescription, codecMimeType, codecParams);
11134
+ });
11116
11135
  if (options.twccDisabled) {
11117
11136
  disableTwcc(mediaDescription);
11118
11137
  }
@@ -11133,17 +11152,16 @@ class IngressSdpMunger {
11133
11152
  if (retainCandidatesByTransportType(mediaDescription, ['udp', 'tcp'])) {
11134
11153
  logger.log(`Some unsupported remote candidates have been removed from mid ${mediaDescription.mid}`);
11135
11154
  }
11136
- applyFormatParameters(mediaDescription, ['rtx'], this.customRtxCodecParameters);
11155
+ const rtxParams = this.customCodecParameters.get(exports.MediaCodecMimeType.RTX);
11156
+ if (rtxParams) {
11157
+ setFormatParameters(mediaDescription, exports.MediaCodecMimeType.RTX, rtxParams);
11158
+ }
11137
11159
  }
11138
- setCodecParameters(parameters) {
11139
- Object.entries(parameters).forEach(([param, value]) => {
11140
- this.customCodecParameters.set(param, value);
11141
- });
11160
+ setCustomCodecParameters(codecMimeType, parameters) {
11161
+ setCodecParameters(this.customCodecParameters, codecMimeType, parameters);
11142
11162
  }
11143
- setRtxCodecParameters(parameters) {
11144
- Object.entries(parameters).forEach(([param, value]) => {
11145
- this.customRtxCodecParameters.set(param, value);
11146
- });
11163
+ markCustomCodecParametersForDeletion(codecMimeType, parameters) {
11164
+ markCodecParametersForDeletion(this.customCodecParameters, codecMimeType, parameters);
11147
11165
  }
11148
11166
  reset() {
11149
11167
  this.ssrc = generateSsrc();
@@ -11456,11 +11474,8 @@ class ReceiveOnlyTransceiver extends Transceiver {
11456
11474
  this.metadata.lastActiveSpeakerUpdateTimestamp = getCurrentTimestamp();
11457
11475
  }
11458
11476
  }
11459
- setCodecParameters(parameters) {
11460
- this.munger.setCodecParameters(parameters);
11461
- }
11462
- setRtxCodecParameters(parameters) {
11463
- this.munger.setRtxCodecParameters(parameters);
11477
+ setCustomCodecParameters(codecMimeType, parameters) {
11478
+ this.munger.setCustomCodecParameters(codecMimeType, parameters);
11464
11479
  }
11465
11480
  }
11466
11481
  ReceiveOnlyTransceiver.rid = '1';
@@ -15436,12 +15451,12 @@ class SendOnlyTransceiver extends Transceiver {
15436
15451
  resetSdpMunger() {
15437
15452
  this.munger.reset();
15438
15453
  }
15439
- setCodecParameters(parameters) {
15440
- this.munger.setCodecParameters(parameters);
15454
+ setCustomCodecParameters(codecMimeType, codecParams) {
15455
+ this.munger.setCustomCodecParameters(codecMimeType, codecParams);
15441
15456
  this.negotiationNeeded.emit(OfferAnswerType.LocalOnly);
15442
15457
  }
15443
- deleteCodecParameters(parameters) {
15444
- this.munger.deleteCodecParameters(parameters);
15458
+ markCustomCodecParametersForDeletion(codecMimeType, parameters) {
15459
+ this.munger.markCustomCodecParametersForDeletion(codecMimeType, parameters);
15445
15460
  this.negotiationNeeded.emit(OfferAnswerType.LocalOnly);
15446
15461
  }
15447
15462
  setSourceStateOverride(state) {
@@ -15502,12 +15517,26 @@ class SendSlot {
15502
15517
  }
15503
15518
  setCodecParameters(parameters) {
15504
15519
  return __awaiter(this, void 0, void 0, function* () {
15505
- this.sendTransceiver.setCodecParameters(parameters);
15520
+ [exports.MediaCodecMimeType.H264, exports.MediaCodecMimeType.OPUS].forEach((codecMimeType) => {
15521
+ this.setCustomCodecParameters(codecMimeType, parameters);
15522
+ });
15506
15523
  });
15507
15524
  }
15508
15525
  deleteCodecParameters(parameters) {
15509
15526
  return __awaiter(this, void 0, void 0, function* () {
15510
- this.sendTransceiver.deleteCodecParameters(parameters);
15527
+ [exports.MediaCodecMimeType.H264, exports.MediaCodecMimeType.OPUS].forEach((codecMimeType) => {
15528
+ this.markCustomCodecParametersForDeletion(codecMimeType, parameters);
15529
+ });
15530
+ });
15531
+ }
15532
+ setCustomCodecParameters(codecMimeType, parameters) {
15533
+ return __awaiter(this, void 0, void 0, function* () {
15534
+ this.sendTransceiver.setCustomCodecParameters(codecMimeType, parameters);
15535
+ });
15536
+ }
15537
+ markCustomCodecParametersForDeletion(codecMimeType, parameters) {
15538
+ return __awaiter(this, void 0, void 0, function* () {
15539
+ this.sendTransceiver.markCustomCodecParametersForDeletion(codecMimeType, parameters);
15511
15540
  });
15512
15541
  }
15513
15542
  setSourceStateOverride(state) {
@@ -15701,7 +15730,7 @@ function getWorkerManager() {
15701
15730
  return WorkerManager.workerManagerInstance;
15702
15731
  }
15703
15732
 
15704
- function toMediaStreamTrackKind(mediaType) {
15733
+ function mediaTypeToTrackKind(mediaType) {
15705
15734
  return [exports.MediaType.VideoMain, exports.MediaType.VideoSlides].includes(mediaType)
15706
15735
  ? exports.MediaStreamTrackKind.Video
15707
15736
  : exports.MediaStreamTrackKind.Audio;
@@ -15771,9 +15800,10 @@ class MultistreamConnection extends EventEmitter$2 {
15771
15800
  const slidesSceneId = generateSceneId();
15772
15801
  const videoMainEncodingOptions = this.getVideoEncodingOptions(exports.MediaContent.Main);
15773
15802
  const videoSlidesEncodingOptions = this.getVideoEncodingOptions(exports.MediaContent.Slides);
15774
- this.createSendTransceiver(exports.MediaType.VideoMain, mainSceneId, videoMainEncodingOptions);
15803
+ const sendVideoCodecParams = this.getCustomSendVideoCodecParams();
15804
+ this.createSendTransceiver(exports.MediaType.VideoMain, mainSceneId, videoMainEncodingOptions, sendVideoCodecParams);
15775
15805
  this.createSendTransceiver(exports.MediaType.AudioMain, mainSceneId);
15776
- this.createSendTransceiver(exports.MediaType.VideoSlides, slidesSceneId, videoSlidesEncodingOptions);
15806
+ this.createSendTransceiver(exports.MediaType.VideoSlides, slidesSceneId, videoSlidesEncodingOptions, sendVideoCodecParams);
15777
15807
  this.createSendTransceiver(exports.MediaType.AudioSlides, slidesSceneId);
15778
15808
  }
15779
15809
  startWorkerIfNeeded() {
@@ -15851,10 +15881,29 @@ class MultistreamConnection extends EventEmitter$2 {
15851
15881
  ]
15852
15882
  : [{ active: false }];
15853
15883
  }
15854
- createSendTransceiver(mediaType, sceneId, sendEncodingsOptions) {
15884
+ getCustomSendVideoCodecParams() {
15885
+ return {
15886
+ [exports.MediaCodecMimeType.H264]: {
15887
+ 'x-google-start-bitrate': `${this.options.preferredStartingBitrateKbps}`,
15888
+ 'max-mbps': `${defaultMaxVideoEncodeMbps}`,
15889
+ 'max-fs': `${defaultMaxVideoEncodeFrameSize}`,
15890
+ },
15891
+ };
15892
+ }
15893
+ getCustomReceiveVideoCodecParams(mediaType) {
15894
+ return {
15895
+ [exports.MediaCodecMimeType.H264]: {
15896
+ 'sps-pps-idr-in-keyframe': '1',
15897
+ },
15898
+ [exports.MediaCodecMimeType.RTX]: {
15899
+ 'rtx-time': mediaType === exports.MediaType.VideoMain ? defaultVideoMainRtxTime : defaultVideoSlidesRtxTime,
15900
+ },
15901
+ };
15902
+ }
15903
+ createSendTransceiver(mediaType, sceneId, sendEncodingsOptions, codecParams) {
15855
15904
  let rtcRtpTransceiver;
15856
15905
  try {
15857
- rtcRtpTransceiver = this.pc.addTransceiver(toMediaStreamTrackKind(mediaType), {
15906
+ rtcRtpTransceiver = this.pc.addTransceiver(mediaTypeToTrackKind(mediaType), {
15858
15907
  direction: 'sendrecv',
15859
15908
  sendEncodings: sendEncodingsOptions,
15860
15909
  });
@@ -15873,14 +15922,12 @@ class MultistreamConnection extends EventEmitter$2 {
15873
15922
  munger,
15874
15923
  csi,
15875
15924
  });
15876
- let codecParameters = {
15877
- 'x-google-start-bitrate': `${this.options.preferredStartingBitrateKbps}`,
15878
- };
15879
15925
  if (getMediaFamily(mediaType) === exports.MediaFamily.Video) {
15880
15926
  transceiver.rtxEnabled = true;
15881
- codecParameters = Object.assign(Object.assign({}, codecParameters), { 'max-mbps': `${defaultMaxVideoEncodeMbps}`, 'max-fs': `${defaultMaxVideoEncodeFrameSize}` });
15882
15927
  }
15883
- transceiver.setCodecParameters(codecParameters);
15928
+ Object.entries(codecParams !== null && codecParams !== void 0 ? codecParams : {}).forEach(([codec, params]) => {
15929
+ transceiver.setCustomCodecParameters(codec, params);
15930
+ });
15884
15931
  transceiver.twccDisabled =
15885
15932
  getMediaFamily(mediaType) === exports.MediaFamily.Audio ? this.options.disableAudioTwcc : false;
15886
15933
  transceiver.dtxDisabled = mediaType !== exports.MediaType.AudioMain || this.options.disableAudioMainDtx;
@@ -16181,8 +16228,8 @@ SCTP Max Message Size: ${maxMessageSize}`);
16181
16228
  static getEncodedTransformId(mediaType, mid) {
16182
16229
  return `INBOUND-${mediaType}-${mid}`;
16183
16230
  }
16184
- createReceiveTransceiver(mediaType) {
16185
- const rtcRtpTransceiver = this.pc.addTransceiver(toMediaStreamTrackKind(mediaType), {
16231
+ createReceiveTransceiver(mediaType, codecParams) {
16232
+ const rtcRtpTransceiver = this.pc.addTransceiver(mediaTypeToTrackKind(mediaType), {
16186
16233
  direction: 'recvonly',
16187
16234
  });
16188
16235
  const mid = this.midPredictor.getNextMid(mediaType);
@@ -16210,14 +16257,9 @@ SCTP Max Message Size: ${maxMessageSize}`);
16210
16257
  logger.warn(`Failed to setup encoded transform for audio level monitoring of mid=${mid}: ${e}`);
16211
16258
  }
16212
16259
  }
16213
- if (getMediaFamily(mediaType) === exports.MediaFamily.Video) {
16214
- recvOnlyTransceiver.setCodecParameters({
16215
- 'sps-pps-idr-in-keyframe': '1',
16216
- });
16217
- recvOnlyTransceiver.setRtxCodecParameters({
16218
- 'rtx-time': mediaType === exports.MediaType.VideoMain ? defaultVideoMainRtxTime : defaultVideoSlidesRtxTime,
16219
- });
16220
- }
16260
+ Object.entries(codecParams !== null && codecParams !== void 0 ? codecParams : {}).forEach(([codec, params]) => {
16261
+ recvOnlyTransceiver.setCustomCodecParameters(codec, params);
16262
+ });
16221
16263
  recvOnlyTransceiver.twccDisabled =
16222
16264
  getMediaFamily(mediaType) === exports.MediaFamily.Audio ? this.options.disableAudioTwcc : false;
16223
16265
  this.recvTransceivers.set(mediaType, [
@@ -16236,8 +16278,11 @@ SCTP Max Message Size: ${maxMessageSize}`);
16236
16278
  return new Promise((createReceiveSlotsResolve) => {
16237
16279
  this.offerAnswerQueue.push(() => __awaiter(this, void 0, void 0, function* () {
16238
16280
  const createdReceiveOnlyTransceivers = [];
16281
+ const codecParams = mediaTypeToTrackKind(mediaType) === exports.MediaStreamTrackKind.Video
16282
+ ? this.getCustomReceiveVideoCodecParams(mediaType)
16283
+ : undefined;
16239
16284
  for (let i = 0; i < count; i++) {
16240
- const recvOnlyTransceiver = this.createReceiveTransceiver(mediaType);
16285
+ const recvOnlyTransceiver = this.createReceiveTransceiver(mediaType, codecParams);
16241
16286
  createdReceiveOnlyTransceivers.push(recvOnlyTransceiver);
16242
16287
  }
16243
16288
  if (this.pc.getRemoteDescription()) {
@@ -16614,7 +16659,7 @@ SCTP Max Message Size: ${maxMessageSize}`);
16614
16659
  const mediaContent = getMediaContent(mediaType);
16615
16660
  const sceneId = mediaContent === exports.MediaContent.Main ? mainSceneId : slidesSceneId;
16616
16661
  const mid = this.midPredictor.getNextMid(mediaType);
16617
- transceiver.replaceTransceiver(this.pc.addTransceiver(toMediaStreamTrackKind(mediaType), {
16662
+ transceiver.replaceTransceiver(this.pc.addTransceiver(mediaTypeToTrackKind(mediaType), {
16618
16663
  direction: 'sendrecv',
16619
16664
  sendEncodings: getMediaFamily(mediaType) === exports.MediaFamily.Video
16620
16665
  ? this.getVideoEncodingOptions(mediaContent)
@@ -16629,7 +16674,7 @@ SCTP Max Message Size: ${maxMessageSize}`);
16629
16674
  this.recvTransceivers.forEach((transceivers, mediaType) => {
16630
16675
  transceivers.forEach((t) => {
16631
16676
  const mid = this.midPredictor.getNextMid(mediaType);
16632
- const rtcRtpTransceiver = this.pc.addTransceiver(toMediaStreamTrackKind(mediaType), {
16677
+ const rtcRtpTransceiver = this.pc.addTransceiver(mediaTypeToTrackKind(mediaType), {
16633
16678
  direction: 'recvonly',
16634
16679
  });
16635
16680
  t.replaceTransceiver(rtcRtpTransceiver);