livekit-client 1.6.2 → 1.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/livekit-client.esm.mjs +468 -140
- 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/api/SignalClient.d.ts +3 -3
- package/dist/src/api/SignalClient.d.ts.map +1 -1
- package/dist/src/connectionHelper/ConnectionCheck.d.ts +2 -2
- package/dist/src/connectionHelper/ConnectionCheck.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/proto/livekit_models.d.ts +53 -4
- package/dist/src/proto/livekit_models.d.ts.map +1 -1
- package/dist/src/proto/livekit_rtc.d.ts +650 -91
- package/dist/src/proto/livekit_rtc.d.ts.map +1 -1
- package/dist/src/room/PCTransport.d.ts +1 -0
- package/dist/src/room/PCTransport.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts +2 -0
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts +1 -1
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/errors.d.ts +3 -0
- package/dist/src/room/errors.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts +1 -3
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/participant/Participant.d.ts +1 -1
- package/dist/src/room/participant/Participant.d.ts.map +1 -1
- package/dist/src/room/timers.d.ts +13 -0
- package/dist/src/room/timers.d.ts.map +1 -0
- package/dist/src/room/track/RemoteVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/create.d.ts.map +1 -1
- package/dist/src/room/track/options.d.ts +2 -2
- package/dist/src/room/track/options.d.ts.map +1 -1
- package/dist/src/test/mocks.d.ts +1 -1
- package/dist/ts4.2/src/api/SignalClient.d.ts +3 -3
- package/dist/ts4.2/src/connectionHelper/ConnectionCheck.d.ts +2 -2
- package/dist/ts4.2/src/index.d.ts +2 -1
- package/dist/ts4.2/src/proto/livekit_models.d.ts +59 -4
- package/dist/ts4.2/src/proto/livekit_rtc.d.ts +739 -120
- package/dist/ts4.2/src/room/PCTransport.d.ts +1 -0
- package/dist/ts4.2/src/room/RTCEngine.d.ts +2 -0
- package/dist/ts4.2/src/room/Room.d.ts +1 -1
- package/dist/ts4.2/src/room/errors.d.ts +3 -0
- package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +1 -3
- package/dist/ts4.2/src/room/participant/Participant.d.ts +1 -1
- package/dist/ts4.2/src/room/timers.d.ts +13 -0
- package/dist/ts4.2/src/room/track/options.d.ts +2 -2
- package/dist/ts4.2/src/test/mocks.d.ts +1 -1
- package/package.json +17 -17
- package/src/api/SignalClient.ts +33 -21
- package/src/connectionHelper/ConnectionCheck.ts +1 -1
- package/src/index.ts +2 -0
- package/src/proto/google/protobuf/timestamp.ts +2 -2
- package/src/proto/livekit_models.ts +158 -10
- package/src/proto/livekit_rtc.ts +205 -6
- package/src/room/PCTransport.ts +22 -6
- package/src/room/RTCEngine.ts +58 -45
- package/src/room/Room.ts +8 -10
- package/src/room/errors.ts +6 -0
- package/src/room/participant/LocalParticipant.ts +12 -17
- package/src/room/participant/Participant.ts +10 -2
- package/src/room/timers.ts +16 -0
- package/src/room/track/RemoteVideoTrack.ts +2 -1
- package/src/room/track/create.ts +6 -1
- package/src/room/track/options.ts +2 -2
package/src/proto/livekit_rtc.ts
CHANGED
@@ -9,6 +9,9 @@ import {
|
|
9
9
|
DisconnectReason,
|
10
10
|
disconnectReasonFromJSON,
|
11
11
|
disconnectReasonToJSON,
|
12
|
+
Encryption_Type,
|
13
|
+
encryption_TypeFromJSON,
|
14
|
+
encryption_TypeToJSON,
|
12
15
|
ParticipantInfo,
|
13
16
|
ParticipantTracks,
|
14
17
|
Room,
|
@@ -148,7 +151,8 @@ export interface SignalRequest {
|
|
148
151
|
| { $case: "subscriptionPermission"; subscriptionPermission: SubscriptionPermission }
|
149
152
|
| { $case: "syncState"; syncState: SyncState }
|
150
153
|
| { $case: "simulate"; simulate: SimulateScenario }
|
151
|
-
| { $case: "ping"; ping: number }
|
154
|
+
| { $case: "ping"; ping: number }
|
155
|
+
| { $case: "updateMetadata"; updateMetadata: UpdateParticipantMetadata };
|
152
156
|
}
|
153
157
|
|
154
158
|
export interface SignalResponse {
|
@@ -169,7 +173,8 @@ export interface SignalResponse {
|
|
169
173
|
| { $case: "subscriptionPermissionUpdate"; subscriptionPermissionUpdate: SubscriptionPermissionUpdate }
|
170
174
|
| { $case: "refreshToken"; refreshToken: string }
|
171
175
|
| { $case: "trackUnpublished"; trackUnpublished: TrackUnpublishedResponse }
|
172
|
-
| { $case: "pong"; pong: number }
|
176
|
+
| { $case: "pong"; pong: number }
|
177
|
+
| { $case: "reconnect"; reconnect: ReconnectResponse };
|
173
178
|
}
|
174
179
|
|
175
180
|
export interface SimulcastCodec {
|
@@ -198,6 +203,7 @@ export interface AddTrackRequest {
|
|
198
203
|
stereo: boolean;
|
199
204
|
/** true if RED (Redundant Encoding) is disabled for audio */
|
200
205
|
disableRed: boolean;
|
206
|
+
encryption: Encryption_Type;
|
201
207
|
}
|
202
208
|
|
203
209
|
export interface TrickleRequest {
|
@@ -232,6 +238,11 @@ export interface JoinResponse {
|
|
232
238
|
serverInfo?: ServerInfo;
|
233
239
|
}
|
234
240
|
|
241
|
+
export interface ReconnectResponse {
|
242
|
+
iceServers: ICEServer[];
|
243
|
+
clientConfiguration?: ClientConfiguration;
|
244
|
+
}
|
245
|
+
|
235
246
|
export interface TrackPublishedResponse {
|
236
247
|
cid: string;
|
237
248
|
track?: TrackInfo;
|
@@ -267,8 +278,17 @@ export interface UpdateTrackSettings {
|
|
267
278
|
width: number;
|
268
279
|
/** for video, height to receive */
|
269
280
|
height: number;
|
270
|
-
/** for video, frame rate to receive */
|
271
281
|
fps: number;
|
282
|
+
/**
|
283
|
+
* subscription priority. 1 being the highest (0 is unset)
|
284
|
+
* when unset, server sill assign priority based on the order of subscription
|
285
|
+
* server will use priority in the following ways:
|
286
|
+
* 1. when subscribed tracks exceed per-participant subscription limit, server will
|
287
|
+
* pause the lowest priority tracks
|
288
|
+
* 2. when the network is congested, server will assign available bandwidth to
|
289
|
+
* higher priority tracks first. lowest priority tracks can be paused
|
290
|
+
*/
|
291
|
+
priority: number;
|
272
292
|
}
|
273
293
|
|
274
294
|
export interface LeaveRequest {
|
@@ -286,6 +306,10 @@ export interface UpdateVideoLayers {
|
|
286
306
|
layers: VideoLayer[];
|
287
307
|
}
|
288
308
|
|
309
|
+
export interface UpdateParticipantMetadata {
|
310
|
+
metadata: string;
|
311
|
+
}
|
312
|
+
|
289
313
|
export interface ICEServer {
|
290
314
|
urls: string[];
|
291
315
|
username: string;
|
@@ -425,6 +449,9 @@ export const SignalRequest = {
|
|
425
449
|
if (message.message?.$case === "ping") {
|
426
450
|
writer.uint32(112).int64(message.message.ping);
|
427
451
|
}
|
452
|
+
if (message.message?.$case === "updateMetadata") {
|
453
|
+
UpdateParticipantMetadata.encode(message.message.updateMetadata, writer.uint32(122).fork()).ldelim();
|
454
|
+
}
|
428
455
|
return writer;
|
429
456
|
},
|
430
457
|
|
@@ -480,6 +507,12 @@ export const SignalRequest = {
|
|
480
507
|
case 14:
|
481
508
|
message.message = { $case: "ping", ping: longToNumber(reader.int64() as Long) };
|
482
509
|
break;
|
510
|
+
case 15:
|
511
|
+
message.message = {
|
512
|
+
$case: "updateMetadata",
|
513
|
+
updateMetadata: UpdateParticipantMetadata.decode(reader, reader.uint32()),
|
514
|
+
};
|
515
|
+
break;
|
483
516
|
default:
|
484
517
|
reader.skipType(tag & 7);
|
485
518
|
break;
|
@@ -519,6 +552,8 @@ export const SignalRequest = {
|
|
519
552
|
? { $case: "simulate", simulate: SimulateScenario.fromJSON(object.simulate) }
|
520
553
|
: isSet(object.ping)
|
521
554
|
? { $case: "ping", ping: Number(object.ping) }
|
555
|
+
: isSet(object.updateMetadata)
|
556
|
+
? { $case: "updateMetadata", updateMetadata: UpdateParticipantMetadata.fromJSON(object.updateMetadata) }
|
522
557
|
: undefined,
|
523
558
|
};
|
524
559
|
},
|
@@ -555,6 +590,9 @@ export const SignalRequest = {
|
|
555
590
|
message.message?.$case === "simulate" &&
|
556
591
|
(obj.simulate = message.message?.simulate ? SimulateScenario.toJSON(message.message?.simulate) : undefined);
|
557
592
|
message.message?.$case === "ping" && (obj.ping = Math.round(message.message?.ping));
|
593
|
+
message.message?.$case === "updateMetadata" && (obj.updateMetadata = message.message?.updateMetadata
|
594
|
+
? UpdateParticipantMetadata.toJSON(message.message?.updateMetadata)
|
595
|
+
: undefined);
|
558
596
|
return obj;
|
559
597
|
},
|
560
598
|
|
@@ -641,6 +679,16 @@ export const SignalRequest = {
|
|
641
679
|
if (object.message?.$case === "ping" && object.message?.ping !== undefined && object.message?.ping !== null) {
|
642
680
|
message.message = { $case: "ping", ping: object.message.ping };
|
643
681
|
}
|
682
|
+
if (
|
683
|
+
object.message?.$case === "updateMetadata" &&
|
684
|
+
object.message?.updateMetadata !== undefined &&
|
685
|
+
object.message?.updateMetadata !== null
|
686
|
+
) {
|
687
|
+
message.message = {
|
688
|
+
$case: "updateMetadata",
|
689
|
+
updateMetadata: UpdateParticipantMetadata.fromPartial(object.message.updateMetadata),
|
690
|
+
};
|
691
|
+
}
|
644
692
|
return message;
|
645
693
|
},
|
646
694
|
};
|
@@ -703,6 +751,9 @@ export const SignalResponse = {
|
|
703
751
|
if (message.message?.$case === "pong") {
|
704
752
|
writer.uint32(144).int64(message.message.pong);
|
705
753
|
}
|
754
|
+
if (message.message?.$case === "reconnect") {
|
755
|
+
ReconnectResponse.encode(message.message.reconnect, writer.uint32(154).fork()).ldelim();
|
756
|
+
}
|
706
757
|
return writer;
|
707
758
|
},
|
708
759
|
|
@@ -785,6 +836,9 @@ export const SignalResponse = {
|
|
785
836
|
case 18:
|
786
837
|
message.message = { $case: "pong", pong: longToNumber(reader.int64() as Long) };
|
787
838
|
break;
|
839
|
+
case 19:
|
840
|
+
message.message = { $case: "reconnect", reconnect: ReconnectResponse.decode(reader, reader.uint32()) };
|
841
|
+
break;
|
788
842
|
default:
|
789
843
|
reader.skipType(tag & 7);
|
790
844
|
break;
|
@@ -835,6 +889,8 @@ export const SignalResponse = {
|
|
835
889
|
? { $case: "trackUnpublished", trackUnpublished: TrackUnpublishedResponse.fromJSON(object.trackUnpublished) }
|
836
890
|
: isSet(object.pong)
|
837
891
|
? { $case: "pong", pong: Number(object.pong) }
|
892
|
+
: isSet(object.reconnect)
|
893
|
+
? { $case: "reconnect", reconnect: ReconnectResponse.fromJSON(object.reconnect) }
|
838
894
|
: undefined,
|
839
895
|
};
|
840
896
|
},
|
@@ -882,6 +938,8 @@ export const SignalResponse = {
|
|
882
938
|
? TrackUnpublishedResponse.toJSON(message.message?.trackUnpublished)
|
883
939
|
: undefined);
|
884
940
|
message.message?.$case === "pong" && (obj.pong = Math.round(message.message?.pong));
|
941
|
+
message.message?.$case === "reconnect" &&
|
942
|
+
(obj.reconnect = message.message?.reconnect ? ReconnectResponse.toJSON(message.message?.reconnect) : undefined);
|
885
943
|
return obj;
|
886
944
|
},
|
887
945
|
|
@@ -999,6 +1057,13 @@ export const SignalResponse = {
|
|
999
1057
|
if (object.message?.$case === "pong" && object.message?.pong !== undefined && object.message?.pong !== null) {
|
1000
1058
|
message.message = { $case: "pong", pong: object.message.pong };
|
1001
1059
|
}
|
1060
|
+
if (
|
1061
|
+
object.message?.$case === "reconnect" &&
|
1062
|
+
object.message?.reconnect !== undefined &&
|
1063
|
+
object.message?.reconnect !== null
|
1064
|
+
) {
|
1065
|
+
message.message = { $case: "reconnect", reconnect: ReconnectResponse.fromPartial(object.message.reconnect) };
|
1066
|
+
}
|
1002
1067
|
return message;
|
1003
1068
|
},
|
1004
1069
|
};
|
@@ -1085,6 +1150,7 @@ function createBaseAddTrackRequest(): AddTrackRequest {
|
|
1085
1150
|
sid: "",
|
1086
1151
|
stereo: false,
|
1087
1152
|
disableRed: false,
|
1153
|
+
encryption: 0,
|
1088
1154
|
};
|
1089
1155
|
}
|
1090
1156
|
|
@@ -1129,6 +1195,9 @@ export const AddTrackRequest = {
|
|
1129
1195
|
if (message.disableRed === true) {
|
1130
1196
|
writer.uint32(104).bool(message.disableRed);
|
1131
1197
|
}
|
1198
|
+
if (message.encryption !== 0) {
|
1199
|
+
writer.uint32(112).int32(message.encryption);
|
1200
|
+
}
|
1132
1201
|
return writer;
|
1133
1202
|
},
|
1134
1203
|
|
@@ -1178,6 +1247,9 @@ export const AddTrackRequest = {
|
|
1178
1247
|
case 13:
|
1179
1248
|
message.disableRed = reader.bool();
|
1180
1249
|
break;
|
1250
|
+
case 14:
|
1251
|
+
message.encryption = reader.int32() as any;
|
1252
|
+
break;
|
1181
1253
|
default:
|
1182
1254
|
reader.skipType(tag & 7);
|
1183
1255
|
break;
|
@@ -1203,6 +1275,7 @@ export const AddTrackRequest = {
|
|
1203
1275
|
sid: isSet(object.sid) ? String(object.sid) : "",
|
1204
1276
|
stereo: isSet(object.stereo) ? Boolean(object.stereo) : false,
|
1205
1277
|
disableRed: isSet(object.disableRed) ? Boolean(object.disableRed) : false,
|
1278
|
+
encryption: isSet(object.encryption) ? encryption_TypeFromJSON(object.encryption) : 0,
|
1206
1279
|
};
|
1207
1280
|
},
|
1208
1281
|
|
@@ -1229,6 +1302,7 @@ export const AddTrackRequest = {
|
|
1229
1302
|
message.sid !== undefined && (obj.sid = message.sid);
|
1230
1303
|
message.stereo !== undefined && (obj.stereo = message.stereo);
|
1231
1304
|
message.disableRed !== undefined && (obj.disableRed = message.disableRed);
|
1305
|
+
message.encryption !== undefined && (obj.encryption = encryption_TypeToJSON(message.encryption));
|
1232
1306
|
return obj;
|
1233
1307
|
},
|
1234
1308
|
|
@@ -1247,6 +1321,7 @@ export const AddTrackRequest = {
|
|
1247
1321
|
message.sid = object.sid ?? "";
|
1248
1322
|
message.stereo = object.stereo ?? false;
|
1249
1323
|
message.disableRed = object.disableRed ?? false;
|
1324
|
+
message.encryption = object.encryption ?? 0;
|
1250
1325
|
return message;
|
1251
1326
|
},
|
1252
1327
|
};
|
@@ -1550,6 +1625,74 @@ export const JoinResponse = {
|
|
1550
1625
|
},
|
1551
1626
|
};
|
1552
1627
|
|
1628
|
+
function createBaseReconnectResponse(): ReconnectResponse {
|
1629
|
+
return { iceServers: [], clientConfiguration: undefined };
|
1630
|
+
}
|
1631
|
+
|
1632
|
+
export const ReconnectResponse = {
|
1633
|
+
encode(message: ReconnectResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
|
1634
|
+
for (const v of message.iceServers) {
|
1635
|
+
ICEServer.encode(v!, writer.uint32(10).fork()).ldelim();
|
1636
|
+
}
|
1637
|
+
if (message.clientConfiguration !== undefined) {
|
1638
|
+
ClientConfiguration.encode(message.clientConfiguration, writer.uint32(18).fork()).ldelim();
|
1639
|
+
}
|
1640
|
+
return writer;
|
1641
|
+
},
|
1642
|
+
|
1643
|
+
decode(input: _m0.Reader | Uint8Array, length?: number): ReconnectResponse {
|
1644
|
+
const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
|
1645
|
+
let end = length === undefined ? reader.len : reader.pos + length;
|
1646
|
+
const message = createBaseReconnectResponse();
|
1647
|
+
while (reader.pos < end) {
|
1648
|
+
const tag = reader.uint32();
|
1649
|
+
switch (tag >>> 3) {
|
1650
|
+
case 1:
|
1651
|
+
message.iceServers.push(ICEServer.decode(reader, reader.uint32()));
|
1652
|
+
break;
|
1653
|
+
case 2:
|
1654
|
+
message.clientConfiguration = ClientConfiguration.decode(reader, reader.uint32());
|
1655
|
+
break;
|
1656
|
+
default:
|
1657
|
+
reader.skipType(tag & 7);
|
1658
|
+
break;
|
1659
|
+
}
|
1660
|
+
}
|
1661
|
+
return message;
|
1662
|
+
},
|
1663
|
+
|
1664
|
+
fromJSON(object: any): ReconnectResponse {
|
1665
|
+
return {
|
1666
|
+
iceServers: Array.isArray(object?.iceServers) ? object.iceServers.map((e: any) => ICEServer.fromJSON(e)) : [],
|
1667
|
+
clientConfiguration: isSet(object.clientConfiguration)
|
1668
|
+
? ClientConfiguration.fromJSON(object.clientConfiguration)
|
1669
|
+
: undefined,
|
1670
|
+
};
|
1671
|
+
},
|
1672
|
+
|
1673
|
+
toJSON(message: ReconnectResponse): unknown {
|
1674
|
+
const obj: any = {};
|
1675
|
+
if (message.iceServers) {
|
1676
|
+
obj.iceServers = message.iceServers.map((e) => e ? ICEServer.toJSON(e) : undefined);
|
1677
|
+
} else {
|
1678
|
+
obj.iceServers = [];
|
1679
|
+
}
|
1680
|
+
message.clientConfiguration !== undefined && (obj.clientConfiguration = message.clientConfiguration
|
1681
|
+
? ClientConfiguration.toJSON(message.clientConfiguration)
|
1682
|
+
: undefined);
|
1683
|
+
return obj;
|
1684
|
+
},
|
1685
|
+
|
1686
|
+
fromPartial<I extends Exact<DeepPartial<ReconnectResponse>, I>>(object: I): ReconnectResponse {
|
1687
|
+
const message = createBaseReconnectResponse();
|
1688
|
+
message.iceServers = object.iceServers?.map((e) => ICEServer.fromPartial(e)) || [];
|
1689
|
+
message.clientConfiguration = (object.clientConfiguration !== undefined && object.clientConfiguration !== null)
|
1690
|
+
? ClientConfiguration.fromPartial(object.clientConfiguration)
|
1691
|
+
: undefined;
|
1692
|
+
return message;
|
1693
|
+
},
|
1694
|
+
};
|
1695
|
+
|
1553
1696
|
function createBaseTrackPublishedResponse(): TrackPublishedResponse {
|
1554
1697
|
return { cid: "", track: undefined };
|
1555
1698
|
}
|
@@ -1845,7 +1988,7 @@ export const UpdateSubscription = {
|
|
1845
1988
|
};
|
1846
1989
|
|
1847
1990
|
function createBaseUpdateTrackSettings(): UpdateTrackSettings {
|
1848
|
-
return { trackSids: [], disabled: false, quality: 0, width: 0, height: 0, fps: 0 };
|
1991
|
+
return { trackSids: [], disabled: false, quality: 0, width: 0, height: 0, fps: 0, priority: 0 };
|
1849
1992
|
}
|
1850
1993
|
|
1851
1994
|
export const UpdateTrackSettings = {
|
@@ -1868,6 +2011,9 @@ export const UpdateTrackSettings = {
|
|
1868
2011
|
if (message.fps !== 0) {
|
1869
2012
|
writer.uint32(56).uint32(message.fps);
|
1870
2013
|
}
|
2014
|
+
if (message.priority !== 0) {
|
2015
|
+
writer.uint32(64).uint32(message.priority);
|
2016
|
+
}
|
1871
2017
|
return writer;
|
1872
2018
|
},
|
1873
2019
|
|
@@ -1896,6 +2042,9 @@ export const UpdateTrackSettings = {
|
|
1896
2042
|
case 7:
|
1897
2043
|
message.fps = reader.uint32();
|
1898
2044
|
break;
|
2045
|
+
case 8:
|
2046
|
+
message.priority = reader.uint32();
|
2047
|
+
break;
|
1899
2048
|
default:
|
1900
2049
|
reader.skipType(tag & 7);
|
1901
2050
|
break;
|
@@ -1912,6 +2061,7 @@ export const UpdateTrackSettings = {
|
|
1912
2061
|
width: isSet(object.width) ? Number(object.width) : 0,
|
1913
2062
|
height: isSet(object.height) ? Number(object.height) : 0,
|
1914
2063
|
fps: isSet(object.fps) ? Number(object.fps) : 0,
|
2064
|
+
priority: isSet(object.priority) ? Number(object.priority) : 0,
|
1915
2065
|
};
|
1916
2066
|
},
|
1917
2067
|
|
@@ -1927,6 +2077,7 @@ export const UpdateTrackSettings = {
|
|
1927
2077
|
message.width !== undefined && (obj.width = Math.round(message.width));
|
1928
2078
|
message.height !== undefined && (obj.height = Math.round(message.height));
|
1929
2079
|
message.fps !== undefined && (obj.fps = Math.round(message.fps));
|
2080
|
+
message.priority !== undefined && (obj.priority = Math.round(message.priority));
|
1930
2081
|
return obj;
|
1931
2082
|
},
|
1932
2083
|
|
@@ -1938,6 +2089,7 @@ export const UpdateTrackSettings = {
|
|
1938
2089
|
message.width = object.width ?? 0;
|
1939
2090
|
message.height = object.height ?? 0;
|
1940
2091
|
message.fps = object.fps ?? 0;
|
2092
|
+
message.priority = object.priority ?? 0;
|
1941
2093
|
return message;
|
1942
2094
|
},
|
1943
2095
|
};
|
@@ -2062,6 +2214,53 @@ export const UpdateVideoLayers = {
|
|
2062
2214
|
},
|
2063
2215
|
};
|
2064
2216
|
|
2217
|
+
function createBaseUpdateParticipantMetadata(): UpdateParticipantMetadata {
|
2218
|
+
return { metadata: "" };
|
2219
|
+
}
|
2220
|
+
|
2221
|
+
export const UpdateParticipantMetadata = {
|
2222
|
+
encode(message: UpdateParticipantMetadata, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
|
2223
|
+
if (message.metadata !== "") {
|
2224
|
+
writer.uint32(10).string(message.metadata);
|
2225
|
+
}
|
2226
|
+
return writer;
|
2227
|
+
},
|
2228
|
+
|
2229
|
+
decode(input: _m0.Reader | Uint8Array, length?: number): UpdateParticipantMetadata {
|
2230
|
+
const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
|
2231
|
+
let end = length === undefined ? reader.len : reader.pos + length;
|
2232
|
+
const message = createBaseUpdateParticipantMetadata();
|
2233
|
+
while (reader.pos < end) {
|
2234
|
+
const tag = reader.uint32();
|
2235
|
+
switch (tag >>> 3) {
|
2236
|
+
case 1:
|
2237
|
+
message.metadata = reader.string();
|
2238
|
+
break;
|
2239
|
+
default:
|
2240
|
+
reader.skipType(tag & 7);
|
2241
|
+
break;
|
2242
|
+
}
|
2243
|
+
}
|
2244
|
+
return message;
|
2245
|
+
},
|
2246
|
+
|
2247
|
+
fromJSON(object: any): UpdateParticipantMetadata {
|
2248
|
+
return { metadata: isSet(object.metadata) ? String(object.metadata) : "" };
|
2249
|
+
},
|
2250
|
+
|
2251
|
+
toJSON(message: UpdateParticipantMetadata): unknown {
|
2252
|
+
const obj: any = {};
|
2253
|
+
message.metadata !== undefined && (obj.metadata = message.metadata);
|
2254
|
+
return obj;
|
2255
|
+
},
|
2256
|
+
|
2257
|
+
fromPartial<I extends Exact<DeepPartial<UpdateParticipantMetadata>, I>>(object: I): UpdateParticipantMetadata {
|
2258
|
+
const message = createBaseUpdateParticipantMetadata();
|
2259
|
+
message.metadata = object.metadata ?? "";
|
2260
|
+
return message;
|
2261
|
+
},
|
2262
|
+
};
|
2263
|
+
|
2065
2264
|
function createBaseICEServer(): ICEServer {
|
2066
2265
|
return { urls: [], username: "", credential: "" };
|
2067
2266
|
}
|
@@ -3192,7 +3391,7 @@ export const SimulateScenario = {
|
|
3192
3391
|
declare var self: any | undefined;
|
3193
3392
|
declare var window: any | undefined;
|
3194
3393
|
declare var global: any | undefined;
|
3195
|
-
var
|
3394
|
+
var tsProtoGlobalThis: any = (() => {
|
3196
3395
|
if (typeof globalThis !== "undefined") {
|
3197
3396
|
return globalThis;
|
3198
3397
|
}
|
@@ -3222,7 +3421,7 @@ export type Exact<P, I extends P> = P extends Builtin ? P
|
|
3222
3421
|
|
3223
3422
|
function longToNumber(long: Long): number {
|
3224
3423
|
if (long.gt(Number.MAX_SAFE_INTEGER)) {
|
3225
|
-
throw new
|
3424
|
+
throw new tsProtoGlobalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER");
|
3226
3425
|
}
|
3227
3426
|
return long.toNumber();
|
3228
3427
|
}
|
package/src/room/PCTransport.ts
CHANGED
@@ -30,6 +30,8 @@ export default class PCTransport extends EventEmitter {
|
|
30
30
|
|
31
31
|
remoteStereoMids: string[] = [];
|
32
32
|
|
33
|
+
remoteNackMids: string[] = [];
|
34
|
+
|
33
35
|
onOffer?: (offer: RTCSessionDescriptionInit) => void;
|
34
36
|
|
35
37
|
constructor(config?: RTCConfiguration) {
|
@@ -50,7 +52,9 @@ export default class PCTransport extends EventEmitter {
|
|
50
52
|
|
51
53
|
async setRemoteDescription(sd: RTCSessionDescriptionInit): Promise<void> {
|
52
54
|
if (sd.type === 'offer') {
|
53
|
-
|
55
|
+
let { stereoMids, nackMids } = extractStereoAndNackAudioFromOffer(sd);
|
56
|
+
this.remoteStereoMids = stereoMids;
|
57
|
+
this.remoteNackMids = nackMids;
|
54
58
|
}
|
55
59
|
await this.pc.setRemoteDescription(sd);
|
56
60
|
|
@@ -116,7 +120,7 @@ export default class PCTransport extends EventEmitter {
|
|
116
120
|
const sdpParsed = parse(offer.sdp ?? '');
|
117
121
|
sdpParsed.media.forEach((media) => {
|
118
122
|
if (media.type === 'audio') {
|
119
|
-
ensureAudioNackAndStereo(media, []);
|
123
|
+
ensureAudioNackAndStereo(media, [], []);
|
120
124
|
} else if (media.type === 'video') {
|
121
125
|
// mung sdp for codec bitrate setting that can't apply by sendEncoding
|
122
126
|
this.trackBitrates.some((trackbr): boolean => {
|
@@ -169,7 +173,7 @@ export default class PCTransport extends EventEmitter {
|
|
169
173
|
const sdpParsed = parse(answer.sdp ?? '');
|
170
174
|
sdpParsed.media.forEach((media) => {
|
171
175
|
if (media.type === 'audio') {
|
172
|
-
ensureAudioNackAndStereo(media, this.remoteStereoMids);
|
176
|
+
ensureAudioNackAndStereo(media, this.remoteStereoMids, this.remoteNackMids);
|
173
177
|
}
|
174
178
|
});
|
175
179
|
await this.setMungedLocalDescription(answer, write(sdpParsed));
|
@@ -226,6 +230,7 @@ function ensureAudioNackAndStereo(
|
|
226
230
|
payloads?: string | undefined;
|
227
231
|
} & MediaDescription,
|
228
232
|
stereoMids: string[],
|
233
|
+
nackMids: string[],
|
229
234
|
) {
|
230
235
|
// found opus codec to add nack fb
|
231
236
|
let opusPayload = 0;
|
@@ -243,7 +248,10 @@ function ensureAudioNackAndStereo(
|
|
243
248
|
media.rtcpFb = [];
|
244
249
|
}
|
245
250
|
|
246
|
-
if (
|
251
|
+
if (
|
252
|
+
nackMids.includes(media.mid!) &&
|
253
|
+
!media.rtcpFb.some((fb) => fb.payload === opusPayload && fb.type === 'nack')
|
254
|
+
) {
|
247
255
|
media.rtcpFb.push({
|
248
256
|
payload: opusPayload,
|
249
257
|
type: 'nack',
|
@@ -264,8 +272,12 @@ function ensureAudioNackAndStereo(
|
|
264
272
|
}
|
265
273
|
}
|
266
274
|
|
267
|
-
function
|
275
|
+
function extractStereoAndNackAudioFromOffer(offer: RTCSessionDescriptionInit): {
|
276
|
+
stereoMids: string[];
|
277
|
+
nackMids: string[];
|
278
|
+
} {
|
268
279
|
const stereoMids: string[] = [];
|
280
|
+
const nackMids: string[] = [];
|
269
281
|
const sdpParsed = parse(offer.sdp ?? '');
|
270
282
|
let opusPayload = 0;
|
271
283
|
sdpParsed.media.forEach((media) => {
|
@@ -278,6 +290,10 @@ function extractStereoTracksFromOffer(offer: RTCSessionDescriptionInit): string[
|
|
278
290
|
return false;
|
279
291
|
});
|
280
292
|
|
293
|
+
if (media.rtcpFb?.some((fb) => fb.payload === opusPayload && fb.type === 'nack')) {
|
294
|
+
nackMids.push(media.mid!);
|
295
|
+
}
|
296
|
+
|
281
297
|
media.fmtp.some((fmtp): boolean => {
|
282
298
|
if (fmtp.payload === opusPayload) {
|
283
299
|
if (fmtp.config.includes('sprop-stereo=1')) {
|
@@ -289,5 +305,5 @@ function extractStereoTracksFromOffer(offer: RTCSessionDescriptionInit): string[
|
|
289
305
|
});
|
290
306
|
}
|
291
307
|
});
|
292
|
-
return stereoMids;
|
308
|
+
return { stereoMids, nackMids };
|
293
309
|
}
|
package/src/room/RTCEngine.ts
CHANGED
@@ -17,6 +17,7 @@ import {
|
|
17
17
|
AddTrackRequest,
|
18
18
|
JoinResponse,
|
19
19
|
LeaveRequest,
|
20
|
+
ReconnectResponse,
|
20
21
|
SignalTarget,
|
21
22
|
TrackPublishedResponse,
|
22
23
|
} from '../proto/livekit_rtc';
|
@@ -31,6 +32,7 @@ import {
|
|
31
32
|
import { EngineEvent } from './events';
|
32
33
|
import PCTransport, { PCEvents } from './PCTransport';
|
33
34
|
import type { ReconnectContext, ReconnectPolicy } from './ReconnectPolicy';
|
35
|
+
import CriticalTimers from './timers';
|
34
36
|
import type LocalTrack from './track/LocalTrack';
|
35
37
|
import type LocalVideoTrack from './track/LocalVideoTrack';
|
36
38
|
import type { SimulcastTrackInfo } from './track/LocalVideoTrack';
|
@@ -279,35 +281,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
279
281
|
|
280
282
|
this.participantSid = joinResponse.participant?.sid;
|
281
283
|
|
282
|
-
const rtcConfig =
|
283
|
-
|
284
|
-
// update ICE servers before creating PeerConnection
|
285
|
-
if (joinResponse.iceServers && !rtcConfig.iceServers) {
|
286
|
-
const rtcIceServers: RTCIceServer[] = [];
|
287
|
-
joinResponse.iceServers.forEach((iceServer) => {
|
288
|
-
const rtcIceServer: RTCIceServer = {
|
289
|
-
urls: iceServer.urls,
|
290
|
-
};
|
291
|
-
if (iceServer.username) rtcIceServer.username = iceServer.username;
|
292
|
-
if (iceServer.credential) {
|
293
|
-
rtcIceServer.credential = iceServer.credential;
|
294
|
-
}
|
295
|
-
rtcIceServers.push(rtcIceServer);
|
296
|
-
});
|
297
|
-
rtcConfig.iceServers = rtcIceServers;
|
298
|
-
}
|
299
|
-
|
300
|
-
if (
|
301
|
-
joinResponse.clientConfiguration &&
|
302
|
-
joinResponse.clientConfiguration.forceRelay === ClientConfigSetting.ENABLED
|
303
|
-
) {
|
304
|
-
rtcConfig.iceTransportPolicy = 'relay';
|
305
|
-
}
|
306
|
-
|
307
|
-
// @ts-ignore
|
308
|
-
rtcConfig.sdpSemantics = 'unified-plan';
|
309
|
-
// @ts-ignore
|
310
|
-
rtcConfig.continualGatheringPolicy = 'gather_continually';
|
284
|
+
const rtcConfig = this.makeRTCConfiguration(joinResponse);
|
311
285
|
|
312
286
|
this.publisher = new PCTransport(rtcConfig);
|
313
287
|
this.subscriber = new PCTransport(rtcConfig);
|
@@ -448,6 +422,40 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
448
422
|
};
|
449
423
|
}
|
450
424
|
|
425
|
+
private makeRTCConfiguration(serverResponse: JoinResponse | ReconnectResponse): RTCConfiguration {
|
426
|
+
const rtcConfig = { ...this.rtcConfig };
|
427
|
+
|
428
|
+
// update ICE servers before creating PeerConnection
|
429
|
+
if (serverResponse.iceServers && !rtcConfig.iceServers) {
|
430
|
+
const rtcIceServers: RTCIceServer[] = [];
|
431
|
+
serverResponse.iceServers.forEach((iceServer) => {
|
432
|
+
const rtcIceServer: RTCIceServer = {
|
433
|
+
urls: iceServer.urls,
|
434
|
+
};
|
435
|
+
if (iceServer.username) rtcIceServer.username = iceServer.username;
|
436
|
+
if (iceServer.credential) {
|
437
|
+
rtcIceServer.credential = iceServer.credential;
|
438
|
+
}
|
439
|
+
rtcIceServers.push(rtcIceServer);
|
440
|
+
});
|
441
|
+
rtcConfig.iceServers = rtcIceServers;
|
442
|
+
}
|
443
|
+
|
444
|
+
if (
|
445
|
+
serverResponse.clientConfiguration &&
|
446
|
+
serverResponse.clientConfiguration.forceRelay === ClientConfigSetting.ENABLED
|
447
|
+
) {
|
448
|
+
rtcConfig.iceTransportPolicy = 'relay';
|
449
|
+
}
|
450
|
+
|
451
|
+
// @ts-ignore
|
452
|
+
rtcConfig.sdpSemantics = 'unified-plan';
|
453
|
+
// @ts-ignore
|
454
|
+
rtcConfig.continualGatheringPolicy = 'gather_continually';
|
455
|
+
|
456
|
+
return rtcConfig;
|
457
|
+
}
|
458
|
+
|
451
459
|
private createDataChannels() {
|
452
460
|
if (!this.publisher) {
|
453
461
|
return;
|
@@ -673,14 +681,14 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
673
681
|
return;
|
674
682
|
}
|
675
683
|
|
676
|
-
log.
|
684
|
+
log.warn(`${connection} disconnected`);
|
677
685
|
if (this.reconnectAttempts === 0) {
|
678
686
|
// only reset start time on the first try
|
679
687
|
this.reconnectStart = Date.now();
|
680
688
|
}
|
681
689
|
|
682
690
|
const disconnect = (duration: number) => {
|
683
|
-
log.
|
691
|
+
log.warn(
|
684
692
|
`could not recover connection after ${this.reconnectAttempts} attempts, ${duration}ms. giving up`,
|
685
693
|
);
|
686
694
|
this.emit(EngineEvent.Disconnected);
|
@@ -703,10 +711,11 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
703
711
|
|
704
712
|
log.debug(`reconnecting in ${delay}ms`);
|
705
713
|
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
714
|
+
this.clearReconnectTimeout();
|
715
|
+
this.reconnectTimeout = CriticalTimers.setTimeout(
|
716
|
+
() => this.attemptReconnect(signalEvents),
|
717
|
+
delay,
|
718
|
+
);
|
710
719
|
};
|
711
720
|
|
712
721
|
private async attemptReconnect(signalEvents: boolean = false) {
|
@@ -733,11 +742,8 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
733
742
|
} else {
|
734
743
|
await this.resumeConnection(signalEvents);
|
735
744
|
}
|
736
|
-
this.
|
745
|
+
this.clearPendingReconnect();
|
737
746
|
this.fullReconnectOnNext = false;
|
738
|
-
if (this.reconnectTimeout) {
|
739
|
-
clearTimeout(this.reconnectTimeout);
|
740
|
-
}
|
741
747
|
} catch (e) {
|
742
748
|
this.reconnectAttempts += 1;
|
743
749
|
let reconnectRequired = false;
|
@@ -841,7 +847,12 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
841
847
|
}
|
842
848
|
|
843
849
|
try {
|
844
|
-
await this.client.reconnect(this.url, this.token, this.participantSid);
|
850
|
+
const res = await this.client.reconnect(this.url, this.token, this.participantSid);
|
851
|
+
if (res) {
|
852
|
+
const rtcConfig = this.makeRTCConfiguration(res);
|
853
|
+
this.publisher.pc.setConfiguration(rtcConfig);
|
854
|
+
this.subscriber.pc.setConfiguration(rtcConfig);
|
855
|
+
}
|
845
856
|
} catch (e) {
|
846
857
|
let message = '';
|
847
858
|
if (e instanceof Error) {
|
@@ -1034,19 +1045,21 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
1034
1045
|
}
|
1035
1046
|
}
|
1036
1047
|
|
1037
|
-
private
|
1048
|
+
private clearReconnectTimeout() {
|
1038
1049
|
if (this.reconnectTimeout) {
|
1039
|
-
clearTimeout(this.reconnectTimeout);
|
1050
|
+
CriticalTimers.clearTimeout(this.reconnectTimeout);
|
1040
1051
|
}
|
1052
|
+
}
|
1053
|
+
|
1054
|
+
private clearPendingReconnect() {
|
1055
|
+
this.clearReconnectTimeout();
|
1041
1056
|
this.reconnectAttempts = 0;
|
1042
1057
|
}
|
1043
1058
|
|
1044
1059
|
private handleBrowserOnLine = () => {
|
1045
1060
|
// in case the engine is currently reconnecting, attempt a reconnect immediately after the browser state has changed to 'onLine'
|
1046
1061
|
if (this.client.isReconnecting) {
|
1047
|
-
|
1048
|
-
clearTimeout(this.reconnectTimeout);
|
1049
|
-
}
|
1062
|
+
this.clearReconnectTimeout();
|
1050
1063
|
this.attemptReconnect(true);
|
1051
1064
|
}
|
1052
1065
|
};
|