livekit-client 1.14.1 → 1.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/livekit-client.e2ee.worker.js +1 -1
- package/dist/livekit-client.e2ee.worker.js.map +1 -1
- package/dist/livekit-client.e2ee.worker.mjs +25 -44
- package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
- package/dist/livekit-client.esm.mjs +399 -196
- package/dist/livekit-client.esm.mjs.map +1 -1
- package/dist/livekit-client.umd.js +1 -1
- package/dist/livekit-client.umd.js.map +1 -1
- package/dist/src/e2ee/E2eeManager.d.ts.map +1 -1
- package/dist/src/e2ee/utils.d.ts +0 -1
- package/dist/src/e2ee/utils.d.ts.map +1 -1
- package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
- package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts.map +1 -1
- package/dist/src/proto/livekit_models_pb.d.ts +87 -11
- package/dist/src/proto/livekit_models_pb.d.ts.map +1 -1
- package/dist/src/proto/livekit_rtc_pb.d.ts +0 -4
- package/dist/src/proto/livekit_rtc_pb.d.ts.map +1 -1
- package/dist/src/room/PCTransport.d.ts +20 -1
- package/dist/src/room/PCTransport.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts +1 -1
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/defaults.d.ts +1 -0
- package/dist/src/room/defaults.d.ts.map +1 -1
- package/dist/src/room/events.d.ts +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/timers.d.ts +1 -1
- package/dist/src/room/timers.d.ts.map +1 -1
- package/dist/src/room/track/LocalAudioTrack.d.ts +1 -1
- package/dist/src/room/track/LocalAudioTrack.d.ts.map +1 -1
- package/dist/src/room/track/LocalTrack.d.ts +3 -3
- package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
- package/dist/src/room/track/LocalVideoTrack.d.ts +2 -1
- package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/options.d.ts +0 -1
- package/dist/src/room/track/options.d.ts.map +1 -1
- package/dist/src/room/track/utils.d.ts +2 -1
- package/dist/src/room/track/utils.d.ts.map +1 -1
- package/dist/src/utils/cloneDeep.d.ts +2 -0
- package/dist/src/utils/cloneDeep.d.ts.map +1 -0
- package/dist/ts4.2/src/e2ee/utils.d.ts +0 -1
- package/dist/ts4.2/src/proto/livekit_models_pb.d.ts +87 -11
- package/dist/ts4.2/src/proto/livekit_rtc_pb.d.ts +0 -4
- package/dist/ts4.2/src/room/PCTransport.d.ts +20 -1
- package/dist/ts4.2/src/room/RTCEngine.d.ts +1 -1
- package/dist/ts4.2/src/room/defaults.d.ts +1 -0
- package/dist/ts4.2/src/room/events.d.ts +1 -1
- package/dist/ts4.2/src/room/timers.d.ts +1 -1
- package/dist/ts4.2/src/room/track/LocalAudioTrack.d.ts +1 -1
- package/dist/ts4.2/src/room/track/LocalTrack.d.ts +3 -3
- package/dist/ts4.2/src/room/track/LocalVideoTrack.d.ts +2 -1
- package/dist/ts4.2/src/room/track/options.d.ts +0 -1
- package/dist/ts4.2/src/room/track/utils.d.ts +1 -0
- package/dist/ts4.2/src/utils/cloneDeep.d.ts +2 -0
- package/package.json +14 -14
- package/src/connectionHelper/checks/webrtc.ts +1 -1
- package/src/e2ee/E2eeManager.ts +2 -1
- package/src/e2ee/utils.ts +0 -10
- package/src/e2ee/worker/FrameCryptor.ts +13 -14
- package/src/e2ee/worker/ParticipantKeyHandler.ts +4 -5
- package/src/e2ee/worker/e2ee.worker.ts +3 -1
- package/src/proto/livekit_models_pb.ts +140 -15
- package/src/proto/livekit_rtc_pb.ts +1 -7
- package/src/room/PCTransport.ts +116 -1
- package/src/room/RTCEngine.ts +49 -85
- package/src/room/Room.ts +10 -9
- package/src/room/defaults.ts +4 -2
- package/src/room/events.ts +1 -1
- package/src/room/participant/LocalParticipant.ts +44 -56
- package/src/room/track/LocalAudioTrack.ts +1 -1
- package/src/room/track/LocalTrack.ts +8 -5
- package/src/room/track/LocalVideoTrack.ts +2 -1
- package/src/room/track/options.ts +0 -7
- package/src/room/track/utils.ts +17 -8
- package/src/utils/cloneDeep.test.ts +54 -0
- package/src/utils/cloneDeep.ts +11 -0
@@ -326,11 +326,11 @@ export class FrameCryptor extends BaseFrameCryptor {
|
|
326
326
|
}
|
327
327
|
} else if (!this.keys.getKeySet(keyIndex) && this.keys.hasValidKey) {
|
328
328
|
// emit an error in case the key index is out of bounds but the key handler thinks we still have a valid key
|
329
|
-
workerLogger.warn(
|
329
|
+
workerLogger.warn(`skipping decryption due to missing key at index ${keyIndex}`);
|
330
330
|
this.emit(
|
331
331
|
CryptorEvent.Error,
|
332
332
|
new CryptorError(
|
333
|
-
`missing key at index for participant ${this.participantIdentity}`,
|
333
|
+
`missing key at index ${keyIndex} for participant ${this.participantIdentity}`,
|
334
334
|
CryptorErrorReason.MissingKey,
|
335
335
|
),
|
336
336
|
);
|
@@ -418,7 +418,7 @@ export class FrameCryptor extends BaseFrameCryptor {
|
|
418
418
|
);
|
419
419
|
|
420
420
|
let ratchetedKeySet: KeySet | undefined;
|
421
|
-
if (keySet === this.keys.getKeySet(keyIndex)) {
|
421
|
+
if ((initialMaterial ?? keySet) === this.keys.getKeySet(keyIndex)) {
|
422
422
|
// only ratchet if the currently set key is still the same as the one used to decrypt this frame
|
423
423
|
// if not, it might be that a different frame has already ratcheted and we try with that one first
|
424
424
|
const newMaterial = await this.keys.ratchetKey(keyIndex, false);
|
@@ -431,22 +431,21 @@ export class FrameCryptor extends BaseFrameCryptor {
|
|
431
431
|
encryptionKey: ratchetedKeySet?.encryptionKey,
|
432
432
|
});
|
433
433
|
if (frame && ratchetedKeySet) {
|
434
|
-
|
435
|
-
//
|
436
|
-
this.keys.
|
434
|
+
// before updating the keys, make sure that the keySet used for this frame is still the same as the currently set key
|
435
|
+
// if it's not, a new key might have been set already, which we don't want to override
|
436
|
+
if ((initialMaterial ?? keySet) === this.keys.getKeySet(keyIndex)) {
|
437
|
+
this.keys.setKeySet(ratchetedKeySet, keyIndex, true);
|
438
|
+
// decryption was successful, set the new key index to reflect the ratcheted key set
|
439
|
+
this.keys.setCurrentKeyIndex(keyIndex);
|
440
|
+
}
|
437
441
|
}
|
438
442
|
return frame;
|
439
443
|
} else {
|
440
444
|
/**
|
441
|
-
*
|
442
|
-
*
|
443
|
-
*
|
444
|
-
* we come back to the initial key.
|
445
|
+
* Because we only set a new key once decryption has been successful,
|
446
|
+
* we can be sure that we don't need to reset the key to the initial material at this point
|
447
|
+
* as the key has not been updated on the keyHandler instance
|
445
448
|
*/
|
446
|
-
if (initialMaterial) {
|
447
|
-
workerLogger.debug('resetting to initial material');
|
448
|
-
this.keys.setKeyFromMaterial(initialMaterial.material, keyIndex);
|
449
|
-
}
|
450
449
|
|
451
450
|
workerLogger.warn('maximum ratchet attempts exceeded');
|
452
451
|
throw new CryptorError(
|
@@ -138,12 +138,11 @@ export class ParticipantKeyHandler extends (EventEmitter as new () => TypedEvent
|
|
138
138
|
* also updates the currentKeyIndex
|
139
139
|
*/
|
140
140
|
async setKeyFromMaterial(material: CryptoKey, keyIndex = 0, emitRatchetEvent = false) {
|
141
|
-
|
142
|
-
|
143
|
-
this.currentKeyIndex = keyIndex % this.cryptoKeyRing.length;
|
144
|
-
}
|
141
|
+
const newIndex = keyIndex >= 0 ? keyIndex % this.cryptoKeyRing.length : -1;
|
142
|
+
workerLogger.debug(`setting new key with index ${newIndex}`);
|
145
143
|
const keySet = await deriveKeys(material, this.keyProviderOptions.ratchetSalt);
|
146
|
-
this.setKeySet(keySet, this.currentKeyIndex, emitRatchetEvent);
|
144
|
+
this.setKeySet(keySet, newIndex >= 0 ? newIndex : this.currentKeyIndex, emitRatchetEvent);
|
145
|
+
if (newIndex >= 0) this.currentKeyIndex = newIndex;
|
147
146
|
}
|
148
147
|
|
149
148
|
setKeySet(keySet: KeySet, keyIndex: number, emitRatchetEvent = false) {
|
@@ -75,7 +75,9 @@ onmessage = (ev) => {
|
|
75
75
|
workerLogger.warn('set shared key');
|
76
76
|
setSharedKey(data.key, data.keyIndex);
|
77
77
|
} else if (data.participantIdentity) {
|
78
|
-
workerLogger.warn(
|
78
|
+
workerLogger.warn(
|
79
|
+
`set participant sender key ${data.participantIdentity} index ${data.keyIndex}`,
|
80
|
+
);
|
79
81
|
getParticipantKeyHandler(data.participantIdentity).setKey(data.key, data.keyIndex);
|
80
82
|
} else {
|
81
83
|
workerLogger.error('no participant Id was provided and shared key usage is disabled');
|
@@ -12,7 +12,7 @@
|
|
12
12
|
// See the License for the specific language governing permissions and
|
13
13
|
// limitations under the License.
|
14
14
|
|
15
|
-
// @generated by protoc-gen-es v1.3.
|
15
|
+
// @generated by protoc-gen-es v1.3.3 with parameter "target=ts"
|
16
16
|
// @generated from file livekit_models.proto (package livekit, syntax proto3)
|
17
17
|
/* eslint-disable */
|
18
18
|
// @ts-nocheck
|
@@ -84,6 +84,26 @@ proto3.util.setEnumType(VideoCodec, "livekit.VideoCodec", [
|
|
84
84
|
{ no: 4, name: "VP8" },
|
85
85
|
]);
|
86
86
|
|
87
|
+
/**
|
88
|
+
* @generated from enum livekit.ImageCodec
|
89
|
+
*/
|
90
|
+
export enum ImageCodec {
|
91
|
+
/**
|
92
|
+
* @generated from enum value: IC_DEFAULT = 0;
|
93
|
+
*/
|
94
|
+
IC_DEFAULT = 0,
|
95
|
+
|
96
|
+
/**
|
97
|
+
* @generated from enum value: IC_JPEG = 1;
|
98
|
+
*/
|
99
|
+
IC_JPEG = 1,
|
100
|
+
}
|
101
|
+
// Retrieve enum metadata with: proto3.getEnumType(ImageCodec)
|
102
|
+
proto3.util.setEnumType(ImageCodec, "livekit.ImageCodec", [
|
103
|
+
{ no: 0, name: "IC_DEFAULT" },
|
104
|
+
{ no: 1, name: "IC_JPEG" },
|
105
|
+
]);
|
106
|
+
|
87
107
|
/**
|
88
108
|
* @generated from enum livekit.TrackType
|
89
109
|
*/
|
@@ -411,11 +431,6 @@ export class Room extends Message<Room> {
|
|
411
431
|
*/
|
412
432
|
activeRecording = false;
|
413
433
|
|
414
|
-
/**
|
415
|
-
* @generated from field: livekit.PlayoutDelay playout_delay = 12;
|
416
|
-
*/
|
417
|
-
playoutDelay?: PlayoutDelay;
|
418
|
-
|
419
434
|
constructor(data?: PartialMessage<Room>) {
|
420
435
|
super();
|
421
436
|
proto3.util.initPartial(data, this);
|
@@ -435,7 +450,6 @@ export class Room extends Message<Room> {
|
|
435
450
|
{ no: 9, name: "num_participants", kind: "scalar", T: 13 /* ScalarType.UINT32 */ },
|
436
451
|
{ no: 11, name: "num_publishers", kind: "scalar", T: 13 /* ScalarType.UINT32 */ },
|
437
452
|
{ no: 10, name: "active_recording", kind: "scalar", T: 8 /* ScalarType.BOOL */ },
|
438
|
-
{ no: 12, name: "playout_delay", kind: "message", T: PlayoutDelay },
|
439
453
|
]);
|
440
454
|
|
441
455
|
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): Room {
|
@@ -1282,6 +1296,11 @@ export class UserPacket extends Message<UserPacket> {
|
|
1282
1296
|
*/
|
1283
1297
|
participantSid = "";
|
1284
1298
|
|
1299
|
+
/**
|
1300
|
+
* @generated from field: string participant_identity = 5;
|
1301
|
+
*/
|
1302
|
+
participantIdentity = "";
|
1303
|
+
|
1285
1304
|
/**
|
1286
1305
|
* user defined payload
|
1287
1306
|
*
|
@@ -1290,12 +1309,19 @@ export class UserPacket extends Message<UserPacket> {
|
|
1290
1309
|
payload = new Uint8Array(0);
|
1291
1310
|
|
1292
1311
|
/**
|
1293
|
-
* the ID of the participants who will receive the message (
|
1312
|
+
* the ID of the participants who will receive the message (sent to all by default)
|
1294
1313
|
*
|
1295
1314
|
* @generated from field: repeated string destination_sids = 3;
|
1296
1315
|
*/
|
1297
1316
|
destinationSids: string[] = [];
|
1298
1317
|
|
1318
|
+
/**
|
1319
|
+
* identities of participants who will receive the message (sent to all by default)
|
1320
|
+
*
|
1321
|
+
* @generated from field: repeated string destination_identities = 6;
|
1322
|
+
*/
|
1323
|
+
destinationIdentities: string[] = [];
|
1324
|
+
|
1299
1325
|
/**
|
1300
1326
|
* topic under which the message was published
|
1301
1327
|
*
|
@@ -1312,8 +1338,10 @@ export class UserPacket extends Message<UserPacket> {
|
|
1312
1338
|
static readonly typeName = "livekit.UserPacket";
|
1313
1339
|
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
1314
1340
|
{ no: 1, name: "participant_sid", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
1341
|
+
{ no: 5, name: "participant_identity", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
1315
1342
|
{ no: 2, name: "payload", kind: "scalar", T: 12 /* ScalarType.BYTES */ },
|
1316
1343
|
{ no: 3, name: "destination_sids", kind: "scalar", T: 9 /* ScalarType.STRING */, repeated: true },
|
1344
|
+
{ no: 6, name: "destination_identities", kind: "scalar", T: 9 /* ScalarType.STRING */, repeated: true },
|
1317
1345
|
{ no: 4, name: "topic", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true },
|
1318
1346
|
]);
|
1319
1347
|
|
@@ -1613,6 +1641,16 @@ export enum ClientInfo_SDK {
|
|
1613
1641
|
* @generated from enum value: RUST = 8;
|
1614
1642
|
*/
|
1615
1643
|
RUST = 8,
|
1644
|
+
|
1645
|
+
/**
|
1646
|
+
* @generated from enum value: PYTHON = 9;
|
1647
|
+
*/
|
1648
|
+
PYTHON = 9,
|
1649
|
+
|
1650
|
+
/**
|
1651
|
+
* @generated from enum value: CPP = 10;
|
1652
|
+
*/
|
1653
|
+
CPP = 10,
|
1616
1654
|
}
|
1617
1655
|
// Retrieve enum metadata with: proto3.getEnumType(ClientInfo_SDK)
|
1618
1656
|
proto3.util.setEnumType(ClientInfo_SDK, "livekit.ClientInfo.SDK", [
|
@@ -1625,6 +1663,8 @@ proto3.util.setEnumType(ClientInfo_SDK, "livekit.ClientInfo.SDK", [
|
|
1625
1663
|
{ no: 6, name: "UNITY" },
|
1626
1664
|
{ no: 7, name: "REACT_NATIVE" },
|
1627
1665
|
{ no: 8, name: "RUST" },
|
1666
|
+
{ no: 9, name: "PYTHON" },
|
1667
|
+
{ no: 10, name: "CPP" },
|
1628
1668
|
]);
|
1629
1669
|
|
1630
1670
|
/**
|
@@ -1774,6 +1814,91 @@ export class DisabledCodecs extends Message<DisabledCodecs> {
|
|
1774
1814
|
}
|
1775
1815
|
}
|
1776
1816
|
|
1817
|
+
/**
|
1818
|
+
* @generated from message livekit.RTPDrift
|
1819
|
+
*/
|
1820
|
+
export class RTPDrift extends Message<RTPDrift> {
|
1821
|
+
/**
|
1822
|
+
* @generated from field: google.protobuf.Timestamp start_time = 1;
|
1823
|
+
*/
|
1824
|
+
startTime?: Timestamp;
|
1825
|
+
|
1826
|
+
/**
|
1827
|
+
* @generated from field: google.protobuf.Timestamp end_time = 2;
|
1828
|
+
*/
|
1829
|
+
endTime?: Timestamp;
|
1830
|
+
|
1831
|
+
/**
|
1832
|
+
* @generated from field: double duration = 3;
|
1833
|
+
*/
|
1834
|
+
duration = 0;
|
1835
|
+
|
1836
|
+
/**
|
1837
|
+
* @generated from field: uint64 start_timestamp = 4;
|
1838
|
+
*/
|
1839
|
+
startTimestamp = protoInt64.zero;
|
1840
|
+
|
1841
|
+
/**
|
1842
|
+
* @generated from field: uint64 end_timestamp = 5;
|
1843
|
+
*/
|
1844
|
+
endTimestamp = protoInt64.zero;
|
1845
|
+
|
1846
|
+
/**
|
1847
|
+
* @generated from field: uint64 rtp_clock_ticks = 6;
|
1848
|
+
*/
|
1849
|
+
rtpClockTicks = protoInt64.zero;
|
1850
|
+
|
1851
|
+
/**
|
1852
|
+
* @generated from field: int64 drift_samples = 7;
|
1853
|
+
*/
|
1854
|
+
driftSamples = protoInt64.zero;
|
1855
|
+
|
1856
|
+
/**
|
1857
|
+
* @generated from field: double drift_ms = 8;
|
1858
|
+
*/
|
1859
|
+
driftMs = 0;
|
1860
|
+
|
1861
|
+
/**
|
1862
|
+
* @generated from field: double clock_rate = 9;
|
1863
|
+
*/
|
1864
|
+
clockRate = 0;
|
1865
|
+
|
1866
|
+
constructor(data?: PartialMessage<RTPDrift>) {
|
1867
|
+
super();
|
1868
|
+
proto3.util.initPartial(data, this);
|
1869
|
+
}
|
1870
|
+
|
1871
|
+
static readonly runtime: typeof proto3 = proto3;
|
1872
|
+
static readonly typeName = "livekit.RTPDrift";
|
1873
|
+
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
1874
|
+
{ no: 1, name: "start_time", kind: "message", T: Timestamp },
|
1875
|
+
{ no: 2, name: "end_time", kind: "message", T: Timestamp },
|
1876
|
+
{ no: 3, name: "duration", kind: "scalar", T: 1 /* ScalarType.DOUBLE */ },
|
1877
|
+
{ no: 4, name: "start_timestamp", kind: "scalar", T: 4 /* ScalarType.UINT64 */ },
|
1878
|
+
{ no: 5, name: "end_timestamp", kind: "scalar", T: 4 /* ScalarType.UINT64 */ },
|
1879
|
+
{ no: 6, name: "rtp_clock_ticks", kind: "scalar", T: 4 /* ScalarType.UINT64 */ },
|
1880
|
+
{ no: 7, name: "drift_samples", kind: "scalar", T: 3 /* ScalarType.INT64 */ },
|
1881
|
+
{ no: 8, name: "drift_ms", kind: "scalar", T: 1 /* ScalarType.DOUBLE */ },
|
1882
|
+
{ no: 9, name: "clock_rate", kind: "scalar", T: 1 /* ScalarType.DOUBLE */ },
|
1883
|
+
]);
|
1884
|
+
|
1885
|
+
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): RTPDrift {
|
1886
|
+
return new RTPDrift().fromBinary(bytes, options);
|
1887
|
+
}
|
1888
|
+
|
1889
|
+
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): RTPDrift {
|
1890
|
+
return new RTPDrift().fromJson(jsonValue, options);
|
1891
|
+
}
|
1892
|
+
|
1893
|
+
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): RTPDrift {
|
1894
|
+
return new RTPDrift().fromJsonString(jsonString, options);
|
1895
|
+
}
|
1896
|
+
|
1897
|
+
static equals(a: RTPDrift | PlainMessage<RTPDrift> | undefined, b: RTPDrift | PlainMessage<RTPDrift> | undefined): boolean {
|
1898
|
+
return proto3.util.equals(RTPDrift, a, b);
|
1899
|
+
}
|
1900
|
+
}
|
1901
|
+
|
1777
1902
|
/**
|
1778
1903
|
* @generated from message livekit.RTPStats
|
1779
1904
|
*/
|
@@ -1984,16 +2109,16 @@ export class RTPStats extends Message<RTPStats> {
|
|
1984
2109
|
lastLayerLockPli?: Timestamp;
|
1985
2110
|
|
1986
2111
|
/**
|
1987
|
-
* @generated from field:
|
2112
|
+
* @generated from field: livekit.RTPDrift packet_drift = 44;
|
1988
2113
|
*/
|
1989
|
-
|
2114
|
+
packetDrift?: RTPDrift;
|
1990
2115
|
|
1991
2116
|
/**
|
1992
|
-
* NEXT_ID:
|
2117
|
+
* NEXT_ID: 46
|
1993
2118
|
*
|
1994
|
-
* @generated from field:
|
2119
|
+
* @generated from field: livekit.RTPDrift report_drift = 45;
|
1995
2120
|
*/
|
1996
|
-
|
2121
|
+
reportDrift?: RTPDrift;
|
1997
2122
|
|
1998
2123
|
constructor(data?: PartialMessage<RTPStats>) {
|
1999
2124
|
super();
|
@@ -2044,8 +2169,8 @@ export class RTPStats extends Message<RTPStats> {
|
|
2044
2169
|
{ no: 34, name: "last_key_frame", kind: "message", T: Timestamp },
|
2045
2170
|
{ no: 35, name: "layer_lock_plis", kind: "scalar", T: 13 /* ScalarType.UINT32 */ },
|
2046
2171
|
{ no: 36, name: "last_layer_lock_pli", kind: "message", T: Timestamp },
|
2047
|
-
{ no:
|
2048
|
-
{ no:
|
2172
|
+
{ no: 44, name: "packet_drift", kind: "message", T: RTPDrift },
|
2173
|
+
{ no: 45, name: "report_drift", kind: "message", T: RTPDrift },
|
2049
2174
|
]);
|
2050
2175
|
|
2051
2176
|
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): RTPStats {
|
@@ -12,7 +12,7 @@
|
|
12
12
|
// See the License for the specific language governing permissions and
|
13
13
|
// limitations under the License.
|
14
14
|
|
15
|
-
// @generated by protoc-gen-es v1.3.
|
15
|
+
// @generated by protoc-gen-es v1.3.3 with parameter "target=ts"
|
16
16
|
// @generated from file livekit_rtc.proto (package livekit, syntax proto3)
|
17
17
|
/* eslint-disable */
|
18
18
|
// @ts-nocheck
|
@@ -487,11 +487,6 @@ export class SimulcastCodec extends Message<SimulcastCodec> {
|
|
487
487
|
*/
|
488
488
|
cid = "";
|
489
489
|
|
490
|
-
/**
|
491
|
-
* @generated from field: bool enable_simulcast_layers = 3;
|
492
|
-
*/
|
493
|
-
enableSimulcastLayers = false;
|
494
|
-
|
495
490
|
constructor(data?: PartialMessage<SimulcastCodec>) {
|
496
491
|
super();
|
497
492
|
proto3.util.initPartial(data, this);
|
@@ -502,7 +497,6 @@ export class SimulcastCodec extends Message<SimulcastCodec> {
|
|
502
497
|
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
503
498
|
{ no: 1, name: "codec", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
504
499
|
{ no: 2, name: "cid", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
505
|
-
{ no: 3, name: "enable_simulcast_layers", kind: "scalar", T: 8 /* ScalarType.BOOL */ },
|
506
500
|
]);
|
507
501
|
|
508
502
|
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): SimulcastCodec {
|
package/src/room/PCTransport.ts
CHANGED
@@ -32,7 +32,7 @@ export const PCEvents = {
|
|
32
32
|
export default class PCTransport extends EventEmitter {
|
33
33
|
private _pc: RTCPeerConnection | null;
|
34
34
|
|
35
|
-
|
35
|
+
private get pc() {
|
36
36
|
if (this._pc) return this._pc;
|
37
37
|
throw new UnexpectedConnectionState('Expected peer connection to be available');
|
38
38
|
}
|
@@ -51,12 +51,38 @@ export default class PCTransport extends EventEmitter {
|
|
51
51
|
|
52
52
|
onOffer?: (offer: RTCSessionDescriptionInit) => void;
|
53
53
|
|
54
|
+
onIceCandidate?: (candidate: RTCIceCandidate) => void;
|
55
|
+
|
56
|
+
onIceCandidateError?: (ev: Event) => void;
|
57
|
+
|
58
|
+
onConnectionStateChange?: (state: RTCPeerConnectionState) => void;
|
59
|
+
|
60
|
+
onDataChannel?: (ev: RTCDataChannelEvent) => void;
|
61
|
+
|
62
|
+
onTrack?: (ev: RTCTrackEvent) => void;
|
63
|
+
|
54
64
|
constructor(config?: RTCConfiguration, mediaConstraints: Record<string, unknown> = {}) {
|
55
65
|
super();
|
56
66
|
this._pc = isChromiumBased()
|
57
67
|
? // @ts-expect-error chrome allows additional media constraints to be passed into the RTCPeerConnection constructor
|
58
68
|
new RTCPeerConnection(config, mediaConstraints)
|
59
69
|
: new RTCPeerConnection(config);
|
70
|
+
this._pc.onicecandidate = (ev) => {
|
71
|
+
if (!ev.candidate) return;
|
72
|
+
this.onIceCandidate?.(ev.candidate);
|
73
|
+
};
|
74
|
+
this._pc.onicecandidateerror = (ev) => {
|
75
|
+
this.onIceCandidateError?.(ev);
|
76
|
+
};
|
77
|
+
this._pc.onconnectionstatechange = () => {
|
78
|
+
this.onConnectionStateChange?.(this._pc?.connectionState ?? 'closed');
|
79
|
+
};
|
80
|
+
this._pc.ondatachannel = (ev) => {
|
81
|
+
this.onDataChannel?.(ev);
|
82
|
+
};
|
83
|
+
this._pc.ontrack = (ev) => {
|
84
|
+
this.onTrack?.(ev);
|
85
|
+
};
|
60
86
|
}
|
61
87
|
|
62
88
|
get isICEConnected(): boolean {
|
@@ -270,10 +296,99 @@ export default class PCTransport extends EventEmitter {
|
|
270
296
|
return answer;
|
271
297
|
}
|
272
298
|
|
299
|
+
createDataChannel(label: string, dataChannelDict: RTCDataChannelInit) {
|
300
|
+
return this.pc.createDataChannel(label, dataChannelDict);
|
301
|
+
}
|
302
|
+
|
303
|
+
addTransceiver(mediaStreamTrack: MediaStreamTrack, transceiverInit: RTCRtpTransceiverInit) {
|
304
|
+
return this.pc.addTransceiver(mediaStreamTrack, transceiverInit);
|
305
|
+
}
|
306
|
+
|
307
|
+
addTrack(track: MediaStreamTrack) {
|
308
|
+
return this.pc.addTrack(track);
|
309
|
+
}
|
310
|
+
|
273
311
|
setTrackCodecBitrate(info: TrackBitrateInfo) {
|
274
312
|
this.trackBitrates.push(info);
|
275
313
|
}
|
276
314
|
|
315
|
+
setConfiguration(rtcConfig: RTCConfiguration) {
|
316
|
+
return this.pc.setConfiguration(rtcConfig);
|
317
|
+
}
|
318
|
+
|
319
|
+
canRemoveTrack(): boolean {
|
320
|
+
return !!this.pc.removeTrack;
|
321
|
+
}
|
322
|
+
|
323
|
+
removeTrack(sender: RTCRtpSender) {
|
324
|
+
return this.pc.removeTrack(sender);
|
325
|
+
}
|
326
|
+
|
327
|
+
getConnectionState() {
|
328
|
+
return this.pc.connectionState;
|
329
|
+
}
|
330
|
+
|
331
|
+
getICEConnectionState() {
|
332
|
+
return this.pc.iceConnectionState;
|
333
|
+
}
|
334
|
+
|
335
|
+
getSignallingState() {
|
336
|
+
return this.pc.signalingState;
|
337
|
+
}
|
338
|
+
|
339
|
+
getTransceivers() {
|
340
|
+
return this.pc.getTransceivers();
|
341
|
+
}
|
342
|
+
|
343
|
+
getSenders() {
|
344
|
+
return this.pc.getSenders();
|
345
|
+
}
|
346
|
+
|
347
|
+
getLocalDescription() {
|
348
|
+
return this.pc.localDescription;
|
349
|
+
}
|
350
|
+
|
351
|
+
getRemoteDescription() {
|
352
|
+
return this.pc.remoteDescription;
|
353
|
+
}
|
354
|
+
|
355
|
+
async getConnectedAddress(): Promise<string | undefined> {
|
356
|
+
if (!this._pc) {
|
357
|
+
return;
|
358
|
+
}
|
359
|
+
let selectedCandidatePairId = '';
|
360
|
+
const candidatePairs = new Map<string, RTCIceCandidatePairStats>();
|
361
|
+
// id -> candidate ip
|
362
|
+
const candidates = new Map<string, string>();
|
363
|
+
const stats: RTCStatsReport = await this._pc.getStats();
|
364
|
+
stats.forEach((v) => {
|
365
|
+
switch (v.type) {
|
366
|
+
case 'transport':
|
367
|
+
selectedCandidatePairId = v.selectedCandidatePairId;
|
368
|
+
break;
|
369
|
+
case 'candidate-pair':
|
370
|
+
if (selectedCandidatePairId === '' && v.selected) {
|
371
|
+
selectedCandidatePairId = v.id;
|
372
|
+
}
|
373
|
+
candidatePairs.set(v.id, v);
|
374
|
+
break;
|
375
|
+
case 'remote-candidate':
|
376
|
+
candidates.set(v.id, `${v.address}:${v.port}`);
|
377
|
+
break;
|
378
|
+
default:
|
379
|
+
}
|
380
|
+
});
|
381
|
+
|
382
|
+
if (selectedCandidatePairId === '') {
|
383
|
+
return undefined;
|
384
|
+
}
|
385
|
+
const selectedID = candidatePairs.get(selectedCandidatePairId)?.remoteCandidateId;
|
386
|
+
if (selectedID === undefined) {
|
387
|
+
return undefined;
|
388
|
+
}
|
389
|
+
return candidates.get(selectedID);
|
390
|
+
}
|
391
|
+
|
277
392
|
close() {
|
278
393
|
if (!this._pc) {
|
279
394
|
return;
|