livekit-client 1.14.1 → 1.14.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. package/dist/livekit-client.e2ee.worker.js +1 -1
  2. package/dist/livekit-client.e2ee.worker.js.map +1 -1
  3. package/dist/livekit-client.e2ee.worker.mjs +25 -44
  4. package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
  5. package/dist/livekit-client.esm.mjs +399 -196
  6. package/dist/livekit-client.esm.mjs.map +1 -1
  7. package/dist/livekit-client.umd.js +1 -1
  8. package/dist/livekit-client.umd.js.map +1 -1
  9. package/dist/src/e2ee/E2eeManager.d.ts.map +1 -1
  10. package/dist/src/e2ee/utils.d.ts +0 -1
  11. package/dist/src/e2ee/utils.d.ts.map +1 -1
  12. package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
  13. package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts.map +1 -1
  14. package/dist/src/proto/livekit_models_pb.d.ts +87 -11
  15. package/dist/src/proto/livekit_models_pb.d.ts.map +1 -1
  16. package/dist/src/proto/livekit_rtc_pb.d.ts +0 -4
  17. package/dist/src/proto/livekit_rtc_pb.d.ts.map +1 -1
  18. package/dist/src/room/PCTransport.d.ts +20 -1
  19. package/dist/src/room/PCTransport.d.ts.map +1 -1
  20. package/dist/src/room/RTCEngine.d.ts +1 -1
  21. package/dist/src/room/RTCEngine.d.ts.map +1 -1
  22. package/dist/src/room/Room.d.ts.map +1 -1
  23. package/dist/src/room/defaults.d.ts +1 -0
  24. package/dist/src/room/defaults.d.ts.map +1 -1
  25. package/dist/src/room/events.d.ts +1 -1
  26. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  27. package/dist/src/room/timers.d.ts +1 -1
  28. package/dist/src/room/timers.d.ts.map +1 -1
  29. package/dist/src/room/track/LocalAudioTrack.d.ts +1 -1
  30. package/dist/src/room/track/LocalAudioTrack.d.ts.map +1 -1
  31. package/dist/src/room/track/LocalTrack.d.ts +3 -3
  32. package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
  33. package/dist/src/room/track/LocalVideoTrack.d.ts +2 -1
  34. package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
  35. package/dist/src/room/track/options.d.ts +0 -1
  36. package/dist/src/room/track/options.d.ts.map +1 -1
  37. package/dist/src/room/track/utils.d.ts +2 -1
  38. package/dist/src/room/track/utils.d.ts.map +1 -1
  39. package/dist/src/utils/cloneDeep.d.ts +2 -0
  40. package/dist/src/utils/cloneDeep.d.ts.map +1 -0
  41. package/dist/ts4.2/src/e2ee/utils.d.ts +0 -1
  42. package/dist/ts4.2/src/proto/livekit_models_pb.d.ts +87 -11
  43. package/dist/ts4.2/src/proto/livekit_rtc_pb.d.ts +0 -4
  44. package/dist/ts4.2/src/room/PCTransport.d.ts +20 -1
  45. package/dist/ts4.2/src/room/RTCEngine.d.ts +1 -1
  46. package/dist/ts4.2/src/room/defaults.d.ts +1 -0
  47. package/dist/ts4.2/src/room/events.d.ts +1 -1
  48. package/dist/ts4.2/src/room/timers.d.ts +1 -1
  49. package/dist/ts4.2/src/room/track/LocalAudioTrack.d.ts +1 -1
  50. package/dist/ts4.2/src/room/track/LocalTrack.d.ts +3 -3
  51. package/dist/ts4.2/src/room/track/LocalVideoTrack.d.ts +2 -1
  52. package/dist/ts4.2/src/room/track/options.d.ts +0 -1
  53. package/dist/ts4.2/src/room/track/utils.d.ts +1 -0
  54. package/dist/ts4.2/src/utils/cloneDeep.d.ts +2 -0
  55. package/package.json +14 -14
  56. package/src/connectionHelper/checks/webrtc.ts +1 -1
  57. package/src/e2ee/E2eeManager.ts +2 -1
  58. package/src/e2ee/utils.ts +0 -10
  59. package/src/e2ee/worker/FrameCryptor.ts +13 -14
  60. package/src/e2ee/worker/ParticipantKeyHandler.ts +4 -5
  61. package/src/e2ee/worker/e2ee.worker.ts +3 -1
  62. package/src/proto/livekit_models_pb.ts +140 -15
  63. package/src/proto/livekit_rtc_pb.ts +1 -7
  64. package/src/room/PCTransport.ts +116 -1
  65. package/src/room/RTCEngine.ts +49 -85
  66. package/src/room/Room.ts +10 -9
  67. package/src/room/defaults.ts +4 -2
  68. package/src/room/events.ts +1 -1
  69. package/src/room/participant/LocalParticipant.ts +44 -56
  70. package/src/room/track/LocalAudioTrack.ts +1 -1
  71. package/src/room/track/LocalTrack.ts +8 -5
  72. package/src/room/track/LocalVideoTrack.ts +2 -1
  73. package/src/room/track/options.ts +0 -7
  74. package/src/room/track/utils.ts +17 -8
  75. package/src/utils/cloneDeep.test.ts +54 -0
  76. package/src/utils/cloneDeep.ts +11 -0
@@ -3572,6 +3572,28 @@ proto3.util.setEnumType(VideoCodec, "livekit.VideoCodec", [{
3572
3572
  no: 4,
3573
3573
  name: "VP8"
3574
3574
  }]);
3575
+ /**
3576
+ * @generated from enum livekit.ImageCodec
3577
+ */
3578
+ var ImageCodec;
3579
+ (function (ImageCodec) {
3580
+ /**
3581
+ * @generated from enum value: IC_DEFAULT = 0;
3582
+ */
3583
+ ImageCodec[ImageCodec["IC_DEFAULT"] = 0] = "IC_DEFAULT";
3584
+ /**
3585
+ * @generated from enum value: IC_JPEG = 1;
3586
+ */
3587
+ ImageCodec[ImageCodec["IC_JPEG"] = 1] = "IC_JPEG";
3588
+ })(ImageCodec || (ImageCodec = {}));
3589
+ // Retrieve enum metadata with: proto3.getEnumType(ImageCodec)
3590
+ proto3.util.setEnumType(ImageCodec, "livekit.ImageCodec", [{
3591
+ no: 0,
3592
+ name: "IC_DEFAULT"
3593
+ }, {
3594
+ no: 1,
3595
+ name: "IC_JPEG"
3596
+ }]);
3575
3597
  /**
3576
3598
  * @generated from enum livekit.TrackType
3577
3599
  */
@@ -3997,11 +4019,6 @@ Room$1.fields = proto3.util.newFieldList(() => [{
3997
4019
  name: "active_recording",
3998
4020
  kind: "scalar",
3999
4021
  T: 8 /* ScalarType.BOOL */
4000
- }, {
4001
- no: 12,
4002
- name: "playout_delay",
4003
- kind: "message",
4004
- T: PlayoutDelay
4005
4022
  }]);
4006
4023
  /**
4007
4024
  * @generated from message livekit.Codec
@@ -4926,6 +4943,10 @@ class UserPacket extends Message {
4926
4943
  * @generated from field: string participant_sid = 1;
4927
4944
  */
4928
4945
  this.participantSid = "";
4946
+ /**
4947
+ * @generated from field: string participant_identity = 5;
4948
+ */
4949
+ this.participantIdentity = "";
4929
4950
  /**
4930
4951
  * user defined payload
4931
4952
  *
@@ -4933,11 +4954,17 @@ class UserPacket extends Message {
4933
4954
  */
4934
4955
  this.payload = new Uint8Array(0);
4935
4956
  /**
4936
- * the ID of the participants who will receive the message (the message will be sent to all the people in the room if this variable is empty)
4957
+ * the ID of the participants who will receive the message (sent to all by default)
4937
4958
  *
4938
4959
  * @generated from field: repeated string destination_sids = 3;
4939
4960
  */
4940
4961
  this.destinationSids = [];
4962
+ /**
4963
+ * identities of participants who will receive the message (sent to all by default)
4964
+ *
4965
+ * @generated from field: repeated string destination_identities = 6;
4966
+ */
4967
+ this.destinationIdentities = [];
4941
4968
  proto3.util.initPartial(data, this);
4942
4969
  }
4943
4970
  static fromBinary(bytes, options) {
@@ -4960,6 +4987,11 @@ UserPacket.fields = proto3.util.newFieldList(() => [{
4960
4987
  name: "participant_sid",
4961
4988
  kind: "scalar",
4962
4989
  T: 9 /* ScalarType.STRING */
4990
+ }, {
4991
+ no: 5,
4992
+ name: "participant_identity",
4993
+ kind: "scalar",
4994
+ T: 9 /* ScalarType.STRING */
4963
4995
  }, {
4964
4996
  no: 2,
4965
4997
  name: "payload",
@@ -4971,6 +5003,12 @@ UserPacket.fields = proto3.util.newFieldList(() => [{
4971
5003
  kind: "scalar",
4972
5004
  T: 9 /* ScalarType.STRING */,
4973
5005
  repeated: true
5006
+ }, {
5007
+ no: 6,
5008
+ name: "destination_identities",
5009
+ kind: "scalar",
5010
+ T: 9 /* ScalarType.STRING */,
5011
+ repeated: true
4974
5012
  }, {
4975
5013
  no: 4,
4976
5014
  name: "topic",
@@ -5286,6 +5324,14 @@ var ClientInfo_SDK;
5286
5324
  * @generated from enum value: RUST = 8;
5287
5325
  */
5288
5326
  ClientInfo_SDK[ClientInfo_SDK["RUST"] = 8] = "RUST";
5327
+ /**
5328
+ * @generated from enum value: PYTHON = 9;
5329
+ */
5330
+ ClientInfo_SDK[ClientInfo_SDK["PYTHON"] = 9] = "PYTHON";
5331
+ /**
5332
+ * @generated from enum value: CPP = 10;
5333
+ */
5334
+ ClientInfo_SDK[ClientInfo_SDK["CPP"] = 10] = "CPP";
5289
5335
  })(ClientInfo_SDK || (ClientInfo_SDK = {}));
5290
5336
  // Retrieve enum metadata with: proto3.getEnumType(ClientInfo_SDK)
5291
5337
  proto3.util.setEnumType(ClientInfo_SDK, "livekit.ClientInfo.SDK", [{
@@ -5315,6 +5361,12 @@ proto3.util.setEnumType(ClientInfo_SDK, "livekit.ClientInfo.SDK", [{
5315
5361
  }, {
5316
5362
  no: 8,
5317
5363
  name: "RUST"
5364
+ }, {
5365
+ no: 9,
5366
+ name: "PYTHON"
5367
+ }, {
5368
+ no: 10,
5369
+ name: "CPP"
5318
5370
  }]);
5319
5371
  /**
5320
5372
  * server provided client configuration
@@ -5456,6 +5508,103 @@ DisabledCodecs.fields = proto3.util.newFieldList(() => [{
5456
5508
  T: Codec,
5457
5509
  repeated: true
5458
5510
  }]);
5511
+ /**
5512
+ * @generated from message livekit.RTPDrift
5513
+ */
5514
+ class RTPDrift extends Message {
5515
+ constructor(data) {
5516
+ super();
5517
+ /**
5518
+ * @generated from field: double duration = 3;
5519
+ */
5520
+ this.duration = 0;
5521
+ /**
5522
+ * @generated from field: uint64 start_timestamp = 4;
5523
+ */
5524
+ this.startTimestamp = protoInt64.zero;
5525
+ /**
5526
+ * @generated from field: uint64 end_timestamp = 5;
5527
+ */
5528
+ this.endTimestamp = protoInt64.zero;
5529
+ /**
5530
+ * @generated from field: uint64 rtp_clock_ticks = 6;
5531
+ */
5532
+ this.rtpClockTicks = protoInt64.zero;
5533
+ /**
5534
+ * @generated from field: int64 drift_samples = 7;
5535
+ */
5536
+ this.driftSamples = protoInt64.zero;
5537
+ /**
5538
+ * @generated from field: double drift_ms = 8;
5539
+ */
5540
+ this.driftMs = 0;
5541
+ /**
5542
+ * @generated from field: double clock_rate = 9;
5543
+ */
5544
+ this.clockRate = 0;
5545
+ proto3.util.initPartial(data, this);
5546
+ }
5547
+ static fromBinary(bytes, options) {
5548
+ return new RTPDrift().fromBinary(bytes, options);
5549
+ }
5550
+ static fromJson(jsonValue, options) {
5551
+ return new RTPDrift().fromJson(jsonValue, options);
5552
+ }
5553
+ static fromJsonString(jsonString, options) {
5554
+ return new RTPDrift().fromJsonString(jsonString, options);
5555
+ }
5556
+ static equals(a, b) {
5557
+ return proto3.util.equals(RTPDrift, a, b);
5558
+ }
5559
+ }
5560
+ RTPDrift.runtime = proto3;
5561
+ RTPDrift.typeName = "livekit.RTPDrift";
5562
+ RTPDrift.fields = proto3.util.newFieldList(() => [{
5563
+ no: 1,
5564
+ name: "start_time",
5565
+ kind: "message",
5566
+ T: Timestamp
5567
+ }, {
5568
+ no: 2,
5569
+ name: "end_time",
5570
+ kind: "message",
5571
+ T: Timestamp
5572
+ }, {
5573
+ no: 3,
5574
+ name: "duration",
5575
+ kind: "scalar",
5576
+ T: 1 /* ScalarType.DOUBLE */
5577
+ }, {
5578
+ no: 4,
5579
+ name: "start_timestamp",
5580
+ kind: "scalar",
5581
+ T: 4 /* ScalarType.UINT64 */
5582
+ }, {
5583
+ no: 5,
5584
+ name: "end_timestamp",
5585
+ kind: "scalar",
5586
+ T: 4 /* ScalarType.UINT64 */
5587
+ }, {
5588
+ no: 6,
5589
+ name: "rtp_clock_ticks",
5590
+ kind: "scalar",
5591
+ T: 4 /* ScalarType.UINT64 */
5592
+ }, {
5593
+ no: 7,
5594
+ name: "drift_samples",
5595
+ kind: "scalar",
5596
+ T: 3 /* ScalarType.INT64 */
5597
+ }, {
5598
+ no: 8,
5599
+ name: "drift_ms",
5600
+ kind: "scalar",
5601
+ T: 1 /* ScalarType.DOUBLE */
5602
+ }, {
5603
+ no: 9,
5604
+ name: "clock_rate",
5605
+ kind: "scalar",
5606
+ T: 1 /* ScalarType.DOUBLE */
5607
+ }]);
5459
5608
  /**
5460
5609
  * @generated from message livekit.RTPStats
5461
5610
  */
@@ -5602,16 +5751,6 @@ class RTPStats extends Message {
5602
5751
  * @generated from field: uint32 layer_lock_plis = 35;
5603
5752
  */
5604
5753
  this.layerLockPlis = 0;
5605
- /**
5606
- * @generated from field: double sample_rate = 42;
5607
- */
5608
- this.sampleRate = 0;
5609
- /**
5610
- * NEXT_ID: 44
5611
- *
5612
- * @generated from field: double drift_ms = 43;
5613
- */
5614
- this.driftMs = 0;
5615
5754
  proto3.util.initPartial(data, this);
5616
5755
  }
5617
5756
  static fromBinary(bytes, options) {
@@ -5839,15 +5978,15 @@ RTPStats.fields = proto3.util.newFieldList(() => [{
5839
5978
  kind: "message",
5840
5979
  T: Timestamp
5841
5980
  }, {
5842
- no: 42,
5843
- name: "sample_rate",
5844
- kind: "scalar",
5845
- T: 1 /* ScalarType.DOUBLE */
5981
+ no: 44,
5982
+ name: "packet_drift",
5983
+ kind: "message",
5984
+ T: RTPDrift
5846
5985
  }, {
5847
- no: 43,
5848
- name: "drift_ms",
5849
- kind: "scalar",
5850
- T: 1 /* ScalarType.DOUBLE */
5986
+ no: 45,
5987
+ name: "report_drift",
5988
+ kind: "message",
5989
+ T: RTPDrift
5851
5990
  }]);
5852
5991
  /**
5853
5992
  * @generated from message livekit.TimedVersion
@@ -5920,7 +6059,7 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
5920
6059
  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
5921
6060
  PERFORMANCE OF THIS SOFTWARE.
5922
6061
  ***************************************************************************** */
5923
- /* global Reflect, Promise */
6062
+ /* global Reflect, Promise, SuppressedError, Symbol */
5924
6063
 
5925
6064
 
5926
6065
  function __awaiter(thisArg, _arguments, P, generator) {
@@ -5951,7 +6090,12 @@ function __asyncValues(o) {
5951
6090
  return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
5952
6091
  function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
5953
6092
  function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
5954
- }
6093
+ }
6094
+
6095
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
6096
+ var e = new Error(message);
6097
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
6098
+ };
5955
6099
 
5956
6100
  var events = {exports: {}};
5957
6101
 
@@ -9825,10 +9969,6 @@ class SimulcastCodec extends Message {
9825
9969
  * @generated from field: string cid = 2;
9826
9970
  */
9827
9971
  this.cid = "";
9828
- /**
9829
- * @generated from field: bool enable_simulcast_layers = 3;
9830
- */
9831
- this.enableSimulcastLayers = false;
9832
9972
  proto3.util.initPartial(data, this);
9833
9973
  }
9834
9974
  static fromBinary(bytes, options) {
@@ -9856,11 +9996,6 @@ SimulcastCodec.fields = proto3.util.newFieldList(() => [{
9856
9996
  name: "cid",
9857
9997
  kind: "scalar",
9858
9998
  T: 9 /* ScalarType.STRING */
9859
- }, {
9860
- no: 3,
9861
- name: "enable_simulcast_layers",
9862
- kind: "scalar",
9863
- T: 8 /* ScalarType.BOOL */
9864
9999
  }]);
9865
10000
  /**
9866
10001
  * @generated from message livekit.AddTrackRequest
@@ -11863,7 +11998,7 @@ function getMatch(exp, ua) {
11863
11998
  return match && match.length >= id && match[id] || '';
11864
11999
  }
11865
12000
 
11866
- var version$1 = "1.14.1";
12001
+ var version$1 = "1.14.2";
11867
12002
 
11868
12003
  const version = version$1;
11869
12004
  const protocolVersion = 10;
@@ -11892,9 +12027,6 @@ const videoCodecs = ['vp8', 'h264', 'vp9', 'av1'];
11892
12027
  function isBackupCodec(codec) {
11893
12028
  return !!backupCodecs.find(backup => backup === codec);
11894
12029
  }
11895
- function isCodecEqual(c1, c2) {
11896
- return (c1 === null || c1 === void 0 ? void 0 : c1.toLowerCase().replace(/audio\/|video\//y, '')) === (c2 === null || c2 === void 0 ? void 0 : c2.toLowerCase().replace(/audio\/|video\//y, ''));
11897
- }
11898
12030
  var AudioPresets;
11899
12031
  (function (AudioPresets) {
11900
12032
  AudioPresets.telephone = {
@@ -11953,6 +12085,17 @@ const ScreenSharePresets = {
11953
12085
  h1080fps30: new VideoPreset(1920, 1080, 4000000, 30, 'medium')
11954
12086
  };
11955
12087
 
12088
+ function cloneDeep(value) {
12089
+ if (typeof value === 'undefined') {
12090
+ return;
12091
+ }
12092
+ if (typeof structuredClone === 'function') {
12093
+ return structuredClone(value);
12094
+ } else {
12095
+ return JSON.parse(JSON.stringify(value));
12096
+ }
12097
+ }
12098
+
11956
12099
  /**
11957
12100
  * Events are the primary way LiveKit notifies your application of changes.
11958
12101
  *
@@ -12152,7 +12295,7 @@ var RoomEvent;
12152
12295
  * be emitted.
12153
12296
  *
12154
12297
  * args: (pub: [[RemoteTrackPublication]],
12155
- * status: [[TrackPublication.SubscriptionStatus]],
12298
+ * status: [[TrackPublication.PermissionStatus]],
12156
12299
  * participant: [[RemoteParticipant]])
12157
12300
  */
12158
12301
  RoomEvent["TrackSubscriptionPermissionChanged"] = "trackSubscriptionPermissionChanged";
@@ -12772,7 +12915,8 @@ function detachTrack(track, element) {
12772
12915
  })(Track || (Track = {}));
12773
12916
 
12774
12917
  function mergeDefaultOptions(options, audioDefaults, videoDefaults) {
12775
- const opts = Object.assign({}, options);
12918
+ var _a;
12919
+ const opts = (_a = cloneDeep(options)) !== null && _a !== void 0 ? _a : {};
12776
12920
  if (opts.audio === true) opts.audio = {};
12777
12921
  if (opts.video === true) opts.video = {};
12778
12922
  // use defaults
@@ -12915,6 +13059,13 @@ function screenCaptureToDisplayMediaStreamOptions(options) {
12915
13059
  systemAudio: options.systemAudio
12916
13060
  };
12917
13061
  }
13062
+ function mimeTypeToVideoCodecString(mimeType) {
13063
+ const codec = mimeType.split('/')[1].toLowerCase();
13064
+ if (!videoCodecs.includes(codec)) {
13065
+ throw Error("Video codec not supported: ".concat(codec));
13066
+ }
13067
+ return codec;
13068
+ }
12918
13069
 
12919
13070
  const separator = '|';
12920
13071
  const ddExtensionURI = 'https://aomediacodec.github.io/av1-rtp-spec/#dependency-descriptor-rtp-header-extension';
@@ -14047,13 +14198,6 @@ function deriveKeys(material, salt) {
14047
14198
  function createE2EEKey() {
14048
14199
  return window.crypto.getRandomValues(new Uint8Array(32));
14049
14200
  }
14050
- function mimeTypeToVideoCodecString(mimeType) {
14051
- const codec = mimeType.split('/')[1].toLowerCase();
14052
- if (!videoCodecs.includes(codec)) {
14053
- throw Error("Video codec not supported: ".concat(codec));
14054
- }
14055
- return codec;
14056
- }
14057
14201
  /**
14058
14202
  * Ratchets a key. See
14059
14203
  * https://tools.ietf.org/html/draft-omara-sframe-00#section-4.3.5.1
@@ -14441,10 +14585,16 @@ class LocalTrack extends Track {
14441
14585
  }
14442
14586
  waitForDimensions() {
14443
14587
  let timeout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultDimensionsTimeout;
14588
+ var _a;
14444
14589
  return __awaiter(this, void 0, void 0, function* () {
14445
14590
  if (this.kind === Track.Kind.Audio) {
14446
14591
  throw new Error('cannot get dimensions for audio tracks');
14447
14592
  }
14593
+ if (((_a = getBrowser()) === null || _a === void 0 ? void 0 : _a.os) === 'iOS') {
14594
+ // browsers report wrong initial resolution on iOS.
14595
+ // when slightly delaying the call to .getSettings(), the correct resolution is being reported
14596
+ yield sleep(10);
14597
+ }
14448
14598
  const started = Date.now();
14449
14599
  while (Date.now() - started < timeout) {
14450
14600
  const dims = this.dimensions;
@@ -15773,6 +15923,27 @@ class PCTransport extends eventsExports.EventEmitter {
15773
15923
  this._pc = isChromiumBased() ?
15774
15924
  // @ts-expect-error chrome allows additional media constraints to be passed into the RTCPeerConnection constructor
15775
15925
  new RTCPeerConnection(config, mediaConstraints) : new RTCPeerConnection(config);
15926
+ this._pc.onicecandidate = ev => {
15927
+ var _a;
15928
+ if (!ev.candidate) return;
15929
+ (_a = this.onIceCandidate) === null || _a === void 0 ? void 0 : _a.call(this, ev.candidate);
15930
+ };
15931
+ this._pc.onicecandidateerror = ev => {
15932
+ var _a;
15933
+ (_a = this.onIceCandidateError) === null || _a === void 0 ? void 0 : _a.call(this, ev);
15934
+ };
15935
+ this._pc.onconnectionstatechange = () => {
15936
+ var _a, _b, _c;
15937
+ (_a = this.onConnectionStateChange) === null || _a === void 0 ? void 0 : _a.call(this, (_c = (_b = this._pc) === null || _b === void 0 ? void 0 : _b.connectionState) !== null && _c !== void 0 ? _c : 'closed');
15938
+ };
15939
+ this._pc.ondatachannel = ev => {
15940
+ var _a;
15941
+ (_a = this.onDataChannel) === null || _a === void 0 ? void 0 : _a.call(this, ev);
15942
+ };
15943
+ this._pc.ontrack = ev => {
15944
+ var _a;
15945
+ (_a = this.onTrack) === null || _a === void 0 ? void 0 : _a.call(this, ev);
15946
+ };
15776
15947
  }
15777
15948
  get isICEConnected() {
15778
15949
  return this._pc !== null && (this.pc.iceConnectionState === 'connected' || this.pc.iceConnectionState === 'completed');
@@ -15955,9 +16126,85 @@ class PCTransport extends eventsExports.EventEmitter {
15955
16126
  return answer;
15956
16127
  });
15957
16128
  }
16129
+ createDataChannel(label, dataChannelDict) {
16130
+ return this.pc.createDataChannel(label, dataChannelDict);
16131
+ }
16132
+ addTransceiver(mediaStreamTrack, transceiverInit) {
16133
+ return this.pc.addTransceiver(mediaStreamTrack, transceiverInit);
16134
+ }
16135
+ addTrack(track) {
16136
+ return this.pc.addTrack(track);
16137
+ }
15958
16138
  setTrackCodecBitrate(info) {
15959
16139
  this.trackBitrates.push(info);
15960
16140
  }
16141
+ setConfiguration(rtcConfig) {
16142
+ return this.pc.setConfiguration(rtcConfig);
16143
+ }
16144
+ canRemoveTrack() {
16145
+ return !!this.pc.removeTrack;
16146
+ }
16147
+ removeTrack(sender) {
16148
+ return this.pc.removeTrack(sender);
16149
+ }
16150
+ getConnectionState() {
16151
+ return this.pc.connectionState;
16152
+ }
16153
+ getICEConnectionState() {
16154
+ return this.pc.iceConnectionState;
16155
+ }
16156
+ getSignallingState() {
16157
+ return this.pc.signalingState;
16158
+ }
16159
+ getTransceivers() {
16160
+ return this.pc.getTransceivers();
16161
+ }
16162
+ getSenders() {
16163
+ return this.pc.getSenders();
16164
+ }
16165
+ getLocalDescription() {
16166
+ return this.pc.localDescription;
16167
+ }
16168
+ getRemoteDescription() {
16169
+ return this.pc.remoteDescription;
16170
+ }
16171
+ getConnectedAddress() {
16172
+ var _a;
16173
+ return __awaiter(this, void 0, void 0, function* () {
16174
+ if (!this._pc) {
16175
+ return;
16176
+ }
16177
+ let selectedCandidatePairId = '';
16178
+ const candidatePairs = new Map();
16179
+ // id -> candidate ip
16180
+ const candidates = new Map();
16181
+ const stats = yield this._pc.getStats();
16182
+ stats.forEach(v => {
16183
+ switch (v.type) {
16184
+ case 'transport':
16185
+ selectedCandidatePairId = v.selectedCandidatePairId;
16186
+ break;
16187
+ case 'candidate-pair':
16188
+ if (selectedCandidatePairId === '' && v.selected) {
16189
+ selectedCandidatePairId = v.id;
16190
+ }
16191
+ candidatePairs.set(v.id, v);
16192
+ break;
16193
+ case 'remote-candidate':
16194
+ candidates.set(v.id, "".concat(v.address, ":").concat(v.port));
16195
+ break;
16196
+ }
16197
+ });
16198
+ if (selectedCandidatePairId === '') {
16199
+ return undefined;
16200
+ }
16201
+ const selectedID = (_a = candidatePairs.get(selectedCandidatePairId)) === null || _a === void 0 ? void 0 : _a.remoteCandidateId;
16202
+ if (selectedID === undefined) {
16203
+ return undefined;
16204
+ }
16205
+ return candidates.get(selectedID);
16206
+ });
16207
+ }
15961
16208
  close() {
15962
16209
  if (!this._pc) {
15963
16210
  return;
@@ -16118,6 +16365,7 @@ function extractStereoAndNackAudioFromOffer(offer) {
16118
16365
  };
16119
16366
  }
16120
16367
 
16368
+ const defaultVideoCodec = 'vp8';
16121
16369
  const publishDefaults = {
16122
16370
  /**
16123
16371
  * @deprecated
@@ -16130,7 +16378,7 @@ const publishDefaults = {
16130
16378
  simulcast: true,
16131
16379
  screenShareEncoding: ScreenSharePresets.h1080fps15.encoding,
16132
16380
  stopMicTrackOnMute: false,
16133
- videoCodec: 'vp8',
16381
+ videoCodec: defaultVideoCodec,
16134
16382
  backupCodec: false
16135
16383
  };
16136
16384
  const audioDefaults = {
@@ -16403,13 +16651,13 @@ class RTCEngine extends eventsExports.EventEmitter {
16403
16651
  }
16404
16652
  cleanupPeerConnections() {
16405
16653
  return __awaiter(this, void 0, void 0, function* () {
16406
- if (this.publisher && this.publisher.pc.signalingState !== 'closed') {
16407
- this.publisher.pc.getSenders().forEach(sender => {
16654
+ if (this.publisher && this.publisher.getSignallingState() !== 'closed') {
16655
+ this.publisher.getSenders().forEach(sender => {
16408
16656
  var _a, _b;
16409
16657
  try {
16410
16658
  // TODO: react-native-webrtc doesn't have removeTrack yet.
16411
- if ((_a = this.publisher) === null || _a === void 0 ? void 0 : _a.pc.removeTrack) {
16412
- (_b = this.publisher) === null || _b === void 0 ? void 0 : _b.pc.removeTrack(sender);
16659
+ if ((_a = this.publisher) === null || _a === void 0 ? void 0 : _a.canRemoveTrack()) {
16660
+ (_b = this.publisher) === null || _b === void 0 ? void 0 : _b.removeTrack(sender);
16413
16661
  }
16414
16662
  } catch (e) {
16415
16663
  livekitLogger.warn('could not removeTrack', {
@@ -16427,7 +16675,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16427
16675
  this.subscriber = undefined;
16428
16676
  }
16429
16677
  this.hasPublished = false;
16430
- this.primaryPC = undefined;
16678
+ this.primaryTransport = undefined;
16431
16679
  const dcCleanup = dc => {
16432
16680
  if (!dc) return;
16433
16681
  dc.close();
@@ -16494,7 +16742,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16494
16742
  delete this.pendingTrackResolvers[sender.track.id];
16495
16743
  }
16496
16744
  try {
16497
- (_a = this.publisher) === null || _a === void 0 ? void 0 : _a.pc.removeTrack(sender);
16745
+ (_a = this.publisher) === null || _a === void 0 ? void 0 : _a.removeTrack(sender);
16498
16746
  return true;
16499
16747
  } catch (e) {
16500
16748
  livekitLogger.warn('failed to remove track', {
@@ -16513,10 +16761,10 @@ class RTCEngine extends eventsExports.EventEmitter {
16513
16761
  }
16514
16762
  getConnectedServerAddress() {
16515
16763
  return __awaiter(this, void 0, void 0, function* () {
16516
- if (this.primaryPC === undefined) {
16764
+ if (this.primaryTransport === undefined) {
16517
16765
  return undefined;
16518
16766
  }
16519
- return getConnectedAddress(this.primaryPC);
16767
+ return this.primaryTransport.getConnectedAddress();
16520
16768
  });
16521
16769
  }
16522
16770
  /* @internal */
@@ -16545,37 +16793,35 @@ class RTCEngine extends eventsExports.EventEmitter {
16545
16793
  this.publisher = new PCTransport(rtcConfig, googConstraints);
16546
16794
  this.subscriber = new PCTransport(rtcConfig);
16547
16795
  this.emit(EngineEvent.TransportsCreated, this.publisher, this.subscriber);
16548
- this.publisher.pc.onicecandidate = ev => {
16549
- if (!ev.candidate) return;
16550
- livekitLogger.trace('adding ICE candidate for peer', ev.candidate);
16551
- this.client.sendIceCandidate(ev.candidate, SignalTarget.PUBLISHER);
16796
+ this.publisher.onIceCandidate = candidate => {
16797
+ livekitLogger.trace('adding ICE candidate for peer', candidate);
16798
+ this.client.sendIceCandidate(candidate, SignalTarget.PUBLISHER);
16552
16799
  };
16553
- this.subscriber.pc.onicecandidate = ev => {
16554
- if (!ev.candidate) return;
16555
- this.client.sendIceCandidate(ev.candidate, SignalTarget.SUBSCRIBER);
16800
+ this.subscriber.onIceCandidate = candidate => {
16801
+ this.client.sendIceCandidate(candidate, SignalTarget.SUBSCRIBER);
16556
16802
  };
16557
16803
  this.publisher.onOffer = offer => {
16558
16804
  this.client.sendOffer(offer);
16559
16805
  };
16560
- let primaryPC = this.publisher.pc;
16561
- let secondaryPC = this.subscriber.pc;
16806
+ let primaryTransport = this.publisher;
16807
+ let secondaryTransport = this.subscriber;
16562
16808
  let subscriberPrimary = joinResponse.subscriberPrimary;
16563
16809
  if (subscriberPrimary) {
16564
- primaryPC = this.subscriber.pc;
16565
- secondaryPC = this.publisher.pc;
16810
+ primaryTransport = this.subscriber;
16811
+ secondaryTransport = this.publisher;
16566
16812
  // in subscriber primary mode, server side opens sub data channels.
16567
- this.subscriber.pc.ondatachannel = this.handleDataChannel;
16813
+ this.subscriber.onDataChannel = this.handleDataChannel;
16568
16814
  }
16569
- this.primaryPC = primaryPC;
16570
- primaryPC.onconnectionstatechange = () => __awaiter(this, void 0, void 0, function* () {
16571
- livekitLogger.debug("primary PC state changed ".concat(primaryPC.connectionState));
16572
- if (primaryPC.connectionState === 'connected') {
16815
+ this.primaryTransport = primaryTransport;
16816
+ primaryTransport.onConnectionStateChange = connectionState => __awaiter(this, void 0, void 0, function* () {
16817
+ livekitLogger.debug("primary PC state changed ".concat(connectionState));
16818
+ if (connectionState === 'connected') {
16573
16819
  const shouldEmit = this.pcState === PCState.New;
16574
16820
  this.pcState = PCState.Connected;
16575
16821
  if (shouldEmit) {
16576
16822
  this.emit(EngineEvent.Connected, joinResponse);
16577
16823
  }
16578
- } else if (primaryPC.connectionState === 'failed') {
16824
+ } else if (connectionState === 'failed') {
16579
16825
  // on Safari, PeerConnection will switch to 'disconnected' during renegotiation
16580
16826
  if (this.pcState === PCState.Connected) {
16581
16827
  this.pcState = PCState.Disconnected;
@@ -16583,14 +16829,14 @@ class RTCEngine extends eventsExports.EventEmitter {
16583
16829
  }
16584
16830
  }
16585
16831
  });
16586
- secondaryPC.onconnectionstatechange = () => __awaiter(this, void 0, void 0, function* () {
16587
- livekitLogger.debug("secondary PC state changed ".concat(secondaryPC.connectionState));
16832
+ secondaryTransport.onConnectionStateChange = connectionState => __awaiter(this, void 0, void 0, function* () {
16833
+ livekitLogger.debug("secondary PC state changed ".concat(connectionState));
16588
16834
  // also reconnect if secondary peerconnection fails
16589
- if (secondaryPC.connectionState === 'failed') {
16835
+ if (connectionState === 'failed') {
16590
16836
  this.handleDisconnect('secondary peerconnection', subscriberPrimary ? ReconnectReason.RR_PUBLISHER_FAILED : ReconnectReason.RR_SUBSCRIBER_FAILED);
16591
16837
  }
16592
16838
  });
16593
- this.subscriber.pc.ontrack = ev => {
16839
+ this.subscriber.onTrack = ev => {
16594
16840
  this.emit(EngineEvent.MediaTrackAdded, ev.track, ev.streams[0], ev.receiver);
16595
16841
  };
16596
16842
  this.createDataChannels();
@@ -16603,7 +16849,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16603
16849
  }
16604
16850
  livekitLogger.debug('received server answer', {
16605
16851
  RTCSdpType: sd.type,
16606
- signalingState: this.publisher.pc.signalingState.toString()
16852
+ signalingState: this.publisher.getSignallingState().toString()
16607
16853
  });
16608
16854
  yield this.publisher.setRemoteDescription(sd);
16609
16855
  });
@@ -16629,7 +16875,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16629
16875
  }
16630
16876
  livekitLogger.debug('received server offer', {
16631
16877
  RTCSdpType: sd.type,
16632
- signalingState: this.subscriber.pc.signalingState.toString()
16878
+ signalingState: this.subscriber.getSignallingState().toString()
16633
16879
  });
16634
16880
  yield this.subscriber.setRemoteDescription(sd);
16635
16881
  // answer the offer
@@ -16657,7 +16903,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16657
16903
  this.client.onLeave = leave => {
16658
16904
  if (leave === null || leave === void 0 ? void 0 : leave.canReconnect) {
16659
16905
  this.fullReconnectOnNext = true;
16660
- this.primaryPC = undefined;
16906
+ this.primaryTransport = undefined;
16661
16907
  // reconnect immediately instead of waiting for next attempt
16662
16908
  this.handleDisconnect(leaveReconnect);
16663
16909
  } else {
@@ -16709,12 +16955,12 @@ class RTCEngine extends eventsExports.EventEmitter {
16709
16955
  this.reliableDC.onerror = null;
16710
16956
  }
16711
16957
  // create data channels
16712
- this.lossyDC = this.publisher.pc.createDataChannel(lossyDataChannel, {
16958
+ this.lossyDC = this.publisher.createDataChannel(lossyDataChannel, {
16713
16959
  // will drop older packets that arrive
16714
16960
  ordered: true,
16715
16961
  maxRetransmits: 0
16716
16962
  });
16717
- this.reliableDC = this.publisher.pc.createDataChannel(reliableDataChannel, {
16963
+ this.reliableDC = this.publisher.createDataChannel(reliableDataChannel, {
16718
16964
  ordered: true
16719
16965
  });
16720
16966
  // also handle messages over the pub channel, for backwards compatibility
@@ -16811,7 +17057,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16811
17057
  transceiverInit.sendEncodings = encodings;
16812
17058
  }
16813
17059
  // addTransceiver for react-native is async. web is synchronous, but await won't effect it.
16814
- const transceiver = yield this.publisher.pc.addTransceiver(track.mediaStreamTrack, transceiverInit);
17060
+ const transceiver = yield this.publisher.addTransceiver(track.mediaStreamTrack, transceiverInit);
16815
17061
  if (track.kind === Track.Kind.Video && opts.videoCodec) {
16816
17062
  this.setPreferredCodec(transceiver, track.kind, opts.videoCodec);
16817
17063
  track.codec = opts.videoCodec;
@@ -16831,7 +17077,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16831
17077
  transceiverInit.sendEncodings = encodings;
16832
17078
  }
16833
17079
  // addTransceiver for react-native is async. web is synchronous, but await won't effect it.
16834
- const transceiver = yield this.publisher.pc.addTransceiver(simulcastTrack.mediaStreamTrack, transceiverInit);
17080
+ const transceiver = yield this.publisher.addTransceiver(simulcastTrack.mediaStreamTrack, transceiverInit);
16835
17081
  if (!opts.videoCodec) {
16836
17082
  return;
16837
17083
  }
@@ -16845,7 +17091,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16845
17091
  if (!this.publisher) {
16846
17092
  throw new UnexpectedConnectionState('publisher is closed');
16847
17093
  }
16848
- return this.publisher.pc.addTrack(track);
17094
+ return this.publisher.addTrack(track);
16849
17095
  });
16850
17096
  }
16851
17097
  attemptReconnect(reason) {
@@ -16861,7 +17107,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16861
17107
  if (((_a = this.clientConfiguration) === null || _a === void 0 ? void 0 : _a.resumeConnection) === ClientConfigSetting.DISABLED ||
16862
17108
  // signaling state could change to closed due to hardware sleep
16863
17109
  // those connections cannot be resumed
16864
- ((_c = (_b = this.primaryPC) === null || _b === void 0 ? void 0 : _b.signalingState) !== null && _c !== void 0 ? _c : 'closed') === 'closed') {
17110
+ ((_c = (_b = this.primaryTransport) === null || _b === void 0 ? void 0 : _b.getSignallingState()) !== null && _c !== void 0 ? _c : 'closed') === 'closed') {
16865
17111
  this.fullReconnectOnNext = true;
16866
17112
  }
16867
17113
  try {
@@ -16979,8 +17225,8 @@ class RTCEngine extends eventsExports.EventEmitter {
16979
17225
  const res = yield this.client.reconnect(this.url, this.token, this.participantSid, reason);
16980
17226
  if (res) {
16981
17227
  const rtcConfig = this.makeRTCConfiguration(res);
16982
- this.publisher.pc.setConfiguration(rtcConfig);
16983
- this.subscriber.pc.setConfiguration(rtcConfig);
17228
+ this.publisher.setConfiguration(rtcConfig);
17229
+ this.subscriber.setConfiguration(rtcConfig);
16984
17230
  }
16985
17231
  } catch (e) {
16986
17232
  let message = '';
@@ -17055,14 +17301,14 @@ class RTCEngine extends eventsExports.EventEmitter {
17055
17301
  this.pcState = PCState.Reconnecting;
17056
17302
  livekitLogger.debug('waiting for peer connection to reconnect');
17057
17303
  while (now - startTime < this.peerConnectionTimeout) {
17058
- if (this.primaryPC === undefined) {
17304
+ if (this.primaryTransport === undefined) {
17059
17305
  // we can abort early, connection is hosed
17060
17306
  break;
17061
17307
  } else if (
17062
17308
  // on Safari, we don't get a connectionstatechanged event during ICE restart
17063
17309
  // this means we'd have to check its status manually and update address
17064
17310
  // manually
17065
- now - startTime > minReconnectWait && ((_a = this.primaryPC) === null || _a === void 0 ? void 0 : _a.connectionState) === 'connected' && (!this.hasPublished || ((_b = this.publisher) === null || _b === void 0 ? void 0 : _b.pc.connectionState) === 'connected')) {
17311
+ now - startTime > minReconnectWait && ((_a = this.primaryTransport) === null || _a === void 0 ? void 0 : _a.getConnectionState()) === 'connected' && (!this.hasPublished || ((_b = this.publisher) === null || _b === void 0 ? void 0 : _b.getConnectionState()) === 'connected')) {
17066
17312
  this.pcState = PCState.Connected;
17067
17313
  }
17068
17314
  if (this.pcState === PCState.Connected) {
@@ -17100,7 +17346,7 @@ class RTCEngine extends eventsExports.EventEmitter {
17100
17346
  if (!transport) {
17101
17347
  throw new ConnectionError("".concat(transportName, " connection not set"));
17102
17348
  }
17103
- if (!subscriber && !((_a = this.publisher) === null || _a === void 0 ? void 0 : _a.isICEConnected) && ((_b = this.publisher) === null || _b === void 0 ? void 0 : _b.pc.iceConnectionState) !== 'checking') {
17349
+ if (!subscriber && !((_a = this.publisher) === null || _a === void 0 ? void 0 : _a.isICEConnected) && ((_b = this.publisher) === null || _b === void 0 ? void 0 : _b.getICEConnectionState()) !== 'checking') {
17104
17350
  // start negotiation
17105
17351
  this.negotiate();
17106
17352
  }
@@ -17116,7 +17362,7 @@ class RTCEngine extends eventsExports.EventEmitter {
17116
17362
  }
17117
17363
  yield sleep(50);
17118
17364
  }
17119
- throw new ConnectionError("could not establish ".concat(transportName, " connection, state: ").concat(transport.pc.iceConnectionState));
17365
+ throw new ConnectionError("could not establish ".concat(transportName, " connection, state: ").concat(transport.getICEConnectionState()));
17120
17366
  });
17121
17367
  }
17122
17368
  ensurePublisherConnected(kind) {
@@ -17127,10 +17373,10 @@ class RTCEngine extends eventsExports.EventEmitter {
17127
17373
  /* @internal */
17128
17374
  verifyTransport() {
17129
17375
  // primary connection
17130
- if (!this.primaryPC) {
17376
+ if (!this.primaryTransport) {
17131
17377
  return false;
17132
17378
  }
17133
- if (this.primaryPC.connectionState === 'closed' || this.primaryPC.connectionState === 'failed') {
17379
+ if (this.primaryTransport.getConnectionState() === 'closed' || this.primaryTransport.getConnectionState() === 'failed') {
17134
17380
  return false;
17135
17381
  }
17136
17382
  // also verify publisher connection if it's needed or different
@@ -17138,7 +17384,7 @@ class RTCEngine extends eventsExports.EventEmitter {
17138
17384
  if (!this.publisher) {
17139
17385
  return false;
17140
17386
  }
17141
- if (this.publisher.pc.connectionState === 'closed' || this.publisher.pc.connectionState === 'failed') {
17387
+ if (this.publisher.getConnectionState() === 'closed' || this.publisher.getConnectionState() === 'failed') {
17142
17388
  return false;
17143
17389
  }
17144
17390
  }
@@ -17244,40 +17490,6 @@ class RTCEngine extends eventsExports.EventEmitter {
17244
17490
  }
17245
17491
  }
17246
17492
  }
17247
- function getConnectedAddress(pc) {
17248
- var _a;
17249
- return __awaiter(this, void 0, void 0, function* () {
17250
- let selectedCandidatePairId = '';
17251
- const candidatePairs = new Map();
17252
- // id -> candidate ip
17253
- const candidates = new Map();
17254
- const stats = yield pc.getStats();
17255
- stats.forEach(v => {
17256
- switch (v.type) {
17257
- case 'transport':
17258
- selectedCandidatePairId = v.selectedCandidatePairId;
17259
- break;
17260
- case 'candidate-pair':
17261
- if (selectedCandidatePairId === '' && v.selected) {
17262
- selectedCandidatePairId = v.id;
17263
- }
17264
- candidatePairs.set(v.id, v);
17265
- break;
17266
- case 'remote-candidate':
17267
- candidates.set(v.id, "".concat(v.address, ":").concat(v.port));
17268
- break;
17269
- }
17270
- });
17271
- if (selectedCandidatePairId === '') {
17272
- return undefined;
17273
- }
17274
- const selectedID = (_a = candidatePairs.get(selectedCandidatePairId)) === null || _a === void 0 ? void 0 : _a.remoteCandidateId;
17275
- if (selectedID === undefined) {
17276
- return undefined;
17277
- }
17278
- return candidates.get(selectedID);
17279
- });
17280
- }
17281
17493
  class SignalReconnectError extends Error {}
17282
17494
 
17283
17495
  class RegionUrlProvider {
@@ -18211,7 +18423,8 @@ class LocalVideoTrack extends LocalTrack {
18211
18423
  }
18212
18424
  /**
18213
18425
  * @internal
18214
- * Sets codecs that should be publishing
18426
+ * Sets codecs that should be publishing, returns new codecs that have not yet
18427
+ * been published
18215
18428
  */
18216
18429
  setPublishingCodecs(codecs) {
18217
18430
  var _a, codecs_1, codecs_1_1;
@@ -20428,7 +20641,7 @@ class LocalParticipant extends Participant {
20428
20641
  });
20429
20642
  }
20430
20643
  publish(track, opts, isStereo) {
20431
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
20644
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
20432
20645
  return __awaiter(this, void 0, void 0, function* () {
20433
20646
  const existingTrackOfSource = Array.from(this.tracks.values()).find(publishedTrack => track instanceof LocalTrack && publishedTrack.source === track.source);
20434
20647
  if (existingTrackOfSource && track.source !== Track.Source.Unknown) {
@@ -20460,6 +20673,10 @@ class LocalParticipant extends Participant {
20460
20673
  if (opts.videoCodec === 'vp9' && !supportsVP9()) {
20461
20674
  opts.videoCodec = undefined;
20462
20675
  }
20676
+ if (opts.videoCodec === undefined) {
20677
+ opts.videoCodec = defaultVideoCodec;
20678
+ }
20679
+ const videoCodec = opts.videoCodec;
20463
20680
  // handle track actions
20464
20681
  track.on(TrackEvent.Muted, this.onTrackMuted);
20465
20682
  track.on(TrackEvent.Unmuted, this.onTrackUnmuted);
@@ -20482,7 +20699,6 @@ class LocalParticipant extends Participant {
20482
20699
  });
20483
20700
  // compute encodings and layers for video
20484
20701
  let encodings;
20485
- let simEncodings;
20486
20702
  if (track.kind === Track.Kind.Video) {
20487
20703
  let dims = {
20488
20704
  width: 0,
@@ -20506,74 +20722,60 @@ class LocalParticipant extends Participant {
20506
20722
  req.height = dims.height;
20507
20723
  // for svc codecs, disable simulcast and use vp8 for backup codec
20508
20724
  if (track instanceof LocalVideoTrack) {
20509
- if (isSVCCodec(opts.videoCodec)) {
20725
+ if (isSVCCodec(videoCodec)) {
20510
20726
  // vp9 svc with screenshare has problem to encode, always use L1T3 here
20511
- if (track.source === Track.Source.ScreenShare && opts.videoCodec === 'vp9') {
20727
+ if (track.source === Track.Source.ScreenShare && videoCodec === 'vp9') {
20512
20728
  opts.scalabilityMode = 'L1T3';
20513
20729
  }
20514
20730
  // set scalabilityMode to 'L3T3_KEY' by default
20515
20731
  opts.scalabilityMode = (_e = opts.scalabilityMode) !== null && _e !== void 0 ? _e : 'L3T3_KEY';
20516
20732
  }
20733
+ req.simulcastCodecs = [new SimulcastCodec({
20734
+ codec: videoCodec,
20735
+ cid: track.mediaStreamTrack.id
20736
+ })];
20517
20737
  // set up backup
20518
- if (opts.videoCodec && opts.backupCodec && opts.videoCodec !== opts.backupCodec.codec) {
20738
+ if (opts.backupCodec && videoCodec !== opts.backupCodec.codec) {
20519
20739
  if (!this.roomOptions.dynacast) {
20520
20740
  this.roomOptions.dynacast = true;
20521
20741
  }
20522
- const simOpts = Object.assign({}, opts);
20523
- simOpts.simulcast = true;
20524
- simEncodings = computeTrackBackupEncodings(track, opts.backupCodec.codec, simOpts);
20525
- req.simulcastCodecs = [new SimulcastCodec({
20526
- codec: opts.videoCodec,
20527
- cid: track.mediaStreamTrack.id,
20528
- enableSimulcastLayers: true
20529
- }), new SimulcastCodec({
20742
+ req.simulcastCodecs.push(new SimulcastCodec({
20530
20743
  codec: opts.backupCodec.codec,
20531
- cid: '',
20532
- enableSimulcastLayers: true
20533
- })];
20534
- } else if (opts.videoCodec) {
20535
- // pass codec info to sfu so it can prefer codec for the client which don't support
20536
- // setCodecPreferences
20537
- req.simulcastCodecs = [new SimulcastCodec({
20538
- codec: opts.videoCodec,
20539
- cid: track.mediaStreamTrack.id,
20540
- enableSimulcastLayers: (_f = opts.simulcast) !== null && _f !== void 0 ? _f : false
20541
- })];
20744
+ cid: ''
20745
+ }));
20542
20746
  }
20543
20747
  }
20544
- encodings = computeVideoEncodings(track.source === Track.Source.ScreenShare, dims.width, dims.height, opts);
20748
+ encodings = computeVideoEncodings(track.source === Track.Source.ScreenShare, req.width, req.height, opts);
20545
20749
  req.layers = videoLayersFromEncodings(req.width, req.height, encodings, isSVCCodec(opts.videoCodec));
20546
20750
  } else if (track.kind === Track.Kind.Audio) {
20547
20751
  encodings = [{
20548
- maxBitrate: (_h = (_g = opts.audioPreset) === null || _g === void 0 ? void 0 : _g.maxBitrate) !== null && _h !== void 0 ? _h : opts.audioBitrate,
20549
- priority: (_k = (_j = opts.audioPreset) === null || _j === void 0 ? void 0 : _j.priority) !== null && _k !== void 0 ? _k : 'high',
20550
- networkPriority: (_m = (_l = opts.audioPreset) === null || _l === void 0 ? void 0 : _l.priority) !== null && _m !== void 0 ? _m : 'high'
20752
+ maxBitrate: (_g = (_f = opts.audioPreset) === null || _f === void 0 ? void 0 : _f.maxBitrate) !== null && _g !== void 0 ? _g : opts.audioBitrate,
20753
+ priority: (_j = (_h = opts.audioPreset) === null || _h === void 0 ? void 0 : _h.priority) !== null && _j !== void 0 ? _j : 'high',
20754
+ networkPriority: (_l = (_k = opts.audioPreset) === null || _k === void 0 ? void 0 : _k.priority) !== null && _l !== void 0 ? _l : 'high'
20551
20755
  }];
20552
20756
  }
20553
20757
  if (!this.engine || this.engine.isClosed) {
20554
20758
  throw new UnexpectedConnectionState('cannot publish track when not connected');
20555
20759
  }
20556
20760
  const ti = yield this.engine.addTrack(req);
20557
- let primaryCodecSupported = false;
20558
- let backupCodecSupported = false;
20559
- ti.codecs.forEach(c => {
20560
- if (isCodecEqual(c.mimeType, opts.videoCodec)) {
20561
- primaryCodecSupported = true;
20562
- } else if (opts.backupCodec && isCodecEqual(c.mimeType, opts.backupCodec.codec)) {
20563
- backupCodecSupported = true;
20761
+ // server might not support the codec the client has requested, in that case, fallback
20762
+ // to a supported codec
20763
+ let primaryCodecMime;
20764
+ ti.codecs.forEach(codec => {
20765
+ if (primaryCodecMime === undefined) {
20766
+ primaryCodecMime = codec.mimeType;
20564
20767
  }
20565
20768
  });
20566
- if (req.simulcastCodecs.length > 0) {
20567
- if (!primaryCodecSupported && !backupCodecSupported) {
20568
- throw Error('cannot publish track, codec not supported by server');
20569
- }
20570
- if (!primaryCodecSupported && opts.backupCodec) {
20571
- const backupCodec = opts.backupCodec;
20572
- opts = Object.assign({}, opts);
20573
- livekitLogger.debug("primary codec ".concat(opts.videoCodec, " not supported, fallback to ").concat(backupCodec.codec));
20574
- opts.videoCodec = backupCodec.codec;
20575
- opts.videoEncoding = backupCodec.encoding;
20576
- encodings = simEncodings;
20769
+ if (primaryCodecMime && track.kind === Track.Kind.Video) {
20770
+ const updatedCodec = mimeTypeToVideoCodecString(primaryCodecMime);
20771
+ if (updatedCodec !== videoCodec) {
20772
+ livekitLogger.debug('falling back to server selected codec', {
20773
+ codec: updatedCodec
20774
+ });
20775
+ /* @ts-ignore */
20776
+ opts.videoCodec = updatedCodec;
20777
+ // recompute encodings since bitrates/etc could have changed
20778
+ encodings = computeVideoEncodings(track.source === Track.Source.ScreenShare, req.width, req.height, opts);
20577
20779
  }
20578
20780
  }
20579
20781
  const publication = new LocalTrackPublication(track.kind, ti, track);
@@ -20587,19 +20789,18 @@ class LocalParticipant extends Participant {
20587
20789
  encodings,
20588
20790
  trackInfo: ti
20589
20791
  });
20590
- // store RTPSender
20591
20792
  track.sender = yield this.engine.createSender(track, opts, encodings);
20592
20793
  if (encodings) {
20593
20794
  if (isFireFox() && track.kind === Track.Kind.Audio) {
20594
20795
  /* Refer to RFC https://datatracker.ietf.org/doc/html/rfc7587#section-6.1,
20595
- livekit-server uses maxaveragebitrate=510000in the answer sdp to permit client to
20796
+ livekit-server uses maxaveragebitrate=510000 in the answer sdp to permit client to
20596
20797
  publish high quality audio track. But firefox always uses this value as the actual
20597
20798
  bitrates, causing the audio bitrates to rise to 510Kbps in any stereo case unexpectedly.
20598
20799
  So the client need to modify maxaverragebitrates in answer sdp to user provided value to
20599
20800
  fix the issue.
20600
20801
  */
20601
20802
  let trackTransceiver = undefined;
20602
- for (const transceiver of this.engine.publisher.pc.getTransceivers()) {
20803
+ for (const transceiver of this.engine.publisher.getTransceivers()) {
20603
20804
  if (transceiver.sender === track.sender) {
20604
20805
  trackTransceiver = transceiver;
20605
20806
  break;
@@ -20609,10 +20810,10 @@ class LocalParticipant extends Participant {
20609
20810
  this.engine.publisher.setTrackCodecBitrate({
20610
20811
  transceiver: trackTransceiver,
20611
20812
  codec: 'opus',
20612
- maxbr: ((_o = encodings[0]) === null || _o === void 0 ? void 0 : _o.maxBitrate) ? encodings[0].maxBitrate / 1000 : 0
20813
+ maxbr: ((_m = encodings[0]) === null || _m === void 0 ? void 0 : _m.maxBitrate) ? encodings[0].maxBitrate / 1000 : 0
20613
20814
  });
20614
20815
  }
20615
- } else if (track.codec && isSVCCodec(track.codec) && ((_p = encodings[0]) === null || _p === void 0 ? void 0 : _p.maxBitrate)) {
20816
+ } else if (track.codec && isSVCCodec(track.codec) && ((_o = encodings[0]) === null || _o === void 0 ? void 0 : _o.maxBitrate)) {
20616
20817
  this.engine.publisher.setTrackCodecBitrate({
20617
20818
  cid: req.cid,
20618
20819
  codec: track.codec,
@@ -20672,8 +20873,7 @@ class LocalParticipant extends Participant {
20672
20873
  sid: track.sid,
20673
20874
  simulcastCodecs: [{
20674
20875
  codec: opts.videoCodec,
20675
- cid: simulcastTrack.mediaStreamTrack.id,
20676
- enableSimulcastLayers: opts.simulcast
20876
+ cid: simulcastTrack.mediaStreamTrack.id
20677
20877
  }]
20678
20878
  });
20679
20879
  req.layers = videoLayersFromEncodings(req.width, req.height, encodings);
@@ -20720,9 +20920,9 @@ class LocalParticipant extends Participant {
20720
20920
  let negotiationNeeded = false;
20721
20921
  const trackSender = track.sender;
20722
20922
  track.sender = undefined;
20723
- if (this.engine.publisher && this.engine.publisher.pc.connectionState !== 'closed' && trackSender) {
20923
+ if (this.engine.publisher && this.engine.publisher.getConnectionState() !== 'closed' && trackSender) {
20724
20924
  try {
20725
- for (const transceiver of this.engine.publisher.pc.getTransceivers()) {
20925
+ for (const transceiver of this.engine.publisher.getTransceivers()) {
20726
20926
  // if sender is not currently sending (after replaceTrack(null))
20727
20927
  // removeTrack would have no effect.
20728
20928
  // to ensure we end up successfully removing the track, manually set
@@ -21033,6 +21233,7 @@ class Room extends eventsExports.EventEmitter {
21033
21233
  nextUrl = yield this.regionUrlProvider.getNextBestRegionUrl((_c = this.abortController) === null || _c === void 0 ? void 0 : _c.signal);
21034
21234
  } catch (error) {
21035
21235
  if (error instanceof ConnectionError && (error.status === 401 || error.reason === 3 /* ConnectionErrorReason.Cancelled */)) {
21236
+ this.handleDisconnect(this.options.stopLocalTrackOnUnpublish);
21036
21237
  reject(error);
21037
21238
  return;
21038
21239
  }
@@ -21041,9 +21242,11 @@ class Room extends eventsExports.EventEmitter {
21041
21242
  livekitLogger.info("Initial connection failed with ConnectionError: ".concat(e.message, ". Retrying with another region: ").concat(nextUrl));
21042
21243
  yield connectFn(resolve, reject, nextUrl);
21043
21244
  } else {
21245
+ this.handleDisconnect(this.options.stopLocalTrackOnUnpublish);
21044
21246
  reject(e);
21045
21247
  }
21046
21248
  } else {
21249
+ this.handleDisconnect(this.options.stopLocalTrackOnUnpublish);
21047
21250
  reject(e);
21048
21251
  }
21049
21252
  }
@@ -21128,8 +21331,8 @@ class Room extends eventsExports.EventEmitter {
21128
21331
  this.setupLocalParticipantEvents();
21129
21332
  this.emit(RoomEvent.SignalConnected);
21130
21333
  } catch (err) {
21334
+ yield this.engine.close();
21131
21335
  this.recreateEngine();
21132
- this.handleDisconnect(this.options.stopLocalTrackOnUnpublish);
21133
21336
  const resultingError = new ConnectionError("could not establish signal connection");
21134
21337
  if (err instanceof Error) {
21135
21338
  resultingError.message = "".concat(resultingError.message, ": ").concat(err.message);
@@ -21144,15 +21347,15 @@ class Room extends eventsExports.EventEmitter {
21144
21347
  throw resultingError;
21145
21348
  }
21146
21349
  if (abortController.signal.aborted) {
21350
+ yield this.engine.close();
21147
21351
  this.recreateEngine();
21148
- this.handleDisconnect(this.options.stopLocalTrackOnUnpublish);
21149
21352
  throw new ConnectionError("Connection attempt aborted");
21150
21353
  }
21151
21354
  try {
21152
21355
  yield this.engine.waitForPCInitialConnection(this.connOptions.peerConnectionTimeout, abortController);
21153
21356
  } catch (e) {
21357
+ yield this.engine.close();
21154
21358
  this.recreateEngine();
21155
- this.handleDisconnect(this.options.stopLocalTrackOnUnpublish);
21156
21359
  throw e;
21157
21360
  }
21158
21361
  // also hook unload event
@@ -22147,18 +22350,18 @@ class Room extends eventsExports.EventEmitter {
22147
22350
  return participant;
22148
22351
  }
22149
22352
  sendSyncState() {
22150
- var _a, _b;
22151
- if (this.engine.subscriber === undefined || this.engine.subscriber.pc.localDescription === null) {
22353
+ var _a, _b, _c, _d;
22354
+ const previousAnswer = (_a = this.engine.subscriber) === null || _a === void 0 ? void 0 : _a.getLocalDescription();
22355
+ const previousOffer = (_b = this.engine.subscriber) === null || _b === void 0 ? void 0 : _b.getRemoteDescription();
22356
+ if (!previousAnswer) {
22152
22357
  return;
22153
22358
  }
22154
- const previousAnswer = this.engine.subscriber.pc.localDescription;
22155
- const previousOffer = this.engine.subscriber.pc.remoteDescription;
22156
22359
  /* 1. autosubscribe on, so subscribed tracks = all tracks - unsub tracks,
22157
22360
  in this case, we send unsub tracks, so server add all tracks to this
22158
22361
  subscribe pc and unsub special tracks from it.
22159
22362
  2. autosubscribe off, we send subscribed tracks.
22160
22363
  */
22161
- const autoSubscribe = (_b = (_a = this.connOptions) === null || _a === void 0 ? void 0 : _a.autoSubscribe) !== null && _b !== void 0 ? _b : true;
22364
+ const autoSubscribe = (_d = (_c = this.connOptions) === null || _c === void 0 ? void 0 : _c.autoSubscribe) !== null && _d !== void 0 ? _d : true;
22162
22365
  const trackSids = new Array();
22163
22366
  this.participants.forEach(participant => {
22164
22367
  participant.tracks.forEach(track => {
@@ -22773,7 +22976,7 @@ class WebRTCCheck extends Checker {
22773
22976
  }
22774
22977
  };
22775
22978
  if (this.room.engine.subscriber) {
22776
- this.room.engine.subscriber.pc.onicecandidateerror = ev => {
22979
+ this.room.engine.subscriber.onIceCandidateError = ev => {
22777
22980
  if (ev instanceof RTCPeerConnectionIceErrorEvent) {
22778
22981
  this.appendWarning("error with ICE candidate: ".concat(ev.errorCode, " ").concat(ev.errorText, " ").concat(ev.url));
22779
22982
  }
@@ -22992,5 +23195,5 @@ function isFacingModeValue(item) {
22992
23195
  return item === undefined || allowedValues.includes(item);
22993
23196
  }
22994
23197
 
22995
- export { AudioPresets, BaseKeyProvider, ConnectionCheck, ConnectionError, ConnectionQuality, ConnectionState, CriticalTimers, CryptorEvent, DataPacket_Kind, DefaultReconnectPolicy, DeviceUnsupportedError, DisconnectReason, EncryptionEvent, EngineEvent, ExternalE2EEKeyProvider, KeyHandlerEvent, KeyProviderEvent, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalVideoTrack, LogLevel, MediaDeviceFailure, NegotiationError, Participant, ParticipantEvent, PublishDataError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, RoomState, ScreenSharePresets, Track, TrackEvent, TrackInvalidError, TrackPublication, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, attachToElement, createAudioAnalyser, createE2EEKey, createKeyMaterialFromBuffer, createKeyMaterialFromString, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, deriveKeys, detachTrack, facingModeFromDeviceLabel, facingModeFromLocalTrack, getEmptyAudioStreamTrack, getEmptyVideoStreamTrack, importKey, isBackupCodec, isBrowserSupported, isCodecEqual, isE2EESupported, isInsertableStreamSupported, isScriptTransformSupported, isVideoFrame, mimeTypeToVideoCodecString, needsRbspUnescaping, parseRbsp, protocolVersion, ratchet, setLogExtension, setLogLevel, supportsAV1, supportsAdaptiveStream, supportsDynacast, supportsVP9, version, videoCodecs, writeRbsp };
23198
+ export { AudioPresets, BaseKeyProvider, ConnectionCheck, ConnectionError, ConnectionQuality, ConnectionState, CriticalTimers, CryptorEvent, DataPacket_Kind, DefaultReconnectPolicy, DeviceUnsupportedError, DisconnectReason, EncryptionEvent, EngineEvent, ExternalE2EEKeyProvider, KeyHandlerEvent, KeyProviderEvent, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalVideoTrack, LogLevel, MediaDeviceFailure, NegotiationError, Participant, ParticipantEvent, PublishDataError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, RoomState, ScreenSharePresets, Track, TrackEvent, TrackInvalidError, TrackPublication, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, attachToElement, createAudioAnalyser, createE2EEKey, createKeyMaterialFromBuffer, createKeyMaterialFromString, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, deriveKeys, detachTrack, facingModeFromDeviceLabel, facingModeFromLocalTrack, getEmptyAudioStreamTrack, getEmptyVideoStreamTrack, importKey, isBackupCodec, isBrowserSupported, isE2EESupported, isInsertableStreamSupported, isScriptTransformSupported, isVideoFrame, needsRbspUnescaping, parseRbsp, protocolVersion, ratchet, setLogExtension, setLogLevel, supportsAV1, supportsAdaptiveStream, supportsDynacast, supportsVP9, version, videoCodecs, writeRbsp };
22996
23199
  //# sourceMappingURL=livekit-client.esm.mjs.map