@webex/internal-media-core 1.35.2 → 1.35.4

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
@@ -2933,6 +2933,22 @@ class FingerprintLine$1 extends Line$1 {
2933
2933
  }
2934
2934
  }
2935
2935
  FingerprintLine$1.regex = new RegExp("^fingerprint:(".concat(REST$1, ")"));
2936
+ function parseFmtpParams$1(fmtpParams) {
2937
+ fmtpParams = fmtpParams.replace(/^a=fmtp:\d+\x20/, '');
2938
+ var fmtpObj = new Map();
2939
+ if (/^\d+([/-]\d+)+$/.test(fmtpParams)) {
2940
+ fmtpObj.set(fmtpParams, undefined);
2941
+ return fmtpObj;
2942
+ }
2943
+ fmtpParams.split(';').forEach(param => {
2944
+ var paramArr = param && param.split('=');
2945
+ if (paramArr.length !== 2 || !paramArr[0] || !paramArr[1]) {
2946
+ throw new Error("Fmtp params is invalid with ".concat(fmtpParams));
2947
+ }
2948
+ fmtpObj.set(paramArr[0], paramArr[1]);
2949
+ });
2950
+ return fmtpObj;
2951
+ }
2936
2952
  class FmtpLine$1 extends Line$1 {
2937
2953
  constructor(payloadType, params) {
2938
2954
  super();
@@ -2946,10 +2962,16 @@ class FmtpLine$1 extends Line$1 {
2946
2962
  var tokens = line.match(FmtpLine$1.regex);
2947
2963
  var payloadType = parseInt(tokens[1], 10);
2948
2964
  var params = tokens[2];
2949
- return new FmtpLine$1(payloadType, params);
2965
+ return new FmtpLine$1(payloadType, parseFmtpParams$1(params));
2950
2966
  }
2951
2967
  toSdpLine() {
2952
- return "a=fmtp:".concat(this.payloadType, " ").concat(this.params);
2968
+ var fmtParams = Array.from(this.params.keys()).map(key => {
2969
+ if (this.params.get(key) !== undefined) {
2970
+ return "".concat(key, "=").concat(this.params.get(key));
2971
+ }
2972
+ return "".concat(key);
2973
+ }).join(';');
2974
+ return "a=fmtp:".concat(this.payloadType, " ").concat(fmtParams);
2953
2975
  }
2954
2976
  }
2955
2977
  FmtpLine$1.regex = new RegExp("^fmtp:(".concat(NUM$1, ") (").concat(REST$1, ")"));
@@ -3610,7 +3632,7 @@ class ApplicationMediaDescription$1 extends MediaDescription$1 {
3610
3632
  }
3611
3633
  class CodecInfo$2 {
3612
3634
  constructor(pt) {
3613
- this.fmtParams = [];
3635
+ this.fmtParams = new Map();
3614
3636
  this.feedback = [];
3615
3637
  this.pt = pt;
3616
3638
  }
@@ -3622,9 +3644,9 @@ class CodecInfo$2 {
3622
3644
  return true;
3623
3645
  }
3624
3646
  if (line instanceof FmtpLine$1) {
3625
- this.fmtParams.push(line.params);
3626
- if (line.params.indexOf('apt') !== -1) {
3627
- var apt = line.params.split('=')[1];
3647
+ this.fmtParams = new Map([...Array.from(this.fmtParams.entries()), ...Array.from(line.params.entries())]);
3648
+ if (line.params.has('apt')) {
3649
+ var apt = line.params.get('apt');
3628
3650
  this.primaryCodecPt = parseInt(apt, 10);
3629
3651
  }
3630
3652
  return true;
@@ -3637,13 +3659,15 @@ class CodecInfo$2 {
3637
3659
  }
3638
3660
  toLines() {
3639
3661
  var lines = [];
3640
- lines.push(new RtpMapLine$1(this.pt, this.name, this.clockRate, this.encodingParams));
3662
+ if (this.name && this.clockRate) {
3663
+ lines.push(new RtpMapLine$1(this.pt, this.name, this.clockRate, this.encodingParams));
3664
+ }
3641
3665
  this.feedback.forEach(fb => {
3642
3666
  lines.push(new RtcpFbLine$1(this.pt, fb));
3643
3667
  });
3644
- this.fmtParams.forEach(fmt => {
3645
- lines.push(new FmtpLine$1(this.pt, fmt));
3646
- });
3668
+ if (this.fmtParams.size > 0) {
3669
+ lines.push(new FmtpLine$1(this.pt, this.fmtParams));
3670
+ }
3647
3671
  return lines;
3648
3672
  }
3649
3673
  }
@@ -4044,13 +4068,13 @@ function disableExtmap(sdp) {
4044
4068
  media.extMaps.length = 0;
4045
4069
  });
4046
4070
  }
4047
- function appendToH264fmtpParams(sdp, paramsToAppend) {
4071
+ function updateH264fmtpParams(sdp, paramsToUpdate) {
4048
4072
  sdp.avMedia.forEach(media => {
4049
4073
  if (media.type === 'video') {
4050
4074
  media.codecs.forEach(codec => {
4051
4075
  var _codec$name2;
4052
4076
  if (((_codec$name2 = codec.name) === null || _codec$name2 === void 0 ? void 0 : _codec$name2.toUpperCase()) === 'H264') {
4053
- codec.fmtParams = codec.fmtParams.map(fmtp => "".concat(fmtp, ";").concat(paramsToAppend));
4077
+ paramsToUpdate.forEach((value, key) => codec.fmtParams.set(key, value));
4054
4078
  }
4055
4079
  });
4056
4080
  }
@@ -4084,32 +4108,30 @@ function adjustH264Profile(sdp, maxFsValue) {
4084
4108
  media.codecs.forEach(codec => {
4085
4109
  var _codec$name3;
4086
4110
  if (((_codec$name3 = codec.name) === null || _codec$name3 === void 0 ? void 0 : _codec$name3.toUpperCase()) === 'H264') {
4087
- codec.fmtParams = codec.fmtParams.map(fmtp => {
4088
- var parsedRegex = fmtp.match(/(.*)profile-level-id=(\w{4})(\w{2})(.*)/);
4089
- if (parsedRegex && parsedRegex.length === 5) {
4090
- var stuffBeforeProfileLevelId = parsedRegex[1];
4091
- var profile = parsedRegex[2].toLowerCase();
4092
- var levelId = parseInt(parsedRegex[3], 16);
4093
- var stuffAfterProfileLevelId = parsedRegex[4];
4094
- if (!maxFsForProfileLevel[levelId]) {
4095
- throw new Error("found unsupported h264 profile level id value in the SDP: ".concat(levelId));
4096
- }
4097
- if (maxFsForProfileLevel[levelId] === maxFsValue) {
4098
- return fmtp;
4099
- }
4100
- if (maxFsForProfileLevel[levelId] < maxFsValue) {
4101
- return "".concat(fmtp, ";max-fs=").concat(maxFsValue, ";max-mbps=").concat(maxFsValue * framesPerSecond);
4102
- }
4103
- var newLevelId = Object.keys(maxFsForProfileLevel).reverse().find(key => maxFsForProfileLevel[key] === maxFsValue);
4104
- if (newLevelId) {
4105
- var newLevelIdHex = parseInt(newLevelId, 10).toString(16);
4106
- var maxMbps = "max-mbps=".concat(maxFsValue * framesPerSecond);
4107
- return "".concat(stuffBeforeProfileLevelId, "profile-level-id=").concat(profile).concat(newLevelIdHex, ";").concat(maxMbps).concat(stuffAfterProfileLevelId);
4108
- }
4109
- throw new Error("unsupported maxFsValue: ".concat(maxFsValue));
4111
+ var profileLevelIdValue = codec.fmtParams.get('profile-level-id');
4112
+ if (profileLevelIdValue) {
4113
+ var profile = profileLevelIdValue.substring(0, 4).toLowerCase();
4114
+ var levelId = parseInt(profileLevelIdValue.substring(4, 6), 16);
4115
+ if (!maxFsForProfileLevel[levelId]) {
4116
+ throw new Error("found unsupported h264 profile level id value in the SDP: ".concat(levelId));
4110
4117
  }
4111
- return fmtp;
4112
- });
4118
+ if (maxFsForProfileLevel[levelId] === maxFsValue) {
4119
+ return;
4120
+ }
4121
+ if (maxFsForProfileLevel[levelId] < maxFsValue) {
4122
+ codec.fmtParams.set('max-fs', "".concat(maxFsValue));
4123
+ codec.fmtParams.set('max-mbps', "".concat(maxFsValue * framesPerSecond));
4124
+ return;
4125
+ }
4126
+ var newLevelId = Object.keys(maxFsForProfileLevel).reverse().find(key => maxFsForProfileLevel[key] === maxFsValue);
4127
+ if (newLevelId) {
4128
+ var newLevelIdHex = parseInt(newLevelId, 10).toString(16);
4129
+ codec.fmtParams.set('profile-level-id', "".concat(profile).concat(newLevelIdHex));
4130
+ codec.fmtParams.set('max-mbps', "".concat(maxFsValue * framesPerSecond));
4131
+ return;
4132
+ }
4133
+ throw new Error("unsupported maxFsValue: ".concat(maxFsValue));
4134
+ }
4113
4135
  }
4114
4136
  });
4115
4137
  }
@@ -4160,7 +4182,7 @@ function mungeLocalSdp(config, sdp) {
4160
4182
  return parsedSdp.toString();
4161
4183
  }
4162
4184
  function setStartBitrate(sdp, startBitrate) {
4163
- appendToH264fmtpParams(sdp, "x-google-start-bitrate=".concat(startBitrate));
4185
+ updateH264fmtpParams(sdp, new Map([['x-google-start-bitrate', startBitrate.toString()]]));
4164
4186
  }
4165
4187
  function removeXtlsIceCandidates(sdp) {
4166
4188
  sdp.media.forEach(media => {
@@ -4926,6 +4948,10 @@ exports.LocalTrackEvents = void 0;
4926
4948
  * Fires when there has been a change in the underlying track.
4927
4949
  */
4928
4950
  LocalTrackEvents["UnderlyingTrackChange"] = "underlying-track-change";
4951
+ /**
4952
+ * Fires when the applyConstraints() has been called for the track.
4953
+ */
4954
+ LocalTrackEvents["TrackConstraintsChange"] = "track-constraints-change";
4929
4955
  })(exports.LocalTrackEvents || (exports.LocalTrackEvents = {}));
4930
4956
  // TBD: Fix this once types are published separately
4931
4957
  // export type TrackEffect = BaseMicrophoneEffect | BaseCameraEffect;
@@ -5114,7 +5140,7 @@ class LocalTrack extends EventEmitter$2 {
5114
5140
  return effect;
5115
5141
  }
5116
5142
  /**
5117
- * Cleanup local microphone track.
5143
+ * Cleanup the local microphone track.
5118
5144
  */
5119
5145
  disposeEffects() {
5120
5146
  if (this.effects.size > 0) {
@@ -5124,6 +5150,57 @@ class LocalTrack extends EventEmitter$2 {
5124
5150
  this.emit(exports.LocalTrackEvents.UnderlyingTrackChange);
5125
5151
  }
5126
5152
  }
5153
+ /**
5154
+ * Apply constraints to the track.
5155
+ *
5156
+ * @param constraints - The constraints to apply to the track.
5157
+ * @returns A promise which resolves when the constraints have been successfully applied.
5158
+ */
5159
+ applyConstraints(constraints) {
5160
+ return __awaiter$1(this, void 0, void 0, function* () {
5161
+ logger$3.log("Applying constraints to local track:", constraints);
5162
+ var ret = this.underlyingTrack.applyConstraints(constraints).then(() => {
5163
+ this.emit(exports.LocalTrackEvents.TrackConstraintsChange);
5164
+ });
5165
+ return ret;
5166
+ });
5167
+ }
5168
+ /**
5169
+ * Get the current constraints of the track.
5170
+ *
5171
+ * @returns The constraints of the track.
5172
+ */
5173
+ getConstraints() {
5174
+ return this.underlyingTrack.getConstraints();
5175
+ }
5176
+ /**
5177
+ * Get the current settings of the track.
5178
+ *
5179
+ * @returns The settings of the track.
5180
+ */
5181
+ getSettings() {
5182
+ return this.underlyingTrack.getSettings();
5183
+ }
5184
+ /**
5185
+ * Check the resolution and then return how many layers will be active.
5186
+ *
5187
+ * @returns The active layers count.
5188
+ */
5189
+ getNumActiveSimulcastLayers() {
5190
+ var activeSimulcastLayersNumber = 0;
5191
+ if (this.trackState.type === 'audio') {
5192
+ return activeSimulcastLayersNumber;
5193
+ }
5194
+ var videoHeight = this.underlyingTrack.getSettings().height;
5195
+ if (videoHeight <= 180) {
5196
+ activeSimulcastLayersNumber = 1;
5197
+ } else if (videoHeight <= 360) {
5198
+ activeSimulcastLayersNumber = 2;
5199
+ } else {
5200
+ activeSimulcastLayersNumber = 3;
5201
+ }
5202
+ return activeSimulcastLayersNumber;
5203
+ }
5127
5204
  }
5128
5205
  LocalTrack.Events = exports.LocalTrackEvents;
5129
5206
 
@@ -8552,6 +8629,44 @@ class PeerConnection extends EventEmitter$2 {
8552
8629
  get iceGatheringState() {
8553
8630
  return this.pc.iceGatheringState;
8554
8631
  }
8632
+ /**
8633
+ * Returns the type of a connection that has been established.
8634
+ *
8635
+ * @returns The connection type which would be `ConnectionType`.
8636
+ */
8637
+ getCurrentConnectionType() {
8638
+ var _a;
8639
+ return __awaiter$1(this, void 0, void 0, function* () {
8640
+ // make sure this method only can be called when the ice connection is established;
8641
+ var isIceConnected = this.pc.iceConnectionState === 'connected' || this.pc.iceConnectionState === 'completed';
8642
+ if (!isIceConnected) {
8643
+ throw new Error('Ice connection is not established');
8644
+ }
8645
+ var succeededLocalCandidateIds = new Set();
8646
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
8647
+ var localCandidateStatsReports = [];
8648
+ (yield this.pc.getStats()).forEach(report => {
8649
+ var _a;
8650
+ // collect all local candidate ids from `candidate-pair` stats reports with `succeeded` state.
8651
+ if (report.type === 'candidate-pair' && ((_a = report.state) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === 'succeeded') {
8652
+ succeededLocalCandidateIds.add(report.localCandidateId);
8653
+ }
8654
+ // collect all `local-candidate` stats.
8655
+ if (report.type === 'local-candidate') {
8656
+ localCandidateStatsReports.push(report);
8657
+ }
8658
+ });
8659
+ // find the `local-candidate` stats which report id contains in `succeededLocalCandidateIds`.
8660
+ var localCandidate = localCandidateStatsReports.find(report => succeededLocalCandidateIds.has(report.id));
8661
+ if (!localCandidate) {
8662
+ return 'unknown';
8663
+ }
8664
+ if (localCandidate.relayProtocol) {
8665
+ return "TURN-".concat(localCandidate.relayProtocol.toUpperCase());
8666
+ }
8667
+ return (_a = localCandidate.protocol) === null || _a === void 0 ? void 0 : _a.toUpperCase();
8668
+ });
8669
+ }
8555
8670
  }
8556
8671
  PeerConnection.Events = PeerConnectionEvents;
8557
8672
 
@@ -12132,7 +12247,7 @@ function injectContentTypes(sdp, contentTypeMap) {
12132
12247
  });
12133
12248
  }
12134
12249
  function injectJmpAttributes(parsedSdp, csiMap, streamSignalingMode) {
12135
- parsedSdp.avMedia.filter(mLine => mLine.direction === 'sendrecv' || mLine.direction === 'sendonly').forEach(mLine => {
12250
+ parsedSdp.avMedia.filter(mLine => mLine.direction === 'sendrecv' || mLine.direction === 'inactive').forEach(mLine => {
12136
12251
  if (!mLine.otherLines.find(line => line instanceof JmpLine)) {
12137
12252
  mLine.addLine(new JmpLine());
12138
12253
  }
@@ -12149,11 +12264,15 @@ function injectJmpAttributes(parsedSdp, csiMap, streamSignalingMode) {
12149
12264
  }
12150
12265
  });
12151
12266
  }
12267
+ function hasSimulcast(av) {
12268
+ return !!av.simulcast || av.ssrcGroups.map(sg => sg.semantics).some(sem => sem === 'SIM');
12269
+ }
12152
12270
  class SendOnlyTransceiver extends Transceiver {
12153
12271
  constructor(rtcpRtpTransceiver, csi) {
12154
12272
  super(rtcpRtpTransceiver);
12155
12273
  this.requested = false;
12156
12274
  this.csi = csi;
12275
+ this.direction = 'sendrecv';
12157
12276
  this.handleTrackChange = this.handleTrackChange.bind(this);
12158
12277
  }
12159
12278
  handleTrackChange() {
@@ -12173,6 +12292,7 @@ class SendOnlyTransceiver extends Transceiver {
12173
12292
  var _a;
12174
12293
  return __awaiter(this, void 0, void 0, function* () {
12175
12294
  _super.replaceTransceiver.call(this, newRtcRtpTransceiver);
12295
+ newRtcRtpTransceiver.direction = this.direction;
12176
12296
  if (this.requested) {
12177
12297
  yield this.sender.replaceTrack(((_a = this.publishedTrack) === null || _a === void 0 ? void 0 : _a.underlyingTrack) || null);
12178
12298
  }
@@ -12242,8 +12362,8 @@ class SendOnlyTransceiver extends Transceiver {
12242
12362
  return this.replacePublishedTrack();
12243
12363
  }
12244
12364
  setActive(enabled) {
12245
- var direction = enabled ? 'sendrecv' : 'inactive';
12246
- this._rtcRtpTransceiver.direction = direction;
12365
+ this.direction = enabled ? 'sendrecv' : 'inactive';
12366
+ this._rtcRtpTransceiver.direction = this.direction;
12247
12367
  return this._rtcRtpTransceiver.direction !== this._rtcRtpTransceiver.currentDirection;
12248
12368
  }
12249
12369
  getStats() {
@@ -14142,11 +14262,14 @@ var defaultMultistreamConnectionOptions = {
14142
14262
  streamSignalingMode: 'SSRC',
14143
14263
  bundlePolicy: 'max-compat',
14144
14264
  iceServers: undefined,
14145
- disableContentSimulcast: true
14265
+ disableContentSimulcast: true,
14266
+ enableMainAudio: true,
14267
+ enableMainVideo: true
14146
14268
  };
14147
14269
  class MultistreamConnection extends EventEmitter {
14148
14270
  constructor() {
14149
14271
  var userOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
14272
+ var _a, _b;
14150
14273
  super();
14151
14274
  this.sendTransceivers = new Map();
14152
14275
  this.recvTransceivers = new Map();
@@ -14154,6 +14277,7 @@ class MultistreamConnection extends EventEmitter {
14154
14277
  this.pendingJmpTasks = [];
14155
14278
  this.metricsCallback = () => {};
14156
14279
  this.overuseUpdateCallback = () => {};
14280
+ this.customCodecParameters = new Map();
14157
14281
  this.midMap = new Map();
14158
14282
  this.currentMid = 0;
14159
14283
  this.options = Object.assign(Object.assign({}, defaultMultistreamConnectionOptions), userOptions);
@@ -14167,6 +14291,8 @@ class MultistreamConnection extends EventEmitter {
14167
14291
  var videoMainEncodingOptions = this.getVideoEncodingOptions(MediaContent$1.Main);
14168
14292
  this.createSendTransceiver(MediaType.VideoMain, mainSceneId, videoMainEncodingOptions);
14169
14293
  this.createSendTransceiver(MediaType.AudioMain, mainSceneId);
14294
+ (_a = this.sendTransceivers.get(MediaType.VideoMain)) === null || _a === void 0 ? void 0 : _a.setActive(this.options.enableMainVideo);
14295
+ (_b = this.sendTransceivers.get(MediaType.AudioMain)) === null || _b === void 0 ? void 0 : _b.setActive(this.options.enableMainAudio);
14170
14296
  if (this.options.floorControlledPresentation) {
14171
14297
  var videoPresentationEncodingOptions = this.getVideoEncodingOptions(MediaContent$1.Slides);
14172
14298
  var contentSceneId = generateSceneId();
@@ -14288,9 +14414,11 @@ class MultistreamConnection extends EventEmitter {
14288
14414
  this.jmpSessions.set(mediaType, jmpSession);
14289
14415
  }
14290
14416
  sendSourceWarnings(mediaType, requests) {
14417
+ var _a;
14291
14418
  if (getMediaFamily$1(mediaType) === MediaFamily.Video) {
14292
14419
  var sendTransceiver = this.getSendTransceiverOrThrow(mediaType);
14293
14420
  var signaler = this.streamSignalerManager.getEgressStreamSignalerOrThrow(sendTransceiver.mid);
14421
+ var activeSimulcastLayerNumber = ((_a = sendTransceiver.publishedTrack) === null || _a === void 0 ? void 0 : _a.getNumActiveSimulcastLayers()) || 0;
14294
14422
  var sourceWarnings = [];
14295
14423
  requests.forEach(_ref5 => {
14296
14424
  var {
@@ -14310,6 +14438,12 @@ class MultistreamConnection extends EventEmitter {
14310
14438
  state: 'invalid source',
14311
14439
  csi: sendTransceiver.csi
14312
14440
  });
14441
+ } else if (signaler.getEncodingIndexForStreamId(id) > activeSimulcastLayerNumber) {
14442
+ sourceWarnings.push({
14443
+ id,
14444
+ state: 'no source',
14445
+ csi: sendTransceiver.csi
14446
+ });
14313
14447
  }
14314
14448
  });
14315
14449
  });
@@ -14486,22 +14620,19 @@ class MultistreamConnection extends EventEmitter {
14486
14620
  });
14487
14621
  }
14488
14622
  addTrackListeners(mediaType, track) {
14489
- var onTrackMute = event => {
14490
- var sendTransceiver = this.getSendTransceiverOrThrow(mediaType);
14491
- var signaler = this.streamSignalerManager.getEgressStreamSignaler(sendTransceiver.mid);
14492
- if (!signaler) {
14493
- return;
14623
+ var onTrackResolutionChange = () => {
14624
+ var sources = this.getVideoSources(mediaType);
14625
+ if (sources != null) {
14626
+ this.sendSourceIndication(mediaType, 1, sources);
14494
14627
  }
14495
- if (this.getPublishedTracks().includes(track)) {
14496
- if (getMediaFamily$1(mediaType) === MediaFamily.Audio) {
14497
- this.sendSourceIndication(mediaType, +!event.trackState.muted);
14498
- } else {
14499
- var state = event.trackState.muted ? 'avatar' : 'live';
14500
- var sources = signaler.getSenderIds().map(id => ({
14501
- id,
14502
- state,
14503
- csi: sendTransceiver.csi
14504
- }));
14628
+ };
14629
+ track.on(LocalTrack.Events.TrackConstraintsChange, onTrackResolutionChange);
14630
+ var onTrackMute = event => {
14631
+ if (getMediaFamily$1(mediaType) === MediaFamily.Audio) {
14632
+ this.sendSourceIndication(mediaType, +!event.trackState.muted);
14633
+ } else {
14634
+ var sources = this.getVideoSources(mediaType);
14635
+ if (sources != null) {
14505
14636
  this.sendSourceIndication(mediaType, +!event.trackState.muted, sources);
14506
14637
  }
14507
14638
  }
@@ -14511,28 +14642,47 @@ class MultistreamConnection extends EventEmitter {
14511
14642
  if (!event.isPublished) {
14512
14643
  track.off(LocalTrack.Events.Muted, onTrackMute);
14513
14644
  track.off(LocalTrack.Events.PublishedStateUpdate, onTrackPublish);
14645
+ track.off(LocalTrack.Events.TrackConstraintsChange, onTrackResolutionChange);
14514
14646
  }
14515
- var sendTransceiver = this.getSendTransceiverOrThrow(mediaType);
14516
- var signaler = this.streamSignalerManager.getEgressStreamSignaler(sendTransceiver.mid);
14517
- if (!signaler) {
14518
- return;
14519
- }
14520
- if (!event.trackState.muted) {
14521
- if (getMediaFamily$1(mediaType) === MediaFamily.Audio) {
14522
- this.sendSourceIndication(mediaType, +event.isPublished);
14523
- } else {
14524
- var state = event.isPublished ? 'live' : 'no source';
14525
- var sources = signaler.getSenderIds().map(id => ({
14526
- id,
14527
- state,
14528
- csi: sendTransceiver.csi
14529
- }));
14647
+ if (getMediaFamily$1(mediaType) === MediaFamily.Audio) {
14648
+ this.sendSourceIndication(mediaType, +event.isPublished);
14649
+ } else {
14650
+ var sources = this.getVideoSources(mediaType);
14651
+ if (sources != null) {
14530
14652
  this.sendSourceIndication(mediaType, +event.isPublished, sources);
14531
14653
  }
14532
14654
  }
14533
14655
  };
14534
14656
  track.on(LocalTrack.Events.PublishedStateUpdate, onTrackPublish);
14535
14657
  }
14658
+ getVideoSources(mediaType) {
14659
+ var _a, _b, _c;
14660
+ var sendTransceiver = this.getSendTransceiverOrThrow(mediaType);
14661
+ var signaler = this.streamSignalerManager.getEgressStreamSignaler(sendTransceiver.mid);
14662
+ if (!signaler) {
14663
+ return null;
14664
+ }
14665
+ var activeSimulcastLayerNumber = ((_a = sendTransceiver.publishedTrack) === null || _a === void 0 ? void 0 : _a.getNumActiveSimulcastLayers()) || 0;
14666
+ var published = (_b = sendTransceiver.publishedTrack) === null || _b === void 0 ? void 0 : _b.published;
14667
+ var muted = ((_c = sendTransceiver.publishedTrack) === null || _c === void 0 ? void 0 : _c.muted) === true;
14668
+ return signaler.getSenderIds().map(id => {
14669
+ var state;
14670
+ if (!published) {
14671
+ state = 'no source';
14672
+ } else if (muted) {
14673
+ state = 'avatar';
14674
+ } else if (activeSimulcastLayerNumber <= signaler.getEncodingIndexForStreamId(id)) {
14675
+ state = 'no source';
14676
+ } else {
14677
+ state = 'live';
14678
+ }
14679
+ return {
14680
+ id,
14681
+ state,
14682
+ csi: sendTransceiver.csi
14683
+ };
14684
+ });
14685
+ }
14536
14686
  createReceiveSlot(mediaType) {
14537
14687
  return __awaiter(this, void 0, void 0, function* () {
14538
14688
  var rtcRtpTransceiver = this.pc.addTransceiver(toMediaStreamTrackKind(mediaType), {
@@ -14547,20 +14697,7 @@ class MultistreamConnection extends EventEmitter {
14547
14697
  return ingressSignaler.getReceiverId();
14548
14698
  });
14549
14699
  if (this.pc.getRemoteDescription()) {
14550
- yield this.pc.createOffer().then(offer => {
14551
- if (!offer.sdp) {
14552
- throw new Error('No SDP offer');
14553
- }
14554
- offer.sdp = this.preProcessLocalOffer(offer.sdp);
14555
- return this.pc.setLocalDescription(offer);
14556
- }).then(() => {
14557
- var _a;
14558
- var answer = this.preProcessRemoteAnswer((_a = this.pc.getRemoteDescription()) === null || _a === void 0 ? void 0 : _a.sdp);
14559
- return this.pc.setRemoteDescription({
14560
- type: 'answer',
14561
- sdp: answer
14562
- });
14563
- });
14700
+ yield this.doLocalOfferAnswer();
14564
14701
  }
14565
14702
  this.recvTransceivers.set(mediaType, [...(this.recvTransceivers.get(mediaType) || []), recvOnlyTransceiver]);
14566
14703
  return recvOnlyTransceiver.receiveSlot;
@@ -14608,10 +14745,31 @@ class MultistreamConnection extends EventEmitter {
14608
14745
  }
14609
14746
  setAnswer(answer) {
14610
14747
  return __awaiter(this, void 0, void 0, function* () {
14748
+ var isInitialAnswer = !this.pc.getRemoteDescription();
14611
14749
  var sdp = this.preProcessRemoteAnswer(answer);
14612
14750
  return this.pc.setRemoteDescription({
14613
14751
  type: 'answer',
14614
14752
  sdp
14753
+ }).then(() => {
14754
+ if (isInitialAnswer && this.customCodecParameters.size > 0) {
14755
+ this.doLocalOfferAnswer();
14756
+ }
14757
+ });
14758
+ });
14759
+ }
14760
+ doLocalOfferAnswer() {
14761
+ var _a;
14762
+ return __awaiter(this, void 0, void 0, function* () {
14763
+ var offer = yield this.pc.createOffer();
14764
+ if (!offer.sdp) {
14765
+ throw new Error('No SDP offer');
14766
+ }
14767
+ offer.sdp = this.preProcessLocalOffer(offer.sdp);
14768
+ yield this.pc.setLocalDescription(offer);
14769
+ var answer = this.preProcessRemoteAnswer((_a = this.pc.getRemoteDescription()) === null || _a === void 0 ? void 0 : _a.sdp);
14770
+ return this.pc.setRemoteDescription({
14771
+ type: 'answer',
14772
+ sdp: answer
14615
14773
  });
14616
14774
  });
14617
14775
  }
@@ -14632,7 +14790,7 @@ class MultistreamConnection extends EventEmitter {
14632
14790
  });
14633
14791
  parsed.avMedia.filter(av => av.direction === 'sendrecv').forEach(av => {
14634
14792
  var egressSignaler = this.streamSignalerManager.getOrCreateEgressStreamSignaler(av.mid);
14635
- var simulcastEnabled = !!av.simulcast;
14793
+ var simulcastEnabled = hasSimulcast(av);
14636
14794
  var rtxEnabled = av.type === 'video';
14637
14795
  egressSignaler.signalStreams(simulcastEnabled, rtxEnabled, av);
14638
14796
  if (av.type === 'video') {
@@ -14641,6 +14799,22 @@ class MultistreamConnection extends EventEmitter {
14641
14799
  ci.fmtParams.set('max-fs', "".concat(defaultMaxVideoEncodeFrameSize));
14642
14800
  });
14643
14801
  }
14802
+ var mediaType = [...this.sendTransceivers.keys()].find(key => {
14803
+ var _a;
14804
+ return ((_a = this.sendTransceivers.get(key)) === null || _a === void 0 ? void 0 : _a.mid) === av.mid;
14805
+ });
14806
+ if (mediaType && this.customCodecParameters.has(mediaType)) {
14807
+ [...av.codecs.values()].filter(ci => ci.name === (av.type === 'audio' ? 'opus' : 'H264')).forEach(ci => {
14808
+ var _a;
14809
+ (_a = this.customCodecParameters.get(mediaType)) === null || _a === void 0 ? void 0 : _a.forEach((value, param) => {
14810
+ if (value === null) {
14811
+ ci.fmtParams.delete(param);
14812
+ } else {
14813
+ ci.fmtParams.set(param, "".concat(value));
14814
+ }
14815
+ });
14816
+ });
14817
+ }
14644
14818
  });
14645
14819
  if (getBrowserDetails().name !== 'Firefox') {
14646
14820
  setupBundle(parsed, this.options.bundlePolicy, this.midMap);
@@ -14690,6 +14864,31 @@ class MultistreamConnection extends EventEmitter {
14690
14864
  getPublishedTracks() {
14691
14865
  return [...this.sendTransceivers.values()].map(transceiver => transceiver.publishedTrack).filter(Boolean);
14692
14866
  }
14867
+ setCodecParameters(mediaType, parameters) {
14868
+ return __awaiter(this, void 0, void 0, function* () {
14869
+ var currentParams = this.customCodecParameters.get(mediaType) || new Map();
14870
+ Object.entries(parameters).forEach(_ref7 => {
14871
+ var [param, value] = _ref7;
14872
+ currentParams.set(param, value);
14873
+ });
14874
+ this.customCodecParameters.set(mediaType, currentParams);
14875
+ if (this.pc.getRemoteDescription()) {
14876
+ yield this.doLocalOfferAnswer();
14877
+ }
14878
+ });
14879
+ }
14880
+ deleteCodecParameters(mediaType, parameters) {
14881
+ return __awaiter(this, void 0, void 0, function* () {
14882
+ var currentParams = this.customCodecParameters.get(mediaType) || new Map();
14883
+ parameters.forEach(param => {
14884
+ currentParams.set(param, null);
14885
+ });
14886
+ this.customCodecParameters.set(mediaType, currentParams);
14887
+ if (this.pc.getRemoteDescription()) {
14888
+ yield this.doLocalOfferAnswer();
14889
+ }
14890
+ });
14891
+ }
14693
14892
  requestMedia(mediaType, mediaRequests) {
14694
14893
  var _a;
14695
14894
  var task = () => {
@@ -14765,8 +14964,8 @@ class MultistreamConnection extends EventEmitter {
14765
14964
  }
14766
14965
  preProcessStats(stats) {
14767
14966
  return __awaiter(this, void 0, void 0, function* () {
14768
- yield Promise.all([...this.sendTransceivers.entries()].map(_ref7 => {
14769
- var [mediaType, transceiver] = _ref7;
14967
+ yield Promise.all([...this.sendTransceivers.entries()].map(_ref8 => {
14968
+ var [mediaType, transceiver] = _ref8;
14770
14969
  return __awaiter(this, void 0, void 0, function* () {
14771
14970
  (yield transceiver.getStats()).forEach(senderStats => {
14772
14971
  var _a;
@@ -14784,8 +14983,8 @@ class MultistreamConnection extends EventEmitter {
14784
14983
  });
14785
14984
  });
14786
14985
  }));
14787
- yield Promise.all([...this.recvTransceivers.entries()].map(_ref8 => {
14788
- var [mediaType, transceivers] = _ref8;
14986
+ yield Promise.all([...this.recvTransceivers.entries()].map(_ref9 => {
14987
+ var [mediaType, transceivers] = _ref9;
14789
14988
  return __awaiter(this, void 0, void 0, function* () {
14790
14989
  yield Promise.all(transceivers.map(transceiver => __awaiter(this, void 0, void 0, function* () {
14791
14990
  (yield transceiver.getStats()).forEach(receiverStats => {
@@ -23908,6 +24107,14 @@ class MultistreamRoapMediaConnection extends EventEmitter$4 {
23908
24107
  }
23909
24108
  this.roap.roapMessageReceived(roapMessage);
23910
24109
  }
24110
+ enableMultistreamAudio(enabled) {
24111
+ this.log('enableMultistreamAudio()', 'called');
24112
+ var sdpNegotiationNeeded = this.multistreamConnection.enableMultistreamAudio(enabled);
24113
+ if (sdpNegotiationNeeded) {
24114
+ return this.roap.initiateOffer();
24115
+ }
24116
+ return Promise.resolve();
24117
+ }
23911
24118
  publishTrack(track) {
23912
24119
  this.log('publishTrack()', 'called');
23913
24120
  return this.multistreamConnection.publishTrack(track);
package/dist/esm/index.js CHANGED
@@ -2922,6 +2922,22 @@ class FingerprintLine$1 extends Line$1 {
2922
2922
  }
2923
2923
  }
2924
2924
  FingerprintLine$1.regex = new RegExp("^fingerprint:(".concat(REST$1, ")"));
2925
+ function parseFmtpParams$1(fmtpParams) {
2926
+ fmtpParams = fmtpParams.replace(/^a=fmtp:\d+\x20/, '');
2927
+ var fmtpObj = new Map();
2928
+ if (/^\d+([/-]\d+)+$/.test(fmtpParams)) {
2929
+ fmtpObj.set(fmtpParams, undefined);
2930
+ return fmtpObj;
2931
+ }
2932
+ fmtpParams.split(';').forEach(param => {
2933
+ var paramArr = param && param.split('=');
2934
+ if (paramArr.length !== 2 || !paramArr[0] || !paramArr[1]) {
2935
+ throw new Error("Fmtp params is invalid with ".concat(fmtpParams));
2936
+ }
2937
+ fmtpObj.set(paramArr[0], paramArr[1]);
2938
+ });
2939
+ return fmtpObj;
2940
+ }
2925
2941
  class FmtpLine$1 extends Line$1 {
2926
2942
  constructor(payloadType, params) {
2927
2943
  super();
@@ -2935,10 +2951,16 @@ class FmtpLine$1 extends Line$1 {
2935
2951
  var tokens = line.match(FmtpLine$1.regex);
2936
2952
  var payloadType = parseInt(tokens[1], 10);
2937
2953
  var params = tokens[2];
2938
- return new FmtpLine$1(payloadType, params);
2954
+ return new FmtpLine$1(payloadType, parseFmtpParams$1(params));
2939
2955
  }
2940
2956
  toSdpLine() {
2941
- return "a=fmtp:".concat(this.payloadType, " ").concat(this.params);
2957
+ var fmtParams = Array.from(this.params.keys()).map(key => {
2958
+ if (this.params.get(key) !== undefined) {
2959
+ return "".concat(key, "=").concat(this.params.get(key));
2960
+ }
2961
+ return "".concat(key);
2962
+ }).join(';');
2963
+ return "a=fmtp:".concat(this.payloadType, " ").concat(fmtParams);
2942
2964
  }
2943
2965
  }
2944
2966
  FmtpLine$1.regex = new RegExp("^fmtp:(".concat(NUM$1, ") (").concat(REST$1, ")"));
@@ -3599,7 +3621,7 @@ class ApplicationMediaDescription$1 extends MediaDescription$1 {
3599
3621
  }
3600
3622
  class CodecInfo$2 {
3601
3623
  constructor(pt) {
3602
- this.fmtParams = [];
3624
+ this.fmtParams = new Map();
3603
3625
  this.feedback = [];
3604
3626
  this.pt = pt;
3605
3627
  }
@@ -3611,9 +3633,9 @@ class CodecInfo$2 {
3611
3633
  return true;
3612
3634
  }
3613
3635
  if (line instanceof FmtpLine$1) {
3614
- this.fmtParams.push(line.params);
3615
- if (line.params.indexOf('apt') !== -1) {
3616
- var apt = line.params.split('=')[1];
3636
+ this.fmtParams = new Map([...Array.from(this.fmtParams.entries()), ...Array.from(line.params.entries())]);
3637
+ if (line.params.has('apt')) {
3638
+ var apt = line.params.get('apt');
3617
3639
  this.primaryCodecPt = parseInt(apt, 10);
3618
3640
  }
3619
3641
  return true;
@@ -3626,13 +3648,15 @@ class CodecInfo$2 {
3626
3648
  }
3627
3649
  toLines() {
3628
3650
  var lines = [];
3629
- lines.push(new RtpMapLine$1(this.pt, this.name, this.clockRate, this.encodingParams));
3651
+ if (this.name && this.clockRate) {
3652
+ lines.push(new RtpMapLine$1(this.pt, this.name, this.clockRate, this.encodingParams));
3653
+ }
3630
3654
  this.feedback.forEach(fb => {
3631
3655
  lines.push(new RtcpFbLine$1(this.pt, fb));
3632
3656
  });
3633
- this.fmtParams.forEach(fmt => {
3634
- lines.push(new FmtpLine$1(this.pt, fmt));
3635
- });
3657
+ if (this.fmtParams.size > 0) {
3658
+ lines.push(new FmtpLine$1(this.pt, this.fmtParams));
3659
+ }
3636
3660
  return lines;
3637
3661
  }
3638
3662
  }
@@ -4033,13 +4057,13 @@ function disableExtmap(sdp) {
4033
4057
  media.extMaps.length = 0;
4034
4058
  });
4035
4059
  }
4036
- function appendToH264fmtpParams(sdp, paramsToAppend) {
4060
+ function updateH264fmtpParams(sdp, paramsToUpdate) {
4037
4061
  sdp.avMedia.forEach(media => {
4038
4062
  if (media.type === 'video') {
4039
4063
  media.codecs.forEach(codec => {
4040
4064
  var _codec$name2;
4041
4065
  if (((_codec$name2 = codec.name) === null || _codec$name2 === void 0 ? void 0 : _codec$name2.toUpperCase()) === 'H264') {
4042
- codec.fmtParams = codec.fmtParams.map(fmtp => "".concat(fmtp, ";").concat(paramsToAppend));
4066
+ paramsToUpdate.forEach((value, key) => codec.fmtParams.set(key, value));
4043
4067
  }
4044
4068
  });
4045
4069
  }
@@ -4073,32 +4097,30 @@ function adjustH264Profile(sdp, maxFsValue) {
4073
4097
  media.codecs.forEach(codec => {
4074
4098
  var _codec$name3;
4075
4099
  if (((_codec$name3 = codec.name) === null || _codec$name3 === void 0 ? void 0 : _codec$name3.toUpperCase()) === 'H264') {
4076
- codec.fmtParams = codec.fmtParams.map(fmtp => {
4077
- var parsedRegex = fmtp.match(/(.*)profile-level-id=(\w{4})(\w{2})(.*)/);
4078
- if (parsedRegex && parsedRegex.length === 5) {
4079
- var stuffBeforeProfileLevelId = parsedRegex[1];
4080
- var profile = parsedRegex[2].toLowerCase();
4081
- var levelId = parseInt(parsedRegex[3], 16);
4082
- var stuffAfterProfileLevelId = parsedRegex[4];
4083
- if (!maxFsForProfileLevel[levelId]) {
4084
- throw new Error("found unsupported h264 profile level id value in the SDP: ".concat(levelId));
4085
- }
4086
- if (maxFsForProfileLevel[levelId] === maxFsValue) {
4087
- return fmtp;
4088
- }
4089
- if (maxFsForProfileLevel[levelId] < maxFsValue) {
4090
- return "".concat(fmtp, ";max-fs=").concat(maxFsValue, ";max-mbps=").concat(maxFsValue * framesPerSecond);
4091
- }
4092
- var newLevelId = Object.keys(maxFsForProfileLevel).reverse().find(key => maxFsForProfileLevel[key] === maxFsValue);
4093
- if (newLevelId) {
4094
- var newLevelIdHex = parseInt(newLevelId, 10).toString(16);
4095
- var maxMbps = "max-mbps=".concat(maxFsValue * framesPerSecond);
4096
- return "".concat(stuffBeforeProfileLevelId, "profile-level-id=").concat(profile).concat(newLevelIdHex, ";").concat(maxMbps).concat(stuffAfterProfileLevelId);
4097
- }
4098
- throw new Error("unsupported maxFsValue: ".concat(maxFsValue));
4100
+ var profileLevelIdValue = codec.fmtParams.get('profile-level-id');
4101
+ if (profileLevelIdValue) {
4102
+ var profile = profileLevelIdValue.substring(0, 4).toLowerCase();
4103
+ var levelId = parseInt(profileLevelIdValue.substring(4, 6), 16);
4104
+ if (!maxFsForProfileLevel[levelId]) {
4105
+ throw new Error("found unsupported h264 profile level id value in the SDP: ".concat(levelId));
4099
4106
  }
4100
- return fmtp;
4101
- });
4107
+ if (maxFsForProfileLevel[levelId] === maxFsValue) {
4108
+ return;
4109
+ }
4110
+ if (maxFsForProfileLevel[levelId] < maxFsValue) {
4111
+ codec.fmtParams.set('max-fs', "".concat(maxFsValue));
4112
+ codec.fmtParams.set('max-mbps', "".concat(maxFsValue * framesPerSecond));
4113
+ return;
4114
+ }
4115
+ var newLevelId = Object.keys(maxFsForProfileLevel).reverse().find(key => maxFsForProfileLevel[key] === maxFsValue);
4116
+ if (newLevelId) {
4117
+ var newLevelIdHex = parseInt(newLevelId, 10).toString(16);
4118
+ codec.fmtParams.set('profile-level-id', "".concat(profile).concat(newLevelIdHex));
4119
+ codec.fmtParams.set('max-mbps', "".concat(maxFsValue * framesPerSecond));
4120
+ return;
4121
+ }
4122
+ throw new Error("unsupported maxFsValue: ".concat(maxFsValue));
4123
+ }
4102
4124
  }
4103
4125
  });
4104
4126
  }
@@ -4149,7 +4171,7 @@ function mungeLocalSdp(config, sdp) {
4149
4171
  return parsedSdp.toString();
4150
4172
  }
4151
4173
  function setStartBitrate(sdp, startBitrate) {
4152
- appendToH264fmtpParams(sdp, "x-google-start-bitrate=".concat(startBitrate));
4174
+ updateH264fmtpParams(sdp, new Map([['x-google-start-bitrate', startBitrate.toString()]]));
4153
4175
  }
4154
4176
  function removeXtlsIceCandidates(sdp) {
4155
4177
  sdp.media.forEach(media => {
@@ -4915,6 +4937,10 @@ var LocalTrackEvents;
4915
4937
  * Fires when there has been a change in the underlying track.
4916
4938
  */
4917
4939
  LocalTrackEvents["UnderlyingTrackChange"] = "underlying-track-change";
4940
+ /**
4941
+ * Fires when the applyConstraints() has been called for the track.
4942
+ */
4943
+ LocalTrackEvents["TrackConstraintsChange"] = "track-constraints-change";
4918
4944
  })(LocalTrackEvents || (LocalTrackEvents = {}));
4919
4945
  // TBD: Fix this once types are published separately
4920
4946
  // export type TrackEffect = BaseMicrophoneEffect | BaseCameraEffect;
@@ -5103,7 +5129,7 @@ class LocalTrack extends EventEmitter$2 {
5103
5129
  return effect;
5104
5130
  }
5105
5131
  /**
5106
- * Cleanup local microphone track.
5132
+ * Cleanup the local microphone track.
5107
5133
  */
5108
5134
  disposeEffects() {
5109
5135
  if (this.effects.size > 0) {
@@ -5113,6 +5139,57 @@ class LocalTrack extends EventEmitter$2 {
5113
5139
  this.emit(LocalTrackEvents.UnderlyingTrackChange);
5114
5140
  }
5115
5141
  }
5142
+ /**
5143
+ * Apply constraints to the track.
5144
+ *
5145
+ * @param constraints - The constraints to apply to the track.
5146
+ * @returns A promise which resolves when the constraints have been successfully applied.
5147
+ */
5148
+ applyConstraints(constraints) {
5149
+ return __awaiter$1(this, void 0, void 0, function* () {
5150
+ logger$3.log("Applying constraints to local track:", constraints);
5151
+ var ret = this.underlyingTrack.applyConstraints(constraints).then(() => {
5152
+ this.emit(LocalTrackEvents.TrackConstraintsChange);
5153
+ });
5154
+ return ret;
5155
+ });
5156
+ }
5157
+ /**
5158
+ * Get the current constraints of the track.
5159
+ *
5160
+ * @returns The constraints of the track.
5161
+ */
5162
+ getConstraints() {
5163
+ return this.underlyingTrack.getConstraints();
5164
+ }
5165
+ /**
5166
+ * Get the current settings of the track.
5167
+ *
5168
+ * @returns The settings of the track.
5169
+ */
5170
+ getSettings() {
5171
+ return this.underlyingTrack.getSettings();
5172
+ }
5173
+ /**
5174
+ * Check the resolution and then return how many layers will be active.
5175
+ *
5176
+ * @returns The active layers count.
5177
+ */
5178
+ getNumActiveSimulcastLayers() {
5179
+ var activeSimulcastLayersNumber = 0;
5180
+ if (this.trackState.type === 'audio') {
5181
+ return activeSimulcastLayersNumber;
5182
+ }
5183
+ var videoHeight = this.underlyingTrack.getSettings().height;
5184
+ if (videoHeight <= 180) {
5185
+ activeSimulcastLayersNumber = 1;
5186
+ } else if (videoHeight <= 360) {
5187
+ activeSimulcastLayersNumber = 2;
5188
+ } else {
5189
+ activeSimulcastLayersNumber = 3;
5190
+ }
5191
+ return activeSimulcastLayersNumber;
5192
+ }
5116
5193
  }
5117
5194
  LocalTrack.Events = LocalTrackEvents;
5118
5195
 
@@ -8541,6 +8618,44 @@ class PeerConnection extends EventEmitter$2 {
8541
8618
  get iceGatheringState() {
8542
8619
  return this.pc.iceGatheringState;
8543
8620
  }
8621
+ /**
8622
+ * Returns the type of a connection that has been established.
8623
+ *
8624
+ * @returns The connection type which would be `ConnectionType`.
8625
+ */
8626
+ getCurrentConnectionType() {
8627
+ var _a;
8628
+ return __awaiter$1(this, void 0, void 0, function* () {
8629
+ // make sure this method only can be called when the ice connection is established;
8630
+ var isIceConnected = this.pc.iceConnectionState === 'connected' || this.pc.iceConnectionState === 'completed';
8631
+ if (!isIceConnected) {
8632
+ throw new Error('Ice connection is not established');
8633
+ }
8634
+ var succeededLocalCandidateIds = new Set();
8635
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
8636
+ var localCandidateStatsReports = [];
8637
+ (yield this.pc.getStats()).forEach(report => {
8638
+ var _a;
8639
+ // collect all local candidate ids from `candidate-pair` stats reports with `succeeded` state.
8640
+ if (report.type === 'candidate-pair' && ((_a = report.state) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === 'succeeded') {
8641
+ succeededLocalCandidateIds.add(report.localCandidateId);
8642
+ }
8643
+ // collect all `local-candidate` stats.
8644
+ if (report.type === 'local-candidate') {
8645
+ localCandidateStatsReports.push(report);
8646
+ }
8647
+ });
8648
+ // find the `local-candidate` stats which report id contains in `succeededLocalCandidateIds`.
8649
+ var localCandidate = localCandidateStatsReports.find(report => succeededLocalCandidateIds.has(report.id));
8650
+ if (!localCandidate) {
8651
+ return 'unknown';
8652
+ }
8653
+ if (localCandidate.relayProtocol) {
8654
+ return "TURN-".concat(localCandidate.relayProtocol.toUpperCase());
8655
+ }
8656
+ return (_a = localCandidate.protocol) === null || _a === void 0 ? void 0 : _a.toUpperCase();
8657
+ });
8658
+ }
8544
8659
  }
8545
8660
  PeerConnection.Events = PeerConnectionEvents;
8546
8661
 
@@ -12121,7 +12236,7 @@ function injectContentTypes(sdp, contentTypeMap) {
12121
12236
  });
12122
12237
  }
12123
12238
  function injectJmpAttributes(parsedSdp, csiMap, streamSignalingMode) {
12124
- parsedSdp.avMedia.filter(mLine => mLine.direction === 'sendrecv' || mLine.direction === 'sendonly').forEach(mLine => {
12239
+ parsedSdp.avMedia.filter(mLine => mLine.direction === 'sendrecv' || mLine.direction === 'inactive').forEach(mLine => {
12125
12240
  if (!mLine.otherLines.find(line => line instanceof JmpLine)) {
12126
12241
  mLine.addLine(new JmpLine());
12127
12242
  }
@@ -12138,11 +12253,15 @@ function injectJmpAttributes(parsedSdp, csiMap, streamSignalingMode) {
12138
12253
  }
12139
12254
  });
12140
12255
  }
12256
+ function hasSimulcast(av) {
12257
+ return !!av.simulcast || av.ssrcGroups.map(sg => sg.semantics).some(sem => sem === 'SIM');
12258
+ }
12141
12259
  class SendOnlyTransceiver extends Transceiver {
12142
12260
  constructor(rtcpRtpTransceiver, csi) {
12143
12261
  super(rtcpRtpTransceiver);
12144
12262
  this.requested = false;
12145
12263
  this.csi = csi;
12264
+ this.direction = 'sendrecv';
12146
12265
  this.handleTrackChange = this.handleTrackChange.bind(this);
12147
12266
  }
12148
12267
  handleTrackChange() {
@@ -12162,6 +12281,7 @@ class SendOnlyTransceiver extends Transceiver {
12162
12281
  var _a;
12163
12282
  return __awaiter(this, void 0, void 0, function* () {
12164
12283
  _super.replaceTransceiver.call(this, newRtcRtpTransceiver);
12284
+ newRtcRtpTransceiver.direction = this.direction;
12165
12285
  if (this.requested) {
12166
12286
  yield this.sender.replaceTrack(((_a = this.publishedTrack) === null || _a === void 0 ? void 0 : _a.underlyingTrack) || null);
12167
12287
  }
@@ -12231,8 +12351,8 @@ class SendOnlyTransceiver extends Transceiver {
12231
12351
  return this.replacePublishedTrack();
12232
12352
  }
12233
12353
  setActive(enabled) {
12234
- var direction = enabled ? 'sendrecv' : 'inactive';
12235
- this._rtcRtpTransceiver.direction = direction;
12354
+ this.direction = enabled ? 'sendrecv' : 'inactive';
12355
+ this._rtcRtpTransceiver.direction = this.direction;
12236
12356
  return this._rtcRtpTransceiver.direction !== this._rtcRtpTransceiver.currentDirection;
12237
12357
  }
12238
12358
  getStats() {
@@ -14131,11 +14251,14 @@ var defaultMultistreamConnectionOptions = {
14131
14251
  streamSignalingMode: 'SSRC',
14132
14252
  bundlePolicy: 'max-compat',
14133
14253
  iceServers: undefined,
14134
- disableContentSimulcast: true
14254
+ disableContentSimulcast: true,
14255
+ enableMainAudio: true,
14256
+ enableMainVideo: true
14135
14257
  };
14136
14258
  class MultistreamConnection extends EventEmitter {
14137
14259
  constructor() {
14138
14260
  var userOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
14261
+ var _a, _b;
14139
14262
  super();
14140
14263
  this.sendTransceivers = new Map();
14141
14264
  this.recvTransceivers = new Map();
@@ -14143,6 +14266,7 @@ class MultistreamConnection extends EventEmitter {
14143
14266
  this.pendingJmpTasks = [];
14144
14267
  this.metricsCallback = () => {};
14145
14268
  this.overuseUpdateCallback = () => {};
14269
+ this.customCodecParameters = new Map();
14146
14270
  this.midMap = new Map();
14147
14271
  this.currentMid = 0;
14148
14272
  this.options = Object.assign(Object.assign({}, defaultMultistreamConnectionOptions), userOptions);
@@ -14156,6 +14280,8 @@ class MultistreamConnection extends EventEmitter {
14156
14280
  var videoMainEncodingOptions = this.getVideoEncodingOptions(MediaContent$1.Main);
14157
14281
  this.createSendTransceiver(MediaType$1.VideoMain, mainSceneId, videoMainEncodingOptions);
14158
14282
  this.createSendTransceiver(MediaType$1.AudioMain, mainSceneId);
14283
+ (_a = this.sendTransceivers.get(MediaType$1.VideoMain)) === null || _a === void 0 ? void 0 : _a.setActive(this.options.enableMainVideo);
14284
+ (_b = this.sendTransceivers.get(MediaType$1.AudioMain)) === null || _b === void 0 ? void 0 : _b.setActive(this.options.enableMainAudio);
14159
14285
  if (this.options.floorControlledPresentation) {
14160
14286
  var videoPresentationEncodingOptions = this.getVideoEncodingOptions(MediaContent$1.Slides);
14161
14287
  var contentSceneId = generateSceneId();
@@ -14277,9 +14403,11 @@ class MultistreamConnection extends EventEmitter {
14277
14403
  this.jmpSessions.set(mediaType, jmpSession);
14278
14404
  }
14279
14405
  sendSourceWarnings(mediaType, requests) {
14406
+ var _a;
14280
14407
  if (getMediaFamily$1(mediaType) === MediaFamily$1.Video) {
14281
14408
  var sendTransceiver = this.getSendTransceiverOrThrow(mediaType);
14282
14409
  var signaler = this.streamSignalerManager.getEgressStreamSignalerOrThrow(sendTransceiver.mid);
14410
+ var activeSimulcastLayerNumber = ((_a = sendTransceiver.publishedTrack) === null || _a === void 0 ? void 0 : _a.getNumActiveSimulcastLayers()) || 0;
14283
14411
  var sourceWarnings = [];
14284
14412
  requests.forEach(_ref5 => {
14285
14413
  var {
@@ -14299,6 +14427,12 @@ class MultistreamConnection extends EventEmitter {
14299
14427
  state: 'invalid source',
14300
14428
  csi: sendTransceiver.csi
14301
14429
  });
14430
+ } else if (signaler.getEncodingIndexForStreamId(id) > activeSimulcastLayerNumber) {
14431
+ sourceWarnings.push({
14432
+ id,
14433
+ state: 'no source',
14434
+ csi: sendTransceiver.csi
14435
+ });
14302
14436
  }
14303
14437
  });
14304
14438
  });
@@ -14475,22 +14609,19 @@ class MultistreamConnection extends EventEmitter {
14475
14609
  });
14476
14610
  }
14477
14611
  addTrackListeners(mediaType, track) {
14478
- var onTrackMute = event => {
14479
- var sendTransceiver = this.getSendTransceiverOrThrow(mediaType);
14480
- var signaler = this.streamSignalerManager.getEgressStreamSignaler(sendTransceiver.mid);
14481
- if (!signaler) {
14482
- return;
14612
+ var onTrackResolutionChange = () => {
14613
+ var sources = this.getVideoSources(mediaType);
14614
+ if (sources != null) {
14615
+ this.sendSourceIndication(mediaType, 1, sources);
14483
14616
  }
14484
- if (this.getPublishedTracks().includes(track)) {
14485
- if (getMediaFamily$1(mediaType) === MediaFamily$1.Audio) {
14486
- this.sendSourceIndication(mediaType, +!event.trackState.muted);
14487
- } else {
14488
- var state = event.trackState.muted ? 'avatar' : 'live';
14489
- var sources = signaler.getSenderIds().map(id => ({
14490
- id,
14491
- state,
14492
- csi: sendTransceiver.csi
14493
- }));
14617
+ };
14618
+ track.on(LocalTrack.Events.TrackConstraintsChange, onTrackResolutionChange);
14619
+ var onTrackMute = event => {
14620
+ if (getMediaFamily$1(mediaType) === MediaFamily$1.Audio) {
14621
+ this.sendSourceIndication(mediaType, +!event.trackState.muted);
14622
+ } else {
14623
+ var sources = this.getVideoSources(mediaType);
14624
+ if (sources != null) {
14494
14625
  this.sendSourceIndication(mediaType, +!event.trackState.muted, sources);
14495
14626
  }
14496
14627
  }
@@ -14500,28 +14631,47 @@ class MultistreamConnection extends EventEmitter {
14500
14631
  if (!event.isPublished) {
14501
14632
  track.off(LocalTrack.Events.Muted, onTrackMute);
14502
14633
  track.off(LocalTrack.Events.PublishedStateUpdate, onTrackPublish);
14634
+ track.off(LocalTrack.Events.TrackConstraintsChange, onTrackResolutionChange);
14503
14635
  }
14504
- var sendTransceiver = this.getSendTransceiverOrThrow(mediaType);
14505
- var signaler = this.streamSignalerManager.getEgressStreamSignaler(sendTransceiver.mid);
14506
- if (!signaler) {
14507
- return;
14508
- }
14509
- if (!event.trackState.muted) {
14510
- if (getMediaFamily$1(mediaType) === MediaFamily$1.Audio) {
14511
- this.sendSourceIndication(mediaType, +event.isPublished);
14512
- } else {
14513
- var state = event.isPublished ? 'live' : 'no source';
14514
- var sources = signaler.getSenderIds().map(id => ({
14515
- id,
14516
- state,
14517
- csi: sendTransceiver.csi
14518
- }));
14636
+ if (getMediaFamily$1(mediaType) === MediaFamily$1.Audio) {
14637
+ this.sendSourceIndication(mediaType, +event.isPublished);
14638
+ } else {
14639
+ var sources = this.getVideoSources(mediaType);
14640
+ if (sources != null) {
14519
14641
  this.sendSourceIndication(mediaType, +event.isPublished, sources);
14520
14642
  }
14521
14643
  }
14522
14644
  };
14523
14645
  track.on(LocalTrack.Events.PublishedStateUpdate, onTrackPublish);
14524
14646
  }
14647
+ getVideoSources(mediaType) {
14648
+ var _a, _b, _c;
14649
+ var sendTransceiver = this.getSendTransceiverOrThrow(mediaType);
14650
+ var signaler = this.streamSignalerManager.getEgressStreamSignaler(sendTransceiver.mid);
14651
+ if (!signaler) {
14652
+ return null;
14653
+ }
14654
+ var activeSimulcastLayerNumber = ((_a = sendTransceiver.publishedTrack) === null || _a === void 0 ? void 0 : _a.getNumActiveSimulcastLayers()) || 0;
14655
+ var published = (_b = sendTransceiver.publishedTrack) === null || _b === void 0 ? void 0 : _b.published;
14656
+ var muted = ((_c = sendTransceiver.publishedTrack) === null || _c === void 0 ? void 0 : _c.muted) === true;
14657
+ return signaler.getSenderIds().map(id => {
14658
+ var state;
14659
+ if (!published) {
14660
+ state = 'no source';
14661
+ } else if (muted) {
14662
+ state = 'avatar';
14663
+ } else if (activeSimulcastLayerNumber <= signaler.getEncodingIndexForStreamId(id)) {
14664
+ state = 'no source';
14665
+ } else {
14666
+ state = 'live';
14667
+ }
14668
+ return {
14669
+ id,
14670
+ state,
14671
+ csi: sendTransceiver.csi
14672
+ };
14673
+ });
14674
+ }
14525
14675
  createReceiveSlot(mediaType) {
14526
14676
  return __awaiter(this, void 0, void 0, function* () {
14527
14677
  var rtcRtpTransceiver = this.pc.addTransceiver(toMediaStreamTrackKind(mediaType), {
@@ -14536,20 +14686,7 @@ class MultistreamConnection extends EventEmitter {
14536
14686
  return ingressSignaler.getReceiverId();
14537
14687
  });
14538
14688
  if (this.pc.getRemoteDescription()) {
14539
- yield this.pc.createOffer().then(offer => {
14540
- if (!offer.sdp) {
14541
- throw new Error('No SDP offer');
14542
- }
14543
- offer.sdp = this.preProcessLocalOffer(offer.sdp);
14544
- return this.pc.setLocalDescription(offer);
14545
- }).then(() => {
14546
- var _a;
14547
- var answer = this.preProcessRemoteAnswer((_a = this.pc.getRemoteDescription()) === null || _a === void 0 ? void 0 : _a.sdp);
14548
- return this.pc.setRemoteDescription({
14549
- type: 'answer',
14550
- sdp: answer
14551
- });
14552
- });
14689
+ yield this.doLocalOfferAnswer();
14553
14690
  }
14554
14691
  this.recvTransceivers.set(mediaType, [...(this.recvTransceivers.get(mediaType) || []), recvOnlyTransceiver]);
14555
14692
  return recvOnlyTransceiver.receiveSlot;
@@ -14597,10 +14734,31 @@ class MultistreamConnection extends EventEmitter {
14597
14734
  }
14598
14735
  setAnswer(answer) {
14599
14736
  return __awaiter(this, void 0, void 0, function* () {
14737
+ var isInitialAnswer = !this.pc.getRemoteDescription();
14600
14738
  var sdp = this.preProcessRemoteAnswer(answer);
14601
14739
  return this.pc.setRemoteDescription({
14602
14740
  type: 'answer',
14603
14741
  sdp
14742
+ }).then(() => {
14743
+ if (isInitialAnswer && this.customCodecParameters.size > 0) {
14744
+ this.doLocalOfferAnswer();
14745
+ }
14746
+ });
14747
+ });
14748
+ }
14749
+ doLocalOfferAnswer() {
14750
+ var _a;
14751
+ return __awaiter(this, void 0, void 0, function* () {
14752
+ var offer = yield this.pc.createOffer();
14753
+ if (!offer.sdp) {
14754
+ throw new Error('No SDP offer');
14755
+ }
14756
+ offer.sdp = this.preProcessLocalOffer(offer.sdp);
14757
+ yield this.pc.setLocalDescription(offer);
14758
+ var answer = this.preProcessRemoteAnswer((_a = this.pc.getRemoteDescription()) === null || _a === void 0 ? void 0 : _a.sdp);
14759
+ return this.pc.setRemoteDescription({
14760
+ type: 'answer',
14761
+ sdp: answer
14604
14762
  });
14605
14763
  });
14606
14764
  }
@@ -14621,7 +14779,7 @@ class MultistreamConnection extends EventEmitter {
14621
14779
  });
14622
14780
  parsed.avMedia.filter(av => av.direction === 'sendrecv').forEach(av => {
14623
14781
  var egressSignaler = this.streamSignalerManager.getOrCreateEgressStreamSignaler(av.mid);
14624
- var simulcastEnabled = !!av.simulcast;
14782
+ var simulcastEnabled = hasSimulcast(av);
14625
14783
  var rtxEnabled = av.type === 'video';
14626
14784
  egressSignaler.signalStreams(simulcastEnabled, rtxEnabled, av);
14627
14785
  if (av.type === 'video') {
@@ -14630,6 +14788,22 @@ class MultistreamConnection extends EventEmitter {
14630
14788
  ci.fmtParams.set('max-fs', "".concat(defaultMaxVideoEncodeFrameSize));
14631
14789
  });
14632
14790
  }
14791
+ var mediaType = [...this.sendTransceivers.keys()].find(key => {
14792
+ var _a;
14793
+ return ((_a = this.sendTransceivers.get(key)) === null || _a === void 0 ? void 0 : _a.mid) === av.mid;
14794
+ });
14795
+ if (mediaType && this.customCodecParameters.has(mediaType)) {
14796
+ [...av.codecs.values()].filter(ci => ci.name === (av.type === 'audio' ? 'opus' : 'H264')).forEach(ci => {
14797
+ var _a;
14798
+ (_a = this.customCodecParameters.get(mediaType)) === null || _a === void 0 ? void 0 : _a.forEach((value, param) => {
14799
+ if (value === null) {
14800
+ ci.fmtParams.delete(param);
14801
+ } else {
14802
+ ci.fmtParams.set(param, "".concat(value));
14803
+ }
14804
+ });
14805
+ });
14806
+ }
14633
14807
  });
14634
14808
  if (getBrowserDetails().name !== 'Firefox') {
14635
14809
  setupBundle(parsed, this.options.bundlePolicy, this.midMap);
@@ -14679,6 +14853,31 @@ class MultistreamConnection extends EventEmitter {
14679
14853
  getPublishedTracks() {
14680
14854
  return [...this.sendTransceivers.values()].map(transceiver => transceiver.publishedTrack).filter(Boolean);
14681
14855
  }
14856
+ setCodecParameters(mediaType, parameters) {
14857
+ return __awaiter(this, void 0, void 0, function* () {
14858
+ var currentParams = this.customCodecParameters.get(mediaType) || new Map();
14859
+ Object.entries(parameters).forEach(_ref7 => {
14860
+ var [param, value] = _ref7;
14861
+ currentParams.set(param, value);
14862
+ });
14863
+ this.customCodecParameters.set(mediaType, currentParams);
14864
+ if (this.pc.getRemoteDescription()) {
14865
+ yield this.doLocalOfferAnswer();
14866
+ }
14867
+ });
14868
+ }
14869
+ deleteCodecParameters(mediaType, parameters) {
14870
+ return __awaiter(this, void 0, void 0, function* () {
14871
+ var currentParams = this.customCodecParameters.get(mediaType) || new Map();
14872
+ parameters.forEach(param => {
14873
+ currentParams.set(param, null);
14874
+ });
14875
+ this.customCodecParameters.set(mediaType, currentParams);
14876
+ if (this.pc.getRemoteDescription()) {
14877
+ yield this.doLocalOfferAnswer();
14878
+ }
14879
+ });
14880
+ }
14682
14881
  requestMedia(mediaType, mediaRequests) {
14683
14882
  var _a;
14684
14883
  var task = () => {
@@ -14754,8 +14953,8 @@ class MultistreamConnection extends EventEmitter {
14754
14953
  }
14755
14954
  preProcessStats(stats) {
14756
14955
  return __awaiter(this, void 0, void 0, function* () {
14757
- yield Promise.all([...this.sendTransceivers.entries()].map(_ref7 => {
14758
- var [mediaType, transceiver] = _ref7;
14956
+ yield Promise.all([...this.sendTransceivers.entries()].map(_ref8 => {
14957
+ var [mediaType, transceiver] = _ref8;
14759
14958
  return __awaiter(this, void 0, void 0, function* () {
14760
14959
  (yield transceiver.getStats()).forEach(senderStats => {
14761
14960
  var _a;
@@ -14773,8 +14972,8 @@ class MultistreamConnection extends EventEmitter {
14773
14972
  });
14774
14973
  });
14775
14974
  }));
14776
- yield Promise.all([...this.recvTransceivers.entries()].map(_ref8 => {
14777
- var [mediaType, transceivers] = _ref8;
14975
+ yield Promise.all([...this.recvTransceivers.entries()].map(_ref9 => {
14976
+ var [mediaType, transceivers] = _ref9;
14778
14977
  return __awaiter(this, void 0, void 0, function* () {
14779
14978
  yield Promise.all(transceivers.map(transceiver => __awaiter(this, void 0, void 0, function* () {
14780
14979
  (yield transceiver.getStats()).forEach(receiverStats => {
@@ -23897,6 +24096,14 @@ class MultistreamRoapMediaConnection extends EventEmitter$4 {
23897
24096
  }
23898
24097
  this.roap.roapMessageReceived(roapMessage);
23899
24098
  }
24099
+ enableMultistreamAudio(enabled) {
24100
+ this.log('enableMultistreamAudio()', 'called');
24101
+ var sdpNegotiationNeeded = this.multistreamConnection.enableMultistreamAudio(enabled);
24102
+ if (sdpNegotiationNeeded) {
24103
+ return this.roap.initiateOffer();
24104
+ }
24105
+ return Promise.resolve();
24106
+ }
23900
24107
  publishTrack(track) {
23901
24108
  this.log('publishTrack()', 'called');
23902
24109
  return this.multistreamConnection.publishTrack(track);
@@ -27,6 +27,7 @@ export declare class MultistreamRoapMediaConnection extends EventEmitter {
27
27
  getStats(): Promise<RTCStatsReport>;
28
28
  getTransceiverStats(): Promise<TransceiverStats>;
29
29
  roapMessageReceived(roapMessage: RoapMessage): void;
30
+ enableMultistreamAudio(enabled: boolean): Promise<void>;
30
31
  publishTrack(track: LocalTrack): Promise<void>;
31
32
  unpublishTrack(track: LocalTrack): Promise<void>;
32
33
  createReceiveSlot(mediaType: MediaType): Promise<ReceiveSlot>;
@@ -1 +1 @@
1
- {"version":3,"file":"MultistreamRoapMediaConnection.d.ts","sourceRoot":"","sources":["../../../src/MediaConnection/MultistreamRoapMediaConnection.ts"],"names":[],"mappings":";AAAA,OAAO,YAAY,MAAM,QAAQ,CAAC;AAElC,OAAO,EAEL,UAAU,EACV,YAAY,EAGZ,WAAW,EACX,gBAAgB,EACjB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAA6C,SAAS,EAAC,MAAM,yBAAyB,CAAC;AAG9F,OAAO,EAAQ,eAAe,EAAE,WAAW,EAAmB,MAAM,cAAc,CAAC;AAKnF,OAAO,EAAC,2BAA2B,EAAC,MAAM,UAAU,CAAC;AAGrD,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,iBAAiB,GAClB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EACL,iBAAiB,EACjB,SAAS,EACT,cAAc,EACd,SAAS,EACT,WAAW,EACX,SAAS,EACT,WAAW,EACX,MAAM,EACN,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AAGjC,qBAAa,8BAA+B,SAAQ,YAAY;IAC9D,OAAO,CAAC,EAAE,CAAC,CAAS;IAEpB,OAAO,CAAC,OAAO,CAAC,CAAS;IAEzB,OAAO,CAAC,qBAAqB,CAAwB;IAErD,OAAO,CAAC,IAAI,CAAO;IAEnB,OAAO,CAAC,qBAAqB,CAAS;gBAS1B,qBAAqB,EAAE,2BAA2B,EAAE,OAAO,CAAC,EAAE,MAAM;IAehF,OAAO,CAAC,mBAAmB;IAqC3B,OAAO,CAAC,GAAG;IAIX,OAAO,CAAC,KAAK;IAIb,OAAO,CAAC,2BAA2B;IAyCnC,OAAO,CAAC,UAAU;IA4BX,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB9B,KAAK,IAAI,IAAI;IAOpB,OAAO,CAAC,oBAAoB;IAK5B,OAAO,CAAC,eAAe;IAiBhB,SAAS,CAAC,UAAU,EAAE,YAAY,EAAE,EAAE,aAAa,UAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA2B1E,kBAAkB,IAAI,eAAe;IAWrC,QAAQ,IAAI,OAAO,CAAC,cAAc,CAAC;IAOnC,mBAAmB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAShD,mBAAmB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI;IAanD,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAM9C,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAMhD,iBAAiB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC;IAM7D,YAAY,CAAC,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,IAAI;IAM9E,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,kBAAkB;CAkB3B"}
1
+ {"version":3,"file":"MultistreamRoapMediaConnection.d.ts","sourceRoot":"","sources":["../../../src/MediaConnection/MultistreamRoapMediaConnection.ts"],"names":[],"mappings":";AAAA,OAAO,YAAY,MAAM,QAAQ,CAAC;AAElC,OAAO,EAEL,UAAU,EACV,YAAY,EAGZ,WAAW,EACX,gBAAgB,EACjB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAA6C,SAAS,EAAC,MAAM,yBAAyB,CAAC;AAG9F,OAAO,EAAQ,eAAe,EAAE,WAAW,EAAmB,MAAM,cAAc,CAAC;AAKnF,OAAO,EAAC,2BAA2B,EAAC,MAAM,UAAU,CAAC;AAGrD,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,iBAAiB,GAClB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EACL,iBAAiB,EACjB,SAAS,EACT,cAAc,EACd,SAAS,EACT,WAAW,EACX,SAAS,EACT,WAAW,EACX,MAAM,EACN,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AAGjC,qBAAa,8BAA+B,SAAQ,YAAY;IAC9D,OAAO,CAAC,EAAE,CAAC,CAAS;IAEpB,OAAO,CAAC,OAAO,CAAC,CAAS;IAEzB,OAAO,CAAC,qBAAqB,CAAwB;IAErD,OAAO,CAAC,IAAI,CAAO;IAEnB,OAAO,CAAC,qBAAqB,CAAS;gBAS1B,qBAAqB,EAAE,2BAA2B,EAAE,OAAO,CAAC,EAAE,MAAM;IAehF,OAAO,CAAC,mBAAmB;IAqC3B,OAAO,CAAC,GAAG;IAIX,OAAO,CAAC,KAAK;IAIb,OAAO,CAAC,2BAA2B;IAyCnC,OAAO,CAAC,UAAU;IA4BX,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB9B,KAAK,IAAI,IAAI;IAOpB,OAAO,CAAC,oBAAoB;IAK5B,OAAO,CAAC,eAAe;IAiBhB,SAAS,CAAC,UAAU,EAAE,YAAY,EAAE,EAAE,aAAa,UAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA2B1E,kBAAkB,IAAI,eAAe;IAWrC,QAAQ,IAAI,OAAO,CAAC,cAAc,CAAC;IAOnC,mBAAmB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAShD,mBAAmB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI;IAanD,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAYvD,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAM9C,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAMhD,iBAAiB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC;IAM7D,YAAY,CAAC,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,IAAI;IAM9E,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,kBAAkB;CAkB3B"}
@@ -20,5 +20,7 @@ export interface MediaConnectionConfig {
20
20
  }
21
21
  export interface MultistreamConnectionConfig {
22
22
  iceServers: Array<RTCIceServer>;
23
+ enableMainAudio: boolean;
24
+ enableMainVideo: boolean;
23
25
  }
24
26
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/MediaConnection/config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAoE;IAC7F,gBAAgB,CAAC,EAAE,OAAO,CAAuE;IACjG,kBAAkB,CAAC,EAAE,OAAO,CAAoE;IAChG,eAAe,CAAC,EAAE;QAChB,KAAK,EAAE,MAAM,CAA6E;QAC1F,KAAK,EAAE,MAAM,CAA6E;KAC3F,CAAC;IACF,YAAY,CAAC,EAAE,MAAM,CACmE;IACxF,iBAAiB,CAAC,EAAE,MAAM,CAAqE;IAC/F,aAAa,CAAC,EAAE,OAAO,CACkC;IACzD,UAAU,CAAC,EAAE,OAAO,CAC4C;IAChE,SAAS,CAAC,EAAE,MAAM,CAEkD;CACrE;AAED,MAAM,WAAW,qBAAqB;IAEpC,UAAU,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;IAChC,wBAAwB,EAAE,OAAO,CAmBM;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,gBAAgB,CAAC;CAC9B;AAED,MAAM,WAAW,2BAA2B;IAE1C,UAAU,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;CACjC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/MediaConnection/config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAoE;IAC7F,gBAAgB,CAAC,EAAE,OAAO,CAAuE;IACjG,kBAAkB,CAAC,EAAE,OAAO,CAAoE;IAChG,eAAe,CAAC,EAAE;QAChB,KAAK,EAAE,MAAM,CAA6E;QAC1F,KAAK,EAAE,MAAM,CAA6E;KAC3F,CAAC;IACF,YAAY,CAAC,EAAE,MAAM,CACmE;IACxF,iBAAiB,CAAC,EAAE,MAAM,CAAqE;IAC/F,aAAa,CAAC,EAAE,OAAO,CACkC;IACzD,UAAU,CAAC,EAAE,OAAO,CAC4C;IAChE,SAAS,CAAC,EAAE,MAAM,CAEkD;CACrE;AAED,MAAM,WAAW,qBAAqB;IAEpC,UAAU,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;IAChC,wBAAwB,EAAE,OAAO,CAmBM;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,gBAAgB,CAAC;CAC9B;AAED,MAAM,WAAW,2BAA2B;IAC1C,UAAU,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;IAChC,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,OAAO,CAAC;CAC1B"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/MediaConnection/utils.ts"],"names":[],"mappings":"AAYA,OAAO,EAAC,gBAAgB,EAAC,MAAM,UAAU,CAAC;AAI1C,oBAAY,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAE1C,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,OAAO,EAChB,UAAU,CAAC,EAAE,gBAAgB,GAAG,IAAI,GACnC;IAAC,WAAW,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAAC,SAAS,EAAE,0BAA0B,CAAA;CAAC,CAYpF;AAmBD,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE;IACP,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;CACtB,EACD,GAAG,CAAC,EAAE,MAAM,GACX,KAAK,GAAG,KAAK,CA6Bf;AA8ND,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAQrF;AASD,wBAAgB,aAAa,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CA2B3E;AAcD,wBAAgB,cAAc,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAc5E"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/MediaConnection/utils.ts"],"names":[],"mappings":"AAYA,OAAO,EAAC,gBAAgB,EAAC,MAAM,UAAU,CAAC;AAI1C,oBAAY,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAE1C,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,OAAO,EAChB,UAAU,CAAC,EAAE,gBAAgB,GAAG,IAAI,GACnC;IAAC,WAAW,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAAC,SAAS,EAAE,0BAA0B,CAAA;CAAC,CAYpF;AAmBD,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE;IACP,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;CACtB,EACD,GAAG,CAAC,EAAE,MAAM,GACX,KAAK,GAAG,KAAK,CA6Bf;AAkOD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAQrF;AASD,wBAAgB,aAAa,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CA2B3E;AAcD,wBAAgB,cAAc,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAc5E"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webex/internal-media-core",
3
- "version": "1.35.2",
3
+ "version": "1.35.4",
4
4
  "files": [
5
5
  "dist/cjs",
6
6
  "dist/esm",
@@ -46,8 +46,8 @@
46
46
  "dependencies": {
47
47
  "@babel/runtime": "^7.18.9",
48
48
  "@webex/json-multistream": "1.20.2",
49
- "@webex/ts-sdp": "1.3.0",
50
- "@webex/web-client-media-engine": "1.38.4",
49
+ "@webex/ts-sdp": "1.3.2",
50
+ "@webex/web-client-media-engine": "1.40.2",
51
51
  "detectrtc": "^1.4.1",
52
52
  "events": "^3.3.0",
53
53
  "typed-emitter": "^2.1.0",