@webex/web-client-media-engine 1.40.3 → 1.40.5

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
@@ -477,6 +477,134 @@ var media = /*#__PURE__*/Object.freeze({
477
477
  ensureDevicePermissions: ensureDevicePermissions
478
478
  });
479
479
 
480
+ var ErrorTypes;
481
+ (function (ErrorTypes) {
482
+ ErrorTypes["DEVICE_PERMISSION_DENIED"] = "DEVICE_PERMISSION_DENIED";
483
+ ErrorTypes["CREATE_CAMERA_TRACK_FAILED"] = "CREATE_CAMERA_TRACK_FAILED";
484
+ ErrorTypes["CREATE_MICROPHONE_TRACK_FAILED"] = "CREATE_MICROPHONE_TRACK_FAILED";
485
+ })(ErrorTypes || (ErrorTypes = {}));
486
+ /**
487
+ * Represents a WCME error, which contains error type and error message.
488
+ */
489
+ class WcmeError {
490
+ /**
491
+ * Creates new error.
492
+ *
493
+ * @param type - Error type.
494
+ * @param message - Error message.
495
+ */
496
+ constructor(type, message = '') {
497
+ this.type = type;
498
+ this.message = message;
499
+ }
500
+ }
501
+ /**
502
+ * Creates a camera video track. Please note that the constraint params in second getUserMedia call would NOT take effect when:
503
+ *
504
+ * 1. Previous captured video track from the same device is not stopped .
505
+ * 2. Previous createCameraTrack() call for the same device is in progress.
506
+ *
507
+ * @param constructor - Constructor for the local camera track.
508
+ * @param constraints - Video device constraints.
509
+ * @returns A LocalTrack object or an error.
510
+ */
511
+ function createCameraTrack(constructor, constraints) {
512
+ return __awaiter$1(this, void 0, void 0, function* () {
513
+ let stream;
514
+ try {
515
+ stream = yield getUserMedia({ video: Object.assign({}, constraints) });
516
+ }
517
+ catch (error) {
518
+ throw new WcmeError(ErrorTypes.CREATE_CAMERA_TRACK_FAILED, `Failed to create camera track ${error}`);
519
+ }
520
+ return new constructor(stream);
521
+ });
522
+ }
523
+ /**
524
+ * Creates a microphone audio track.
525
+ *
526
+ * @param constructor - Constructor for the local microphone track.
527
+ * @param constraints - Audio device constraints.
528
+ * @returns A LocalTrack object or an error.
529
+ */
530
+ function createMicrophoneTrack(constructor, constraints) {
531
+ return __awaiter$1(this, void 0, void 0, function* () {
532
+ let stream;
533
+ try {
534
+ stream = yield getUserMedia({ audio: Object.assign({}, constraints) });
535
+ }
536
+ catch (error) {
537
+ throw new WcmeError(ErrorTypes.CREATE_MICROPHONE_TRACK_FAILED, `Failed to create microphone track ${error}`);
538
+ }
539
+ return new constructor(stream);
540
+ });
541
+ }
542
+ /**
543
+ * Creates a display video track.
544
+ *
545
+ * @param constructor - Constructor for the local display track.
546
+ * @param videoContentHint - An optional parameters to give a hint for the content of the track.
547
+ * @returns A Promise that resolves to a LocalDisplayTrack.
548
+ */
549
+ function createDisplayTrack(constructor, videoContentHint) {
550
+ return __awaiter$1(this, void 0, void 0, function* () {
551
+ const stream = yield getDisplayMedia({ video: true });
552
+ return new constructor(stream, videoContentHint);
553
+ });
554
+ }
555
+ /**
556
+ * Enumerates the media input and output devices available.
557
+ *
558
+ * @param deviceKind - Optional filter to return a specific device kind.
559
+ * @returns List of media devices in an array of MediaDeviceInfo objects.
560
+ */
561
+ function getDevices(deviceKind) {
562
+ return __awaiter$1(this, void 0, void 0, function* () {
563
+ let devices;
564
+ try {
565
+ devices = yield ensureDevicePermissions([DeviceKind.AudioInput, DeviceKind.VideoInput], enumerateDevices);
566
+ }
567
+ catch (error) {
568
+ throw new WcmeError(ErrorTypes.DEVICE_PERMISSION_DENIED, 'Failed to ensure device permissions');
569
+ }
570
+ return devices.filter((v) => (deviceKind ? v.kind === deviceKind : true));
571
+ });
572
+ }
573
+ /**
574
+ * Helper function to get a list of microphone devices.
575
+ *
576
+ * @returns List of microphone devices in an array of MediaDeviceInfo objects.
577
+ */
578
+ function getAudioInputDevices() {
579
+ return __awaiter$1(this, void 0, void 0, function* () {
580
+ return getDevices(DeviceKind.AudioInput);
581
+ });
582
+ }
583
+ /**
584
+ * Helper function to get a list of speaker devices.
585
+ *
586
+ * @returns List of speaker devices in an array of MediaDeviceInfo objects.
587
+ */
588
+ function getAudioOutputDevices() {
589
+ return __awaiter$1(this, void 0, void 0, function* () {
590
+ return getDevices(DeviceKind.AudioOutput);
591
+ });
592
+ }
593
+ /**
594
+ * Helper function to get a list of camera devices.
595
+ *
596
+ * @returns List of camera devices in an array of MediaDeviceInfo objects.
597
+ */
598
+ function getVideoInputDevices() {
599
+ return __awaiter$1(this, void 0, void 0, function* () {
600
+ return getDevices(DeviceKind.VideoInput);
601
+ });
602
+ }
603
+ /**
604
+ * Export the setOnDeviceChangeHandler method directly from the core lib.
605
+ */
606
+ const { setOnDeviceChangeHandler } = media;
607
+
480
608
  var events$1 = {exports: {}};
481
609
 
482
610
  var R$1 = typeof Reflect === 'object' ? Reflect : null;
@@ -1227,6 +1355,25 @@ class LocalCameraTrack extends LocalTrack {
1227
1355
  * Represents a local track for a display source.
1228
1356
  */
1229
1357
  class LocalDisplayTrack extends LocalTrack {
1358
+ /**
1359
+ * Create a LocalDisplayTrack from the given values.
1360
+ *
1361
+ * @param stream - The MediaStream for this track.
1362
+ * @param videoContentHint - An optional content hint, describing the content of the track.
1363
+ */
1364
+ constructor(stream, videoContentHint) {
1365
+ super(stream);
1366
+ this._videoContentHint = videoContentHint;
1367
+ this.underlyingTrack.contentHint = videoContentHint || '';
1368
+ }
1369
+ /**
1370
+ * Get the VideoContentHint for this track.
1371
+ *
1372
+ * @returns The VideoContentHint for this track.
1373
+ */
1374
+ get videoContentHint() {
1375
+ return this._videoContentHint;
1376
+ }
1230
1377
  }
1231
1378
 
1232
1379
  /**
@@ -1235,130 +1382,6 @@ class LocalDisplayTrack extends LocalTrack {
1235
1382
  class LocalMicrophoneTrack extends LocalTrack {
1236
1383
  }
1237
1384
 
1238
- var ErrorTypes;
1239
- (function (ErrorTypes) {
1240
- ErrorTypes["DEVICE_PERMISSION_DENIED"] = "DEVICE_PERMISSION_DENIED";
1241
- ErrorTypes["CREATE_CAMERA_TRACK_FAILED"] = "CREATE_CAMERA_TRACK_FAILED";
1242
- ErrorTypes["CREATE_MICROPHONE_TRACK_FAILED"] = "CREATE_MICROPHONE_TRACK_FAILED";
1243
- })(ErrorTypes || (ErrorTypes = {}));
1244
- /**
1245
- * Represents a WCME error, which contains error type and error message.
1246
- */
1247
- class WcmeError {
1248
- /**
1249
- * Creates new error.
1250
- *
1251
- * @param type - Error type.
1252
- * @param message - Error message.
1253
- */
1254
- constructor(type, message = '') {
1255
- this.type = type;
1256
- this.message = message;
1257
- }
1258
- }
1259
- /**
1260
- * Creates a camera video track. Please note that the constraint params in second getUserMedia call would NOT take effect when:
1261
- *
1262
- * 1. Previous captured video track from the same device is not stopped .
1263
- * 2. Previous createCameraTrack() call for the same device is in progress.
1264
- *
1265
- * @param constraints - Video device constraints.
1266
- * @returns A LocalTrack object or an error.
1267
- */
1268
- function createCameraTrack(constraints) {
1269
- return __awaiter$1(this, void 0, void 0, function* () {
1270
- let stream;
1271
- try {
1272
- stream = yield getUserMedia({ video: Object.assign({}, constraints) });
1273
- }
1274
- catch (error) {
1275
- throw new WcmeError(ErrorTypes.CREATE_CAMERA_TRACK_FAILED, `Failed to create camera track ${error}`);
1276
- }
1277
- return new LocalCameraTrack(stream);
1278
- });
1279
- }
1280
- /**
1281
- * Creates a microphone audio track.
1282
- *
1283
- * @param constraints - Audio device constraints.
1284
- * @returns A LocalTrack object or an error.
1285
- */
1286
- function createMicrophoneTrack(constraints) {
1287
- return __awaiter$1(this, void 0, void 0, function* () {
1288
- let stream;
1289
- try {
1290
- stream = yield getUserMedia({ audio: Object.assign({}, constraints) });
1291
- }
1292
- catch (error) {
1293
- throw new WcmeError(ErrorTypes.CREATE_MICROPHONE_TRACK_FAILED, `Failed to create microphone track ${error}`);
1294
- }
1295
- return new LocalMicrophoneTrack(stream);
1296
- });
1297
- }
1298
- /**
1299
- * Creates a display video track.
1300
- *
1301
- * @returns A Promise that resolves to a LocalDisplayTrack.
1302
- */
1303
- function createDisplayTrack() {
1304
- return __awaiter$1(this, void 0, void 0, function* () {
1305
- const stream = yield getDisplayMedia({ video: true });
1306
- return new LocalDisplayTrack(stream);
1307
- });
1308
- }
1309
- /**
1310
- * Enumerates the media input and output devices available.
1311
- *
1312
- * @param deviceKind - Optional filter to return a specific device kind.
1313
- * @returns List of media devices in an array of MediaDeviceInfo objects.
1314
- */
1315
- function getDevices(deviceKind) {
1316
- return __awaiter$1(this, void 0, void 0, function* () {
1317
- let devices;
1318
- try {
1319
- devices = yield ensureDevicePermissions([DeviceKind.AudioInput, DeviceKind.VideoInput], enumerateDevices);
1320
- }
1321
- catch (error) {
1322
- throw new WcmeError(ErrorTypes.DEVICE_PERMISSION_DENIED, 'Failed to ensure device permissions');
1323
- }
1324
- return devices.filter((v) => (deviceKind ? v.kind === deviceKind : true));
1325
- });
1326
- }
1327
- /**
1328
- * Helper function to get a list of microphone devices.
1329
- *
1330
- * @returns List of microphone devices in an array of MediaDeviceInfo objects.
1331
- */
1332
- function getAudioInputDevices() {
1333
- return __awaiter$1(this, void 0, void 0, function* () {
1334
- return getDevices(DeviceKind.AudioInput);
1335
- });
1336
- }
1337
- /**
1338
- * Helper function to get a list of speaker devices.
1339
- *
1340
- * @returns List of speaker devices in an array of MediaDeviceInfo objects.
1341
- */
1342
- function getAudioOutputDevices() {
1343
- return __awaiter$1(this, void 0, void 0, function* () {
1344
- return getDevices(DeviceKind.AudioOutput);
1345
- });
1346
- }
1347
- /**
1348
- * Helper function to get a list of camera devices.
1349
- *
1350
- * @returns List of camera devices in an array of MediaDeviceInfo objects.
1351
- */
1352
- function getVideoInputDevices() {
1353
- return __awaiter$1(this, void 0, void 0, function* () {
1354
- return getDevices(DeviceKind.VideoInput);
1355
- });
1356
- }
1357
- /**
1358
- * Export the setOnDeviceChangeHandler method directly from the core lib.
1359
- */
1360
- const { setOnDeviceChangeHandler } = media;
1361
-
1362
1385
  // Overall connection state (based on the ICE and DTLS connection states)
1363
1386
  var ConnectionState;
1364
1387
  (function (ConnectionState) {
@@ -5702,11 +5725,12 @@ function compareStreamIds(id1, id2) {
5702
5725
  }
5703
5726
 
5704
5727
  class SourceIndicationMsg {
5705
- constructor(seqNum, numTotalSources, numLiveSources, sources) {
5728
+ constructor(seqNum, numTotalSources, numLiveSources, sources, videoContentHint) {
5706
5729
  this.seqNum = seqNum;
5707
5730
  this.numTotalSources = numTotalSources;
5708
5731
  this.numLiveSources = numLiveSources;
5709
5732
  this.sources = sources;
5733
+ this.videoContentHint = videoContentHint;
5710
5734
  }
5711
5735
  sourcesToString() {
5712
5736
  return this.sources
@@ -5802,13 +5826,13 @@ class JmpSession extends EventEmitter$3 {
5802
5826
  this.logger.warn(`Retransmits for message expired: ${expiredJmpMsg}`);
5803
5827
  });
5804
5828
  }
5805
- updateSourceIndication(numTotalSources, numLiveSources, sources) {
5829
+ updateSourceIndication(numTotalSources, numLiveSources, sources, videoContentHint) {
5806
5830
  var _a;
5807
5831
  const filteredSources = sources.filter((source) => {
5808
5832
  var _a;
5809
5833
  return (_a = this.lastReceivedScr) === null || _a === void 0 ? void 0 : _a.requests.some((req) => req.ids.find((streamId) => compareStreamIds(streamId, source.id)));
5810
5834
  });
5811
- const sourceIndicationMsg = new SourceIndicationMsg(this.currSourceIndicationSeqNum++, numTotalSources, numLiveSources, filteredSources);
5835
+ const sourceIndicationMsg = new SourceIndicationMsg(this.currSourceIndicationSeqNum++, numTotalSources, numLiveSources, filteredSources, videoContentHint);
5812
5836
  const jmpMsg = new JmpMsg(this.mediaFamily, this.mediaContent, {
5813
5837
  msgType: JmpMsgType.SourceIndication,
5814
5838
  payload: sourceIndicationMsg,
@@ -9194,23 +9218,58 @@ class SsrcEgressStreamSignaler {
9194
9218
  this.streamIds = [];
9195
9219
  }
9196
9220
  signalStreams(simulcastEnabled, rtxEnabled, mLine) {
9221
+ var _a;
9197
9222
  mLine.rids = [];
9198
9223
  mLine.simulcast = undefined;
9199
- mLine.ssrcs = [];
9200
- mLine.ssrcGroups = [];
9201
9224
  mLine.extMaps = mLine.extMaps.filter((extMapLine) => !/^urn:ietf:params:rtp-hdrext:sdes:(?:mid|rtp-stream-id|repaired-rtp-stream-id)$/.test(extMapLine.uri));
9202
- if (this.streamIds.length === 0) {
9203
- const numStreams = simulcastEnabled ? 3 : 1;
9204
- [...Array(numStreams).keys()].forEach(() => {
9205
- const newStreamId = {
9206
- ssrc: generateSsrc(),
9207
- };
9208
- if (rtxEnabled) {
9209
- newStreamId.rtxSsrc = generateSsrc();
9225
+ const numStreams = simulcastEnabled ? 3 : 1;
9226
+ if (!this.streamIds.length) {
9227
+ if (mLine.ssrcs.length) {
9228
+ const ssrcs = [...new Set(mLine.ssrcs.map((ssrcLine) => ssrcLine.ssrcId))];
9229
+ mLine.ssrcGroups.forEach((sg) => {
9230
+ if (!sg.ssrcs.every((ssrc) => ssrcs.includes(ssrc))) {
9231
+ throw new Error('SSRC present in SSRC groups is missing from SSRC lines');
9232
+ }
9233
+ });
9234
+ const rtxSsrcGroups = mLine.ssrcGroups.filter((sg) => sg.semantics === 'FID');
9235
+ if (rtxSsrcGroups.length && rtxSsrcGroups.length !== numStreams) {
9236
+ throw new Error(`Expect ${numStreams} RTX SSRC groups, got ${rtxSsrcGroups.length}`);
9210
9237
  }
9211
- this.streamIds.push(newStreamId);
9212
- });
9238
+ rtxSsrcGroups.forEach((sg) => {
9239
+ this.streamIds.push({
9240
+ ssrc: sg.ssrcs[0],
9241
+ rtxSsrc: sg.ssrcs[1],
9242
+ });
9243
+ });
9244
+ const simulcastSsrcs = (_a = mLine.ssrcGroups.find((sg) => sg.semantics === 'SIM')) === null || _a === void 0 ? void 0 : _a.ssrcs;
9245
+ if (simulcastSsrcs) {
9246
+ if (simulcastSsrcs.length !== numStreams ||
9247
+ !this.streamIds.every((streamId) => simulcastSsrcs.includes(streamId.ssrc))) {
9248
+ throw new Error('SSRCs in simulcast SSRC group do not match primary SSRCs in RTX SSRC groups');
9249
+ }
9250
+ this.streamIds.sort((a, b) => simulcastSsrcs.indexOf(a.ssrc) - simulcastSsrcs.indexOf(b.ssrc));
9251
+ }
9252
+ else if (rtxSsrcGroups.length > 1) {
9253
+ throw new Error('Multiple RTX SSRC groups but no simulcast SSRC group found');
9254
+ }
9255
+ if (!this.streamIds.length) {
9256
+ this.streamIds.push({ ssrc: ssrcs[0] });
9257
+ }
9258
+ }
9259
+ else {
9260
+ [...Array(numStreams).keys()].forEach(() => {
9261
+ const newStreamId = {
9262
+ ssrc: generateSsrc(),
9263
+ };
9264
+ if (rtxEnabled) {
9265
+ newStreamId.rtxSsrc = generateSsrc();
9266
+ }
9267
+ this.streamIds.push(newStreamId);
9268
+ });
9269
+ }
9213
9270
  }
9271
+ mLine.ssrcs = [];
9272
+ mLine.ssrcGroups = [];
9214
9273
  this.streamIds.forEach((streamId) => {
9215
9274
  const rtpSsrc = streamId.ssrc;
9216
9275
  mLine.addLine(new SsrcLine(rtpSsrc, 'cname', `${rtpSsrc}-cname`));
@@ -9678,6 +9737,15 @@ function toMediaStreamTrackKind(mediaType) {
9678
9737
  ? MediaStreamTrackKind.Video
9679
9738
  : MediaStreamTrackKind.Audio;
9680
9739
  }
9740
+ function webRtcVideoContentHintToJmpVideoContentHint(hint) {
9741
+ if (hint === 'motion') {
9742
+ return 'motion';
9743
+ }
9744
+ if (hint === 'detail') {
9745
+ return 'sharpness';
9746
+ }
9747
+ return undefined;
9748
+ }
9681
9749
  function toMediaFamily(kind) {
9682
9750
  if (kind === MediaStreamTrackKind.Video) {
9683
9751
  return MediaFamily.Video;
@@ -9926,24 +9994,8 @@ class MultistreamConnection extends EventEmitter {
9926
9994
  const dataChannel = this.pc.createDataChannel('datachannel', {});
9927
9995
  dataChannel.onopen = (e) => {
9928
9996
  logger.info('DataChannel opened: ', e);
9929
- this.sendTransceivers.forEach((transceiver, mediaType) => {
9930
- const track = transceiver.publishedTrack;
9931
- if (track) {
9932
- if (getMediaFamily(mediaType) === MediaFamily.Audio) {
9933
- this.sendSourceIndication(mediaType, +!track.muted);
9934
- }
9935
- else {
9936
- const signaler = this.streamSignalerManager.getEgressStreamSignalerOrThrow(transceiver.mid);
9937
- const state = track.muted ? 'avatar' : 'live';
9938
- const sources = signaler
9939
- .getSenderIds()
9940
- .map((id) => ({ id, state, csi: transceiver.csi }));
9941
- this.sendSourceIndication(mediaType, +!track.muted, sources);
9942
- }
9943
- }
9944
- else {
9945
- this.sendSourceIndication(mediaType, 0);
9946
- }
9997
+ [...this.sendTransceivers.keys()].forEach((mediaType) => {
9998
+ this.maybeSendSourceIndication(mediaType);
9947
9999
  });
9948
10000
  logger.info(`Flushing pending JMP task queue`);
9949
10001
  this.pendingJmpTasks.forEach((t) => t());
@@ -9992,11 +10044,31 @@ class MultistreamConnection extends EventEmitter {
9992
10044
  });
9993
10045
  this.pc.close();
9994
10046
  }
9995
- sendSourceIndication(mediaType, numLiveSources, sources = []) {
10047
+ maybeSendSourceIndication(mediaType) {
10048
+ var _a;
10049
+ const transceiver = this.getSendTransceiverOrThrow(mediaType);
10050
+ const numLiveSources = ((_a = transceiver.publishedTrack) === null || _a === void 0 ? void 0 : _a.muted) === false ? 1 : 0;
10051
+ if (getMediaFamily(mediaType) === MediaFamily.Video) {
10052
+ const sources = this.getVideoSources(mediaType);
10053
+ if (sources === null) {
10054
+ return;
10055
+ }
10056
+ let webRtcVideoContentHint;
10057
+ if (transceiver.publishedTrack instanceof LocalDisplayTrack) {
10058
+ webRtcVideoContentHint = transceiver.publishedTrack.videoContentHint;
10059
+ }
10060
+ this.sendSourceIndication(mediaType, numLiveSources, sources, webRtcVideoContentHintToJmpVideoContentHint(webRtcVideoContentHint));
10061
+ }
10062
+ else {
10063
+ this.sendSourceIndication(mediaType, numLiveSources);
10064
+ }
10065
+ }
10066
+ sendSourceIndication(mediaType, numLiveSources, sources = [], videoContentHint = undefined) {
9996
10067
  var _a;
9997
10068
  const task = () => {
9998
10069
  var _a;
9999
- (_a = this.jmpSessions.get(mediaType)) === null || _a === void 0 ? void 0 : _a.updateSourceIndication(1, numLiveSources, sources);
10070
+ (_a = this.jmpSessions
10071
+ .get(mediaType)) === null || _a === void 0 ? void 0 : _a.updateSourceIndication(1, numLiveSources, sources, videoContentHint);
10000
10072
  };
10001
10073
  if (((_a = this.dataChannel) === null || _a === void 0 ? void 0 : _a.readyState) === 'open') {
10002
10074
  task();
@@ -10041,24 +10113,9 @@ class MultistreamConnection extends EventEmitter {
10041
10113
  });
10042
10114
  }
10043
10115
  addTrackListeners(mediaType, track) {
10044
- const onTrackResolutionChange = () => {
10045
- const sources = this.getVideoSources(mediaType);
10046
- if (sources != null) {
10047
- this.sendSourceIndication(mediaType, 1, sources);
10048
- }
10049
- };
10116
+ const onTrackResolutionChange = () => this.maybeSendSourceIndication(mediaType);
10050
10117
  track.on(LocalTrack.Events.TrackConstraintsChange, onTrackResolutionChange);
10051
- const onTrackMute = (event) => {
10052
- if (getMediaFamily(mediaType) === MediaFamily.Audio) {
10053
- this.sendSourceIndication(mediaType, +!event.trackState.muted);
10054
- }
10055
- else {
10056
- const sources = this.getVideoSources(mediaType);
10057
- if (sources != null) {
10058
- this.sendSourceIndication(mediaType, +!event.trackState.muted, sources);
10059
- }
10060
- }
10061
- };
10118
+ const onTrackMute = () => this.maybeSendSourceIndication(mediaType);
10062
10119
  track.on(LocalTrack.Events.Muted, onTrackMute);
10063
10120
  const onTrackPublish = (event) => {
10064
10121
  if (!event.isPublished) {
@@ -10066,14 +10123,8 @@ class MultistreamConnection extends EventEmitter {
10066
10123
  track.off(LocalTrack.Events.PublishedStateUpdate, onTrackPublish);
10067
10124
  track.off(LocalTrack.Events.TrackConstraintsChange, onTrackResolutionChange);
10068
10125
  }
10069
- if (getMediaFamily(mediaType) === MediaFamily.Audio) {
10070
- this.sendSourceIndication(mediaType, +event.isPublished);
10071
- }
10072
- else {
10073
- const sources = this.getVideoSources(mediaType);
10074
- if (sources != null) {
10075
- this.sendSourceIndication(mediaType, +event.isPublished, sources);
10076
- }
10126
+ if (!track.muted) {
10127
+ this.maybeSendSourceIndication(mediaType);
10077
10128
  }
10078
10129
  };
10079
10130
  track.on(LocalTrack.Events.PublishedStateUpdate, onTrackPublish);
@@ -10365,7 +10416,7 @@ class MultistreamConnection extends EventEmitter {
10365
10416
  }
10366
10417
  renewPeerConnection(userOptions) {
10367
10418
  if (userOptions) {
10368
- this.options = Object.assign(Object.assign({}, defaultMultistreamConnectionOptions), userOptions);
10419
+ this.options = Object.assign(Object.assign({}, this.options), userOptions);
10369
10420
  }
10370
10421
  logger.info(`Renewing multistream connection with options ${JSON.stringify(this.options)}`);
10371
10422
  this.clearMids();