livekit-client 1.14.1 → 1.14.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) 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 +555 -306
  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 +1 -1
  23. package/dist/src/room/Room.d.ts.map +1 -1
  24. package/dist/src/room/defaults.d.ts +1 -0
  25. package/dist/src/room/defaults.d.ts.map +1 -1
  26. package/dist/src/room/events.d.ts +3 -1
  27. package/dist/src/room/events.d.ts.map +1 -1
  28. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  29. package/dist/src/room/participant/Participant.d.ts +1 -0
  30. package/dist/src/room/participant/Participant.d.ts.map +1 -1
  31. package/dist/src/room/timers.d.ts +1 -1
  32. package/dist/src/room/timers.d.ts.map +1 -1
  33. package/dist/src/room/track/LocalAudioTrack.d.ts +1 -1
  34. package/dist/src/room/track/LocalAudioTrack.d.ts.map +1 -1
  35. package/dist/src/room/track/LocalTrack.d.ts +3 -3
  36. package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
  37. package/dist/src/room/track/LocalVideoTrack.d.ts +2 -1
  38. package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
  39. package/dist/src/room/track/Track.d.ts.map +1 -1
  40. package/dist/src/room/track/options.d.ts +0 -1
  41. package/dist/src/room/track/options.d.ts.map +1 -1
  42. package/dist/src/room/track/utils.d.ts +2 -1
  43. package/dist/src/room/track/utils.d.ts.map +1 -1
  44. package/dist/src/utils/cloneDeep.d.ts +2 -0
  45. package/dist/src/utils/cloneDeep.d.ts.map +1 -0
  46. package/dist/ts4.2/src/e2ee/utils.d.ts +0 -1
  47. package/dist/ts4.2/src/proto/livekit_models_pb.d.ts +87 -11
  48. package/dist/ts4.2/src/proto/livekit_rtc_pb.d.ts +0 -4
  49. package/dist/ts4.2/src/room/PCTransport.d.ts +20 -1
  50. package/dist/ts4.2/src/room/RTCEngine.d.ts +1 -1
  51. package/dist/ts4.2/src/room/Room.d.ts +1 -1
  52. package/dist/ts4.2/src/room/defaults.d.ts +1 -0
  53. package/dist/ts4.2/src/room/events.d.ts +3 -1
  54. package/dist/ts4.2/src/room/participant/Participant.d.ts +1 -0
  55. package/dist/ts4.2/src/room/timers.d.ts +1 -1
  56. package/dist/ts4.2/src/room/track/LocalAudioTrack.d.ts +1 -1
  57. package/dist/ts4.2/src/room/track/LocalTrack.d.ts +3 -3
  58. package/dist/ts4.2/src/room/track/LocalVideoTrack.d.ts +2 -1
  59. package/dist/ts4.2/src/room/track/options.d.ts +0 -1
  60. package/dist/ts4.2/src/room/track/utils.d.ts +1 -0
  61. package/dist/ts4.2/src/utils/cloneDeep.d.ts +2 -0
  62. package/package.json +15 -15
  63. package/src/connectionHelper/checks/webrtc.ts +1 -1
  64. package/src/e2ee/E2eeManager.ts +2 -1
  65. package/src/e2ee/utils.ts +0 -10
  66. package/src/e2ee/worker/FrameCryptor.ts +13 -14
  67. package/src/e2ee/worker/ParticipantKeyHandler.ts +4 -5
  68. package/src/e2ee/worker/e2ee.worker.ts +3 -1
  69. package/src/proto/livekit_models_pb.ts +140 -15
  70. package/src/proto/livekit_rtc_pb.ts +1 -7
  71. package/src/room/PCTransport.ts +122 -5
  72. package/src/room/RTCEngine.ts +56 -92
  73. package/src/room/Room.ts +14 -11
  74. package/src/room/defaults.ts +4 -2
  75. package/src/room/events.ts +5 -1
  76. package/src/room/participant/LocalParticipant.ts +47 -68
  77. package/src/room/participant/Participant.ts +1 -0
  78. package/src/room/track/LocalAudioTrack.ts +1 -1
  79. package/src/room/track/LocalTrack.ts +8 -5
  80. package/src/room/track/LocalVideoTrack.ts +2 -1
  81. package/src/room/track/Track.ts +6 -1
  82. package/src/room/track/options.ts +0 -7
  83. package/src/room/track/utils.ts +17 -8
  84. package/src/utils/cloneDeep.test.ts +54 -0
  85. package/src/utils/cloneDeep.ts +11 -0
@@ -723,6 +723,34 @@ var ScalarType;
723
723
  ScalarType[ScalarType["SINT32"] = 17] = "SINT32";
724
724
  ScalarType[ScalarType["SINT64"] = 18] = "SINT64";
725
725
  })(ScalarType || (ScalarType = {}));
726
+ /**
727
+ * JavaScript representation of fields with 64 bit integral types (int64, uint64,
728
+ * sint64, fixed64, sfixed64).
729
+ *
730
+ * This is a subset of google.protobuf.FieldOptions.JSType, which defines JS_NORMAL,
731
+ * JS_STRING, and JS_NUMBER. Protobuf-ES uses BigInt by default, but will use
732
+ * String if `[jstype = JS_STRING]` is specified.
733
+ *
734
+ * ```protobuf
735
+ * uint64 field_a = 1; // BigInt
736
+ * uint64 field_b = 2 [jstype = JS_NORMAL]; // BigInt
737
+ * uint64 field_b = 2 [jstype = JS_NUMBER]; // BigInt
738
+ * uint64 field_b = 2 [jstype = JS_STRING]; // String
739
+ * ```
740
+ */
741
+ var LongType;
742
+ (function (LongType) {
743
+ /**
744
+ * Use JavaScript BigInt.
745
+ */
746
+ LongType[LongType["BIGINT"] = 0] = "BIGINT";
747
+ /**
748
+ * Use JavaScript String.
749
+ *
750
+ * Field option `[jstype = JS_STRING]`.
751
+ */
752
+ LongType[LongType["STRING"] = 1] = "STRING";
753
+ })(LongType || (LongType = {}));
726
754
 
727
755
  // Copyright 2008 Google Inc. All rights reserved.
728
756
  //
@@ -1681,7 +1709,7 @@ function scalarEquals(type, a, b) {
1681
1709
  * Returns the default value for the given scalar type, following
1682
1710
  * proto3 semantics.
1683
1711
  */
1684
- function scalarDefaultValue(type) {
1712
+ function scalarDefaultValue(type, longType) {
1685
1713
  switch (type) {
1686
1714
  case ScalarType.BOOL:
1687
1715
  return false;
@@ -1690,7 +1718,8 @@ function scalarDefaultValue(type) {
1690
1718
  case ScalarType.INT64:
1691
1719
  case ScalarType.SFIXED64:
1692
1720
  case ScalarType.SINT64:
1693
- return protoInt64.zero;
1721
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison -- acceptable since it's covered by tests
1722
+ return longType == 0 ? protoInt64.zero : "0";
1694
1723
  case ScalarType.DOUBLE:
1695
1724
  case ScalarType.FLOAT:
1696
1725
  return 0.0;
@@ -1734,13 +1763,13 @@ function scalarTypeInfo(type, value) {
1734
1763
  wireType = WireType.Bit32;
1735
1764
  break;
1736
1765
  case ScalarType.INT64:
1737
- isIntrinsicDefault = isUndefined || value == 0;
1766
+ isIntrinsicDefault = isUndefined || value == 0; // Loose comparison matches 0n, 0 and "0"
1738
1767
  break;
1739
1768
  case ScalarType.UINT64:
1740
- isIntrinsicDefault = isUndefined || value == 0;
1769
+ isIntrinsicDefault = isUndefined || value == 0; // Loose comparison matches 0n, 0 and "0"
1741
1770
  break;
1742
1771
  case ScalarType.FIXED64:
1743
- isIntrinsicDefault = isUndefined || value == 0;
1772
+ isIntrinsicDefault = isUndefined || value == 0; // Loose comparison matches 0n, 0 and "0"
1744
1773
  wireType = WireType.Bit64;
1745
1774
  break;
1746
1775
  case ScalarType.BYTES:
@@ -1855,18 +1884,23 @@ function makeBinaryFormatCommon() {
1855
1884
  case "scalar":
1856
1885
  case "enum":
1857
1886
  const scalarType = field.kind == "enum" ? ScalarType.INT32 : field.T;
1887
+ let read = readScalar$1;
1888
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison -- acceptable since it's covered by tests
1889
+ if (field.kind == "scalar" && field.L > 0) {
1890
+ read = readScalarLTString;
1891
+ }
1858
1892
  if (repeated) {
1859
1893
  let arr = target[localName]; // safe to assume presence of array, oneof cannot contain repeated values
1860
1894
  if (wireType == WireType.LengthDelimited && scalarType != ScalarType.STRING && scalarType != ScalarType.BYTES) {
1861
1895
  let e = reader.uint32() + reader.pos;
1862
1896
  while (reader.pos < e) {
1863
- arr.push(readScalar$1(reader, scalarType));
1897
+ arr.push(read(reader, scalarType));
1864
1898
  }
1865
1899
  } else {
1866
- arr.push(readScalar$1(reader, scalarType));
1900
+ arr.push(read(reader, scalarType));
1867
1901
  }
1868
1902
  } else {
1869
- target[localName] = readScalar$1(reader, scalarType);
1903
+ target[localName] = read(reader, scalarType);
1870
1904
  }
1871
1905
  break;
1872
1906
  case "message":
@@ -1929,7 +1963,7 @@ function readMapEntry(field, reader, options) {
1929
1963
  }
1930
1964
  }
1931
1965
  if (key === undefined) {
1932
- let keyRaw = scalarDefaultValue(field.K);
1966
+ let keyRaw = scalarDefaultValue(field.K, LongType.BIGINT);
1933
1967
  key = field.K == ScalarType.BOOL ? keyRaw.toString() : keyRaw;
1934
1968
  }
1935
1969
  if (typeof key != "string" && typeof key != "number") {
@@ -1938,7 +1972,7 @@ function readMapEntry(field, reader, options) {
1938
1972
  if (val === undefined) {
1939
1973
  switch (field.V.kind) {
1940
1974
  case "scalar":
1941
- val = scalarDefaultValue(field.V.T);
1975
+ val = scalarDefaultValue(field.V.T, LongType.BIGINT);
1942
1976
  break;
1943
1977
  case "enum":
1944
1978
  val = 0;
@@ -1950,6 +1984,12 @@ function readMapEntry(field, reader, options) {
1950
1984
  }
1951
1985
  return [key, val];
1952
1986
  }
1987
+ // Read a scalar value, but return 64 bit integral types (int64, uint64,
1988
+ // sint64, fixed64, sfixed64) as string instead of bigint.
1989
+ function readScalarLTString(reader, type) {
1990
+ const v = readScalar$1(reader, type);
1991
+ return typeof v == "bigint" ? v.toString() : v;
1992
+ }
1953
1993
  // Does not use scalarTypeInfo() for better performance.
1954
1994
  function readScalar$1(reader, type) {
1955
1995
  switch (type) {
@@ -2340,7 +2380,7 @@ function makeJsonFormatCommon(makeWriteField) {
2340
2380
  break;
2341
2381
  case "scalar":
2342
2382
  try {
2343
- val = readScalar(field.T, jsonItem);
2383
+ val = readScalar(field.T, jsonItem, field.L);
2344
2384
  } catch (e) {
2345
2385
  let m = "cannot decode field ".concat(type.typeName, ".").concat(field.name, " from JSON: ").concat(this.debug(jsonItem));
2346
2386
  if (e instanceof Error && e.message.length > 0) {
@@ -2375,7 +2415,7 @@ function makeJsonFormatCommon(makeWriteField) {
2375
2415
  break;
2376
2416
  case "scalar":
2377
2417
  try {
2378
- val = readScalar(field.V.T, jsonMapValue);
2418
+ val = readScalar(field.V.T, jsonMapValue, LongType.BIGINT);
2379
2419
  } catch (e) {
2380
2420
  let m = "cannot decode map value for field ".concat(type.typeName, ".").concat(field.name, " from JSON: ").concat(this.debug(jsonValue));
2381
2421
  if (e instanceof Error && e.message.length > 0) {
@@ -2386,7 +2426,7 @@ function makeJsonFormatCommon(makeWriteField) {
2386
2426
  break;
2387
2427
  }
2388
2428
  try {
2389
- targetMap[readScalar(field.K, field.K == ScalarType.BOOL ? jsonMapKey == "true" ? true : jsonMapKey == "false" ? false : jsonMapKey : jsonMapKey).toString()] = val;
2429
+ targetMap[readScalar(field.K, field.K == ScalarType.BOOL ? jsonMapKey == "true" ? true : jsonMapKey == "false" ? false : jsonMapKey : jsonMapKey, LongType.BIGINT).toString()] = val;
2390
2430
  } catch (e) {
2391
2431
  let m = "cannot decode map key for field ".concat(type.typeName, ".").concat(field.name, " from JSON: ").concat(this.debug(jsonValue));
2392
2432
  if (e instanceof Error && e.message.length > 0) {
@@ -2422,7 +2462,7 @@ function makeJsonFormatCommon(makeWriteField) {
2422
2462
  break;
2423
2463
  case "scalar":
2424
2464
  try {
2425
- target[localName] = readScalar(field.T, jsonValue);
2465
+ target[localName] = readScalar(field.T, jsonValue, field.L);
2426
2466
  } catch (e) {
2427
2467
  let m = "cannot decode field ".concat(type.typeName, ".").concat(field.name, " from JSON: ").concat(this.debug(jsonValue));
2428
2468
  if (e instanceof Error && e.message.length > 0) {
@@ -2488,7 +2528,7 @@ function debugJsonValue(json) {
2488
2528
  }
2489
2529
  // May throw an error. If the error message is non-blank, it should be shown.
2490
2530
  // It is up to the caller to provide context.
2491
- function readScalar(type, json) {
2531
+ function readScalar(type, json, longType) {
2492
2532
  // every valid case in the switch below returns, and every fall
2493
2533
  // through is regarded as a failure.
2494
2534
  switch (type) {
@@ -2542,12 +2582,16 @@ function readScalar(type, json) {
2542
2582
  case ScalarType.SINT64:
2543
2583
  if (json === null) return protoInt64.zero;
2544
2584
  if (typeof json != "number" && typeof json != "string") break;
2545
- return protoInt64.parse(json);
2585
+ const long = protoInt64.parse(json);
2586
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
2587
+ return longType ? long.toString() : long;
2546
2588
  case ScalarType.FIXED64:
2547
2589
  case ScalarType.UINT64:
2548
2590
  if (json === null) return protoInt64.zero;
2549
2591
  if (typeof json != "number" && typeof json != "string") break;
2550
- return protoInt64.uParse(json);
2592
+ const uLong = protoInt64.uParse(json);
2593
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
2594
+ return longType ? uLong.toString() : uLong;
2551
2595
  // bool:
2552
2596
  case ScalarType.BOOL:
2553
2597
  if (json === null) return false;
@@ -3238,7 +3282,7 @@ const proto3 = makeProtoRuntime("proto3", makeJsonFormatProto3(), makeBinaryForm
3238
3282
  t[name] = {};
3239
3283
  break;
3240
3284
  case "scalar":
3241
- t[name] = scalarDefaultValue(member.T); // eslint-disable-line @typescript-eslint/no-unsafe-assignment
3285
+ t[name] = scalarDefaultValue(member.T, member.L); // eslint-disable-line @typescript-eslint/no-unsafe-assignment
3242
3286
  break;
3243
3287
  }
3244
3288
  }
@@ -3246,7 +3290,7 @@ const proto3 = makeProtoRuntime("proto3", makeJsonFormatProto3(), makeBinaryForm
3246
3290
  }));
3247
3291
  /* eslint-disable @typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-argument */
3248
3292
  function normalizeFieldInfosProto3(fieldInfos) {
3249
- var _a, _b, _c;
3293
+ var _a, _b, _c, _d;
3250
3294
  const r = [];
3251
3295
  let o;
3252
3296
  for (const field of typeof fieldInfos == "function" ? fieldInfos() : fieldInfos) {
@@ -3254,12 +3298,15 @@ function normalizeFieldInfosProto3(fieldInfos) {
3254
3298
  f.localName = localFieldName(field.name, field.oneof !== undefined);
3255
3299
  f.jsonName = (_a = field.jsonName) !== null && _a !== void 0 ? _a : fieldJsonName(field.name);
3256
3300
  f.repeated = (_b = field.repeated) !== null && _b !== void 0 ? _b : false;
3301
+ if (field.kind == "scalar") {
3302
+ f.L = (_c = field.L) !== null && _c !== void 0 ? _c : LongType.BIGINT;
3303
+ }
3257
3304
  // From the proto3 language guide:
3258
3305
  // > In proto3, repeated fields of scalar numeric types are packed by default.
3259
3306
  // This information is incomplete - according to the conformance tests, BOOL
3260
3307
  // and ENUM are packed by default as well. This means only STRING and BYTES
3261
3308
  // are not packed by default, which makes sense because they are length-delimited.
3262
- f.packed = (_c = field.packed) !== null && _c !== void 0 ? _c : field.kind == "enum" || field.kind == "scalar" && field.T != ScalarType.BYTES && field.T != ScalarType.STRING;
3309
+ f.packed = (_d = field.packed) !== null && _d !== void 0 ? _d : field.kind == "enum" || field.kind == "scalar" && field.T != ScalarType.BYTES && field.T != ScalarType.STRING;
3263
3310
  // We do not surface options at this time
3264
3311
  // f.options = field.options ?? emptyReadonlyObject;
3265
3312
  if (field.oneof !== undefined) {
@@ -3572,6 +3619,28 @@ proto3.util.setEnumType(VideoCodec, "livekit.VideoCodec", [{
3572
3619
  no: 4,
3573
3620
  name: "VP8"
3574
3621
  }]);
3622
+ /**
3623
+ * @generated from enum livekit.ImageCodec
3624
+ */
3625
+ var ImageCodec;
3626
+ (function (ImageCodec) {
3627
+ /**
3628
+ * @generated from enum value: IC_DEFAULT = 0;
3629
+ */
3630
+ ImageCodec[ImageCodec["IC_DEFAULT"] = 0] = "IC_DEFAULT";
3631
+ /**
3632
+ * @generated from enum value: IC_JPEG = 1;
3633
+ */
3634
+ ImageCodec[ImageCodec["IC_JPEG"] = 1] = "IC_JPEG";
3635
+ })(ImageCodec || (ImageCodec = {}));
3636
+ // Retrieve enum metadata with: proto3.getEnumType(ImageCodec)
3637
+ proto3.util.setEnumType(ImageCodec, "livekit.ImageCodec", [{
3638
+ no: 0,
3639
+ name: "IC_DEFAULT"
3640
+ }, {
3641
+ no: 1,
3642
+ name: "IC_JPEG"
3643
+ }]);
3575
3644
  /**
3576
3645
  * @generated from enum livekit.TrackType
3577
3646
  */
@@ -3997,11 +4066,6 @@ Room$1.fields = proto3.util.newFieldList(() => [{
3997
4066
  name: "active_recording",
3998
4067
  kind: "scalar",
3999
4068
  T: 8 /* ScalarType.BOOL */
4000
- }, {
4001
- no: 12,
4002
- name: "playout_delay",
4003
- kind: "message",
4004
- T: PlayoutDelay
4005
4069
  }]);
4006
4070
  /**
4007
4071
  * @generated from message livekit.Codec
@@ -4926,6 +4990,10 @@ class UserPacket extends Message {
4926
4990
  * @generated from field: string participant_sid = 1;
4927
4991
  */
4928
4992
  this.participantSid = "";
4993
+ /**
4994
+ * @generated from field: string participant_identity = 5;
4995
+ */
4996
+ this.participantIdentity = "";
4929
4997
  /**
4930
4998
  * user defined payload
4931
4999
  *
@@ -4933,11 +5001,17 @@ class UserPacket extends Message {
4933
5001
  */
4934
5002
  this.payload = new Uint8Array(0);
4935
5003
  /**
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)
5004
+ * the ID of the participants who will receive the message (sent to all by default)
4937
5005
  *
4938
5006
  * @generated from field: repeated string destination_sids = 3;
4939
5007
  */
4940
5008
  this.destinationSids = [];
5009
+ /**
5010
+ * identities of participants who will receive the message (sent to all by default)
5011
+ *
5012
+ * @generated from field: repeated string destination_identities = 6;
5013
+ */
5014
+ this.destinationIdentities = [];
4941
5015
  proto3.util.initPartial(data, this);
4942
5016
  }
4943
5017
  static fromBinary(bytes, options) {
@@ -4960,6 +5034,11 @@ UserPacket.fields = proto3.util.newFieldList(() => [{
4960
5034
  name: "participant_sid",
4961
5035
  kind: "scalar",
4962
5036
  T: 9 /* ScalarType.STRING */
5037
+ }, {
5038
+ no: 5,
5039
+ name: "participant_identity",
5040
+ kind: "scalar",
5041
+ T: 9 /* ScalarType.STRING */
4963
5042
  }, {
4964
5043
  no: 2,
4965
5044
  name: "payload",
@@ -4971,6 +5050,12 @@ UserPacket.fields = proto3.util.newFieldList(() => [{
4971
5050
  kind: "scalar",
4972
5051
  T: 9 /* ScalarType.STRING */,
4973
5052
  repeated: true
5053
+ }, {
5054
+ no: 6,
5055
+ name: "destination_identities",
5056
+ kind: "scalar",
5057
+ T: 9 /* ScalarType.STRING */,
5058
+ repeated: true
4974
5059
  }, {
4975
5060
  no: 4,
4976
5061
  name: "topic",
@@ -5286,6 +5371,14 @@ var ClientInfo_SDK;
5286
5371
  * @generated from enum value: RUST = 8;
5287
5372
  */
5288
5373
  ClientInfo_SDK[ClientInfo_SDK["RUST"] = 8] = "RUST";
5374
+ /**
5375
+ * @generated from enum value: PYTHON = 9;
5376
+ */
5377
+ ClientInfo_SDK[ClientInfo_SDK["PYTHON"] = 9] = "PYTHON";
5378
+ /**
5379
+ * @generated from enum value: CPP = 10;
5380
+ */
5381
+ ClientInfo_SDK[ClientInfo_SDK["CPP"] = 10] = "CPP";
5289
5382
  })(ClientInfo_SDK || (ClientInfo_SDK = {}));
5290
5383
  // Retrieve enum metadata with: proto3.getEnumType(ClientInfo_SDK)
5291
5384
  proto3.util.setEnumType(ClientInfo_SDK, "livekit.ClientInfo.SDK", [{
@@ -5315,6 +5408,12 @@ proto3.util.setEnumType(ClientInfo_SDK, "livekit.ClientInfo.SDK", [{
5315
5408
  }, {
5316
5409
  no: 8,
5317
5410
  name: "RUST"
5411
+ }, {
5412
+ no: 9,
5413
+ name: "PYTHON"
5414
+ }, {
5415
+ no: 10,
5416
+ name: "CPP"
5318
5417
  }]);
5319
5418
  /**
5320
5419
  * server provided client configuration
@@ -5456,6 +5555,103 @@ DisabledCodecs.fields = proto3.util.newFieldList(() => [{
5456
5555
  T: Codec,
5457
5556
  repeated: true
5458
5557
  }]);
5558
+ /**
5559
+ * @generated from message livekit.RTPDrift
5560
+ */
5561
+ class RTPDrift extends Message {
5562
+ constructor(data) {
5563
+ super();
5564
+ /**
5565
+ * @generated from field: double duration = 3;
5566
+ */
5567
+ this.duration = 0;
5568
+ /**
5569
+ * @generated from field: uint64 start_timestamp = 4;
5570
+ */
5571
+ this.startTimestamp = protoInt64.zero;
5572
+ /**
5573
+ * @generated from field: uint64 end_timestamp = 5;
5574
+ */
5575
+ this.endTimestamp = protoInt64.zero;
5576
+ /**
5577
+ * @generated from field: uint64 rtp_clock_ticks = 6;
5578
+ */
5579
+ this.rtpClockTicks = protoInt64.zero;
5580
+ /**
5581
+ * @generated from field: int64 drift_samples = 7;
5582
+ */
5583
+ this.driftSamples = protoInt64.zero;
5584
+ /**
5585
+ * @generated from field: double drift_ms = 8;
5586
+ */
5587
+ this.driftMs = 0;
5588
+ /**
5589
+ * @generated from field: double clock_rate = 9;
5590
+ */
5591
+ this.clockRate = 0;
5592
+ proto3.util.initPartial(data, this);
5593
+ }
5594
+ static fromBinary(bytes, options) {
5595
+ return new RTPDrift().fromBinary(bytes, options);
5596
+ }
5597
+ static fromJson(jsonValue, options) {
5598
+ return new RTPDrift().fromJson(jsonValue, options);
5599
+ }
5600
+ static fromJsonString(jsonString, options) {
5601
+ return new RTPDrift().fromJsonString(jsonString, options);
5602
+ }
5603
+ static equals(a, b) {
5604
+ return proto3.util.equals(RTPDrift, a, b);
5605
+ }
5606
+ }
5607
+ RTPDrift.runtime = proto3;
5608
+ RTPDrift.typeName = "livekit.RTPDrift";
5609
+ RTPDrift.fields = proto3.util.newFieldList(() => [{
5610
+ no: 1,
5611
+ name: "start_time",
5612
+ kind: "message",
5613
+ T: Timestamp
5614
+ }, {
5615
+ no: 2,
5616
+ name: "end_time",
5617
+ kind: "message",
5618
+ T: Timestamp
5619
+ }, {
5620
+ no: 3,
5621
+ name: "duration",
5622
+ kind: "scalar",
5623
+ T: 1 /* ScalarType.DOUBLE */
5624
+ }, {
5625
+ no: 4,
5626
+ name: "start_timestamp",
5627
+ kind: "scalar",
5628
+ T: 4 /* ScalarType.UINT64 */
5629
+ }, {
5630
+ no: 5,
5631
+ name: "end_timestamp",
5632
+ kind: "scalar",
5633
+ T: 4 /* ScalarType.UINT64 */
5634
+ }, {
5635
+ no: 6,
5636
+ name: "rtp_clock_ticks",
5637
+ kind: "scalar",
5638
+ T: 4 /* ScalarType.UINT64 */
5639
+ }, {
5640
+ no: 7,
5641
+ name: "drift_samples",
5642
+ kind: "scalar",
5643
+ T: 3 /* ScalarType.INT64 */
5644
+ }, {
5645
+ no: 8,
5646
+ name: "drift_ms",
5647
+ kind: "scalar",
5648
+ T: 1 /* ScalarType.DOUBLE */
5649
+ }, {
5650
+ no: 9,
5651
+ name: "clock_rate",
5652
+ kind: "scalar",
5653
+ T: 1 /* ScalarType.DOUBLE */
5654
+ }]);
5459
5655
  /**
5460
5656
  * @generated from message livekit.RTPStats
5461
5657
  */
@@ -5602,16 +5798,6 @@ class RTPStats extends Message {
5602
5798
  * @generated from field: uint32 layer_lock_plis = 35;
5603
5799
  */
5604
5800
  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
5801
  proto3.util.initPartial(data, this);
5616
5802
  }
5617
5803
  static fromBinary(bytes, options) {
@@ -5839,15 +6025,15 @@ RTPStats.fields = proto3.util.newFieldList(() => [{
5839
6025
  kind: "message",
5840
6026
  T: Timestamp
5841
6027
  }, {
5842
- no: 42,
5843
- name: "sample_rate",
5844
- kind: "scalar",
5845
- T: 1 /* ScalarType.DOUBLE */
6028
+ no: 44,
6029
+ name: "packet_drift",
6030
+ kind: "message",
6031
+ T: RTPDrift
5846
6032
  }, {
5847
- no: 43,
5848
- name: "drift_ms",
5849
- kind: "scalar",
5850
- T: 1 /* ScalarType.DOUBLE */
6033
+ no: 45,
6034
+ name: "report_drift",
6035
+ kind: "message",
6036
+ T: RTPDrift
5851
6037
  }]);
5852
6038
  /**
5853
6039
  * @generated from message livekit.TimedVersion
@@ -5920,7 +6106,7 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
5920
6106
  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
5921
6107
  PERFORMANCE OF THIS SOFTWARE.
5922
6108
  ***************************************************************************** */
5923
- /* global Reflect, Promise */
6109
+ /* global Reflect, Promise, SuppressedError, Symbol */
5924
6110
 
5925
6111
 
5926
6112
  function __awaiter(thisArg, _arguments, P, generator) {
@@ -5951,7 +6137,12 @@ function __asyncValues(o) {
5951
6137
  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
6138
  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
6139
  function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
5954
- }
6140
+ }
6141
+
6142
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
6143
+ var e = new Error(message);
6144
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
6145
+ };
5955
6146
 
5956
6147
  var events = {exports: {}};
5957
6148
 
@@ -9825,10 +10016,6 @@ class SimulcastCodec extends Message {
9825
10016
  * @generated from field: string cid = 2;
9826
10017
  */
9827
10018
  this.cid = "";
9828
- /**
9829
- * @generated from field: bool enable_simulcast_layers = 3;
9830
- */
9831
- this.enableSimulcastLayers = false;
9832
10019
  proto3.util.initPartial(data, this);
9833
10020
  }
9834
10021
  static fromBinary(bytes, options) {
@@ -9856,11 +10043,6 @@ SimulcastCodec.fields = proto3.util.newFieldList(() => [{
9856
10043
  name: "cid",
9857
10044
  kind: "scalar",
9858
10045
  T: 9 /* ScalarType.STRING */
9859
- }, {
9860
- no: 3,
9861
- name: "enable_simulcast_layers",
9862
- kind: "scalar",
9863
- T: 8 /* ScalarType.BOOL */
9864
10046
  }]);
9865
10047
  /**
9866
10048
  * @generated from message livekit.AddTrackRequest
@@ -11863,7 +12045,7 @@ function getMatch(exp, ua) {
11863
12045
  return match && match.length >= id && match[id] || '';
11864
12046
  }
11865
12047
 
11866
- var version$1 = "1.14.1";
12048
+ var version$1 = "1.14.3";
11867
12049
 
11868
12050
  const version = version$1;
11869
12051
  const protocolVersion = 10;
@@ -11892,9 +12074,6 @@ const videoCodecs = ['vp8', 'h264', 'vp9', 'av1'];
11892
12074
  function isBackupCodec(codec) {
11893
12075
  return !!backupCodecs.find(backup => backup === codec);
11894
12076
  }
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
12077
  var AudioPresets;
11899
12078
  (function (AudioPresets) {
11900
12079
  AudioPresets.telephone = {
@@ -11953,6 +12132,17 @@ const ScreenSharePresets = {
11953
12132
  h1080fps30: new VideoPreset(1920, 1080, 4000000, 30, 'medium')
11954
12133
  };
11955
12134
 
12135
+ function cloneDeep(value) {
12136
+ if (typeof value === 'undefined') {
12137
+ return;
12138
+ }
12139
+ if (typeof structuredClone === 'function') {
12140
+ return structuredClone(value);
12141
+ } else {
12142
+ return JSON.parse(JSON.stringify(value));
12143
+ }
12144
+ }
12145
+
11956
12146
  /**
11957
12147
  * Events are the primary way LiveKit notifies your application of changes.
11958
12148
  *
@@ -12152,7 +12342,7 @@ var RoomEvent;
12152
12342
  * be emitted.
12153
12343
  *
12154
12344
  * args: (pub: [[RemoteTrackPublication]],
12155
- * status: [[TrackPublication.SubscriptionStatus]],
12345
+ * status: [[TrackPublication.PermissionStatus]],
12156
12346
  * participant: [[RemoteParticipant]])
12157
12347
  */
12158
12348
  RoomEvent["TrackSubscriptionPermissionChanged"] = "trackSubscriptionPermissionChanged";
@@ -12343,6 +12533,9 @@ var ParticipantEvent;
12343
12533
  // fired only on LocalParticipant
12344
12534
  /** @internal */
12345
12535
  ParticipantEvent["MediaDevicesError"] = "mediaDevicesError";
12536
+ // fired only on LocalParticipant
12537
+ /** @internal */
12538
+ ParticipantEvent["AudioStreamAcquired"] = "audioStreamAcquired";
12346
12539
  /**
12347
12540
  * A participant's permission has changed. Currently only fired on LocalParticipant.
12348
12541
  * args: (prevPermissions: [[ParticipantPermission]])
@@ -12639,7 +12832,12 @@ function attachToElement(track, element) {
12639
12832
  });
12640
12833
  mediaStream.addTrack(track);
12641
12834
  }
12642
- element.autoplay = true;
12835
+ if (!isSafari() || !(element instanceof HTMLVideoElement)) {
12836
+ // when in low power mode (applies to both macOS and iOS), Safari will show a play/pause overlay
12837
+ // when a video starts that has the `autoplay` attribute is set.
12838
+ // we work around this by _not_ setting the autoplay attribute on safari and instead call `setTimeout(() => el.play(),0)` further down
12839
+ element.autoplay = true;
12840
+ }
12643
12841
  // In case there are no audio tracks present on the mediastream, we set the element as muted to ensure autoplay works
12644
12842
  element.muted = mediaStream.getAudioTracks().length === 0;
12645
12843
  if (element instanceof HTMLVideoElement) {
@@ -12772,7 +12970,8 @@ function detachTrack(track, element) {
12772
12970
  })(Track || (Track = {}));
12773
12971
 
12774
12972
  function mergeDefaultOptions(options, audioDefaults, videoDefaults) {
12775
- const opts = Object.assign({}, options);
12973
+ var _a;
12974
+ const opts = (_a = cloneDeep(options)) !== null && _a !== void 0 ? _a : {};
12776
12975
  if (opts.audio === true) opts.audio = {};
12777
12976
  if (opts.video === true) opts.video = {};
12778
12977
  // use defaults
@@ -12915,6 +13114,13 @@ function screenCaptureToDisplayMediaStreamOptions(options) {
12915
13114
  systemAudio: options.systemAudio
12916
13115
  };
12917
13116
  }
13117
+ function mimeTypeToVideoCodecString(mimeType) {
13118
+ const codec = mimeType.split('/')[1].toLowerCase();
13119
+ if (!videoCodecs.includes(codec)) {
13120
+ throw Error("Video codec not supported: ".concat(codec));
13121
+ }
13122
+ return codec;
13123
+ }
12918
13124
 
12919
13125
  const separator = '|';
12920
13126
  const ddExtensionURI = 'https://aomediacodec.github.io/av1-rtp-spec/#dependency-descriptor-rtp-header-extension';
@@ -14047,13 +14253,6 @@ function deriveKeys(material, salt) {
14047
14253
  function createE2EEKey() {
14048
14254
  return window.crypto.getRandomValues(new Uint8Array(32));
14049
14255
  }
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
14256
  /**
14058
14257
  * Ratchets a key. See
14059
14258
  * https://tools.ietf.org/html/draft-omara-sframe-00#section-4.3.5.1
@@ -14441,10 +14640,16 @@ class LocalTrack extends Track {
14441
14640
  }
14442
14641
  waitForDimensions() {
14443
14642
  let timeout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultDimensionsTimeout;
14643
+ var _a;
14444
14644
  return __awaiter(this, void 0, void 0, function* () {
14445
14645
  if (this.kind === Track.Kind.Audio) {
14446
14646
  throw new Error('cannot get dimensions for audio tracks');
14447
14647
  }
14648
+ if (((_a = getBrowser()) === null || _a === void 0 ? void 0 : _a.os) === 'iOS') {
14649
+ // browsers report wrong initial resolution on iOS.
14650
+ // when slightly delaying the call to .getSettings(), the correct resolution is being reported
14651
+ yield sleep(10);
14652
+ }
14448
14653
  const started = Date.now();
14449
14654
  while (Date.now() - started < timeout) {
14450
14655
  const dims = this.dimensions;
@@ -15773,6 +15978,27 @@ class PCTransport extends eventsExports.EventEmitter {
15773
15978
  this._pc = isChromiumBased() ?
15774
15979
  // @ts-expect-error chrome allows additional media constraints to be passed into the RTCPeerConnection constructor
15775
15980
  new RTCPeerConnection(config, mediaConstraints) : new RTCPeerConnection(config);
15981
+ this._pc.onicecandidate = ev => {
15982
+ var _a;
15983
+ if (!ev.candidate) return;
15984
+ (_a = this.onIceCandidate) === null || _a === void 0 ? void 0 : _a.call(this, ev.candidate);
15985
+ };
15986
+ this._pc.onicecandidateerror = ev => {
15987
+ var _a;
15988
+ (_a = this.onIceCandidateError) === null || _a === void 0 ? void 0 : _a.call(this, ev);
15989
+ };
15990
+ this._pc.onconnectionstatechange = () => {
15991
+ var _a, _b, _c;
15992
+ (_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');
15993
+ };
15994
+ this._pc.ondatachannel = ev => {
15995
+ var _a;
15996
+ (_a = this.onDataChannel) === null || _a === void 0 ? void 0 : _a.call(this, ev);
15997
+ };
15998
+ this._pc.ontrack = ev => {
15999
+ var _a;
16000
+ (_a = this.onTrack) === null || _a === void 0 ? void 0 : _a.call(this, ev);
16001
+ };
15776
16002
  }
15777
16003
  get isICEConnected() {
15778
16004
  return this._pc !== null && (this.pc.iceConnectionState === 'connected' || this.pc.iceConnectionState === 'completed');
@@ -15918,7 +16144,7 @@ class PCTransport extends eventsExports.EventEmitter {
15918
16144
  for (const fmtp of media.fmtp) {
15919
16145
  if (fmtp.payload === codecPayload) {
15920
16146
  if (!fmtp.config.includes('x-google-start-bitrate')) {
15921
- fmtp.config += ";x-google-start-bitrate=".concat(trackbr.maxbr * startBitrateForSVC);
16147
+ fmtp.config += ";x-google-start-bitrate=".concat(Math.round(trackbr.maxbr * startBitrateForSVC));
15922
16148
  }
15923
16149
  if (!fmtp.config.includes('x-google-max-bitrate')) {
15924
16150
  fmtp.config += ";x-google-max-bitrate=".concat(trackbr.maxbr);
@@ -15930,7 +16156,7 @@ class PCTransport extends eventsExports.EventEmitter {
15930
16156
  if (!fmtpFound) {
15931
16157
  media.fmtp.push({
15932
16158
  payload: codecPayload,
15933
- config: "x-google-start-bitrate=".concat(trackbr.maxbr * startBitrateForSVC, ";x-google-max-bitrate=").concat(trackbr.maxbr)
16159
+ config: "x-google-start-bitrate=".concat(Math.round(trackbr.maxbr * startBitrateForSVC), ";x-google-max-bitrate=").concat(trackbr.maxbr)
15934
16160
  });
15935
16161
  }
15936
16162
  return true;
@@ -15955,9 +16181,85 @@ class PCTransport extends eventsExports.EventEmitter {
15955
16181
  return answer;
15956
16182
  });
15957
16183
  }
16184
+ createDataChannel(label, dataChannelDict) {
16185
+ return this.pc.createDataChannel(label, dataChannelDict);
16186
+ }
16187
+ addTransceiver(mediaStreamTrack, transceiverInit) {
16188
+ return this.pc.addTransceiver(mediaStreamTrack, transceiverInit);
16189
+ }
16190
+ addTrack(track) {
16191
+ return this.pc.addTrack(track);
16192
+ }
15958
16193
  setTrackCodecBitrate(info) {
15959
16194
  this.trackBitrates.push(info);
15960
16195
  }
16196
+ setConfiguration(rtcConfig) {
16197
+ return this.pc.setConfiguration(rtcConfig);
16198
+ }
16199
+ canRemoveTrack() {
16200
+ return !!this.pc.removeTrack;
16201
+ }
16202
+ removeTrack(sender) {
16203
+ return this.pc.removeTrack(sender);
16204
+ }
16205
+ getConnectionState() {
16206
+ return this.pc.connectionState;
16207
+ }
16208
+ getICEConnectionState() {
16209
+ return this.pc.iceConnectionState;
16210
+ }
16211
+ getSignallingState() {
16212
+ return this.pc.signalingState;
16213
+ }
16214
+ getTransceivers() {
16215
+ return this.pc.getTransceivers();
16216
+ }
16217
+ getSenders() {
16218
+ return this.pc.getSenders();
16219
+ }
16220
+ getLocalDescription() {
16221
+ return this.pc.localDescription;
16222
+ }
16223
+ getRemoteDescription() {
16224
+ return this.pc.remoteDescription;
16225
+ }
16226
+ getConnectedAddress() {
16227
+ var _a;
16228
+ return __awaiter(this, void 0, void 0, function* () {
16229
+ if (!this._pc) {
16230
+ return;
16231
+ }
16232
+ let selectedCandidatePairId = '';
16233
+ const candidatePairs = new Map();
16234
+ // id -> candidate ip
16235
+ const candidates = new Map();
16236
+ const stats = yield this._pc.getStats();
16237
+ stats.forEach(v => {
16238
+ switch (v.type) {
16239
+ case 'transport':
16240
+ selectedCandidatePairId = v.selectedCandidatePairId;
16241
+ break;
16242
+ case 'candidate-pair':
16243
+ if (selectedCandidatePairId === '' && v.selected) {
16244
+ selectedCandidatePairId = v.id;
16245
+ }
16246
+ candidatePairs.set(v.id, v);
16247
+ break;
16248
+ case 'remote-candidate':
16249
+ candidates.set(v.id, "".concat(v.address, ":").concat(v.port));
16250
+ break;
16251
+ }
16252
+ });
16253
+ if (selectedCandidatePairId === '') {
16254
+ return undefined;
16255
+ }
16256
+ const selectedID = (_a = candidatePairs.get(selectedCandidatePairId)) === null || _a === void 0 ? void 0 : _a.remoteCandidateId;
16257
+ if (selectedID === undefined) {
16258
+ return undefined;
16259
+ }
16260
+ return candidates.get(selectedID);
16261
+ });
16262
+ }
15961
16263
  close() {
15962
16264
  if (!this._pc) {
15963
16265
  return;
@@ -16118,6 +16420,7 @@ function extractStereoAndNackAudioFromOffer(offer) {
16118
16420
  };
16119
16421
  }
16120
16422
 
16423
+ const defaultVideoCodec = 'vp8';
16121
16424
  const publishDefaults = {
16122
16425
  /**
16123
16426
  * @deprecated
@@ -16130,7 +16433,7 @@ const publishDefaults = {
16130
16433
  simulcast: true,
16131
16434
  screenShareEncoding: ScreenSharePresets.h1080fps15.encoding,
16132
16435
  stopMicTrackOnMute: false,
16133
- videoCodec: 'vp8',
16436
+ videoCodec: defaultVideoCodec,
16134
16437
  backupCodec: false
16135
16438
  };
16136
16439
  const audioDefaults = {
@@ -16403,13 +16706,13 @@ class RTCEngine extends eventsExports.EventEmitter {
16403
16706
  }
16404
16707
  cleanupPeerConnections() {
16405
16708
  return __awaiter(this, void 0, void 0, function* () {
16406
- if (this.publisher && this.publisher.pc.signalingState !== 'closed') {
16407
- this.publisher.pc.getSenders().forEach(sender => {
16709
+ if (this.publisher && this.publisher.getSignallingState() !== 'closed') {
16710
+ this.publisher.getSenders().forEach(sender => {
16408
16711
  var _a, _b;
16409
16712
  try {
16410
16713
  // 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);
16714
+ if ((_a = this.publisher) === null || _a === void 0 ? void 0 : _a.canRemoveTrack()) {
16715
+ (_b = this.publisher) === null || _b === void 0 ? void 0 : _b.removeTrack(sender);
16413
16716
  }
16414
16717
  } catch (e) {
16415
16718
  livekitLogger.warn('could not removeTrack', {
@@ -16427,7 +16730,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16427
16730
  this.subscriber = undefined;
16428
16731
  }
16429
16732
  this.hasPublished = false;
16430
- this.primaryPC = undefined;
16733
+ this.primaryTransport = undefined;
16431
16734
  const dcCleanup = dc => {
16432
16735
  if (!dc) return;
16433
16736
  dc.close();
@@ -16494,7 +16797,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16494
16797
  delete this.pendingTrackResolvers[sender.track.id];
16495
16798
  }
16496
16799
  try {
16497
- (_a = this.publisher) === null || _a === void 0 ? void 0 : _a.pc.removeTrack(sender);
16800
+ (_a = this.publisher) === null || _a === void 0 ? void 0 : _a.removeTrack(sender);
16498
16801
  return true;
16499
16802
  } catch (e) {
16500
16803
  livekitLogger.warn('failed to remove track', {
@@ -16513,10 +16816,10 @@ class RTCEngine extends eventsExports.EventEmitter {
16513
16816
  }
16514
16817
  getConnectedServerAddress() {
16515
16818
  return __awaiter(this, void 0, void 0, function* () {
16516
- if (this.primaryPC === undefined) {
16819
+ if (this.primaryTransport === undefined) {
16517
16820
  return undefined;
16518
16821
  }
16519
- return getConnectedAddress(this.primaryPC);
16822
+ return this.primaryTransport.getConnectedAddress();
16520
16823
  });
16521
16824
  }
16522
16825
  /* @internal */
@@ -16524,19 +16827,13 @@ class RTCEngine extends eventsExports.EventEmitter {
16524
16827
  this.regionUrlProvider = provider;
16525
16828
  }
16526
16829
  configure(joinResponse) {
16527
- var _a, _b;
16830
+ var _a;
16528
16831
  // already configured
16529
16832
  if (this.publisher || this.subscriber) {
16530
16833
  return;
16531
16834
  }
16532
16835
  this.participantSid = (_a = joinResponse.participant) === null || _a === void 0 ? void 0 : _a.sid;
16533
16836
  const rtcConfig = this.makeRTCConfiguration(joinResponse);
16534
- if ((_b = this.signalOpts) === null || _b === void 0 ? void 0 : _b.e2eeEnabled) {
16535
- livekitLogger.debug('E2EE - setting up transports with insertable streams');
16536
- // this makes sure that no data is sent before the transforms are ready
16537
- // @ts-ignore
16538
- rtcConfig.encodedInsertableStreams = true;
16539
- }
16540
16837
  const googConstraints = {
16541
16838
  optional: [{
16542
16839
  googDscp: true
@@ -16545,37 +16842,35 @@ class RTCEngine extends eventsExports.EventEmitter {
16545
16842
  this.publisher = new PCTransport(rtcConfig, googConstraints);
16546
16843
  this.subscriber = new PCTransport(rtcConfig);
16547
16844
  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);
16845
+ this.publisher.onIceCandidate = candidate => {
16846
+ livekitLogger.trace('adding ICE candidate for peer', candidate);
16847
+ this.client.sendIceCandidate(candidate, SignalTarget.PUBLISHER);
16552
16848
  };
16553
- this.subscriber.pc.onicecandidate = ev => {
16554
- if (!ev.candidate) return;
16555
- this.client.sendIceCandidate(ev.candidate, SignalTarget.SUBSCRIBER);
16849
+ this.subscriber.onIceCandidate = candidate => {
16850
+ this.client.sendIceCandidate(candidate, SignalTarget.SUBSCRIBER);
16556
16851
  };
16557
16852
  this.publisher.onOffer = offer => {
16558
16853
  this.client.sendOffer(offer);
16559
16854
  };
16560
- let primaryPC = this.publisher.pc;
16561
- let secondaryPC = this.subscriber.pc;
16855
+ let primaryTransport = this.publisher;
16856
+ let secondaryTransport = this.subscriber;
16562
16857
  let subscriberPrimary = joinResponse.subscriberPrimary;
16563
16858
  if (subscriberPrimary) {
16564
- primaryPC = this.subscriber.pc;
16565
- secondaryPC = this.publisher.pc;
16859
+ primaryTransport = this.subscriber;
16860
+ secondaryTransport = this.publisher;
16566
16861
  // in subscriber primary mode, server side opens sub data channels.
16567
- this.subscriber.pc.ondatachannel = this.handleDataChannel;
16862
+ this.subscriber.onDataChannel = this.handleDataChannel;
16568
16863
  }
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') {
16864
+ this.primaryTransport = primaryTransport;
16865
+ primaryTransport.onConnectionStateChange = connectionState => __awaiter(this, void 0, void 0, function* () {
16866
+ livekitLogger.debug("primary PC state changed ".concat(connectionState));
16867
+ if (connectionState === 'connected') {
16573
16868
  const shouldEmit = this.pcState === PCState.New;
16574
16869
  this.pcState = PCState.Connected;
16575
16870
  if (shouldEmit) {
16576
16871
  this.emit(EngineEvent.Connected, joinResponse);
16577
16872
  }
16578
- } else if (primaryPC.connectionState === 'failed') {
16873
+ } else if (connectionState === 'failed') {
16579
16874
  // on Safari, PeerConnection will switch to 'disconnected' during renegotiation
16580
16875
  if (this.pcState === PCState.Connected) {
16581
16876
  this.pcState = PCState.Disconnected;
@@ -16583,14 +16878,14 @@ class RTCEngine extends eventsExports.EventEmitter {
16583
16878
  }
16584
16879
  }
16585
16880
  });
16586
- secondaryPC.onconnectionstatechange = () => __awaiter(this, void 0, void 0, function* () {
16587
- livekitLogger.debug("secondary PC state changed ".concat(secondaryPC.connectionState));
16881
+ secondaryTransport.onConnectionStateChange = connectionState => __awaiter(this, void 0, void 0, function* () {
16882
+ livekitLogger.debug("secondary PC state changed ".concat(connectionState));
16588
16883
  // also reconnect if secondary peerconnection fails
16589
- if (secondaryPC.connectionState === 'failed') {
16884
+ if (connectionState === 'failed') {
16590
16885
  this.handleDisconnect('secondary peerconnection', subscriberPrimary ? ReconnectReason.RR_PUBLISHER_FAILED : ReconnectReason.RR_SUBSCRIBER_FAILED);
16591
16886
  }
16592
16887
  });
16593
- this.subscriber.pc.ontrack = ev => {
16888
+ this.subscriber.onTrack = ev => {
16594
16889
  this.emit(EngineEvent.MediaTrackAdded, ev.track, ev.streams[0], ev.receiver);
16595
16890
  };
16596
16891
  this.createDataChannels();
@@ -16603,7 +16898,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16603
16898
  }
16604
16899
  livekitLogger.debug('received server answer', {
16605
16900
  RTCSdpType: sd.type,
16606
- signalingState: this.publisher.pc.signalingState.toString()
16901
+ signalingState: this.publisher.getSignallingState().toString()
16607
16902
  });
16608
16903
  yield this.publisher.setRemoteDescription(sd);
16609
16904
  });
@@ -16629,7 +16924,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16629
16924
  }
16630
16925
  livekitLogger.debug('received server offer', {
16631
16926
  RTCSdpType: sd.type,
16632
- signalingState: this.subscriber.pc.signalingState.toString()
16927
+ signalingState: this.subscriber.getSignallingState().toString()
16633
16928
  });
16634
16929
  yield this.subscriber.setRemoteDescription(sd);
16635
16930
  // answer the offer
@@ -16657,7 +16952,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16657
16952
  this.client.onLeave = leave => {
16658
16953
  if (leave === null || leave === void 0 ? void 0 : leave.canReconnect) {
16659
16954
  this.fullReconnectOnNext = true;
16660
- this.primaryPC = undefined;
16955
+ this.primaryTransport = undefined;
16661
16956
  // reconnect immediately instead of waiting for next attempt
16662
16957
  this.handleDisconnect(leaveReconnect);
16663
16958
  } else {
@@ -16670,7 +16965,14 @@ class RTCEngine extends eventsExports.EventEmitter {
16670
16965
  };
16671
16966
  }
16672
16967
  makeRTCConfiguration(serverResponse) {
16968
+ var _a;
16673
16969
  const rtcConfig = Object.assign({}, this.rtcConfig);
16970
+ if ((_a = this.signalOpts) === null || _a === void 0 ? void 0 : _a.e2eeEnabled) {
16971
+ livekitLogger.debug('E2EE - setting up transports with insertable streams');
16972
+ // this makes sure that no data is sent before the transforms are ready
16973
+ // @ts-ignore
16974
+ rtcConfig.encodedInsertableStreams = true;
16975
+ }
16674
16976
  // update ICE servers before creating PeerConnection
16675
16977
  if (serverResponse.iceServers && !rtcConfig.iceServers) {
16676
16978
  const rtcIceServers = [];
@@ -16709,12 +17011,12 @@ class RTCEngine extends eventsExports.EventEmitter {
16709
17011
  this.reliableDC.onerror = null;
16710
17012
  }
16711
17013
  // create data channels
16712
- this.lossyDC = this.publisher.pc.createDataChannel(lossyDataChannel, {
17014
+ this.lossyDC = this.publisher.createDataChannel(lossyDataChannel, {
16713
17015
  // will drop older packets that arrive
16714
17016
  ordered: true,
16715
17017
  maxRetransmits: 0
16716
17018
  });
16717
- this.reliableDC = this.publisher.pc.createDataChannel(reliableDataChannel, {
17019
+ this.reliableDC = this.publisher.createDataChannel(reliableDataChannel, {
16718
17020
  ordered: true
16719
17021
  });
16720
17022
  // also handle messages over the pub channel, for backwards compatibility
@@ -16811,7 +17113,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16811
17113
  transceiverInit.sendEncodings = encodings;
16812
17114
  }
16813
17115
  // 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);
17116
+ const transceiver = yield this.publisher.addTransceiver(track.mediaStreamTrack, transceiverInit);
16815
17117
  if (track.kind === Track.Kind.Video && opts.videoCodec) {
16816
17118
  this.setPreferredCodec(transceiver, track.kind, opts.videoCodec);
16817
17119
  track.codec = opts.videoCodec;
@@ -16831,7 +17133,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16831
17133
  transceiverInit.sendEncodings = encodings;
16832
17134
  }
16833
17135
  // 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);
17136
+ const transceiver = yield this.publisher.addTransceiver(simulcastTrack.mediaStreamTrack, transceiverInit);
16835
17137
  if (!opts.videoCodec) {
16836
17138
  return;
16837
17139
  }
@@ -16845,7 +17147,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16845
17147
  if (!this.publisher) {
16846
17148
  throw new UnexpectedConnectionState('publisher is closed');
16847
17149
  }
16848
- return this.publisher.pc.addTrack(track);
17150
+ return this.publisher.addTrack(track);
16849
17151
  });
16850
17152
  }
16851
17153
  attemptReconnect(reason) {
@@ -16861,7 +17163,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16861
17163
  if (((_a = this.clientConfiguration) === null || _a === void 0 ? void 0 : _a.resumeConnection) === ClientConfigSetting.DISABLED ||
16862
17164
  // signaling state could change to closed due to hardware sleep
16863
17165
  // 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') {
17166
+ ((_c = (_b = this.primaryTransport) === null || _b === void 0 ? void 0 : _b.getSignallingState()) !== null && _c !== void 0 ? _c : 'closed') === 'closed') {
16865
17167
  this.fullReconnectOnNext = true;
16866
17168
  }
16867
17169
  try {
@@ -16979,13 +17281,14 @@ class RTCEngine extends eventsExports.EventEmitter {
16979
17281
  const res = yield this.client.reconnect(this.url, this.token, this.participantSid, reason);
16980
17282
  if (res) {
16981
17283
  const rtcConfig = this.makeRTCConfiguration(res);
16982
- this.publisher.pc.setConfiguration(rtcConfig);
16983
- this.subscriber.pc.setConfiguration(rtcConfig);
17284
+ this.publisher.setConfiguration(rtcConfig);
17285
+ this.subscriber.setConfiguration(rtcConfig);
16984
17286
  }
16985
17287
  } catch (e) {
16986
17288
  let message = '';
16987
17289
  if (e instanceof Error) {
16988
17290
  message = e.message;
17291
+ livekitLogger.error(e.message);
16989
17292
  }
16990
17293
  if (e instanceof ConnectionError && e.reason === 0 /* ConnectionErrorReason.NotAllowed */) {
16991
17294
  throw new UnexpectedConnectionState('could not reconnect, token might be expired');
@@ -17055,14 +17358,14 @@ class RTCEngine extends eventsExports.EventEmitter {
17055
17358
  this.pcState = PCState.Reconnecting;
17056
17359
  livekitLogger.debug('waiting for peer connection to reconnect');
17057
17360
  while (now - startTime < this.peerConnectionTimeout) {
17058
- if (this.primaryPC === undefined) {
17361
+ if (this.primaryTransport === undefined) {
17059
17362
  // we can abort early, connection is hosed
17060
17363
  break;
17061
17364
  } else if (
17062
17365
  // on Safari, we don't get a connectionstatechanged event during ICE restart
17063
17366
  // this means we'd have to check its status manually and update address
17064
17367
  // 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')) {
17368
+ 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
17369
  this.pcState = PCState.Connected;
17067
17370
  }
17068
17371
  if (this.pcState === PCState.Connected) {
@@ -17100,7 +17403,7 @@ class RTCEngine extends eventsExports.EventEmitter {
17100
17403
  if (!transport) {
17101
17404
  throw new ConnectionError("".concat(transportName, " connection not set"));
17102
17405
  }
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') {
17406
+ 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
17407
  // start negotiation
17105
17408
  this.negotiate();
17106
17409
  }
@@ -17116,7 +17419,7 @@ class RTCEngine extends eventsExports.EventEmitter {
17116
17419
  }
17117
17420
  yield sleep(50);
17118
17421
  }
17119
- throw new ConnectionError("could not establish ".concat(transportName, " connection, state: ").concat(transport.pc.iceConnectionState));
17422
+ throw new ConnectionError("could not establish ".concat(transportName, " connection, state: ").concat(transport.getICEConnectionState()));
17120
17423
  });
17121
17424
  }
17122
17425
  ensurePublisherConnected(kind) {
@@ -17127,10 +17430,10 @@ class RTCEngine extends eventsExports.EventEmitter {
17127
17430
  /* @internal */
17128
17431
  verifyTransport() {
17129
17432
  // primary connection
17130
- if (!this.primaryPC) {
17433
+ if (!this.primaryTransport) {
17131
17434
  return false;
17132
17435
  }
17133
- if (this.primaryPC.connectionState === 'closed' || this.primaryPC.connectionState === 'failed') {
17436
+ if (this.primaryTransport.getConnectionState() === 'closed' || this.primaryTransport.getConnectionState() === 'failed') {
17134
17437
  return false;
17135
17438
  }
17136
17439
  // also verify publisher connection if it's needed or different
@@ -17138,7 +17441,7 @@ class RTCEngine extends eventsExports.EventEmitter {
17138
17441
  if (!this.publisher) {
17139
17442
  return false;
17140
17443
  }
17141
- if (this.publisher.pc.connectionState === 'closed' || this.publisher.pc.connectionState === 'failed') {
17444
+ if (this.publisher.getConnectionState() === 'closed' || this.publisher.getConnectionState() === 'failed') {
17142
17445
  return false;
17143
17446
  }
17144
17447
  }
@@ -17244,40 +17547,6 @@ class RTCEngine extends eventsExports.EventEmitter {
17244
17547
  }
17245
17548
  }
17246
17549
  }
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
17550
  class SignalReconnectError extends Error {}
17282
17551
 
17283
17552
  class RegionUrlProvider {
@@ -18211,7 +18480,8 @@ class LocalVideoTrack extends LocalTrack {
18211
18480
  }
18212
18481
  /**
18213
18482
  * @internal
18214
- * Sets codecs that should be publishing
18483
+ * Sets codecs that should be publishing, returns new codecs that have not yet
18484
+ * been published
18215
18485
  */
18216
18486
  setPublishingCodecs(codecs) {
18217
18487
  var _a, codecs_1, codecs_1_1;
@@ -20272,6 +20542,7 @@ class LocalParticipant extends Participant {
20272
20542
  }
20273
20543
  if (constraints.audio) {
20274
20544
  this.microphoneError = undefined;
20545
+ this.emit(ParticipantEvent.AudioStreamAcquired);
20275
20546
  }
20276
20547
  if (constraints.video) {
20277
20548
  this.cameraError = undefined;
@@ -20318,6 +20589,7 @@ class LocalParticipant extends Participant {
20318
20589
  screenVideo.source = Track.Source.ScreenShare;
20319
20590
  const localTracks = [screenVideo];
20320
20591
  if (stream.getAudioTracks().length > 0) {
20592
+ this.emit(ParticipantEvent.AudioStreamAcquired);
20321
20593
  const screenAudio = new LocalAudioTrack(stream.getAudioTracks()[0], undefined, false, this.audioContext);
20322
20594
  screenAudio.source = Track.Source.ScreenShareAudio;
20323
20595
  localTracks.push(screenAudio);
@@ -20428,22 +20700,11 @@ class LocalParticipant extends Participant {
20428
20700
  });
20429
20701
  }
20430
20702
  publish(track, opts, isStereo) {
20431
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
20703
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
20432
20704
  return __awaiter(this, void 0, void 0, function* () {
20433
20705
  const existingTrackOfSource = Array.from(this.tracks.values()).find(publishedTrack => track instanceof LocalTrack && publishedTrack.source === track.source);
20434
20706
  if (existingTrackOfSource && track.source !== Track.Source.Unknown) {
20435
- try {
20436
- // throw an Error in order to capture the stack trace
20437
- throw Error("publishing a second track with the same source: ".concat(track.source));
20438
- } catch (e) {
20439
- if (e instanceof Error) {
20440
- livekitLogger.warn(e.message, {
20441
- oldTrack: existingTrackOfSource,
20442
- newTrack: track,
20443
- trace: e.stack
20444
- });
20445
- }
20446
- }
20707
+ livekitLogger.info("publishing a second track with the same source: ".concat(track.source));
20447
20708
  }
20448
20709
  if (opts.stopMicTrackOnMute && track instanceof LocalAudioTrack) {
20449
20710
  track.stopOnMute = true;
@@ -20460,6 +20721,10 @@ class LocalParticipant extends Participant {
20460
20721
  if (opts.videoCodec === 'vp9' && !supportsVP9()) {
20461
20722
  opts.videoCodec = undefined;
20462
20723
  }
20724
+ if (opts.videoCodec === undefined) {
20725
+ opts.videoCodec = defaultVideoCodec;
20726
+ }
20727
+ const videoCodec = opts.videoCodec;
20463
20728
  // handle track actions
20464
20729
  track.on(TrackEvent.Muted, this.onTrackMuted);
20465
20730
  track.on(TrackEvent.Unmuted, this.onTrackUnmuted);
@@ -20482,7 +20747,6 @@ class LocalParticipant extends Participant {
20482
20747
  });
20483
20748
  // compute encodings and layers for video
20484
20749
  let encodings;
20485
- let simEncodings;
20486
20750
  if (track.kind === Track.Kind.Video) {
20487
20751
  let dims = {
20488
20752
  width: 0,
@@ -20506,74 +20770,60 @@ class LocalParticipant extends Participant {
20506
20770
  req.height = dims.height;
20507
20771
  // for svc codecs, disable simulcast and use vp8 for backup codec
20508
20772
  if (track instanceof LocalVideoTrack) {
20509
- if (isSVCCodec(opts.videoCodec)) {
20773
+ if (isSVCCodec(videoCodec)) {
20510
20774
  // vp9 svc with screenshare has problem to encode, always use L1T3 here
20511
- if (track.source === Track.Source.ScreenShare && opts.videoCodec === 'vp9') {
20775
+ if (track.source === Track.Source.ScreenShare && videoCodec === 'vp9') {
20512
20776
  opts.scalabilityMode = 'L1T3';
20513
20777
  }
20514
20778
  // set scalabilityMode to 'L3T3_KEY' by default
20515
20779
  opts.scalabilityMode = (_e = opts.scalabilityMode) !== null && _e !== void 0 ? _e : 'L3T3_KEY';
20516
20780
  }
20781
+ req.simulcastCodecs = [new SimulcastCodec({
20782
+ codec: videoCodec,
20783
+ cid: track.mediaStreamTrack.id
20784
+ })];
20517
20785
  // set up backup
20518
- if (opts.videoCodec && opts.backupCodec && opts.videoCodec !== opts.backupCodec.codec) {
20786
+ if (opts.backupCodec && videoCodec !== opts.backupCodec.codec) {
20519
20787
  if (!this.roomOptions.dynacast) {
20520
20788
  this.roomOptions.dynacast = true;
20521
20789
  }
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({
20790
+ req.simulcastCodecs.push(new SimulcastCodec({
20530
20791
  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
- })];
20792
+ cid: ''
20793
+ }));
20542
20794
  }
20543
20795
  }
20544
- encodings = computeVideoEncodings(track.source === Track.Source.ScreenShare, dims.width, dims.height, opts);
20796
+ encodings = computeVideoEncodings(track.source === Track.Source.ScreenShare, req.width, req.height, opts);
20545
20797
  req.layers = videoLayersFromEncodings(req.width, req.height, encodings, isSVCCodec(opts.videoCodec));
20546
20798
  } else if (track.kind === Track.Kind.Audio) {
20547
20799
  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'
20800
+ maxBitrate: (_g = (_f = opts.audioPreset) === null || _f === void 0 ? void 0 : _f.maxBitrate) !== null && _g !== void 0 ? _g : opts.audioBitrate,
20801
+ priority: (_j = (_h = opts.audioPreset) === null || _h === void 0 ? void 0 : _h.priority) !== null && _j !== void 0 ? _j : 'high',
20802
+ networkPriority: (_l = (_k = opts.audioPreset) === null || _k === void 0 ? void 0 : _k.priority) !== null && _l !== void 0 ? _l : 'high'
20551
20803
  }];
20552
20804
  }
20553
20805
  if (!this.engine || this.engine.isClosed) {
20554
20806
  throw new UnexpectedConnectionState('cannot publish track when not connected');
20555
20807
  }
20556
20808
  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;
20809
+ // server might not support the codec the client has requested, in that case, fallback
20810
+ // to a supported codec
20811
+ let primaryCodecMime;
20812
+ ti.codecs.forEach(codec => {
20813
+ if (primaryCodecMime === undefined) {
20814
+ primaryCodecMime = codec.mimeType;
20564
20815
  }
20565
20816
  });
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;
20817
+ if (primaryCodecMime && track.kind === Track.Kind.Video) {
20818
+ const updatedCodec = mimeTypeToVideoCodecString(primaryCodecMime);
20819
+ if (updatedCodec !== videoCodec) {
20820
+ livekitLogger.debug('falling back to server selected codec', {
20821
+ codec: updatedCodec
20822
+ });
20823
+ /* @ts-ignore */
20824
+ opts.videoCodec = updatedCodec;
20825
+ // recompute encodings since bitrates/etc could have changed
20826
+ encodings = computeVideoEncodings(track.source === Track.Source.ScreenShare, req.width, req.height, opts);
20577
20827
  }
20578
20828
  }
20579
20829
  const publication = new LocalTrackPublication(track.kind, ti, track);
@@ -20587,19 +20837,18 @@ class LocalParticipant extends Participant {
20587
20837
  encodings,
20588
20838
  trackInfo: ti
20589
20839
  });
20590
- // store RTPSender
20591
20840
  track.sender = yield this.engine.createSender(track, opts, encodings);
20592
20841
  if (encodings) {
20593
20842
  if (isFireFox() && track.kind === Track.Kind.Audio) {
20594
20843
  /* 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
20844
+ livekit-server uses maxaveragebitrate=510000 in the answer sdp to permit client to
20596
20845
  publish high quality audio track. But firefox always uses this value as the actual
20597
20846
  bitrates, causing the audio bitrates to rise to 510Kbps in any stereo case unexpectedly.
20598
20847
  So the client need to modify maxaverragebitrates in answer sdp to user provided value to
20599
20848
  fix the issue.
20600
20849
  */
20601
20850
  let trackTransceiver = undefined;
20602
- for (const transceiver of this.engine.publisher.pc.getTransceivers()) {
20851
+ for (const transceiver of this.engine.publisher.getTransceivers()) {
20603
20852
  if (transceiver.sender === track.sender) {
20604
20853
  trackTransceiver = transceiver;
20605
20854
  break;
@@ -20609,10 +20858,10 @@ class LocalParticipant extends Participant {
20609
20858
  this.engine.publisher.setTrackCodecBitrate({
20610
20859
  transceiver: trackTransceiver,
20611
20860
  codec: 'opus',
20612
- maxbr: ((_o = encodings[0]) === null || _o === void 0 ? void 0 : _o.maxBitrate) ? encodings[0].maxBitrate / 1000 : 0
20861
+ maxbr: ((_m = encodings[0]) === null || _m === void 0 ? void 0 : _m.maxBitrate) ? encodings[0].maxBitrate / 1000 : 0
20613
20862
  });
20614
20863
  }
20615
- } else if (track.codec && isSVCCodec(track.codec) && ((_p = encodings[0]) === null || _p === void 0 ? void 0 : _p.maxBitrate)) {
20864
+ } else if (track.codec && isSVCCodec(track.codec) && ((_o = encodings[0]) === null || _o === void 0 ? void 0 : _o.maxBitrate)) {
20616
20865
  this.engine.publisher.setTrackCodecBitrate({
20617
20866
  cid: req.cid,
20618
20867
  codec: track.codec,
@@ -20672,8 +20921,7 @@ class LocalParticipant extends Participant {
20672
20921
  sid: track.sid,
20673
20922
  simulcastCodecs: [{
20674
20923
  codec: opts.videoCodec,
20675
- cid: simulcastTrack.mediaStreamTrack.id,
20676
- enableSimulcastLayers: opts.simulcast
20924
+ cid: simulcastTrack.mediaStreamTrack.id
20677
20925
  }]
20678
20926
  });
20679
20927
  req.layers = videoLayersFromEncodings(req.width, req.height, encodings);
@@ -20720,9 +20968,9 @@ class LocalParticipant extends Participant {
20720
20968
  let negotiationNeeded = false;
20721
20969
  const trackSender = track.sender;
20722
20970
  track.sender = undefined;
20723
- if (this.engine.publisher && this.engine.publisher.pc.connectionState !== 'closed' && trackSender) {
20971
+ if (this.engine.publisher && this.engine.publisher.getConnectionState() !== 'closed' && trackSender) {
20724
20972
  try {
20725
- for (const transceiver of this.engine.publisher.pc.getTransceivers()) {
20973
+ for (const transceiver of this.engine.publisher.getTransceivers()) {
20726
20974
  // if sender is not currently sending (after replaceTrack(null))
20727
20975
  // removeTrack would have no effect.
20728
20976
  // to ensure we end up successfully removing the track, manually set
@@ -21033,6 +21281,7 @@ class Room extends eventsExports.EventEmitter {
21033
21281
  nextUrl = yield this.regionUrlProvider.getNextBestRegionUrl((_c = this.abortController) === null || _c === void 0 ? void 0 : _c.signal);
21034
21282
  } catch (error) {
21035
21283
  if (error instanceof ConnectionError && (error.status === 401 || error.reason === 3 /* ConnectionErrorReason.Cancelled */)) {
21284
+ this.handleDisconnect(this.options.stopLocalTrackOnUnpublish);
21036
21285
  reject(error);
21037
21286
  return;
21038
21287
  }
@@ -21041,9 +21290,11 @@ class Room extends eventsExports.EventEmitter {
21041
21290
  livekitLogger.info("Initial connection failed with ConnectionError: ".concat(e.message, ". Retrying with another region: ").concat(nextUrl));
21042
21291
  yield connectFn(resolve, reject, nextUrl);
21043
21292
  } else {
21293
+ this.handleDisconnect(this.options.stopLocalTrackOnUnpublish);
21044
21294
  reject(e);
21045
21295
  }
21046
21296
  } else {
21297
+ this.handleDisconnect(this.options.stopLocalTrackOnUnpublish);
21047
21298
  reject(e);
21048
21299
  }
21049
21300
  }
@@ -21128,8 +21379,8 @@ class Room extends eventsExports.EventEmitter {
21128
21379
  this.setupLocalParticipantEvents();
21129
21380
  this.emit(RoomEvent.SignalConnected);
21130
21381
  } catch (err) {
21382
+ yield this.engine.close();
21131
21383
  this.recreateEngine();
21132
- this.handleDisconnect(this.options.stopLocalTrackOnUnpublish);
21133
21384
  const resultingError = new ConnectionError("could not establish signal connection");
21134
21385
  if (err instanceof Error) {
21135
21386
  resultingError.message = "".concat(resultingError.message, ": ").concat(err.message);
@@ -21144,15 +21395,15 @@ class Room extends eventsExports.EventEmitter {
21144
21395
  throw resultingError;
21145
21396
  }
21146
21397
  if (abortController.signal.aborted) {
21398
+ yield this.engine.close();
21147
21399
  this.recreateEngine();
21148
- this.handleDisconnect(this.options.stopLocalTrackOnUnpublish);
21149
21400
  throw new ConnectionError("Connection attempt aborted");
21150
21401
  }
21151
21402
  try {
21152
21403
  yield this.engine.waitForPCInitialConnection(this.connOptions.peerConnectionTimeout, abortController);
21153
21404
  } catch (e) {
21405
+ yield this.engine.close();
21154
21406
  this.recreateEngine();
21155
- this.handleDisconnect(this.options.stopLocalTrackOnUnpublish);
21156
21407
  throw e;
21157
21408
  }
21158
21409
  // also hook unload event
@@ -21212,6 +21463,70 @@ class Room extends eventsExports.EventEmitter {
21212
21463
  this.onPageLeave = () => __awaiter(this, void 0, void 0, function* () {
21213
21464
  yield this.disconnect();
21214
21465
  });
21466
+ /**
21467
+ * Browsers have different policies regarding audio playback. Most requiring
21468
+ * some form of user interaction (click/tap/etc).
21469
+ * In those cases, audio will be silent until a click/tap triggering one of the following
21470
+ * - `startAudio`
21471
+ * - `getUserMedia`
21472
+ */
21473
+ this.startAudio = () => __awaiter(this, void 0, void 0, function* () {
21474
+ const elements = [];
21475
+ const browser = getBrowser();
21476
+ if (browser && browser.os === 'iOS') {
21477
+ /**
21478
+ * iOS blocks audio element playback if
21479
+ * - user is not publishing audio themselves and
21480
+ * - no other audio source is playing
21481
+ *
21482
+ * as a workaround, we create an audio element with an empty track, so that
21483
+ * silent audio is always playing
21484
+ */
21485
+ const audioId = 'livekit-dummy-audio-el';
21486
+ let dummyAudioEl = document.getElementById(audioId);
21487
+ if (!dummyAudioEl) {
21488
+ dummyAudioEl = document.createElement('audio');
21489
+ dummyAudioEl.id = audioId;
21490
+ dummyAudioEl.autoplay = true;
21491
+ dummyAudioEl.hidden = true;
21492
+ const track = getEmptyAudioStreamTrack();
21493
+ track.enabled = true;
21494
+ const stream = new MediaStream([track]);
21495
+ dummyAudioEl.srcObject = stream;
21496
+ document.addEventListener('visibilitychange', () => {
21497
+ if (!dummyAudioEl) {
21498
+ return;
21499
+ }
21500
+ // set the srcObject to null on page hide in order to prevent lock screen controls to show up for it
21501
+ dummyAudioEl.srcObject = document.hidden ? null : stream;
21502
+ });
21503
+ document.body.append(dummyAudioEl);
21504
+ this.once(RoomEvent.Disconnected, () => {
21505
+ dummyAudioEl === null || dummyAudioEl === void 0 ? void 0 : dummyAudioEl.remove();
21506
+ });
21507
+ }
21508
+ elements.push(dummyAudioEl);
21509
+ }
21510
+ this.participants.forEach(p => {
21511
+ p.audioTracks.forEach(t => {
21512
+ if (t.track) {
21513
+ t.track.attachedElements.forEach(e => {
21514
+ elements.push(e);
21515
+ });
21516
+ }
21517
+ });
21518
+ });
21519
+ try {
21520
+ yield Promise.all([this.acquireAudioContext(), ...elements.map(e => {
21521
+ e.muted = false;
21522
+ return e.play();
21523
+ })]);
21524
+ this.handleAudioPlaybackStarted();
21525
+ } catch (err) {
21526
+ this.handleAudioPlaybackFailed(err);
21527
+ throw err;
21528
+ }
21529
+ });
21215
21530
  this.handleRestarting = () => {
21216
21531
  this.clearConnectionReconcile();
21217
21532
  // also unwind existing participants & existing subscriptions
@@ -21767,72 +22082,6 @@ class Room extends eventsExports.EventEmitter {
21767
22082
  }
21768
22083
  });
21769
22084
  }
21770
- /**
21771
- * Browsers have different policies regarding audio playback. Most requiring
21772
- * some form of user interaction (click/tap/etc).
21773
- * In those cases, audio will be silent until a click/tap triggering one of the following
21774
- * - `startAudio`
21775
- * - `getUserMedia`
21776
- */
21777
- startAudio() {
21778
- return __awaiter(this, void 0, void 0, function* () {
21779
- const elements = [];
21780
- const browser = getBrowser();
21781
- if (browser && browser.os === 'iOS') {
21782
- /**
21783
- * iOS blocks audio element playback if
21784
- * - user is not publishing audio themselves and
21785
- * - no other audio source is playing
21786
- *
21787
- * as a workaround, we create an audio element with an empty track, so that
21788
- * silent audio is always playing
21789
- */
21790
- const audioId = 'livekit-dummy-audio-el';
21791
- let dummyAudioEl = document.getElementById(audioId);
21792
- if (!dummyAudioEl) {
21793
- dummyAudioEl = document.createElement('audio');
21794
- dummyAudioEl.id = audioId;
21795
- dummyAudioEl.autoplay = true;
21796
- dummyAudioEl.hidden = true;
21797
- const track = getEmptyAudioStreamTrack();
21798
- track.enabled = true;
21799
- const stream = new MediaStream([track]);
21800
- dummyAudioEl.srcObject = stream;
21801
- document.addEventListener('visibilitychange', () => {
21802
- if (!dummyAudioEl) {
21803
- return;
21804
- }
21805
- // set the srcObject to null on page hide in order to prevent lock screen controls to show up for it
21806
- dummyAudioEl.srcObject = document.hidden ? null : stream;
21807
- });
21808
- document.body.append(dummyAudioEl);
21809
- this.once(RoomEvent.Disconnected, () => {
21810
- dummyAudioEl === null || dummyAudioEl === void 0 ? void 0 : dummyAudioEl.remove();
21811
- });
21812
- }
21813
- elements.push(dummyAudioEl);
21814
- }
21815
- this.participants.forEach(p => {
21816
- p.audioTracks.forEach(t => {
21817
- if (t.track) {
21818
- t.track.attachedElements.forEach(e => {
21819
- elements.push(e);
21820
- });
21821
- }
21822
- });
21823
- });
21824
- try {
21825
- yield Promise.all([this.acquireAudioContext(), ...elements.map(e => {
21826
- e.muted = false;
21827
- return e.play();
21828
- })]);
21829
- this.handleAudioPlaybackStarted();
21830
- } catch (err) {
21831
- this.handleAudioPlaybackFailed(err);
21832
- throw err;
21833
- }
21834
- });
21835
- }
21836
22085
  /**
21837
22086
  * Returns true if audio playback is enabled
21838
22087
  */
@@ -21929,7 +22178,7 @@ class Room extends eventsExports.EventEmitter {
21929
22178
  });
21930
22179
  }
21931
22180
  setupLocalParticipantEvents() {
21932
- this.localParticipant.on(ParticipantEvent.ParticipantMetadataChanged, this.onLocalParticipantMetadataChanged).on(ParticipantEvent.ParticipantNameChanged, this.onLocalParticipantNameChanged).on(ParticipantEvent.TrackMuted, this.onLocalTrackMuted).on(ParticipantEvent.TrackUnmuted, this.onLocalTrackUnmuted).on(ParticipantEvent.LocalTrackPublished, this.onLocalTrackPublished).on(ParticipantEvent.LocalTrackUnpublished, this.onLocalTrackUnpublished).on(ParticipantEvent.ConnectionQualityChanged, this.onLocalConnectionQualityChanged).on(ParticipantEvent.MediaDevicesError, this.onMediaDevicesError).on(ParticipantEvent.ParticipantPermissionsChanged, this.onLocalParticipantPermissionsChanged);
22181
+ this.localParticipant.on(ParticipantEvent.ParticipantMetadataChanged, this.onLocalParticipantMetadataChanged).on(ParticipantEvent.ParticipantNameChanged, this.onLocalParticipantNameChanged).on(ParticipantEvent.TrackMuted, this.onLocalTrackMuted).on(ParticipantEvent.TrackUnmuted, this.onLocalTrackUnmuted).on(ParticipantEvent.LocalTrackPublished, this.onLocalTrackPublished).on(ParticipantEvent.LocalTrackUnpublished, this.onLocalTrackUnpublished).on(ParticipantEvent.ConnectionQualityChanged, this.onLocalConnectionQualityChanged).on(ParticipantEvent.MediaDevicesError, this.onMediaDevicesError).on(ParticipantEvent.AudioStreamAcquired, this.startAudio).on(ParticipantEvent.ParticipantPermissionsChanged, this.onLocalParticipantPermissionsChanged);
21933
22182
  }
21934
22183
  recreateEngine() {
21935
22184
  var _a;
@@ -22017,7 +22266,7 @@ class Room extends eventsExports.EventEmitter {
22017
22266
  (_b = pub.track) === null || _b === void 0 ? void 0 : _b.stop();
22018
22267
  }
22019
22268
  });
22020
- this.localParticipant.off(ParticipantEvent.ParticipantMetadataChanged, this.onLocalParticipantMetadataChanged).off(ParticipantEvent.ParticipantNameChanged, this.onLocalParticipantNameChanged).off(ParticipantEvent.TrackMuted, this.onLocalTrackMuted).off(ParticipantEvent.TrackUnmuted, this.onLocalTrackUnmuted).off(ParticipantEvent.LocalTrackPublished, this.onLocalTrackPublished).off(ParticipantEvent.LocalTrackUnpublished, this.onLocalTrackUnpublished).off(ParticipantEvent.ConnectionQualityChanged, this.onLocalConnectionQualityChanged).off(ParticipantEvent.MediaDevicesError, this.onMediaDevicesError).off(ParticipantEvent.ParticipantPermissionsChanged, this.onLocalParticipantPermissionsChanged);
22269
+ this.localParticipant.off(ParticipantEvent.ParticipantMetadataChanged, this.onLocalParticipantMetadataChanged).off(ParticipantEvent.ParticipantNameChanged, this.onLocalParticipantNameChanged).off(ParticipantEvent.TrackMuted, this.onLocalTrackMuted).off(ParticipantEvent.TrackUnmuted, this.onLocalTrackUnmuted).off(ParticipantEvent.LocalTrackPublished, this.onLocalTrackPublished).off(ParticipantEvent.LocalTrackUnpublished, this.onLocalTrackUnpublished).off(ParticipantEvent.ConnectionQualityChanged, this.onLocalConnectionQualityChanged).off(ParticipantEvent.MediaDevicesError, this.onMediaDevicesError).off(ParticipantEvent.AudioStreamAcquired, this.startAudio).off(ParticipantEvent.ParticipantPermissionsChanged, this.onLocalParticipantPermissionsChanged);
22021
22270
  this.localParticipant.tracks.clear();
22022
22271
  this.localParticipant.videoTracks.clear();
22023
22272
  this.localParticipant.audioTracks.clear();
@@ -22147,18 +22396,18 @@ class Room extends eventsExports.EventEmitter {
22147
22396
  return participant;
22148
22397
  }
22149
22398
  sendSyncState() {
22150
- var _a, _b;
22151
- if (this.engine.subscriber === undefined || this.engine.subscriber.pc.localDescription === null) {
22399
+ var _a, _b, _c, _d;
22400
+ const previousAnswer = (_a = this.engine.subscriber) === null || _a === void 0 ? void 0 : _a.getLocalDescription();
22401
+ const previousOffer = (_b = this.engine.subscriber) === null || _b === void 0 ? void 0 : _b.getRemoteDescription();
22402
+ if (!previousAnswer) {
22152
22403
  return;
22153
22404
  }
22154
- const previousAnswer = this.engine.subscriber.pc.localDescription;
22155
- const previousOffer = this.engine.subscriber.pc.remoteDescription;
22156
22405
  /* 1. autosubscribe on, so subscribed tracks = all tracks - unsub tracks,
22157
22406
  in this case, we send unsub tracks, so server add all tracks to this
22158
22407
  subscribe pc and unsub special tracks from it.
22159
22408
  2. autosubscribe off, we send subscribed tracks.
22160
22409
  */
22161
- const autoSubscribe = (_b = (_a = this.connOptions) === null || _a === void 0 ? void 0 : _a.autoSubscribe) !== null && _b !== void 0 ? _b : true;
22410
+ const autoSubscribe = (_d = (_c = this.connOptions) === null || _c === void 0 ? void 0 : _c.autoSubscribe) !== null && _d !== void 0 ? _d : true;
22162
22411
  const trackSids = new Array();
22163
22412
  this.participants.forEach(participant => {
22164
22413
  participant.tracks.forEach(track => {
@@ -22773,7 +23022,7 @@ class WebRTCCheck extends Checker {
22773
23022
  }
22774
23023
  };
22775
23024
  if (this.room.engine.subscriber) {
22776
- this.room.engine.subscriber.pc.onicecandidateerror = ev => {
23025
+ this.room.engine.subscriber.onIceCandidateError = ev => {
22777
23026
  if (ev instanceof RTCPeerConnectionIceErrorEvent) {
22778
23027
  this.appendWarning("error with ICE candidate: ".concat(ev.errorCode, " ").concat(ev.errorText, " ").concat(ev.url));
22779
23028
  }
@@ -22992,5 +23241,5 @@ function isFacingModeValue(item) {
22992
23241
  return item === undefined || allowedValues.includes(item);
22993
23242
  }
22994
23243
 
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 };
23244
+ 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
23245
  //# sourceMappingURL=livekit-client.esm.mjs.map