livekit-client 1.6.2 → 1.6.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
};
|