@webex/web-client-media-engine 3.36.0 → 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/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) {
@@ -15587,31 +15616,6 @@ const organizeTransceiverStats = (sendTransceivers, recvTransceivers, peerConnec
15587
15616
  return result;
15588
15617
  });
15589
15618
 
15590
- var WorkerClass = null;
15591
-
15592
- try {
15593
- var WorkerThreads =
15594
- typeof module !== 'undefined' && typeof module.require === 'function' && module.require('worker_threads') ||
15595
- typeof __non_webpack_require__ === 'function' && __non_webpack_require__('worker_threads') ||
15596
- typeof require === 'function' && require('worker_threads');
15597
- WorkerClass = WorkerThreads.Worker;
15598
- } catch(e) {} // eslint-disable-line
15599
-
15600
- function decodeBase64$1(base64, enableUnicode) {
15601
- return Buffer.from(base64, 'base64').toString(enableUnicode ? 'utf16' : 'utf8');
15602
- }
15603
-
15604
- function createBase64WorkerFactory$2(base64, sourcemapArg, enableUnicodeArg) {
15605
- var sourcemap = sourcemapArg === undefined ? null : sourcemapArg;
15606
- var enableUnicode = enableUnicodeArg === undefined ? false : enableUnicodeArg;
15607
- var source = decodeBase64$1(base64, enableUnicode);
15608
- var start = source.indexOf('\n', 10) + 1;
15609
- var body = source.substring(start) + (sourcemap ? '\/\/# sourceMappingURL=' + sourcemap : '');
15610
- return function WorkerFactory(options) {
15611
- return new WorkerClass(body, Object.assign({}, options, { eval: true }));
15612
- };
15613
- }
15614
-
15615
15619
  function decodeBase64(base64, enableUnicode) {
15616
15620
  var binaryString = atob(base64);
15617
15621
  if (enableUnicode) {
@@ -15635,7 +15639,7 @@ function createURL(base64, sourcemapArg, enableUnicodeArg) {
15635
15639
  return URL.createObjectURL(blob);
15636
15640
  }
15637
15641
 
15638
- function createBase64WorkerFactory$1(base64, sourcemapArg, enableUnicodeArg) {
15642
+ function createBase64WorkerFactory(base64, sourcemapArg, enableUnicodeArg) {
15639
15643
  var url;
15640
15644
  return function WorkerFactory(options) {
15641
15645
  url = url || createURL(base64, sourcemapArg, enableUnicodeArg);
@@ -15643,19 +15647,6 @@ function createBase64WorkerFactory$1(base64, sourcemapArg, enableUnicodeArg) {
15643
15647
  };
15644
15648
  }
15645
15649
 
15646
- var kIsNodeJS = Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]';
15647
-
15648
- function isNodeJS() {
15649
- return kIsNodeJS;
15650
- }
15651
-
15652
- function createBase64WorkerFactory(base64, sourcemapArg, enableUnicodeArg) {
15653
- if (isNodeJS()) {
15654
- return createBase64WorkerFactory$2(base64, sourcemapArg, enableUnicodeArg);
15655
- }
15656
- return createBase64WorkerFactory$1(base64, sourcemapArg, enableUnicodeArg);
15657
- }
15658
-
15659
15650
  var WorkerFactory = /*#__PURE__*/createBase64WorkerFactory('Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewogICAgJ3VzZSBzdHJpY3QnOwoKICAgIHZhciBjb21tb25qc0dsb2JhbCA9IHR5cGVvZiBnbG9iYWxUaGlzICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbFRoaXMgOiB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdyA6IHR5cGVvZiBnbG9iYWwgIT09ICd1bmRlZmluZWQnID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09ICd1bmRlZmluZWQnID8gc2VsZiA6IHt9OwoKICAgIHZhciBsb2dnZXIgPSB7ZXhwb3J0czoge319OwoKICAgIC8qIQ0KICAgICAqIGpzLWxvZ2dlciAtIGh0dHA6Ly9naXRodWIuY29tL2pvbm55cmVldmVzL2pzLWxvZ2dlcg0KICAgICAqIEpvbm55IFJlZXZlcywgaHR0cDovL2pvbm55cmVldmVzLmNvLnVrLw0KICAgICAqIGpzLWxvZ2dlciBtYXkgYmUgZnJlZWx5IGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS4NCiAgICAgKi8KCiAgICAoZnVuY3Rpb24gKG1vZHVsZSkgewogICAgKGZ1bmN0aW9uIChnbG9iYWwpIHsNCg0KICAgIAkvLyBUb3AgbGV2ZWwgbW9kdWxlIGZvciB0aGUgZ2xvYmFsLCBzdGF0aWMgbG9nZ2VyIGluc3RhbmNlLg0KICAgIAl2YXIgTG9nZ2VyID0geyB9Ow0KDQogICAgCS8vIEZvciB0aG9zZSB0aGF0IGFyZSBhdCBob21lIHRoYXQgYXJlIGtlZXBpbmcgc2NvcmUuDQogICAgCUxvZ2dlci5WRVJTSU9OID0gIjEuNi4xIjsNCg0KICAgIAkvLyBGdW5jdGlvbiB3aGljaCBoYW5kbGVzIGFsbCBpbmNvbWluZyBsb2cgbWVzc2FnZXMuDQogICAgCXZhciBsb2dIYW5kbGVyOw0KDQogICAgCS8vIE1hcCBvZiBDb250ZXh0dWFsTG9nZ2VyIGluc3RhbmNlcyBieSBuYW1lOyB1c2VkIGJ5IExvZ2dlci5nZXQoKSB0byByZXR1cm4gdGhlIHNhbWUgbmFtZWQgaW5zdGFuY2UuDQogICAgCXZhciBjb250ZXh0dWFsTG9nZ2Vyc0J5TmFtZU1hcCA9IHt9Ow0KDQogICAgCS8vIFBvbHlmaWxsIGZvciBFUzUncyBGdW5jdGlvbi5iaW5kLg0KICAgIAl2YXIgYmluZCA9IGZ1bmN0aW9uKHNjb3BlLCBmdW5jKSB7DQogICAgCQlyZXR1cm4gZnVuY3Rpb24oKSB7DQogICAgCQkJcmV0dXJuIGZ1bmMuYXBwbHkoc2NvcGUsIGFyZ3VtZW50cyk7DQogICAgCQl9Ow0KICAgIAl9Ow0KDQogICAgCS8vIFN1cGVyIGV4Y2l0aW5nIG9iamVjdCBtZXJnZXItbWF0cm9uIDkwMDAgYWRkaW5nIGFub3RoZXIgMTAwIGJ5dGVzIHRvIHlvdXIgZG93bmxvYWQuDQogICAgCXZhciBtZXJnZSA9IGZ1bmN0aW9uICgpIHsNCiAgICAJCXZhciBhcmdzID0gYXJndW1lbnRzLCB0YXJnZXQgPSBhcmdzWzBdLCBrZXksIGk7DQogICAgCQlmb3IgKGkgPSAxOyBpIDwgYXJncy5sZW5ndGg7IGkrKykgew0KICAgIAkJCWZvciAoa2V5IGluIGFyZ3NbaV0pIHsNCiAgICAJCQkJaWYgKCEoa2V5IGluIHRhcmdldCkgJiYgYXJnc1tpXS5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7DQogICAgCQkJCQl0YXJnZXRba2V5XSA9IGFyZ3NbaV1ba2V5XTsNCiAgICAJCQkJfQ0KICAgIAkJCX0NCiAgICAJCX0NCiAgICAJCXJldHVybiB0YXJnZXQ7DQogICAgCX07DQoNCiAgICAJLy8gSGVscGVyIHRvIGRlZmluZSBhIGxvZ2dpbmcgbGV2ZWwgb2JqZWN0OyBoZWxwcyB3aXRoIG9wdGltaXNhdGlvbi4NCiAgICAJdmFyIGRlZmluZUxvZ0xldmVsID0gZnVuY3Rpb24odmFsdWUsIG5hbWUpIHsNCiAgICAJCXJldHVybiB7IHZhbHVlOiB2YWx1ZSwgbmFtZTogbmFtZSB9Ow0KICAgIAl9Ow0KDQogICAgCS8vIFByZWRlZmluZWQgbG9nZ2luZyBsZXZlbHMuDQogICAgCUxvZ2dlci5UUkFDRSA9IGRlZmluZUxvZ0xldmVsKDEsICdUUkFDRScpOw0KICAgIAlMb2dnZXIuREVCVUcgPSBkZWZpbmVMb2dMZXZlbCgyLCAnREVCVUcnKTsNCiAgICAJTG9nZ2VyLklORk8gPSBkZWZpbmVMb2dMZXZlbCgzLCAnSU5GTycpOw0KICAgIAlMb2dnZXIuVElNRSA9IGRlZmluZUxvZ0xldmVsKDQsICdUSU1FJyk7DQogICAgCUxvZ2dlci5XQVJOID0gZGVmaW5lTG9nTGV2ZWwoNSwgJ1dBUk4nKTsNCiAgICAJTG9nZ2VyLkVSUk9SID0gZGVmaW5lTG9nTGV2ZWwoOCwgJ0VSUk9SJyk7DQogICAgCUxvZ2dlci5PRkYgPSBkZWZpbmVMb2dMZXZlbCg5OSwgJ09GRicpOw0KDQogICAgCS8vIElubmVyIGNsYXNzIHdoaWNoIHBlcmZvcm1zIHRoZSBidWxrIG9mIHRoZSB3b3JrOyBDb250ZXh0dWFsTG9nZ2VyIGluc3RhbmNlcyBjYW4gYmUgY29uZmlndXJlZCBpbmRlcGVuZGVudGx5DQogICAgCS8vIG9mIGVhY2ggb3RoZXIuDQogICAgCXZhciBDb250ZXh0dWFsTG9nZ2VyID0gZnVuY3Rpb24oZGVmYXVsdENvbnRleHQpIHsNCiAgICAJCXRoaXMuY29udGV4dCA9IGRlZmF1bHRDb250ZXh0Ow0KICAgIAkJdGhpcy5zZXRMZXZlbChkZWZhdWx0Q29udGV4dC5maWx0ZXJMZXZlbCk7DQogICAgCQl0aGlzLmxvZyA9IHRoaXMuaW5mbzsgIC8vIENvbnZlbmllbmNlIGFsaWFzLg0KICAgIAl9Ow0KDQogICAgCUNvbnRleHR1YWxMb2dnZXIucHJvdG90eXBlID0gew0KICAgIAkJLy8gQ2hhbmdlcyB0aGUgY3VycmVudCBsb2dnaW5nIGxldmVsIGZvciB0aGUgbG9nZ2luZyBpbnN0YW5jZS4NCiAgICAJCXNldExldmVsOiBmdW5jdGlvbiAobmV3TGV2ZWwpIHsNCiAgICAJCQkvLyBFbnN1cmUgdGhlIHN1cHBsaWVkIExldmVsIG9iamVjdCBsb29rcyB2YWxpZC4NCiAgICAJCQlpZiAobmV3TGV2ZWwgJiYgInZhbHVlIiBpbiBuZXdMZXZlbCkgew0KICAgIAkJCQl0aGlzLmNvbnRleHQuZmlsdGVyTGV2ZWwgPSBuZXdMZXZlbDsNCiAgICAJCQl9DQogICAgCQl9LA0KICAgIAkJDQogICAgCQkvLyBHZXRzIHRoZSBjdXJyZW50IGxvZ2dpbmcgbGV2ZWwgZm9yIHRoZSBsb2dnaW5nIGluc3RhbmNlDQogICAgCQlnZXRMZXZlbDogZnVuY3Rpb24gKCkgew0KICAgIAkJCXJldHVybiB0aGlzLmNvbnRleHQuZmlsdGVyTGV2ZWw7DQogICAgCQl9LA0KDQogICAgCQkvLyBJcyB0aGUgbG9nZ2VyIGNvbmZpZ3VyZWQgdG8gb3V0cHV0IG1lc3NhZ2VzIGF0IHRoZSBzdXBwbGllZCBsZXZlbD8NCiAgICAJCWVuYWJsZWRGb3I6IGZ1bmN0aW9uIChsdmwpIHsNCiAgICAJCQl2YXIgZmlsdGVyTGV2ZWwgPSB0aGlzLmNvbnRleHQuZmlsdGVyTGV2ZWw7DQogICAgCQkJcmV0dXJuIGx2bC52YWx1ZSA+PSBmaWx0ZXJMZXZlbC52YWx1ZTsNCiAgICAJCX0sDQoNCiAgICAJCXRyYWNlOiBmdW5jdGlvbiAoKSB7DQogICAgCQkJdGhpcy5pbnZva2UoTG9nZ2VyLlRSQUNFLCBhcmd1bWVudHMpOw0KICAgIAkJfSwNCg0KICAgIAkJZGVidWc6IGZ1bmN0aW9uICgpIHsNCiAgICAJCQl0aGlzLmludm9rZShMb2dnZXIuREVCVUcsIGFyZ3VtZW50cyk7DQogICAgCQl9LA0KDQogICAgCQlpbmZvOiBmdW5jdGlvbiAoKSB7DQogICAgCQkJdGhpcy5pbnZva2UoTG9nZ2VyLklORk8sIGFyZ3VtZW50cyk7DQogICAgCQl9LA0KDQogICAgCQl3YXJuOiBmdW5jdGlvbiAoKSB7DQogICAgCQkJdGhpcy5pbnZva2UoTG9nZ2VyLldBUk4sIGFyZ3VtZW50cyk7DQogICAgCQl9LA0KDQogICAgCQllcnJvcjogZnVuY3Rpb24gKCkgew0KICAgIAkJCXRoaXMuaW52b2tlKExvZ2dlci5FUlJPUiwgYXJndW1lbnRzKTsNCiAgICAJCX0sDQoNCiAgICAJCXRpbWU6IGZ1bmN0aW9uIChsYWJlbCkgew0KICAgIAkJCWlmICh0eXBlb2YgbGFiZWwgPT09ICdzdHJpbmcnICYmIGxhYmVsLmxlbmd0aCA+IDApIHsNCiAgICAJCQkJdGhpcy5pbnZva2UoTG9nZ2VyLlRJTUUsIFsgbGFiZWwsICdzdGFydCcgXSk7DQogICAgCQkJfQ0KICAgIAkJfSwNCg0KICAgIAkJdGltZUVuZDogZnVuY3Rpb24gKGxhYmVsKSB7DQogICAgCQkJaWYgKHR5cGVvZiBsYWJlbCA9PT0gJ3N0cmluZycgJiYgbGFiZWwubGVuZ3RoID4gMCkgew0KICAgIAkJCQl0aGlzLmludm9rZShMb2dnZXIuVElNRSwgWyBsYWJlbCwgJ2VuZCcgXSk7DQogICAgCQkJfQ0KICAgIAkJfSwNCg0KICAgIAkJLy8gSW52b2tlcyB0aGUgbG9nZ2VyIGNhbGxiYWNrIGlmIGl0J3Mgbm90IGJlaW5nIGZpbHRlcmVkLg0KICAgIAkJaW52b2tlOiBmdW5jdGlvbiAobGV2ZWwsIG1zZ0FyZ3MpIHsNCiAgICAJCQlpZiAobG9nSGFuZGxlciAmJiB0aGlzLmVuYWJsZWRGb3IobGV2ZWwpKSB7DQogICAgCQkJCWxvZ0hhbmRsZXIobXNnQXJncywgbWVyZ2UoeyBsZXZlbDogbGV2ZWwgfSwgdGhpcy5jb250ZXh0KSk7DQogICAgCQkJfQ0KICAgIAkJfQ0KICAgIAl9Ow0KDQogICAgCS8vIFByb3RlY3RlZCBpbnN0YW5jZSB3aGljaCBhbGwgY2FsbHMgdG8gdGhlIHRvIGxldmVsIGBMb2dnZXJgIG1vZHVsZSB3aWxsIGJlIHJvdXRlZCB0aHJvdWdoLg0KICAgIAl2YXIgZ2xvYmFsTG9nZ2VyID0gbmV3IENvbnRleHR1YWxMb2dnZXIoeyBmaWx0ZXJMZXZlbDogTG9nZ2VyLk9GRiB9KTsNCg0KICAgIAkvLyBDb25maWd1cmUgdGhlIGdsb2JhbCBMb2dnZXIgaW5zdGFuY2UuDQogICAgCShmdW5jdGlvbigpIHsNCiAgICAJCS8vIFNob3J0Y3V0IGZvciBvcHRpbWlzZXJzLg0KICAgIAkJdmFyIEwgPSBMb2dnZXI7DQoNCiAgICAJCUwuZW5hYmxlZEZvciA9IGJpbmQoZ2xvYmFsTG9nZ2VyLCBnbG9iYWxMb2dnZXIuZW5hYmxlZEZvcik7DQogICAgCQlMLnRyYWNlID0gYmluZChnbG9iYWxMb2dnZXIsIGdsb2JhbExvZ2dlci50cmFjZSk7DQogICAgCQlMLmRlYnVnID0gYmluZChnbG9iYWxMb2dnZXIsIGdsb2JhbExvZ2dlci5kZWJ1Zyk7DQogICAgCQlMLnRpbWUgPSBiaW5kKGdsb2JhbExvZ2dlciwgZ2xvYmFsTG9nZ2VyLnRpbWUpOw0KICAgIAkJTC50aW1lRW5kID0gYmluZChnbG9iYWxMb2dnZXIsIGdsb2JhbExvZ2dlci50aW1lRW5kKTsNCiAgICAJCUwuaW5mbyA9IGJpbmQoZ2xvYmFsTG9nZ2VyLCBnbG9iYWxMb2dnZXIuaW5mbyk7DQogICAgCQlMLndhcm4gPSBiaW5kKGdsb2JhbExvZ2dlciwgZ2xvYmFsTG9nZ2VyLndhcm4pOw0KICAgIAkJTC5lcnJvciA9IGJpbmQoZ2xvYmFsTG9nZ2VyLCBnbG9iYWxMb2dnZXIuZXJyb3IpOw0KDQogICAgCQkvLyBEb24ndCBmb3JnZXQgdGhlIGNvbnZlbmllbmNlIGFsaWFzIQ0KICAgIAkJTC5sb2cgPSBMLmluZm87DQogICAgCX0oKSk7DQoNCiAgICAJLy8gU2V0IHRoZSBnbG9iYWwgbG9nZ2luZyBoYW5kbGVyLiAgVGhlIHN1cHBsaWVkIGZ1bmN0aW9uIHNob3VsZCBleHBlY3QgdHdvIGFyZ3VtZW50cywgdGhlIGZpcnN0IGJlaW5nIGFuIGFyZ3VtZW50cw0KICAgIAkvLyBvYmplY3Qgd2l0aCB0aGUgc3VwcGxpZWQgbG9nIG1lc3NhZ2VzIGFuZCB0aGUgc2Vjb25kIGJlaW5nIGEgY29udGV4dCBvYmplY3Qgd2hpY2ggY29udGFpbnMgYSBoYXNoIG9mIHN0YXRlZnVsDQogICAgCS8vIHBhcmFtZXRlcnMgd2hpY2ggdGhlIGxvZ2dpbmcgZnVuY3Rpb24gY2FuIGNvbnN1bWUuDQogICAgCUxvZ2dlci5zZXRIYW5kbGVyID0gZnVuY3Rpb24gKGZ1bmMpIHsNCiAgICAJCWxvZ0hhbmRsZXIgPSBmdW5jOw0KICAgIAl9Ow0KDQogICAgCS8vIFNldHMgdGhlIGdsb2JhbCBsb2dnaW5nIGZpbHRlciBsZXZlbCB3aGljaCBhcHBsaWVzIHRvICphbGwqIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCwgYW5kIGZ1dHVyZSBMb2dnZXIgaW5zdGFuY2VzLg0KICAgIAkvLyAobm90ZSB0aGF0IG5hbWVkIGxvZ2dlcnMgKHJldHJpZXZlZCB2aWEgYExvZ2dlci5nZXRgKSBjYW4gYmUgY29uZmlndXJlZCBpbmRlcGVuZGVudGx5IGlmIHJlcXVpcmVkKS4NCiAgICAJTG9nZ2VyLnNldExldmVsID0gZnVuY3Rpb24obGV2ZWwpIHsNCiAgICAJCS8vIFNldCB0aGUgZ2xvYmFsTG9nZ2VyJ3MgbGV2ZWwuDQogICAgCQlnbG9iYWxMb2dnZXIuc2V0TGV2ZWwobGV2ZWwpOw0KDQogICAgCQkvLyBBcHBseSB0aGlzIGxldmVsIHRvIGFsbCByZWdpc3RlcmVkIGNvbnRleHR1YWwgbG9nZ2Vycy4NCiAgICAJCWZvciAodmFyIGtleSBpbiBjb250ZXh0dWFsTG9nZ2Vyc0J5TmFtZU1hcCkgew0KICAgIAkJCWlmIChjb250ZXh0dWFsTG9nZ2Vyc0J5TmFtZU1hcC5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7DQogICAgCQkJCWNvbnRleHR1YWxMb2dnZXJzQnlOYW1lTWFwW2tleV0uc2V0TGV2ZWwobGV2ZWwpOw0KICAgIAkJCX0NCiAgICAJCX0NCiAgICAJfTsNCg0KICAgIAkvLyBHZXRzIHRoZSBnbG9iYWwgbG9nZ2luZyBmaWx0ZXIgbGV2ZWwNCiAgICAJTG9nZ2VyLmdldExldmVsID0gZnVuY3Rpb24oKSB7DQogICAgCQlyZXR1cm4gZ2xvYmFsTG9nZ2VyLmdldExldmVsKCk7DQogICAgCX07DQoNCiAgICAJLy8gUmV0cmlldmUgYSBDb250ZXh0dWFsTG9nZ2VyIGluc3RhbmNlLiAgTm90ZSB0aGF0IG5hbWVkIGxvZ2dlcnMgYXV0b21hdGljYWxseSBpbmhlcml0IHRoZSBnbG9iYWwgbG9nZ2VyJ3MgbGV2ZWwsDQogICAgCS8vIGRlZmF1bHQgY29udGV4dCBhbmQgbG9nIGhhbmRsZXIuDQogICAgCUxvZ2dlci5nZXQgPSBmdW5jdGlvbiAobmFtZSkgew0KICAgIAkJLy8gQWxsIGxvZ2dlciBpbnN0YW5jZXMgYXJlIGNhY2hlZCBzbyB0aGV5IGNhbiBiZSBjb25maWd1cmVkIGFoZWFkIG9mIHVzZS4NCiAgICAJCXJldHVybiBjb250ZXh0dWFsTG9nZ2Vyc0J5TmFtZU1hcFtuYW1lXSB8fA0KICAgIAkJCShjb250ZXh0dWFsTG9nZ2Vyc0J5TmFtZU1hcFtuYW1lXSA9IG5ldyBDb250ZXh0dWFsTG9nZ2VyKG1lcmdlKHsgbmFtZTogbmFtZSB9LCBnbG9iYWxMb2dnZXIuY29udGV4dCkpKTsNCiAgICAJfTsNCg0KICAgIAkvLyBDcmVhdGVEZWZhdWx0SGFuZGxlciByZXR1cm5zIGEgaGFuZGxlciBmdW5jdGlvbiB3aGljaCBjYW4gYmUgcGFzc2VkIHRvIGBMb2dnZXIuc2V0SGFuZGxlcigpYCB3aGljaCB3aWxsDQogICAgCS8vIHdyaXRlIHRvIHRoZSB3aW5kb3cncyBjb25zb2xlIG9iamVjdCAoaWYgcHJlc2VudCk7IHRoZSBvcHRpb25hbCBvcHRpb25zIG9iamVjdCBjYW4gYmUgdXNlZCB0byBjdXN0b21pc2UgdGhlDQogICAgCS8vIGZvcm1hdHRlciB1c2VkIHRvIGZvcm1hdCBlYWNoIGxvZyBtZXNzYWdlLg0KICAgIAlMb2dnZXIuY3JlYXRlRGVmYXVsdEhhbmRsZXIgPSBmdW5jdGlvbiAob3B0aW9ucykgew0KICAgIAkJb3B0aW9ucyA9IG9wdGlvbnMgfHwge307DQoNCiAgICAJCW9wdGlvbnMuZm9ybWF0dGVyID0gb3B0aW9ucy5mb3JtYXR0ZXIgfHwgZnVuY3Rpb24gZGVmYXVsdE1lc3NhZ2VGb3JtYXR0ZXIobWVzc2FnZXMsIGNvbnRleHQpIHsNCiAgICAJCQkvLyBQcmVwZW5kIHRoZSBsb2dnZXIncyBuYW1lIHRvIHRoZSBsb2cgbWVzc2FnZSBmb3IgZWFzeSBpZGVudGlmaWNhdGlvbi4NCiAgICAJCQlpZiAoY29udGV4dC5uYW1lKSB7DQogICAgCQkJCW1lc3NhZ2VzLnVuc2hpZnQoIlsiICsgY29udGV4dC5uYW1lICsgIl0iKTsNCiAgICAJCQl9DQogICAgCQl9Ow0KDQogICAgCQkvLyBNYXAgb2YgdGltZXN0YW1wcyBieSB0aW1lciBsYWJlbHMgdXNlZCB0byB0cmFjayBgI3RpbWVgIGFuZCBgI3RpbWVFbmQoKWAgaW52b2NhdGlvbnMgaW4gZW52aXJvbm1lbnRzDQogICAgCQkvLyB0aGF0IGRvbid0IG9mZmVyIGEgbmF0aXZlIGNvbnNvbGUgbWV0aG9kLg0KICAgIAkJdmFyIHRpbWVyU3RhcnRUaW1lQnlMYWJlbE1hcCA9IHt9Ow0KDQogICAgCQkvLyBTdXBwb3J0IGZvciBJRTgrIChhbmQgb3RoZXIsIHNsaWdodGx5IG1vcmUgc2FuZSBlbnZpcm9ubWVudHMpDQogICAgCQl2YXIgaW52b2tlQ29uc29sZU1ldGhvZCA9IGZ1bmN0aW9uIChoZGxyLCBtZXNzYWdlcykgew0KICAgIAkJCUZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseS5jYWxsKGhkbHIsIGNvbnNvbGUsIG1lc3NhZ2VzKTsNCiAgICAJCX07DQoNCiAgICAJCS8vIENoZWNrIGZvciB0aGUgcHJlc2VuY2Ugb2YgYSBsb2dnZXIuDQogICAgCQlpZiAodHlwZW9mIGNvbnNvbGUgPT09ICJ1bmRlZmluZWQiKSB7DQogICAgCQkJcmV0dXJuIGZ1bmN0aW9uICgpIHsgLyogbm8gY29uc29sZSAqLyB9Ow0KICAgIAkJfQ0KDQogICAgCQlyZXR1cm4gZnVuY3Rpb24obWVzc2FnZXMsIGNvbnRleHQpIHsNCiAgICAJCQkvLyBDb252ZXJ0IGFyZ3VtZW50cyBvYmplY3QgdG8gQXJyYXkuDQogICAgCQkJbWVzc2FnZXMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChtZXNzYWdlcyk7DQoNCiAgICAJCQl2YXIgaGRsciA9IGNvbnNvbGUubG9nOw0KICAgIAkJCXZhciB0aW1lckxhYmVsOw0KDQogICAgCQkJaWYgKGNvbnRleHQubGV2ZWwgPT09IExvZ2dlci5USU1FKSB7DQogICAgCQkJCXRpbWVyTGFiZWwgPSAoY29udGV4dC5uYW1lID8gJ1snICsgY29udGV4dC5uYW1lICsgJ10gJyA6ICcnKSArIG1lc3NhZ2VzWzBdOw0KDQogICAgCQkJCWlmIChtZXNzYWdlc1sxXSA9PT0gJ3N0YXJ0Jykgew0KICAgIAkJCQkJaWYgKGNvbnNvbGUudGltZSkgew0KICAgIAkJCQkJCWNvbnNvbGUudGltZSh0aW1lckxhYmVsKTsNCiAgICAJCQkJCX0NCiAgICAJCQkJCWVsc2Ugew0KICAgIAkJCQkJCXRpbWVyU3RhcnRUaW1lQnlMYWJlbE1hcFt0aW1lckxhYmVsXSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpOw0KICAgIAkJCQkJfQ0KICAgIAkJCQl9DQogICAgCQkJCWVsc2Ugew0KICAgIAkJCQkJaWYgKGNvbnNvbGUudGltZUVuZCkgew0KICAgIAkJCQkJCWNvbnNvbGUudGltZUVuZCh0aW1lckxhYmVsKTsNCiAgICAJCQkJCX0NCiAgICAJCQkJCWVsc2Ugew0KICAgIAkJCQkJCWludm9rZUNvbnNvbGVNZXRob2QoaGRsciwgWyB0aW1lckxhYmVsICsgJzogJyArDQogICAgCQkJCQkJCShuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHRpbWVyU3RhcnRUaW1lQnlMYWJlbE1hcFt0aW1lckxhYmVsXSkgKyAnbXMnIF0pOw0KICAgIAkJCQkJfQ0KICAgIAkJCQl9DQogICAgCQkJfQ0KICAgIAkJCWVsc2Ugew0KICAgIAkJCQkvLyBEZWxlZ2F0ZSB0aHJvdWdoIHRvIGN1c3RvbSB3YXJuL2Vycm9yIGxvZ2dlcnMgaWYgcHJlc2VudCBvbiB0aGUgY29uc29sZS4NCiAgICAJCQkJaWYgKGNvbnRleHQubGV2ZWwgPT09IExvZ2dlci5XQVJOICYmIGNvbnNvbGUud2Fybikgew0KICAgIAkJCQkJaGRsciA9IGNvbnNvbGUud2FybjsNCiAgICAJCQkJfSBlbHNlIGlmIChjb250ZXh0LmxldmVsID09PSBMb2dnZXIuRVJST1IgJiYgY29uc29sZS5lcnJvcikgew0KICAgIAkJCQkJaGRsciA9IGNvbnNvbGUuZXJyb3I7DQogICAgCQkJCX0gZWxzZSBpZiAoY29udGV4dC5sZXZlbCA9PT0gTG9nZ2VyLklORk8gJiYgY29uc29sZS5pbmZvKSB7DQogICAgCQkJCQloZGxyID0gY29uc29sZS5pbmZvOw0KICAgIAkJCQl9IGVsc2UgaWYgKGNvbnRleHQubGV2ZWwgPT09IExvZ2dlci5ERUJVRyAmJiBjb25zb2xlLmRlYnVnKSB7DQogICAgCQkJCQloZGxyID0gY29uc29sZS5kZWJ1ZzsNCiAgICAJCQkJfSBlbHNlIGlmIChjb250ZXh0LmxldmVsID09PSBMb2dnZXIuVFJBQ0UgJiYgY29uc29sZS50cmFjZSkgew0KICAgIAkJCQkJaGRsciA9IGNvbnNvbGUudHJhY2U7DQogICAgCQkJCX0NCg0KICAgIAkJCQlvcHRpb25zLmZvcm1hdHRlcihtZXNzYWdlcywgY29udGV4dCk7DQogICAgCQkJCWludm9rZUNvbnNvbGVNZXRob2QoaGRsciwgbWVzc2FnZXMpOw0KICAgIAkJCX0NCiAgICAJCX07DQogICAgCX07DQoNCiAgICAJLy8gQ29uZmlndXJlIGFuZCBleGFtcGxlIGEgRGVmYXVsdCBpbXBsZW1lbnRhdGlvbiB3aGljaCB3cml0ZXMgdG8gdGhlIGB3aW5kb3cuY29uc29sZWAgKGlmIHByZXNlbnQpLiAgVGhlDQogICAgCS8vIGBvcHRpb25zYCBoYXNoIGNhbiBiZSB1c2VkIHRvIGNvbmZpZ3VyZSB0aGUgZGVmYXVsdCBsb2dMZXZlbCBhbmQgcHJvdmlkZSBhIGN1c3RvbSBtZXNzYWdlIGZvcm1hdHRlci4NCiAgICAJTG9nZ2VyLnVzZURlZmF1bHRzID0gZnVuY3Rpb24ob3B0aW9ucykgew0KICAgIAkJTG9nZ2VyLnNldExldmVsKG9wdGlvbnMgJiYgb3B0aW9ucy5kZWZhdWx0TGV2ZWwgfHwgTG9nZ2VyLkRFQlVHKTsNCiAgICAJCUxvZ2dlci5zZXRIYW5kbGVyKExvZ2dlci5jcmVhdGVEZWZhdWx0SGFuZGxlcihvcHRpb25zKSk7DQogICAgCX07DQoNCiAgICAJLy8gQ3JlYXRlYSBhbiBhbGlhcyB0byB1c2VEZWZhdWx0cyB0byBhdm9pZCByZWFraW5nIGEgcmVhY3QtaG9va3MgcnVsZS4NCiAgICAJTG9nZ2VyLnNldERlZmF1bHRzID0gTG9nZ2VyLnVzZURlZmF1bHRzOw0KDQogICAgCS8vIEV4cG9ydCB0byBwb3B1bGFyIGVudmlyb25tZW50cyBib2lsZXJwbGF0ZS4NCiAgICAJaWYgKG1vZHVsZS5leHBvcnRzKSB7DQogICAgCQltb2R1bGUuZXhwb3J0cyA9IExvZ2dlcjsNCiAgICAJfQ0KICAgIAllbHNlIHsNCiAgICAJCUxvZ2dlci5fcHJldkxvZ2dlciA9IGdsb2JhbC5Mb2dnZXI7DQoNCiAgICAJCUxvZ2dlci5ub0NvbmZsaWN0ID0gZnVuY3Rpb24gKCkgew0KICAgIAkJCWdsb2JhbC5Mb2dnZXIgPSBMb2dnZXIuX3ByZXZMb2dnZXI7DQogICAgCQkJcmV0dXJuIExvZ2dlcjsNCiAgICAJCX07DQoNCiAgICAJCWdsb2JhbC5Mb2dnZXIgPSBMb2dnZXI7DQogICAgCX0NCiAgICB9KGNvbW1vbmpzR2xvYmFsKSk7CiAgICB9KGxvZ2dlcikpOwoKICAgIHZhciBMb2dnZXIgPSBsb2dnZXIuZXhwb3J0czsKCiAgICBMb2dnZXIudXNlRGVmYXVsdHMoew0KICAgICAgICBkZWZhdWx0TGV2ZWw6IExvZ2dlci5ERUJVRywNCiAgICAgICAgZm9ybWF0dGVyOiAobWVzc2FnZXMsIGNvbnRleHQpID0+IHsNCiAgICAgICAgICAgIG1lc3NhZ2VzLnVuc2hpZnQoYFske2NvbnRleHQubmFtZX1dIGApOw0KICAgICAgICB9LA0KICAgIH0pOwoKICAgIHZhciBNZWRpYUZhbWlseTsNCiAgICAoZnVuY3Rpb24gKE1lZGlhRmFtaWx5KSB7DQogICAgICAgIE1lZGlhRmFtaWx5WyJBdWRpbyJdID0gIkFVRElPIjsNCiAgICAgICAgTWVkaWFGYW1pbHlbIlZpZGVvIl0gPSAiVklERU8iOw0KICAgIH0pKE1lZGlhRmFtaWx5IHx8IChNZWRpYUZhbWlseSA9IHt9KSk7DQogICAgdmFyIE1lZGlhQ29udGVudDsNCiAgICAoZnVuY3Rpb24gKE1lZGlhQ29udGVudCkgew0KICAgICAgICBNZWRpYUNvbnRlbnRbIk1haW4iXSA9ICJNQUlOIjsNCiAgICAgICAgTWVkaWFDb250ZW50WyJTbGlkZXMiXSA9ICJTTElERVMiOw0KICAgIH0pKE1lZGlhQ29udGVudCB8fCAoTWVkaWFDb250ZW50ID0ge30pKTsNCiAgICB2YXIgUG9saWN5Ow0KICAgIChmdW5jdGlvbiAoUG9saWN5KSB7DQogICAgICAgIFBvbGljeVsiQWN0aXZlU3BlYWtlciJdID0gImFjdGl2ZS1zcGVha2VyIjsNCiAgICAgICAgUG9saWN5WyJSZWNlaXZlclNlbGVjdGVkIl0gPSAicmVjZWl2ZXItc2VsZWN0ZWQiOw0KICAgIH0pKFBvbGljeSB8fCAoUG9saWN5ID0ge30pKTsNCiAgICB2YXIgTWVkaWFUeXBlOw0KICAgIChmdW5jdGlvbiAoTWVkaWFUeXBlKSB7DQogICAgICAgIE1lZGlhVHlwZVsiVmlkZW9NYWluIl0gPSAiVklERU8tTUFJTiI7DQogICAgICAgIE1lZGlhVHlwZVsiVmlkZW9TbGlkZXMiXSA9ICJWSURFTy1TTElERVMiOw0KICAgICAgICBNZWRpYVR5cGVbIkF1ZGlvTWFpbiJdID0gIkFVRElPLU1BSU4iOw0KICAgICAgICBNZWRpYVR5cGVbIkF1ZGlvU2xpZGVzIl0gPSAiQVVESU8tU0xJREVTIjsNCiAgICB9KShNZWRpYVR5cGUgfHwgKE1lZGlhVHlwZSA9IHt9KSk7CgogICAgdmFyIEptcE1zZ1R5cGU7DQogICAgKGZ1bmN0aW9uIChKbXBNc2dUeXBlKSB7DQogICAgICAgIEptcE1zZ1R5cGVbIk1lZGlhUmVxdWVzdCJdID0gIm1lZGlhUmVxdWVzdCI7DQogICAgICAgIEptcE1zZ1R5cGVbIk1lZGlhUmVxdWVzdEFjayJdID0gIm1lZGlhUmVxdWVzdEFjayI7DQogICAgICAgIEptcE1zZ1R5cGVbIk1lZGlhUmVxdWVzdFN0YXR1cyJdID0gIm1lZGlhUmVxdWVzdFN0YXR1cyI7DQogICAgICAgIEptcE1zZ1R5cGVbIk1lZGlhUmVxdWVzdFN0YXR1c0FjayJdID0gIm1lZGlhUmVxdWVzdFN0YXR1c0FjayI7DQogICAgICAgIEptcE1zZ1R5cGVbIlNvdXJjZUFkdmVydGlzZW1lbnQiXSA9ICJzb3VyY2VBZHZlcnRpc2VtZW50IjsNCiAgICAgICAgSm1wTXNnVHlwZVsiU291cmNlQWR2ZXJ0aXNlbWVudEFjayJdID0gInNvdXJjZUFkdmVydGlzZW1lbnRBY2siOw0KICAgICAgICBKbXBNc2dUeXBlWyJBY3RpdmVTcGVha2VyTm90aWZpY2F0aW9uIl0gPSAiYWN0aXZlU3BlYWtlck5vdGlmaWNhdGlvbiI7DQogICAgfSkoSm1wTXNnVHlwZSB8fCAoSm1wTXNnVHlwZSA9IHt9KSk7DQoKICAgIHZhciBKbXBTZXNzaW9uRXZlbnRzOw0KICAgIChmdW5jdGlvbiAoSm1wU2Vzc2lvbkV2ZW50cykgew0KICAgICAgICBKbXBTZXNzaW9uRXZlbnRzWyJBY3RpdmVTcGVha2VyIl0gPSAiYWN0aXZlLXNwZWFrZXIiOw0KICAgICAgICBKbXBTZXNzaW9uRXZlbnRzWyJNZWRpYVJlcXVlc3RSZWNlaXZlZCJdID0gIm1lZGlhLXJlcXVlc3QtcmVjZWl2ZWQiOw0KICAgICAgICBKbXBTZXNzaW9uRXZlbnRzWyJNZWRpYVJlcXVlc3RTdGF0dXNSZWNlaXZlZCJdID0gIm1lZGlhLXJlcXVlc3Qtc3RhdHVzLXJlY2VpdmVkIjsNCiAgICAgICAgSm1wU2Vzc2lvbkV2ZW50c1siU291cmNlQWR2ZXJ0aXNlbWVudFJlY2VpdmVkIl0gPSAic291cmNlLWFkdmVydGlzZW1lbnQtcmVjZWl2ZWQiOw0KICAgIH0pKEptcFNlc3Npb25FdmVudHMgfHwgKEptcFNlc3Npb25FdmVudHMgPSB7fSkpOwoKICAgIHZhciBFbmNvZGVkVHJhbnNmb3JtVHlwZTsNCiAgICAoZnVuY3Rpb24gKEVuY29kZWRUcmFuc2Zvcm1UeXBlKSB7DQogICAgICAgIEVuY29kZWRUcmFuc2Zvcm1UeXBlWyJBdWRpb0xldmVsTW9uaXRvciJdID0gImF1ZGlvLWxldmVsLW1vbml0b3IiOw0KICAgIH0pKEVuY29kZWRUcmFuc2Zvcm1UeXBlIHx8IChFbmNvZGVkVHJhbnNmb3JtVHlwZSA9IHt9KSk7DQogICAgdmFyIE1haW5Nc2dUeXBlOw0KICAgIChmdW5jdGlvbiAoTWFpbk1zZ1R5cGUpIHsNCiAgICAgICAgTWFpbk1zZ1R5cGVbIkdldE1ldGFkYXRhIl0gPSAiZ2V0LW1ldGFkYXRhIjsNCiAgICAgICAgTWFpbk1zZ1R5cGVbIkNsZWFyTWV0YWRhdGEiXSA9ICJjbGVhci1tZXRhZGF0YSI7DQogICAgfSkoTWFpbk1zZ1R5cGUgfHwgKE1haW5Nc2dUeXBlID0ge30pKTsNCiAgICB2YXIgV29ya2VyTXNnVHlwZTsNCiAgICAoZnVuY3Rpb24gKFdvcmtlck1zZ1R5cGUpIHsNCiAgICAgICAgV29ya2VyTXNnVHlwZVsiUmVzcG9uc2UiXSA9ICJyZXNwb25zZSI7DQogICAgICAgIFdvcmtlck1zZ1R5cGVbIkxvZyJdID0gImxvZyI7DQogICAgfSkoV29ya2VyTXNnVHlwZSB8fCAoV29ya2VyTXNnVHlwZSA9IHt9KSk7CgogICAgY29uc3Qgd29ya2VyTG9nZ2VyID0gew0KICAgICAgICBpbmZvOiAoLi4uYXJncykgPT4gew0KICAgICAgICAgICAgcG9zdE1lc3NhZ2UoeyB0eXBlOiBXb3JrZXJNc2dUeXBlLkxvZywgbGV2ZWw6ICdpbmZvJywgbWVzc2FnZUFyZ3M6IGFyZ3MgfSk7DQogICAgICAgIH0sDQogICAgICAgIHdhcm46ICguLi5hcmdzKSA9PiB7DQogICAgICAgICAgICBwb3N0TWVzc2FnZSh7IHR5cGU6IFdvcmtlck1zZ1R5cGUuTG9nLCBsZXZlbDogJ3dhcm4nLCBtZXNzYWdlQXJnczogYXJncyB9KTsNCiAgICAgICAgfSwNCiAgICAgICAgZXJyb3I6ICguLi5hcmdzKSA9PiB7DQogICAgICAgICAgICBwb3N0TWVzc2FnZSh7IHR5cGU6IFdvcmtlck1zZ1R5cGUuTG9nLCBsZXZlbDogJ2Vycm9yJywgbWVzc2FnZUFyZ3M6IGFyZ3MgfSk7DQogICAgICAgIH0sDQogICAgfTsNCiAgICBjb25zdCBjb2xsZWN0ZWRNZXRhZGF0YSA9IHt9Ow0KICAgIGNvbnN0IGNyZWF0ZUF1ZGlvTGV2ZWxNb25pdG9yVHJhbnNmb3JtID0gKG11bHRpc3RyZWFtQ29ubmVjdGlvbklkLCBlbmNvZGVkVHJhbnNmb3JtSWQpID0+IHsNCiAgICAgICAgaWYgKCEobXVsdGlzdHJlYW1Db25uZWN0aW9uSWQgaW4gY29sbGVjdGVkTWV0YWRhdGEpKSB7DQogICAgICAgICAgICBjb2xsZWN0ZWRNZXRhZGF0YVttdWx0aXN0cmVhbUNvbm5lY3Rpb25JZF0gPSB7DQogICAgICAgICAgICAgICAgW01lZGlhVHlwZS5BdWRpb01haW5dOiB7fSwNCiAgICAgICAgICAgICAgICBbTWVkaWFUeXBlLkF1ZGlvU2xpZGVzXToge30sDQogICAgICAgICAgICAgICAgW01lZGlhVHlwZS5WaWRlb01haW5dOiB7fSwNCiAgICAgICAgICAgICAgICBbTWVkaWFUeXBlLlZpZGVvU2xpZGVzXToge30sDQogICAgICAgICAgICB9Ow0KICAgICAgICB9DQogICAgICAgIGNvbGxlY3RlZE1ldGFkYXRhW211bHRpc3RyZWFtQ29ubmVjdGlvbklkXVtNZWRpYVR5cGUuQXVkaW9NYWluXVtlbmNvZGVkVHJhbnNmb3JtSWRdID0gew0KICAgICAgICAgICAgbWF4QXVkaW9MZXZlbDogdW5kZWZpbmVkLA0KICAgICAgICB9Ow0KICAgICAgICBjb25zdCBjb2xsZWN0ZWRTdHJlYW1NZXRhZGF0YSA9IGNvbGxlY3RlZE1ldGFkYXRhW211bHRpc3RyZWFtQ29ubmVjdGlvbklkXVtNZWRpYVR5cGUuQXVkaW9NYWluXVtlbmNvZGVkVHJhbnNmb3JtSWRdOw0KICAgICAgICB3b3JrZXJMb2dnZXIuaW5mbyhgY3JlYXRpbmcgZW5jb2RlZCB0cmFuc2Zvcm0gZm9yICR7bXVsdGlzdHJlYW1Db25uZWN0aW9uSWR9OiR7ZW5jb2RlZFRyYW5zZm9ybUlkfWApOw0KICAgICAgICByZXR1cm4gbmV3IFRyYW5zZm9ybVN0cmVhbSh7DQogICAgICAgICAgICB0cmFuc2Zvcm06IChlbmNvZGVkRnJhbWUsIGNvbnRyb2xsZXIpID0+IHsNCiAgICAgICAgICAgICAgICBjb25zdCBtZXRhZGF0YSA9IGVuY29kZWRGcmFtZS5nZXRNZXRhZGF0YSgpOw0KICAgICAgICAgICAgICAgIGlmICghY29sbGVjdGVkU3RyZWFtTWV0YWRhdGEubWF4QXVkaW9MZXZlbCB8fA0KICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YS5hdWRpb0xldmVsID4gY29sbGVjdGVkU3RyZWFtTWV0YWRhdGEubWF4QXVkaW9MZXZlbCkgew0KICAgICAgICAgICAgICAgICAgICBjb2xsZWN0ZWRTdHJlYW1NZXRhZGF0YS5tYXhBdWRpb0xldmVsID0gbWV0YWRhdGEuYXVkaW9MZXZlbDsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKGVuY29kZWRGcmFtZSk7DQogICAgICAgICAgICB9LA0KICAgICAgICB9KTsNCiAgICB9Ow0KICAgIGFkZEV2ZW50TGlzdGVuZXIoJ3J0Y3RyYW5zZm9ybScsIChldmVudCkgPT4gew0KICAgICAgICBsZXQgdHJhbnNmb3JtOw0KICAgICAgICBpZiAoIWV2ZW50LnRyYW5zZm9ybWVyLm9wdGlvbnMgfHwgIWV2ZW50LnRyYW5zZm9ybWVyLm9wdGlvbnMudHlwZSkgew0KICAgICAgICAgICAgd29ya2VyTG9nZ2VyLndhcm4oJ21pc3Npbmcgb3IgaW52YWxpZCB0cmFuc2Zvcm1lciBvcHRpb25zPScsIGV2ZW50LnRyYW5zZm9ybWVyLm9wdGlvbnMpOw0KICAgICAgICAgICAgcmV0dXJuOw0KICAgICAgICB9DQogICAgICAgIGNvbnN0IG9wdGlvbnMgPSBldmVudC50cmFuc2Zvcm1lci5vcHRpb25zOw0KICAgICAgICBjb25zdCB7IGVuY29kZWRUcmFuc2Zvcm1JZCwgbXVsdGlzdHJlYW1Db25uZWN0aW9uSWQsIHR5cGUgfSA9IG9wdGlvbnM7DQogICAgICAgIHN3aXRjaCAodHlwZSkgew0KICAgICAgICAgICAgY2FzZSBFbmNvZGVkVHJhbnNmb3JtVHlwZS5BdWRpb0xldmVsTW9uaXRvcjoNCiAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSBjcmVhdGVBdWRpb0xldmVsTW9uaXRvclRyYW5zZm9ybShtdWx0aXN0cmVhbUNvbm5lY3Rpb25JZCwgZW5jb2RlZFRyYW5zZm9ybUlkKTsNCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIGRlZmF1bHQ6DQogICAgICAgICAgICAgICAgd29ya2VyTG9nZ2VyLndhcm4oJ3VuZXhwZWN0ZWQgdHJhbnNmb3JtZXIgdHlwZT0nLCB0eXBlKTsNCiAgICAgICAgfQ0KICAgICAgICBpZiAodHJhbnNmb3JtKSB7DQogICAgICAgICAgICBldmVudC50cmFuc2Zvcm1lci5yZWFkYWJsZS5waXBlVGhyb3VnaCh0cmFuc2Zvcm0pLnBpcGVUbyhldmVudC50cmFuc2Zvcm1lci53cml0YWJsZSk7DQogICAgICAgIH0NCiAgICB9KTsNCiAgICBhZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgKGV2ZW50KSA9PiB7DQogICAgICAgIHZhciBfYSwgX2I7DQogICAgICAgIGNvbnN0IHsgcmVxdWVzdElkIH0gPSBldmVudC5kYXRhOw0KICAgICAgICBjb25zdCB7IHR5cGUgfSA9IGV2ZW50LmRhdGEucGF5bG9hZDsNCiAgICAgICAgbGV0IHJlc3BvbnNlRGF0YTsNCiAgICAgICAgc3dpdGNoICh0eXBlKSB7DQogICAgICAgICAgICBjYXNlIE1haW5Nc2dUeXBlLkdldE1ldGFkYXRhOiB7DQogICAgICAgICAgICAgICAgY29uc3QgeyBtdWx0aXN0cmVhbUNvbm5lY3Rpb25JZCwgbWVkaWFUeXBlLCBlbmNvZGVkVHJhbnNmb3JtSWQgfSA9IGV2ZW50LmRhdGEucGF5bG9hZDsNCiAgICAgICAgICAgICAgICByZXNwb25zZURhdGEgPSAoX2IgPSAoX2EgPSBjb2xsZWN0ZWRNZXRhZGF0YVttdWx0aXN0cmVhbUNvbm5lY3Rpb25JZF0pID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYVttZWRpYVR5cGVdKSA9PT0gbnVsbCB8fCBfYiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2JbZW5jb2RlZFRyYW5zZm9ybUlkXTsNCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGNhc2UgTWFpbk1zZ1R5cGUuQ2xlYXJNZXRhZGF0YTogew0KICAgICAgICAgICAgICAgIGNvbnN0IHsgbXVsdGlzdHJlYW1Db25uZWN0aW9uSWQgfSA9IGV2ZW50LmRhdGEucGF5bG9hZDsNCiAgICAgICAgICAgICAgICBkZWxldGUgY29sbGVjdGVkTWV0YWRhdGFbbXVsdGlzdHJlYW1Db25uZWN0aW9uSWRdOw0KICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZGVmYXVsdDoNCiAgICAgICAgICAgICAgICB3b3JrZXJMb2dnZXIud2FybigndW5leHBlY3RlZCBtZXNzYWdlIHR5cGU9JywgdHlwZSk7DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgIH0NCiAgICAgICAgcG9zdE1lc3NhZ2Uoew0KICAgICAgICAgICAgdHlwZTogV29ya2VyTXNnVHlwZS5SZXNwb25zZSwNCiAgICAgICAgICAgIHJlcXVlc3RJZCwNCiAgICAgICAgICAgIHJlc3BvbnNlRGF0YSwNCiAgICAgICAgfSk7DQogICAgfSk7DQogICAgd29ya2VyTG9nZ2VyLmluZm8oJ1dvcmtlciBmdWxseSBzdGFydGVkLicpOwoKfSkoKTsKCg==', null, false);
15660
15651
  /* eslint-enable */
15661
15652
 
@@ -15735,7 +15726,7 @@ function getWorkerManager() {
15735
15726
  return WorkerManager.workerManagerInstance;
15736
15727
  }
15737
15728
 
15738
- function toMediaStreamTrackKind(mediaType) {
15729
+ function mediaTypeToTrackKind(mediaType) {
15739
15730
  return [MediaType.VideoMain, MediaType.VideoSlides].includes(mediaType)
15740
15731
  ? MediaStreamTrackKind.Video
15741
15732
  : MediaStreamTrackKind.Audio;
@@ -15805,9 +15796,10 @@ class MultistreamConnection extends EventEmitter$2 {
15805
15796
  const slidesSceneId = generateSceneId();
15806
15797
  const videoMainEncodingOptions = this.getVideoEncodingOptions(MediaContent.Main);
15807
15798
  const videoSlidesEncodingOptions = this.getVideoEncodingOptions(MediaContent.Slides);
15808
- this.createSendTransceiver(MediaType.VideoMain, mainSceneId, videoMainEncodingOptions);
15799
+ const sendVideoCodecParams = this.getCustomSendVideoCodecParams();
15800
+ this.createSendTransceiver(MediaType.VideoMain, mainSceneId, videoMainEncodingOptions, sendVideoCodecParams);
15809
15801
  this.createSendTransceiver(MediaType.AudioMain, mainSceneId);
15810
- this.createSendTransceiver(MediaType.VideoSlides, slidesSceneId, videoSlidesEncodingOptions);
15802
+ this.createSendTransceiver(MediaType.VideoSlides, slidesSceneId, videoSlidesEncodingOptions, sendVideoCodecParams);
15811
15803
  this.createSendTransceiver(MediaType.AudioSlides, slidesSceneId);
15812
15804
  }
15813
15805
  startWorkerIfNeeded() {
@@ -15885,10 +15877,29 @@ class MultistreamConnection extends EventEmitter$2 {
15885
15877
  ]
15886
15878
  : [{ active: false }];
15887
15879
  }
15888
- 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) {
15889
15900
  let rtcRtpTransceiver;
15890
15901
  try {
15891
- rtcRtpTransceiver = this.pc.addTransceiver(toMediaStreamTrackKind(mediaType), {
15902
+ rtcRtpTransceiver = this.pc.addTransceiver(mediaTypeToTrackKind(mediaType), {
15892
15903
  direction: 'sendrecv',
15893
15904
  sendEncodings: sendEncodingsOptions,
15894
15905
  });
@@ -15907,14 +15918,12 @@ class MultistreamConnection extends EventEmitter$2 {
15907
15918
  munger,
15908
15919
  csi,
15909
15920
  });
15910
- let codecParameters = {
15911
- 'x-google-start-bitrate': `${this.options.preferredStartingBitrateKbps}`,
15912
- };
15913
15921
  if (getMediaFamily(mediaType) === MediaFamily.Video) {
15914
15922
  transceiver.rtxEnabled = true;
15915
- codecParameters = Object.assign(Object.assign({}, codecParameters), { 'max-mbps': `${defaultMaxVideoEncodeMbps}`, 'max-fs': `${defaultMaxVideoEncodeFrameSize}` });
15916
15923
  }
15917
- transceiver.setCodecParameters(codecParameters);
15924
+ Object.entries(codecParams !== null && codecParams !== void 0 ? codecParams : {}).forEach(([codec, params]) => {
15925
+ transceiver.setCustomCodecParameters(codec, params);
15926
+ });
15918
15927
  transceiver.twccDisabled =
15919
15928
  getMediaFamily(mediaType) === MediaFamily.Audio ? this.options.disableAudioTwcc : false;
15920
15929
  transceiver.dtxDisabled = mediaType !== MediaType.AudioMain || this.options.disableAudioMainDtx;
@@ -16215,8 +16224,8 @@ SCTP Max Message Size: ${maxMessageSize}`);
16215
16224
  static getEncodedTransformId(mediaType, mid) {
16216
16225
  return `INBOUND-${mediaType}-${mid}`;
16217
16226
  }
16218
- createReceiveTransceiver(mediaType) {
16219
- const rtcRtpTransceiver = this.pc.addTransceiver(toMediaStreamTrackKind(mediaType), {
16227
+ createReceiveTransceiver(mediaType, codecParams) {
16228
+ const rtcRtpTransceiver = this.pc.addTransceiver(mediaTypeToTrackKind(mediaType), {
16220
16229
  direction: 'recvonly',
16221
16230
  });
16222
16231
  const mid = this.midPredictor.getNextMid(mediaType);
@@ -16244,14 +16253,9 @@ SCTP Max Message Size: ${maxMessageSize}`);
16244
16253
  logger.warn(`Failed to setup encoded transform for audio level monitoring of mid=${mid}: ${e}`);
16245
16254
  }
16246
16255
  }
16247
- if (getMediaFamily(mediaType) === MediaFamily.Video) {
16248
- recvOnlyTransceiver.setCodecParameters({
16249
- 'sps-pps-idr-in-keyframe': '1',
16250
- });
16251
- recvOnlyTransceiver.setRtxCodecParameters({
16252
- 'rtx-time': mediaType === MediaType.VideoMain ? defaultVideoMainRtxTime : defaultVideoSlidesRtxTime,
16253
- });
16254
- }
16256
+ Object.entries(codecParams !== null && codecParams !== void 0 ? codecParams : {}).forEach(([codec, params]) => {
16257
+ recvOnlyTransceiver.setCustomCodecParameters(codec, params);
16258
+ });
16255
16259
  recvOnlyTransceiver.twccDisabled =
16256
16260
  getMediaFamily(mediaType) === MediaFamily.Audio ? this.options.disableAudioTwcc : false;
16257
16261
  this.recvTransceivers.set(mediaType, [
@@ -16270,8 +16274,11 @@ SCTP Max Message Size: ${maxMessageSize}`);
16270
16274
  return new Promise((createReceiveSlotsResolve) => {
16271
16275
  this.offerAnswerQueue.push(() => __awaiter(this, void 0, void 0, function* () {
16272
16276
  const createdReceiveOnlyTransceivers = [];
16277
+ const codecParams = mediaTypeToTrackKind(mediaType) === MediaStreamTrackKind.Video
16278
+ ? this.getCustomReceiveVideoCodecParams(mediaType)
16279
+ : undefined;
16273
16280
  for (let i = 0; i < count; i++) {
16274
- const recvOnlyTransceiver = this.createReceiveTransceiver(mediaType);
16281
+ const recvOnlyTransceiver = this.createReceiveTransceiver(mediaType, codecParams);
16275
16282
  createdReceiveOnlyTransceivers.push(recvOnlyTransceiver);
16276
16283
  }
16277
16284
  if (this.pc.getRemoteDescription()) {
@@ -16648,7 +16655,7 @@ SCTP Max Message Size: ${maxMessageSize}`);
16648
16655
  const mediaContent = getMediaContent(mediaType);
16649
16656
  const sceneId = mediaContent === MediaContent.Main ? mainSceneId : slidesSceneId;
16650
16657
  const mid = this.midPredictor.getNextMid(mediaType);
16651
- transceiver.replaceTransceiver(this.pc.addTransceiver(toMediaStreamTrackKind(mediaType), {
16658
+ transceiver.replaceTransceiver(this.pc.addTransceiver(mediaTypeToTrackKind(mediaType), {
16652
16659
  direction: 'sendrecv',
16653
16660
  sendEncodings: getMediaFamily(mediaType) === MediaFamily.Video
16654
16661
  ? this.getVideoEncodingOptions(mediaContent)
@@ -16663,7 +16670,7 @@ SCTP Max Message Size: ${maxMessageSize}`);
16663
16670
  this.recvTransceivers.forEach((transceivers, mediaType) => {
16664
16671
  transceivers.forEach((t) => {
16665
16672
  const mid = this.midPredictor.getNextMid(mediaType);
16666
- const rtcRtpTransceiver = this.pc.addTransceiver(toMediaStreamTrackKind(mediaType), {
16673
+ const rtcRtpTransceiver = this.pc.addTransceiver(mediaTypeToTrackKind(mediaType), {
16667
16674
  direction: 'recvonly',
16668
16675
  });
16669
16676
  t.replaceTransceiver(rtcRtpTransceiver);