livekit-client 1.1.8 → 1.2.1
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/README.md +1 -0
- package/dist/livekit-client.esm.mjs +677 -187
- 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 +4 -1
- package/dist/src/api/SignalClient.d.ts.map +1 -1
- package/dist/src/index.d.ts +4 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/options.d.ts +1 -0
- package/dist/src/options.d.ts.map +1 -1
- package/dist/src/proto/livekit_models.d.ts +234 -0
- package/dist/src/proto/livekit_models.d.ts.map +1 -1
- package/dist/src/proto/livekit_rtc.d.ts +944 -6
- package/dist/src/proto/livekit_rtc.d.ts.map +1 -1
- package/dist/src/room/PCTransport.d.ts +9 -0
- package/dist/src/room/PCTransport.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts +3 -2
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts +3 -3
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/events.d.ts +8 -1
- package/dist/src/room/events.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts +3 -3
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
- package/dist/src/room/track/LocalAudioTrack.d.ts.map +1 -1
- package/dist/src/room/track/LocalTrack.d.ts +2 -0
- package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
- package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/RemoteTrack.d.ts.map +1 -1
- package/dist/src/room/track/RemoteTrackPublication.d.ts +4 -1
- package/dist/src/room/track/RemoteTrackPublication.d.ts.map +1 -1
- package/package.json +3 -1
- package/src/api/SignalClient.ts +21 -6
- package/src/index.ts +6 -2
- package/src/options.ts +1 -0
- package/src/proto/livekit_models.ts +179 -4
- package/src/proto/livekit_rtc.ts +14 -1
- package/src/room/PCTransport.ts +39 -0
- package/src/room/RTCEngine.ts +44 -18
- package/src/room/Room.ts +30 -24
- package/src/room/events.ts +7 -0
- package/src/room/participant/LocalParticipant.ts +70 -10
- package/src/room/participant/RemoteParticipant.ts +12 -10
- package/src/room/participant/publishUtils.ts +1 -1
- package/src/room/track/LocalAudioTrack.ts +16 -12
- package/src/room/track/LocalTrack.ts +41 -25
- package/src/room/track/LocalVideoTrack.ts +15 -11
- package/src/room/track/RemoteTrack.ts +1 -0
- package/src/room/track/RemoteTrackPublication.ts +37 -11
- package/dist/src/api/RequestQueue.d.ts +0 -13
- package/dist/src/api/RequestQueue.d.ts.map +0 -1
- package/src/api/RequestQueue.ts +0 -53
@@ -4484,6 +4484,82 @@ function clientConfigSettingToJSON(object) {
|
|
4484
4484
|
return 'UNKNOWN';
|
4485
4485
|
}
|
4486
4486
|
}
|
4487
|
+
var DisconnectReason;
|
4488
|
+
|
4489
|
+
(function (DisconnectReason) {
|
4490
|
+
DisconnectReason[DisconnectReason["UNKNOWN_REASON"] = 0] = "UNKNOWN_REASON";
|
4491
|
+
DisconnectReason[DisconnectReason["CLIENT_INITIATED"] = 1] = "CLIENT_INITIATED";
|
4492
|
+
DisconnectReason[DisconnectReason["DUPLICATE_IDENTITY"] = 2] = "DUPLICATE_IDENTITY";
|
4493
|
+
DisconnectReason[DisconnectReason["SERVER_SHUTDOWN"] = 3] = "SERVER_SHUTDOWN";
|
4494
|
+
DisconnectReason[DisconnectReason["PARTICIPANT_REMOVED"] = 4] = "PARTICIPANT_REMOVED";
|
4495
|
+
DisconnectReason[DisconnectReason["ROOM_DELETED"] = 5] = "ROOM_DELETED";
|
4496
|
+
DisconnectReason[DisconnectReason["STATE_MISMATCH"] = 6] = "STATE_MISMATCH";
|
4497
|
+
DisconnectReason[DisconnectReason["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
|
4498
|
+
})(DisconnectReason || (DisconnectReason = {}));
|
4499
|
+
|
4500
|
+
function disconnectReasonFromJSON(object) {
|
4501
|
+
switch (object) {
|
4502
|
+
case 0:
|
4503
|
+
case 'UNKNOWN_REASON':
|
4504
|
+
return DisconnectReason.UNKNOWN_REASON;
|
4505
|
+
|
4506
|
+
case 1:
|
4507
|
+
case 'CLIENT_INITIATED':
|
4508
|
+
return DisconnectReason.CLIENT_INITIATED;
|
4509
|
+
|
4510
|
+
case 2:
|
4511
|
+
case 'DUPLICATE_IDENTITY':
|
4512
|
+
return DisconnectReason.DUPLICATE_IDENTITY;
|
4513
|
+
|
4514
|
+
case 3:
|
4515
|
+
case 'SERVER_SHUTDOWN':
|
4516
|
+
return DisconnectReason.SERVER_SHUTDOWN;
|
4517
|
+
|
4518
|
+
case 4:
|
4519
|
+
case 'PARTICIPANT_REMOVED':
|
4520
|
+
return DisconnectReason.PARTICIPANT_REMOVED;
|
4521
|
+
|
4522
|
+
case 5:
|
4523
|
+
case 'ROOM_DELETED':
|
4524
|
+
return DisconnectReason.ROOM_DELETED;
|
4525
|
+
|
4526
|
+
case 6:
|
4527
|
+
case 'STATE_MISMATCH':
|
4528
|
+
return DisconnectReason.STATE_MISMATCH;
|
4529
|
+
|
4530
|
+
case -1:
|
4531
|
+
case 'UNRECOGNIZED':
|
4532
|
+
default:
|
4533
|
+
return DisconnectReason.UNRECOGNIZED;
|
4534
|
+
}
|
4535
|
+
}
|
4536
|
+
function disconnectReasonToJSON(object) {
|
4537
|
+
switch (object) {
|
4538
|
+
case DisconnectReason.UNKNOWN_REASON:
|
4539
|
+
return 'UNKNOWN_REASON';
|
4540
|
+
|
4541
|
+
case DisconnectReason.CLIENT_INITIATED:
|
4542
|
+
return 'CLIENT_INITIATED';
|
4543
|
+
|
4544
|
+
case DisconnectReason.DUPLICATE_IDENTITY:
|
4545
|
+
return 'DUPLICATE_IDENTITY';
|
4546
|
+
|
4547
|
+
case DisconnectReason.SERVER_SHUTDOWN:
|
4548
|
+
return 'SERVER_SHUTDOWN';
|
4549
|
+
|
4550
|
+
case DisconnectReason.PARTICIPANT_REMOVED:
|
4551
|
+
return 'PARTICIPANT_REMOVED';
|
4552
|
+
|
4553
|
+
case DisconnectReason.ROOM_DELETED:
|
4554
|
+
return 'ROOM_DELETED';
|
4555
|
+
|
4556
|
+
case DisconnectReason.STATE_MISMATCH:
|
4557
|
+
return 'STATE_MISMATCH';
|
4558
|
+
|
4559
|
+
default:
|
4560
|
+
return 'UNKNOWN';
|
4561
|
+
}
|
4562
|
+
}
|
4487
4563
|
var ParticipantInfo_State;
|
4488
4564
|
|
4489
4565
|
(function (ParticipantInfo_State) {
|
@@ -5204,7 +5280,8 @@ function createBaseSimulcastCodecInfo() {
|
|
5204
5280
|
return {
|
5205
5281
|
mimeType: '',
|
5206
5282
|
mid: '',
|
5207
|
-
cid: ''
|
5283
|
+
cid: '',
|
5284
|
+
layers: []
|
5208
5285
|
};
|
5209
5286
|
}
|
5210
5287
|
|
@@ -5224,6 +5301,10 @@ const SimulcastCodecInfo = {
|
|
5224
5301
|
writer.uint32(26).string(message.cid);
|
5225
5302
|
}
|
5226
5303
|
|
5304
|
+
for (const v of message.layers) {
|
5305
|
+
VideoLayer.encode(v, writer.uint32(34).fork()).ldelim();
|
5306
|
+
}
|
5307
|
+
|
5227
5308
|
return writer;
|
5228
5309
|
},
|
5229
5310
|
|
@@ -5248,6 +5329,10 @@ const SimulcastCodecInfo = {
|
|
5248
5329
|
message.cid = reader.string();
|
5249
5330
|
break;
|
5250
5331
|
|
5332
|
+
case 4:
|
5333
|
+
message.layers.push(VideoLayer.decode(reader, reader.uint32()));
|
5334
|
+
break;
|
5335
|
+
|
5251
5336
|
default:
|
5252
5337
|
reader.skipType(tag & 7);
|
5253
5338
|
break;
|
@@ -5261,7 +5346,8 @@ const SimulcastCodecInfo = {
|
|
5261
5346
|
return {
|
5262
5347
|
mimeType: isSet$1(object.mimeType) ? String(object.mimeType) : '',
|
5263
5348
|
mid: isSet$1(object.mid) ? String(object.mid) : '',
|
5264
|
-
cid: isSet$1(object.cid) ? String(object.cid) : ''
|
5349
|
+
cid: isSet$1(object.cid) ? String(object.cid) : '',
|
5350
|
+
layers: Array.isArray(object === null || object === void 0 ? void 0 : object.layers) ? object.layers.map(e => VideoLayer.fromJSON(e)) : []
|
5265
5351
|
};
|
5266
5352
|
},
|
5267
5353
|
|
@@ -5270,16 +5356,24 @@ const SimulcastCodecInfo = {
|
|
5270
5356
|
message.mimeType !== undefined && (obj.mimeType = message.mimeType);
|
5271
5357
|
message.mid !== undefined && (obj.mid = message.mid);
|
5272
5358
|
message.cid !== undefined && (obj.cid = message.cid);
|
5359
|
+
|
5360
|
+
if (message.layers) {
|
5361
|
+
obj.layers = message.layers.map(e => e ? VideoLayer.toJSON(e) : undefined);
|
5362
|
+
} else {
|
5363
|
+
obj.layers = [];
|
5364
|
+
}
|
5365
|
+
|
5273
5366
|
return obj;
|
5274
5367
|
},
|
5275
5368
|
|
5276
5369
|
fromPartial(object) {
|
5277
|
-
var _a, _b, _c;
|
5370
|
+
var _a, _b, _c, _d;
|
5278
5371
|
|
5279
5372
|
const message = createBaseSimulcastCodecInfo();
|
5280
5373
|
message.mimeType = (_a = object.mimeType) !== null && _a !== void 0 ? _a : '';
|
5281
5374
|
message.mid = (_b = object.mid) !== null && _b !== void 0 ? _b : '';
|
5282
5375
|
message.cid = (_c = object.cid) !== null && _c !== void 0 ? _c : '';
|
5376
|
+
message.layers = ((_d = object.layers) === null || _d === void 0 ? void 0 : _d.map(e => VideoLayer.fromPartial(e))) || [];
|
5283
5377
|
return message;
|
5284
5378
|
}
|
5285
5379
|
|
@@ -6179,7 +6273,8 @@ function createBaseClientConfiguration() {
|
|
6179
6273
|
return {
|
6180
6274
|
video: undefined,
|
6181
6275
|
screen: undefined,
|
6182
|
-
resumeConnection: 0
|
6276
|
+
resumeConnection: 0,
|
6277
|
+
disabledCodecs: undefined
|
6183
6278
|
};
|
6184
6279
|
}
|
6185
6280
|
|
@@ -6199,6 +6294,10 @@ const ClientConfiguration = {
|
|
6199
6294
|
writer.uint32(24).int32(message.resumeConnection);
|
6200
6295
|
}
|
6201
6296
|
|
6297
|
+
if (message.disabledCodecs !== undefined) {
|
6298
|
+
DisabledCodecs.encode(message.disabledCodecs, writer.uint32(34).fork()).ldelim();
|
6299
|
+
}
|
6300
|
+
|
6202
6301
|
return writer;
|
6203
6302
|
},
|
6204
6303
|
|
@@ -6223,6 +6322,10 @@ const ClientConfiguration = {
|
|
6223
6322
|
message.resumeConnection = reader.int32();
|
6224
6323
|
break;
|
6225
6324
|
|
6325
|
+
case 4:
|
6326
|
+
message.disabledCodecs = DisabledCodecs.decode(reader, reader.uint32());
|
6327
|
+
break;
|
6328
|
+
|
6226
6329
|
default:
|
6227
6330
|
reader.skipType(tag & 7);
|
6228
6331
|
break;
|
@@ -6236,7 +6339,8 @@ const ClientConfiguration = {
|
|
6236
6339
|
return {
|
6237
6340
|
video: isSet$1(object.video) ? VideoConfiguration.fromJSON(object.video) : undefined,
|
6238
6341
|
screen: isSet$1(object.screen) ? VideoConfiguration.fromJSON(object.screen) : undefined,
|
6239
|
-
resumeConnection: isSet$1(object.resumeConnection) ? clientConfigSettingFromJSON(object.resumeConnection) : 0
|
6342
|
+
resumeConnection: isSet$1(object.resumeConnection) ? clientConfigSettingFromJSON(object.resumeConnection) : 0,
|
6343
|
+
disabledCodecs: isSet$1(object.disabledCodecs) ? DisabledCodecs.fromJSON(object.disabledCodecs) : undefined
|
6240
6344
|
};
|
6241
6345
|
},
|
6242
6346
|
|
@@ -6245,6 +6349,7 @@ const ClientConfiguration = {
|
|
6245
6349
|
message.video !== undefined && (obj.video = message.video ? VideoConfiguration.toJSON(message.video) : undefined);
|
6246
6350
|
message.screen !== undefined && (obj.screen = message.screen ? VideoConfiguration.toJSON(message.screen) : undefined);
|
6247
6351
|
message.resumeConnection !== undefined && (obj.resumeConnection = clientConfigSettingToJSON(message.resumeConnection));
|
6352
|
+
message.disabledCodecs !== undefined && (obj.disabledCodecs = message.disabledCodecs ? DisabledCodecs.toJSON(message.disabledCodecs) : undefined);
|
6248
6353
|
return obj;
|
6249
6354
|
},
|
6250
6355
|
|
@@ -6255,6 +6360,7 @@ const ClientConfiguration = {
|
|
6255
6360
|
message.video = object.video !== undefined && object.video !== null ? VideoConfiguration.fromPartial(object.video) : undefined;
|
6256
6361
|
message.screen = object.screen !== undefined && object.screen !== null ? VideoConfiguration.fromPartial(object.screen) : undefined;
|
6257
6362
|
message.resumeConnection = (_a = object.resumeConnection) !== null && _a !== void 0 ? _a : 0;
|
6363
|
+
message.disabledCodecs = object.disabledCodecs !== undefined && object.disabledCodecs !== null ? DisabledCodecs.fromPartial(object.disabledCodecs) : undefined;
|
6258
6364
|
return message;
|
6259
6365
|
}
|
6260
6366
|
|
@@ -6321,6 +6427,73 @@ const VideoConfiguration = {
|
|
6321
6427
|
|
6322
6428
|
};
|
6323
6429
|
|
6430
|
+
function createBaseDisabledCodecs() {
|
6431
|
+
return {
|
6432
|
+
codecs: []
|
6433
|
+
};
|
6434
|
+
}
|
6435
|
+
|
6436
|
+
const DisabledCodecs = {
|
6437
|
+
encode(message) {
|
6438
|
+
let writer = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : minimal.Writer.create();
|
6439
|
+
|
6440
|
+
for (const v of message.codecs) {
|
6441
|
+
Codec.encode(v, writer.uint32(10).fork()).ldelim();
|
6442
|
+
}
|
6443
|
+
|
6444
|
+
return writer;
|
6445
|
+
},
|
6446
|
+
|
6447
|
+
decode(input, length) {
|
6448
|
+
const reader = input instanceof minimal.Reader ? input : new minimal.Reader(input);
|
6449
|
+
let end = length === undefined ? reader.len : reader.pos + length;
|
6450
|
+
const message = createBaseDisabledCodecs();
|
6451
|
+
|
6452
|
+
while (reader.pos < end) {
|
6453
|
+
const tag = reader.uint32();
|
6454
|
+
|
6455
|
+
switch (tag >>> 3) {
|
6456
|
+
case 1:
|
6457
|
+
message.codecs.push(Codec.decode(reader, reader.uint32()));
|
6458
|
+
break;
|
6459
|
+
|
6460
|
+
default:
|
6461
|
+
reader.skipType(tag & 7);
|
6462
|
+
break;
|
6463
|
+
}
|
6464
|
+
}
|
6465
|
+
|
6466
|
+
return message;
|
6467
|
+
},
|
6468
|
+
|
6469
|
+
fromJSON(object) {
|
6470
|
+
return {
|
6471
|
+
codecs: Array.isArray(object === null || object === void 0 ? void 0 : object.codecs) ? object.codecs.map(e => Codec.fromJSON(e)) : []
|
6472
|
+
};
|
6473
|
+
},
|
6474
|
+
|
6475
|
+
toJSON(message) {
|
6476
|
+
const obj = {};
|
6477
|
+
|
6478
|
+
if (message.codecs) {
|
6479
|
+
obj.codecs = message.codecs.map(e => e ? Codec.toJSON(e) : undefined);
|
6480
|
+
} else {
|
6481
|
+
obj.codecs = [];
|
6482
|
+
}
|
6483
|
+
|
6484
|
+
return obj;
|
6485
|
+
},
|
6486
|
+
|
6487
|
+
fromPartial(object) {
|
6488
|
+
var _a;
|
6489
|
+
|
6490
|
+
const message = createBaseDisabledCodecs();
|
6491
|
+
message.codecs = ((_a = object.codecs) === null || _a === void 0 ? void 0 : _a.map(e => Codec.fromPartial(e))) || [];
|
6492
|
+
return message;
|
6493
|
+
}
|
6494
|
+
|
6495
|
+
};
|
6496
|
+
|
6324
6497
|
var globalThis$1 = (() => {
|
6325
6498
|
if (typeof globalThis$1 !== 'undefined') return globalThis$1;
|
6326
6499
|
if (typeof self !== 'undefined') return self;
|
@@ -6346,9 +6519,11 @@ const btoa = globalThis$1.btoa || (bin => globalThis$1.Buffer.from(bin, 'binary'
|
|
6346
6519
|
|
6347
6520
|
function base64FromBytes(arr) {
|
6348
6521
|
const bin = [];
|
6349
|
-
|
6522
|
+
|
6523
|
+
for (const byte of arr) {
|
6350
6524
|
bin.push(String.fromCharCode(byte));
|
6351
|
-
}
|
6525
|
+
}
|
6526
|
+
|
6352
6527
|
return btoa(bin.join(''));
|
6353
6528
|
}
|
6354
6529
|
|
@@ -8033,7 +8208,8 @@ const UpdateTrackSettings = {
|
|
8033
8208
|
|
8034
8209
|
function createBaseLeaveRequest() {
|
8035
8210
|
return {
|
8036
|
-
canReconnect: false
|
8211
|
+
canReconnect: false,
|
8212
|
+
reason: 0
|
8037
8213
|
};
|
8038
8214
|
}
|
8039
8215
|
|
@@ -8045,6 +8221,10 @@ const LeaveRequest = {
|
|
8045
8221
|
writer.uint32(8).bool(message.canReconnect);
|
8046
8222
|
}
|
8047
8223
|
|
8224
|
+
if (message.reason !== 0) {
|
8225
|
+
writer.uint32(16).int32(message.reason);
|
8226
|
+
}
|
8227
|
+
|
8048
8228
|
return writer;
|
8049
8229
|
},
|
8050
8230
|
|
@@ -8061,6 +8241,10 @@ const LeaveRequest = {
|
|
8061
8241
|
message.canReconnect = reader.bool();
|
8062
8242
|
break;
|
8063
8243
|
|
8244
|
+
case 2:
|
8245
|
+
message.reason = reader.int32();
|
8246
|
+
break;
|
8247
|
+
|
8064
8248
|
default:
|
8065
8249
|
reader.skipType(tag & 7);
|
8066
8250
|
break;
|
@@ -8072,21 +8256,24 @@ const LeaveRequest = {
|
|
8072
8256
|
|
8073
8257
|
fromJSON(object) {
|
8074
8258
|
return {
|
8075
|
-
canReconnect: isSet(object.canReconnect) ? Boolean(object.canReconnect) : false
|
8259
|
+
canReconnect: isSet(object.canReconnect) ? Boolean(object.canReconnect) : false,
|
8260
|
+
reason: isSet(object.reason) ? disconnectReasonFromJSON(object.reason) : 0
|
8076
8261
|
};
|
8077
8262
|
},
|
8078
8263
|
|
8079
8264
|
toJSON(message) {
|
8080
8265
|
const obj = {};
|
8081
8266
|
message.canReconnect !== undefined && (obj.canReconnect = message.canReconnect);
|
8267
|
+
message.reason !== undefined && (obj.reason = disconnectReasonToJSON(message.reason));
|
8082
8268
|
return obj;
|
8083
8269
|
},
|
8084
8270
|
|
8085
8271
|
fromPartial(object) {
|
8086
|
-
var _a;
|
8272
|
+
var _a, _b;
|
8087
8273
|
|
8088
8274
|
const message = createBaseLeaveRequest();
|
8089
8275
|
message.canReconnect = (_a = object.canReconnect) !== null && _a !== void 0 ? _a : false;
|
8276
|
+
message.reason = (_b = object.reason) !== null && _b !== void 0 ? _b : 0;
|
8090
8277
|
return message;
|
8091
8278
|
}
|
8092
8279
|
|
@@ -10002,6 +10189,8 @@ var TrackEvent;
|
|
10002
10189
|
TrackEvent["Muted"] = "muted";
|
10003
10190
|
TrackEvent["Unmuted"] = "unmuted";
|
10004
10191
|
TrackEvent["Ended"] = "ended";
|
10192
|
+
TrackEvent["Subscribed"] = "subscribed";
|
10193
|
+
TrackEvent["Unsubscribed"] = "unsubscribed";
|
10005
10194
|
/** @internal */
|
10006
10195
|
|
10007
10196
|
TrackEvent["UpdateSettings"] = "updateSettings";
|
@@ -10044,6 +10233,12 @@ var TrackEvent;
|
|
10044
10233
|
*/
|
10045
10234
|
|
10046
10235
|
TrackEvent["UpstreamResumed"] = "upstreamResumed";
|
10236
|
+
/**
|
10237
|
+
* @internal
|
10238
|
+
* Fires on RemoteTrackPublication
|
10239
|
+
*/
|
10240
|
+
|
10241
|
+
TrackEvent["SubscriptionPermissionChanged"] = "subscriptionPermissionChanged";
|
10047
10242
|
})(TrackEvent || (TrackEvent = {}));
|
10048
10243
|
|
10049
10244
|
const monitorFrequency = 2000;
|
@@ -10070,7 +10265,7 @@ function computeBitrate(currentStats, prevStats) {
|
|
10070
10265
|
return (bytesNow - bytesPrev) * 8 * 1000 / (currentStats.timestamp - prevStats.timestamp);
|
10071
10266
|
}
|
10072
10267
|
|
10073
|
-
var version$1 = "1.1
|
10268
|
+
var version$1 = "1.2.1";
|
10074
10269
|
|
10075
10270
|
const version = version$1;
|
10076
10271
|
const protocolVersion = 8;
|
@@ -10190,6 +10385,178 @@ class Future {
|
|
10190
10385
|
|
10191
10386
|
}
|
10192
10387
|
|
10388
|
+
class Queue {
|
10389
|
+
/**
|
10390
|
+
* @class Queue
|
10391
|
+
*
|
10392
|
+
* Priority queue with rate limiting<br>
|
10393
|
+
* See the medium article:<br>
|
10394
|
+
* https://mmomtchev.medium.com/parallelizing-download-loops-in-js-with-async-await-queue-670420880cd6
|
10395
|
+
*
|
10396
|
+
* @param {number} [_maxConcurrent=1] Number of tasks allowed to run simultaneously
|
10397
|
+
* @param {number} [_minCycle=0] Minimum number of milliseconds between two consecutive tasks
|
10398
|
+
*/
|
10399
|
+
constructor(_maxConcurrent, _minCycle) {
|
10400
|
+
this.maxConcurrent = _maxConcurrent || 1;
|
10401
|
+
this.minCycle = _minCycle || 0;
|
10402
|
+
this.queueRunning = [];
|
10403
|
+
this.queueWaiting = {};
|
10404
|
+
this.lastRun = 0;
|
10405
|
+
}
|
10406
|
+
/** @private */
|
10407
|
+
|
10408
|
+
|
10409
|
+
dequeue(hash) {
|
10410
|
+
const q = this.queueRunning;
|
10411
|
+
const idx = q.findIndex(x => x.hash === hash);
|
10412
|
+
if (idx == -1) throw 'queue desync';
|
10413
|
+
const o = q[idx];
|
10414
|
+
q.splice(idx, 1);
|
10415
|
+
return o;
|
10416
|
+
}
|
10417
|
+
/** @private */
|
10418
|
+
|
10419
|
+
|
10420
|
+
getFirstWaiting() {
|
10421
|
+
for (let p of Object.keys(this.queueWaiting).sort((a, b) => a - b)) if (this.queueWaiting[p] !== undefined && this.queueWaiting[p].length > 0) return this.queueWaiting[p];
|
10422
|
+
|
10423
|
+
return undefined;
|
10424
|
+
}
|
10425
|
+
/**
|
10426
|
+
* Signal that the task `hash` has finished.<br>
|
10427
|
+
* Frees its slot in the queue
|
10428
|
+
*
|
10429
|
+
* @method end
|
10430
|
+
* @param {any} hash Unique hash identifying the task, Symbol() works very well
|
10431
|
+
*/
|
10432
|
+
|
10433
|
+
|
10434
|
+
end(hash) {
|
10435
|
+
const me = this.dequeue(hash);
|
10436
|
+
me.resolve();
|
10437
|
+
/* Choose the next task to run and unblock its promise */
|
10438
|
+
|
10439
|
+
const q = this.getFirstWaiting();
|
10440
|
+
|
10441
|
+
if (q !== undefined) {
|
10442
|
+
const next = q.shift();
|
10443
|
+
next.resolve();
|
10444
|
+
}
|
10445
|
+
}
|
10446
|
+
/**
|
10447
|
+
* Wait for a slot in the queue
|
10448
|
+
*
|
10449
|
+
* @method wait
|
10450
|
+
* @param {any} hash Unique hash identifying the task
|
10451
|
+
* @param {number} [priority=0] Optional priority, -1 is higher priority than 1
|
10452
|
+
* @return {Promise<void>} Resolved when the task is ready to run
|
10453
|
+
*/
|
10454
|
+
|
10455
|
+
|
10456
|
+
async wait(hash, _priority) {
|
10457
|
+
const priority = _priority === undefined ? 0 : _priority;
|
10458
|
+
/* Us on the queue */
|
10459
|
+
|
10460
|
+
let me = {
|
10461
|
+
hash,
|
10462
|
+
priority
|
10463
|
+
};
|
10464
|
+
/* Create priorities on the fly */
|
10465
|
+
|
10466
|
+
if (this.queueWaiting[priority] == undefined) this.queueWaiting[priority] = [];
|
10467
|
+
/* Are we allowed to run? */
|
10468
|
+
|
10469
|
+
if (this.queueRunning.length >= this.maxConcurrent) {
|
10470
|
+
/* This promise will be unlocked from the outside */
|
10471
|
+
|
10472
|
+
/* and it cannot reject */
|
10473
|
+
me.promise = new Promise(resolve => {
|
10474
|
+
me.resolve = resolve;
|
10475
|
+
});
|
10476
|
+
/* Get in the line */
|
10477
|
+
|
10478
|
+
this.queueWaiting[priority].push(me);
|
10479
|
+
await me.promise;
|
10480
|
+
}
|
10481
|
+
|
10482
|
+
this.queueRunning.push(me);
|
10483
|
+
me.promise = new Promise(resolve => {
|
10484
|
+
me.resolve = resolve;
|
10485
|
+
});
|
10486
|
+
/* Wait if it is too soon */
|
10487
|
+
|
10488
|
+
while (Date.now() - this.lastRun < this.minCycle) {
|
10489
|
+
await new Promise(resolve => setTimeout(resolve, this.minCycle - Date.now() + this.lastRun));
|
10490
|
+
}
|
10491
|
+
|
10492
|
+
this.lastRun = Date.now();
|
10493
|
+
}
|
10494
|
+
/**
|
10495
|
+
* Run a job (equivalent to calling Queue.wait(), fn() and then Queue.end())<br>
|
10496
|
+
* fn can be both synchronous or asynchronous function
|
10497
|
+
*
|
10498
|
+
* @method run
|
10499
|
+
* @param {Function} fn The job
|
10500
|
+
* @param {number} [priority=0] Optional priority, -1 is higher priority than 1
|
10501
|
+
* @return {Promise<any>} Resolved when the task has finished with the return value of fn
|
10502
|
+
*/
|
10503
|
+
|
10504
|
+
|
10505
|
+
run(job, _priority) {
|
10506
|
+
const priority = _priority === undefined ? 0 : _priority;
|
10507
|
+
const id = Symbol();
|
10508
|
+
return this.wait(id, priority).then(() => job()).finally(() => {
|
10509
|
+
this.end(id);
|
10510
|
+
});
|
10511
|
+
}
|
10512
|
+
/**
|
10513
|
+
* @interface QueueStats {running: number, waiting: number, last: number}
|
10514
|
+
*/
|
10515
|
+
|
10516
|
+
/**
|
10517
|
+
* Return the number of running and waiting jobs
|
10518
|
+
*
|
10519
|
+
* @method stat
|
10520
|
+
* @return {QueueStats} running, waiting, last
|
10521
|
+
*/
|
10522
|
+
|
10523
|
+
|
10524
|
+
stat() {
|
10525
|
+
return {
|
10526
|
+
running: this.queueRunning.length,
|
10527
|
+
waiting: Object.keys(this.queueWaiting).reduce((t, x) => t += this.queueWaiting[x].length, 0),
|
10528
|
+
last: this.lastRun
|
10529
|
+
};
|
10530
|
+
}
|
10531
|
+
/**
|
10532
|
+
* Returns a promise that resolves when the queue is empty
|
10533
|
+
*
|
10534
|
+
* @method flush
|
10535
|
+
* @return {Promise<void>}
|
10536
|
+
*/
|
10537
|
+
|
10538
|
+
|
10539
|
+
async flush() {
|
10540
|
+
/* Aways wait on the lowest priority in the queue */
|
10541
|
+
while (this.stat().waiting > 0) {
|
10542
|
+
for (let p of Object.keys(this.queueWaiting).sort((a, b) => b - a)) {
|
10543
|
+
const qp = this.queueWaiting[p];
|
10544
|
+
|
10545
|
+
if (qp !== undefined && qp.length > 0) {
|
10546
|
+
await qp[qp.length - 1].promise;
|
10547
|
+
}
|
10548
|
+
}
|
10549
|
+
}
|
10550
|
+
/* And then finish on the running queue */
|
10551
|
+
|
10552
|
+
|
10553
|
+
while (this.queueRunning.length > 0) {
|
10554
|
+
await Promise.allSettled(this.queueRunning.map(x => x.promise));
|
10555
|
+
}
|
10556
|
+
}
|
10557
|
+
|
10558
|
+
}
|
10559
|
+
|
10193
10560
|
const defaultId = 'default';
|
10194
10561
|
class DeviceManager {
|
10195
10562
|
static getInstance() {
|
@@ -11098,6 +11465,7 @@ class LocalTrack extends Track {
|
|
11098
11465
|
this.reacquireTrack = false;
|
11099
11466
|
this.wasMuted = false;
|
11100
11467
|
this.providedByUser = userProvidedTrack;
|
11468
|
+
this.muteQueue = new Queue();
|
11101
11469
|
}
|
11102
11470
|
|
11103
11471
|
get id() {
|
@@ -11178,7 +11546,9 @@ class LocalTrack extends Track {
|
|
11178
11546
|
// 'A MediaStreamTrack ended due to a capture failure`
|
11179
11547
|
|
11180
11548
|
|
11181
|
-
this.
|
11549
|
+
if (!this.providedByUser) {
|
11550
|
+
this._mediaStreamTrack.stop();
|
11551
|
+
}
|
11182
11552
|
|
11183
11553
|
track.addEventListener('ended', this.handleEnded);
|
11184
11554
|
livekitLogger.debug('replace MediaStreamTrack');
|
@@ -11188,6 +11558,7 @@ class LocalTrack extends Track {
|
|
11188
11558
|
}
|
11189
11559
|
|
11190
11560
|
this._mediaStreamTrack = track;
|
11561
|
+
await this.resumeUpstream();
|
11191
11562
|
this.attachedElements.forEach(el => {
|
11192
11563
|
attachToElement(track, el);
|
11193
11564
|
});
|
@@ -11237,6 +11608,7 @@ class LocalTrack extends Track {
|
|
11237
11608
|
}
|
11238
11609
|
|
11239
11610
|
this._mediaStreamTrack = newTrack;
|
11611
|
+
await this.resumeUpstream();
|
11240
11612
|
this.attachedElements.forEach(el => {
|
11241
11613
|
attachToElement(newTrack, el);
|
11242
11614
|
});
|
@@ -11246,6 +11618,8 @@ class LocalTrack extends Track {
|
|
11246
11618
|
}
|
11247
11619
|
|
11248
11620
|
setTrackMuted(muted) {
|
11621
|
+
livekitLogger.debug("setting ".concat(this.kind, " track ").concat(muted ? 'muted' : 'unmuted'));
|
11622
|
+
|
11249
11623
|
if (this.isMuted === muted) {
|
11250
11624
|
return;
|
11251
11625
|
}
|
@@ -11279,34 +11653,38 @@ class LocalTrack extends Track {
|
|
11279
11653
|
}
|
11280
11654
|
|
11281
11655
|
async pauseUpstream() {
|
11282
|
-
|
11283
|
-
|
11284
|
-
|
11656
|
+
this.muteQueue.run(async () => {
|
11657
|
+
if (this._isUpstreamPaused === true) {
|
11658
|
+
return;
|
11659
|
+
}
|
11285
11660
|
|
11286
|
-
|
11287
|
-
|
11288
|
-
|
11289
|
-
|
11661
|
+
if (!this.sender) {
|
11662
|
+
livekitLogger.warn('unable to pause upstream for an unpublished track');
|
11663
|
+
return;
|
11664
|
+
}
|
11290
11665
|
|
11291
|
-
|
11292
|
-
|
11293
|
-
|
11294
|
-
|
11666
|
+
this._isUpstreamPaused = true;
|
11667
|
+
this.emit(TrackEvent.UpstreamPaused, this);
|
11668
|
+
const emptyTrack = this.kind === Track.Kind.Audio ? getEmptyAudioStreamTrack() : getEmptyVideoStreamTrack();
|
11669
|
+
await this.sender.replaceTrack(emptyTrack);
|
11670
|
+
});
|
11295
11671
|
}
|
11296
11672
|
|
11297
11673
|
async resumeUpstream() {
|
11298
|
-
|
11299
|
-
|
11300
|
-
|
11674
|
+
this.muteQueue.run(async () => {
|
11675
|
+
if (this._isUpstreamPaused === false) {
|
11676
|
+
return;
|
11677
|
+
}
|
11301
11678
|
|
11302
|
-
|
11303
|
-
|
11304
|
-
|
11305
|
-
|
11679
|
+
if (!this.sender) {
|
11680
|
+
livekitLogger.warn('unable to resume upstream for an unpublished track');
|
11681
|
+
return;
|
11682
|
+
}
|
11306
11683
|
|
11307
|
-
|
11308
|
-
|
11309
|
-
|
11684
|
+
this._isUpstreamPaused = false;
|
11685
|
+
this.emit(TrackEvent.UpstreamResumed, this);
|
11686
|
+
await this.sender.replaceTrack(this._mediaStreamTrack);
|
11687
|
+
});
|
11310
11688
|
}
|
11311
11689
|
|
11312
11690
|
}
|
@@ -11464,24 +11842,28 @@ class LocalAudioTrack extends LocalTrack {
|
|
11464
11842
|
}
|
11465
11843
|
|
11466
11844
|
async mute() {
|
11467
|
-
|
11468
|
-
|
11469
|
-
|
11845
|
+
await this.muteQueue.run(async () => {
|
11846
|
+
// disabled special handling as it will cause BT headsets to switch communication modes
|
11847
|
+
if (this.source === Track.Source.Microphone && this.stopOnMute && !this.isUserProvided) {
|
11848
|
+
livekitLogger.debug('stopping mic track'); // also stop the track, so that microphone indicator is turned off
|
11470
11849
|
|
11471
|
-
|
11472
|
-
|
11850
|
+
this._mediaStreamTrack.stop();
|
11851
|
+
}
|
11473
11852
|
|
11474
|
-
|
11853
|
+
await super.mute();
|
11854
|
+
});
|
11475
11855
|
return this;
|
11476
11856
|
}
|
11477
11857
|
|
11478
11858
|
async unmute() {
|
11479
|
-
|
11480
|
-
|
11481
|
-
|
11482
|
-
|
11859
|
+
await this.muteQueue.run(async () => {
|
11860
|
+
if (this.source === Track.Source.Microphone && this.stopOnMute && !this.isUserProvided) {
|
11861
|
+
livekitLogger.debug('reacquiring mic track');
|
11862
|
+
await this.restartTrack();
|
11863
|
+
}
|
11483
11864
|
|
11484
|
-
|
11865
|
+
await super.unmute();
|
11866
|
+
});
|
11485
11867
|
return this;
|
11486
11868
|
}
|
11487
11869
|
|
@@ -11647,23 +12029,27 @@ class LocalVideoTrack extends LocalTrack {
|
|
11647
12029
|
}
|
11648
12030
|
|
11649
12031
|
async mute() {
|
11650
|
-
|
11651
|
-
|
12032
|
+
await this.muteQueue.run(async () => {
|
12033
|
+
if (this.source === Track.Source.Camera && !this.isUserProvided) {
|
12034
|
+
livekitLogger.debug('stopping camera track'); // also stop the track, so that camera indicator is turned off
|
11652
12035
|
|
11653
|
-
|
11654
|
-
|
12036
|
+
this._mediaStreamTrack.stop();
|
12037
|
+
}
|
11655
12038
|
|
11656
|
-
|
12039
|
+
await super.mute();
|
12040
|
+
});
|
11657
12041
|
return this;
|
11658
12042
|
}
|
11659
12043
|
|
11660
12044
|
async unmute() {
|
11661
|
-
|
11662
|
-
|
11663
|
-
|
11664
|
-
|
12045
|
+
await this.muteQueue.run(async () => {
|
12046
|
+
if (this.source === Track.Source.Camera && !this.isUserProvided) {
|
12047
|
+
livekitLogger.debug('reacquiring camera track');
|
12048
|
+
await this.restartTrack();
|
12049
|
+
}
|
11665
12050
|
|
11666
|
-
|
12051
|
+
await super.unmute();
|
12052
|
+
});
|
11667
12053
|
return this;
|
11668
12054
|
}
|
11669
12055
|
|
@@ -11980,6 +12366,7 @@ class RemoteTrack extends Track {
|
|
11980
12366
|
setMuted(muted) {
|
11981
12367
|
if (this.isMuted !== muted) {
|
11982
12368
|
this.isMuted = muted;
|
12369
|
+
this._mediaStreamTrack.enabled = !muted;
|
11983
12370
|
this.emit(muted ? TrackEvent.Muted : TrackEvent.Unmuted, this);
|
11984
12371
|
}
|
11985
12372
|
}
|
@@ -13068,7 +13455,7 @@ function computeVideoEncodings(isScreenShare, width, height, options) {
|
|
13068
13455
|
encodings.push({
|
13069
13456
|
rid: videoRids[2 - i],
|
13070
13457
|
scaleResolutionDownBy: 2 ** i,
|
13071
|
-
maxBitrate: videoEncoding ? videoEncoding.maxBitrate /
|
13458
|
+
maxBitrate: videoEncoding ? videoEncoding.maxBitrate / 3 ** i : 0,
|
13072
13459
|
|
13073
13460
|
/* @ts-ignore */
|
13074
13461
|
maxFramerate: original.encoding.maxFramerate,
|
@@ -13235,7 +13622,7 @@ class RemoteTrackPublication extends TrackPublication {
|
|
13235
13622
|
super(...arguments);
|
13236
13623
|
/** @internal */
|
13237
13624
|
|
13238
|
-
this.
|
13625
|
+
this.allowed = true;
|
13239
13626
|
this.disabled = false;
|
13240
13627
|
this.currentVideoQuality = VideoQuality.HIGH;
|
13241
13628
|
|
@@ -13267,7 +13654,10 @@ class RemoteTrackPublication extends TrackPublication {
|
|
13267
13654
|
|
13268
13655
|
|
13269
13656
|
setSubscribed(subscribed) {
|
13270
|
-
this.subscribed = subscribed;
|
13657
|
+
this.subscribed = subscribed; // reset allowed status when desired subscription state changes
|
13658
|
+
// server will notify client via signal message if it's not allowed
|
13659
|
+
|
13660
|
+
this.allowed = true;
|
13271
13661
|
const sub = {
|
13272
13662
|
trackSids: [this.trackSid],
|
13273
13663
|
subscribe: this.subscribed,
|
@@ -13283,11 +13673,11 @@ class RemoteTrackPublication extends TrackPublication {
|
|
13283
13673
|
|
13284
13674
|
get subscriptionStatus() {
|
13285
13675
|
if (this.subscribed === false || !super.isSubscribed) {
|
13286
|
-
|
13287
|
-
|
13676
|
+
if (!this.allowed) {
|
13677
|
+
return TrackPublication.SubscriptionStatus.NotAllowed;
|
13678
|
+
}
|
13288
13679
|
|
13289
|
-
|
13290
|
-
return TrackPublication.SubscriptionStatus.NotAllowed;
|
13680
|
+
return TrackPublication.SubscriptionStatus.Unsubscribed;
|
13291
13681
|
}
|
13292
13682
|
|
13293
13683
|
return TrackPublication.SubscriptionStatus.Subscribed;
|
@@ -13302,10 +13692,6 @@ class RemoteTrackPublication extends TrackPublication {
|
|
13302
13692
|
return false;
|
13303
13693
|
}
|
13304
13694
|
|
13305
|
-
if (!this._allowed) {
|
13306
|
-
return false;
|
13307
|
-
}
|
13308
|
-
|
13309
13695
|
return super.isSubscribed;
|
13310
13696
|
}
|
13311
13697
|
|
@@ -13373,11 +13759,14 @@ class RemoteTrackPublication extends TrackPublication {
|
|
13373
13759
|
|
13374
13760
|
|
13375
13761
|
setTrack(track) {
|
13376
|
-
|
13762
|
+
const prevStatus = this.subscriptionStatus;
|
13763
|
+
const prevTrack = this.track;
|
13764
|
+
|
13765
|
+
if (prevTrack) {
|
13377
13766
|
// unregister listener
|
13378
|
-
|
13379
|
-
|
13380
|
-
|
13767
|
+
prevTrack.off(TrackEvent.VideoDimensionsChanged, this.handleVideoDimensionsChange);
|
13768
|
+
prevTrack.off(TrackEvent.VisibilityChanged, this.handleVisibilityChange);
|
13769
|
+
prevTrack.off(TrackEvent.Ended, this.handleEnded);
|
13381
13770
|
}
|
13382
13771
|
|
13383
13772
|
super.setTrack(track);
|
@@ -13388,6 +13777,25 @@ class RemoteTrackPublication extends TrackPublication {
|
|
13388
13777
|
track.on(TrackEvent.VisibilityChanged, this.handleVisibilityChange);
|
13389
13778
|
track.on(TrackEvent.Ended, this.handleEnded);
|
13390
13779
|
}
|
13780
|
+
|
13781
|
+
this.emitSubscriptionUpdateIfChanged(prevStatus);
|
13782
|
+
|
13783
|
+
if (!!track !== !!prevTrack) {
|
13784
|
+
// when undefined status changes, there's a subscription changed event
|
13785
|
+
if (track) {
|
13786
|
+
this.emit(TrackEvent.Subscribed, track);
|
13787
|
+
} else {
|
13788
|
+
this.emit(TrackEvent.Unsubscribed, prevTrack);
|
13789
|
+
}
|
13790
|
+
}
|
13791
|
+
}
|
13792
|
+
/** @internal */
|
13793
|
+
|
13794
|
+
|
13795
|
+
setAllowed(allowed) {
|
13796
|
+
const prevStatus = this.subscriptionStatus;
|
13797
|
+
this.allowed = allowed;
|
13798
|
+
this.emitSubscriptionUpdateIfChanged(prevStatus);
|
13391
13799
|
}
|
13392
13800
|
/** @internal */
|
13393
13801
|
|
@@ -13400,6 +13808,16 @@ class RemoteTrackPublication extends TrackPublication {
|
|
13400
13808
|
(_a = this.track) === null || _a === void 0 ? void 0 : _a.setMuted(info.muted);
|
13401
13809
|
}
|
13402
13810
|
|
13811
|
+
emitSubscriptionUpdateIfChanged(previousStatus) {
|
13812
|
+
const currentStatus = this.subscriptionStatus;
|
13813
|
+
|
13814
|
+
if (previousStatus === currentStatus) {
|
13815
|
+
return;
|
13816
|
+
}
|
13817
|
+
|
13818
|
+
this.emit(TrackEvent.SubscriptionPermissionChanged, currentStatus, previousStatus);
|
13819
|
+
}
|
13820
|
+
|
13403
13821
|
isManualOperationAllowed() {
|
13404
13822
|
if (this.isAdaptiveStream) {
|
13405
13823
|
livekitLogger.warn('adaptive stream is enabled, cannot change track settings', {
|
@@ -13474,8 +13892,14 @@ class RemoteParticipant extends Participant {
|
|
13474
13892
|
});
|
13475
13893
|
this.signalClient.sendUpdateSubscription(sub);
|
13476
13894
|
});
|
13477
|
-
publication.on(TrackEvent.
|
13478
|
-
this.emit(ParticipantEvent.
|
13895
|
+
publication.on(TrackEvent.SubscriptionPermissionChanged, status => {
|
13896
|
+
this.emit(ParticipantEvent.TrackSubscriptionPermissionChanged, publication, status);
|
13897
|
+
});
|
13898
|
+
publication.on(TrackEvent.Subscribed, track => {
|
13899
|
+
this.emit(ParticipantEvent.TrackSubscribed, track, publication);
|
13900
|
+
});
|
13901
|
+
publication.on(TrackEvent.Unsubscribed, previousTrack => {
|
13902
|
+
this.emit(ParticipantEvent.TrackUnsubscribed, previousTrack, publication);
|
13479
13903
|
});
|
13480
13904
|
}
|
13481
13905
|
|
@@ -13576,15 +14000,12 @@ class RemoteParticipant extends Participant {
|
|
13576
14000
|
track.isMuted = publication.isMuted;
|
13577
14001
|
track.setMediaStream(mediaStream);
|
13578
14002
|
track.start();
|
13579
|
-
publication.setTrack(track); //
|
13580
|
-
|
13581
|
-
publication._allowed = true; // set participant volume on new microphone tracks
|
14003
|
+
publication.setTrack(track); // set participant volume on new microphone tracks
|
13582
14004
|
|
13583
14005
|
if (this.volume !== undefined && track instanceof RemoteAudioTrack && track.source === Track.Source.Microphone) {
|
13584
14006
|
track.setVolume(this.volume);
|
13585
14007
|
}
|
13586
14008
|
|
13587
|
-
this.emit(ParticipantEvent.TrackSubscribed, track, publication);
|
13588
14009
|
return publication;
|
13589
14010
|
}
|
13590
14011
|
/** @internal */
|
@@ -13672,15 +14093,8 @@ class RemoteParticipant extends Participant {
|
|
13672
14093
|
} = publication;
|
13673
14094
|
|
13674
14095
|
if (track) {
|
13675
|
-
const {
|
13676
|
-
isSubscribed
|
13677
|
-
} = publication;
|
13678
14096
|
track.stop();
|
13679
|
-
publication.setTrack(undefined);
|
13680
|
-
|
13681
|
-
if (isSubscribed) {
|
13682
|
-
this.emit(ParticipantEvent.TrackUnsubscribed, track, publication);
|
13683
|
-
}
|
14097
|
+
publication.setTrack(undefined);
|
13684
14098
|
}
|
13685
14099
|
|
13686
14100
|
if (sendUnpublish) {
|
@@ -13801,11 +14215,47 @@ class LocalParticipant extends Participant {
|
|
13801
14215
|
this.unpublishTrack(track.track);
|
13802
14216
|
};
|
13803
14217
|
|
13804
|
-
this.handleTrackEnded = track => {
|
13805
|
-
|
13806
|
-
track
|
13807
|
-
|
13808
|
-
|
14218
|
+
this.handleTrackEnded = async track => {
|
14219
|
+
if (track.source === Track.Source.ScreenShare || track.source === Track.Source.ScreenShareAudio) {
|
14220
|
+
livekitLogger.debug('unpublishing local track due to TrackEnded', {
|
14221
|
+
track: track.sid
|
14222
|
+
});
|
14223
|
+
this.unpublishTrack(track);
|
14224
|
+
} else if (track.isUserProvided) {
|
14225
|
+
await track.pauseUpstream();
|
14226
|
+
} else if (track instanceof LocalAudioTrack || track instanceof LocalVideoTrack) {
|
14227
|
+
try {
|
14228
|
+
if (isWeb()) {
|
14229
|
+
try {
|
14230
|
+
const currentPermissions = await (navigator === null || navigator === void 0 ? void 0 : navigator.permissions.query({
|
14231
|
+
// the permission query for camera and microphone currently not supported in Safari and Firefox
|
14232
|
+
// @ts-ignore
|
14233
|
+
name: track.source === Track.Source.Camera ? 'camera' : 'microphone'
|
14234
|
+
}));
|
14235
|
+
|
14236
|
+
if (currentPermissions && currentPermissions.state === 'denied') {
|
14237
|
+
livekitLogger.warn("user has revoked access to ".concat(track.source)); // detect granted change after permissions were denied to try and resume then
|
14238
|
+
|
14239
|
+
currentPermissions.onchange = () => {
|
14240
|
+
if (currentPermissions.state !== 'denied') {
|
14241
|
+
track.restartTrack();
|
14242
|
+
currentPermissions.onchange = null;
|
14243
|
+
}
|
14244
|
+
};
|
14245
|
+
|
14246
|
+
throw new Error('GetUserMedia Permission denied');
|
14247
|
+
}
|
14248
|
+
} catch (e) {// permissions query fails for firefox, we continue and try to restart the track
|
14249
|
+
}
|
14250
|
+
}
|
14251
|
+
|
14252
|
+
livekitLogger.debug('track ended, attempting to use a different device');
|
14253
|
+
await track.restartTrack();
|
14254
|
+
} catch (e) {
|
14255
|
+
livekitLogger.warn("could not restart track, pausing upstream instead");
|
14256
|
+
await track.pauseUpstream();
|
14257
|
+
}
|
14258
|
+
}
|
13809
14259
|
};
|
13810
14260
|
|
13811
14261
|
this.audioTracks = new Map();
|
@@ -13864,8 +14314,8 @@ class LocalParticipant extends Participant {
|
|
13864
14314
|
*/
|
13865
14315
|
|
13866
14316
|
|
13867
|
-
setCameraEnabled(enabled, options) {
|
13868
|
-
return this.setTrackEnabled(Track.Source.Camera, enabled, options);
|
14317
|
+
setCameraEnabled(enabled, options, publishOptions) {
|
14318
|
+
return this.setTrackEnabled(Track.Source.Camera, enabled, options, publishOptions);
|
13869
14319
|
}
|
13870
14320
|
/**
|
13871
14321
|
* Enable or disable a participant's microphone track.
|
@@ -13875,8 +14325,8 @@ class LocalParticipant extends Participant {
|
|
13875
14325
|
*/
|
13876
14326
|
|
13877
14327
|
|
13878
|
-
setMicrophoneEnabled(enabled, options) {
|
13879
|
-
return this.setTrackEnabled(Track.Source.Microphone, enabled, options);
|
14328
|
+
setMicrophoneEnabled(enabled, options, publishOptions) {
|
14329
|
+
return this.setTrackEnabled(Track.Source.Microphone, enabled, options, publishOptions);
|
13880
14330
|
}
|
13881
14331
|
/**
|
13882
14332
|
* Start or stop sharing a participant's screen
|
@@ -13884,8 +14334,8 @@ class LocalParticipant extends Participant {
|
|
13884
14334
|
*/
|
13885
14335
|
|
13886
14336
|
|
13887
|
-
setScreenShareEnabled(enabled, options) {
|
13888
|
-
return this.setTrackEnabled(Track.Source.ScreenShare, enabled, options);
|
14337
|
+
setScreenShareEnabled(enabled, options, publishOptions) {
|
14338
|
+
return this.setTrackEnabled(Track.Source.ScreenShare, enabled, options, publishOptions);
|
13889
14339
|
}
|
13890
14340
|
/** @internal */
|
13891
14341
|
|
@@ -13901,7 +14351,7 @@ class LocalParticipant extends Participant {
|
|
13901
14351
|
return changed;
|
13902
14352
|
}
|
13903
14353
|
|
13904
|
-
async setTrackEnabled(source, enabled, options) {
|
14354
|
+
async setTrackEnabled(source, enabled, options, publishOptions) {
|
13905
14355
|
var _a, _b;
|
13906
14356
|
|
13907
14357
|
livekitLogger.debug('setTrackEnabled', {
|
@@ -13951,7 +14401,7 @@ class LocalParticipant extends Participant {
|
|
13951
14401
|
const publishPromises = [];
|
13952
14402
|
|
13953
14403
|
for (const localTrack of localTracks) {
|
13954
|
-
publishPromises.push(this.publishTrack(localTrack));
|
14404
|
+
publishPromises.push(this.publishTrack(localTrack, publishOptions));
|
13955
14405
|
}
|
13956
14406
|
|
13957
14407
|
const publishedTracks = await Promise.all(publishPromises); // for screen share publications including audio, this will only return the screen share publication, not the screen share audio one
|
@@ -14131,7 +14581,7 @@ class LocalParticipant extends Participant {
|
|
14131
14581
|
|
14132
14582
|
|
14133
14583
|
async publishTrack(track, options) {
|
14134
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
14584
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
14135
14585
|
|
14136
14586
|
const opts = _objectSpread2(_objectSpread2({}, (_a = this.roomOptions) === null || _a === void 0 ? void 0 : _a.publishDefaults), options); // convert raw media track into audio or video track
|
14137
14587
|
|
@@ -14275,6 +14725,10 @@ class LocalParticipant extends Participant {
|
|
14275
14725
|
track.codec = opts.videoCodec;
|
14276
14726
|
}
|
14277
14727
|
|
14728
|
+
if (track.codec === 'av1' && encodings && ((_h = encodings[0]) === null || _h === void 0 ? void 0 : _h.maxBitrate)) {
|
14729
|
+
this.engine.publisher.setTrackCodecBitrate(req.cid, track.codec, encodings[0].maxBitrate / 1000);
|
14730
|
+
}
|
14731
|
+
|
14278
14732
|
this.engine.negotiate(); // store RTPSender
|
14279
14733
|
|
14280
14734
|
track.sender = transceiver.sender;
|
@@ -14296,7 +14750,7 @@ class LocalParticipant extends Participant {
|
|
14296
14750
|
|
14297
14751
|
|
14298
14752
|
async publishAdditionalCodecForTrack(track, videoCodec, options) {
|
14299
|
-
var _a, _b, _c, _d, _e;
|
14753
|
+
var _a, _b, _c, _d, _e, _f;
|
14300
14754
|
|
14301
14755
|
const opts = _objectSpread2(_objectSpread2({}, (_a = this.roomOptions) === null || _a === void 0 ? void 0 : _a.publishDefaults), options); // clear scalabilityMode setting for backup codec
|
14302
14756
|
|
@@ -14364,6 +14818,11 @@ class LocalParticipant extends Participant {
|
|
14364
14818
|
const transceiver = await this.engine.publisher.pc.addTransceiver(simulcastTrack.mediaStreamTrack, transceiverInit);
|
14365
14819
|
this.setPreferredCodec(transceiver, track.kind, opts.videoCodec);
|
14366
14820
|
track.setSimulcastTrackSender(opts.videoCodec, transceiver.sender);
|
14821
|
+
|
14822
|
+
if (videoCodec === 'av1' && ((_f = encodings[0]) === null || _f === void 0 ? void 0 : _f.maxBitrate)) {
|
14823
|
+
this.engine.publisher.setTrackCodecBitrate(req.cid, videoCodec, encodings[0].maxBitrate / 1000);
|
14824
|
+
}
|
14825
|
+
|
14367
14826
|
this.engine.negotiate();
|
14368
14827
|
livekitLogger.debug("published ".concat(opts.videoCodec, " for track ").concat(track.sid), {
|
14369
14828
|
encodings,
|
@@ -18141,57 +18600,6 @@ adapterFactory({
|
|
18141
18600
|
window: typeof window === 'undefined' ? undefined : window
|
18142
18601
|
});
|
18143
18602
|
|
18144
|
-
class Queue {
|
18145
|
-
constructor() {
|
18146
|
-
this.queue = [];
|
18147
|
-
this.running = false;
|
18148
|
-
}
|
18149
|
-
|
18150
|
-
enqueue(cb) {
|
18151
|
-
livekitLogger.trace('enqueuing request to fire later');
|
18152
|
-
this.queue.push(cb);
|
18153
|
-
}
|
18154
|
-
|
18155
|
-
dequeue() {
|
18156
|
-
const evt = this.queue.shift();
|
18157
|
-
if (evt) evt();
|
18158
|
-
livekitLogger.trace('firing request from queue');
|
18159
|
-
}
|
18160
|
-
|
18161
|
-
async run() {
|
18162
|
-
if (this.running) return;
|
18163
|
-
livekitLogger.trace('start queue');
|
18164
|
-
this.running = true;
|
18165
|
-
|
18166
|
-
while (this.running && this.queue.length > 0) {
|
18167
|
-
this.dequeue();
|
18168
|
-
}
|
18169
|
-
|
18170
|
-
this.running = false;
|
18171
|
-
livekitLogger.trace('queue finished');
|
18172
|
-
}
|
18173
|
-
|
18174
|
-
pause() {
|
18175
|
-
livekitLogger.trace('pausing queue');
|
18176
|
-
this.running = false;
|
18177
|
-
}
|
18178
|
-
|
18179
|
-
reset() {
|
18180
|
-
livekitLogger.trace('resetting queue');
|
18181
|
-
this.running = false;
|
18182
|
-
this.queue = [];
|
18183
|
-
}
|
18184
|
-
|
18185
|
-
isRunning() {
|
18186
|
-
return this.running;
|
18187
|
-
}
|
18188
|
-
|
18189
|
-
isEmpty() {
|
18190
|
-
return this.queue.length === 0;
|
18191
|
-
}
|
18192
|
-
|
18193
|
-
}
|
18194
|
-
|
18195
18603
|
const passThroughQueueSignals = ['syncState', 'trickle', 'offer', 'answer', 'simulate', 'leave'];
|
18196
18604
|
|
18197
18605
|
function canPassThroughQueue(req) {
|
@@ -18212,6 +18620,7 @@ class SignalClient {
|
|
18212
18620
|
this.isReconnecting = false;
|
18213
18621
|
this.useJSON = useJSON;
|
18214
18622
|
this.requestQueue = new Queue();
|
18623
|
+
this.queuedRequests = [];
|
18215
18624
|
}
|
18216
18625
|
|
18217
18626
|
async join(url, token, opts, abortSignal) {
|
@@ -18439,14 +18848,20 @@ class SignalClient {
|
|
18439
18848
|
|
18440
18849
|
async sendRequest(req) {
|
18441
18850
|
let fromQueue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
18442
|
-
// capture all requests while reconnecting and put them in a queue
|
18443
|
-
// keep order by queueing up new events as long as the queue is not empty
|
18851
|
+
// capture all requests while reconnecting and put them in a queue
|
18444
18852
|
// unless the request originates from the queue, then don't enqueue again
|
18445
18853
|
const canQueue = !fromQueue && !canPassThroughQueue(req);
|
18446
18854
|
|
18447
|
-
if (canQueue &&
|
18448
|
-
this.
|
18855
|
+
if (canQueue && this.isReconnecting) {
|
18856
|
+
this.queuedRequests.push(async () => {
|
18857
|
+
await this.sendRequest(req, true);
|
18858
|
+
});
|
18449
18859
|
return;
|
18860
|
+
} // make sure previously queued requests are being sent first
|
18861
|
+
|
18862
|
+
|
18863
|
+
if (!fromQueue) {
|
18864
|
+
await this.requestQueue.flush();
|
18450
18865
|
}
|
18451
18866
|
|
18452
18867
|
if (this.signalLatency) {
|
@@ -18544,8 +18959,15 @@ class SignalClient {
|
|
18544
18959
|
}
|
18545
18960
|
|
18546
18961
|
setReconnected() {
|
18962
|
+
while (this.queuedRequests.length > 0) {
|
18963
|
+
const req = this.queuedRequests.shift();
|
18964
|
+
|
18965
|
+
if (req) {
|
18966
|
+
this.requestQueue.run(req);
|
18967
|
+
}
|
18968
|
+
}
|
18969
|
+
|
18547
18970
|
this.isReconnecting = false;
|
18548
|
-
this.requestQueue.run();
|
18549
18971
|
}
|
18550
18972
|
|
18551
18973
|
handleWSError(ev) {
|
@@ -18634,7 +19056,8 @@ class PCTransport {
|
|
18634
19056
|
constructor(config) {
|
18635
19057
|
this.pendingCandidates = [];
|
18636
19058
|
this.restartingIce = false;
|
18637
|
-
this.renegotiate = false;
|
19059
|
+
this.renegotiate = false;
|
19060
|
+
this.trackBitrates = []; // debounced negotiate interface
|
18638
19061
|
|
18639
19062
|
this.negotiate = r(() => {
|
18640
19063
|
this.createAndSendOffer();
|
@@ -18698,11 +19121,38 @@ class PCTransport {
|
|
18698
19121
|
|
18699
19122
|
|
18700
19123
|
livekitLogger.debug('starting to negotiate');
|
18701
|
-
const offer = await this.pc.createOffer(options);
|
19124
|
+
const offer = await this.pc.createOffer(options); // mung sdp for codec bitrate setting that can't apply by sendEncoding
|
19125
|
+
|
19126
|
+
this.trackBitrates.forEach(trackbr => {
|
19127
|
+
var _a;
|
19128
|
+
|
19129
|
+
let sdp = (_a = offer.sdp) !== null && _a !== void 0 ? _a : '';
|
19130
|
+
const sidIndex = sdp.search(new RegExp("msid.* ".concat(trackbr.sid)));
|
19131
|
+
|
19132
|
+
if (sidIndex < 0) {
|
19133
|
+
return;
|
19134
|
+
}
|
19135
|
+
|
19136
|
+
const mlineStart = sdp.substring(0, sidIndex).lastIndexOf('m=');
|
19137
|
+
const mlineEnd = sdp.indexOf('m=', sidIndex);
|
19138
|
+
const mediaSection = sdp.substring(mlineStart, mlineEnd);
|
19139
|
+
const mungedMediaSection = mediaSection.replace(new RegExp("a=rtpmap:(\\d+) ".concat(trackbr.codec, "/\\d+"), 'i'), "$&\r\na=fmtp:$1 x-google-max-bitrate=".concat(trackbr.maxbr));
|
19140
|
+
sdp = sdp.substring(0, mlineStart) + mungedMediaSection + sdp.substring(mlineEnd);
|
19141
|
+
offer.sdp = sdp;
|
19142
|
+
});
|
19143
|
+
this.trackBitrates = [];
|
18702
19144
|
await this.pc.setLocalDescription(offer);
|
18703
19145
|
this.onOffer(offer);
|
18704
19146
|
}
|
18705
19147
|
|
19148
|
+
setTrackCodecBitrate(sid, codec, maxbr) {
|
19149
|
+
this.trackBitrates.push({
|
19150
|
+
sid,
|
19151
|
+
codec,
|
19152
|
+
maxbr
|
19153
|
+
});
|
19154
|
+
}
|
19155
|
+
|
18706
19156
|
close() {
|
18707
19157
|
this.pc.close();
|
18708
19158
|
}
|
@@ -19082,23 +19532,9 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19082
19532
|
const track = ev.stream.getTracks()[0];
|
19083
19533
|
this.emit(EngineEvent.MediaTrackAdded, track, ev.stream);
|
19084
19534
|
};
|
19085
|
-
}
|
19086
|
-
|
19087
|
-
|
19088
|
-
this.lossyDC = this.publisher.pc.createDataChannel(lossyDataChannel, {
|
19089
|
-
// will drop older packets that arrive
|
19090
|
-
ordered: true,
|
19091
|
-
maxRetransmits: 0
|
19092
|
-
});
|
19093
|
-
this.reliableDC = this.publisher.pc.createDataChannel(reliableDataChannel, {
|
19094
|
-
ordered: true
|
19095
|
-
}); // also handle messages over the pub channel, for backwards compatibility
|
19096
|
-
|
19097
|
-
this.lossyDC.onmessage = this.handleDataMessage;
|
19098
|
-
this.reliableDC.onmessage = this.handleDataMessage; // handle datachannel errors
|
19535
|
+
}
|
19099
19536
|
|
19100
|
-
this.
|
19101
|
-
this.reliableDC.onerror = this.handleDataError; // configure signaling client
|
19537
|
+
this.createDataChannels(); // configure signaling client
|
19102
19538
|
|
19103
19539
|
this.client.onAnswer = async sd => {
|
19104
19540
|
if (!this.publisher) {
|
@@ -19173,7 +19609,7 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19173
19609
|
this.fullReconnectOnNext = true;
|
19174
19610
|
this.primaryPC = undefined;
|
19175
19611
|
} else {
|
19176
|
-
this.emit(EngineEvent.Disconnected);
|
19612
|
+
this.emit(EngineEvent.Disconnected, leave === null || leave === void 0 ? void 0 : leave.reason);
|
19177
19613
|
this.close();
|
19178
19614
|
}
|
19179
19615
|
|
@@ -19183,6 +19619,39 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19183
19619
|
};
|
19184
19620
|
}
|
19185
19621
|
|
19622
|
+
createDataChannels() {
|
19623
|
+
if (!this.publisher) {
|
19624
|
+
return;
|
19625
|
+
} // clear old data channel callbacks if recreate
|
19626
|
+
|
19627
|
+
|
19628
|
+
if (this.lossyDC) {
|
19629
|
+
this.lossyDC.onmessage = null;
|
19630
|
+
this.lossyDC.onerror = null;
|
19631
|
+
}
|
19632
|
+
|
19633
|
+
if (this.reliableDC) {
|
19634
|
+
this.reliableDC.onmessage = null;
|
19635
|
+
this.reliableDC.onerror = null;
|
19636
|
+
} // create data channels
|
19637
|
+
|
19638
|
+
|
19639
|
+
this.lossyDC = this.publisher.pc.createDataChannel(lossyDataChannel, {
|
19640
|
+
// will drop older packets that arrive
|
19641
|
+
ordered: true,
|
19642
|
+
maxRetransmits: 0
|
19643
|
+
});
|
19644
|
+
this.reliableDC = this.publisher.pc.createDataChannel(reliableDataChannel, {
|
19645
|
+
ordered: true
|
19646
|
+
}); // also handle messages over the pub channel, for backwards compatibility
|
19647
|
+
|
19648
|
+
this.lossyDC.onmessage = this.handleDataMessage;
|
19649
|
+
this.reliableDC.onmessage = this.handleDataMessage; // handle datachannel errors
|
19650
|
+
|
19651
|
+
this.lossyDC.onerror = this.handleDataError;
|
19652
|
+
this.reliableDC.onerror = this.handleDataError;
|
19653
|
+
}
|
19654
|
+
|
19186
19655
|
async restartConnection() {
|
19187
19656
|
var _a, _b;
|
19188
19657
|
|
@@ -19222,6 +19691,8 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19222
19691
|
}
|
19223
19692
|
|
19224
19693
|
async resumeConnection() {
|
19694
|
+
var _a;
|
19695
|
+
|
19225
19696
|
if (!this.url || !this.token) {
|
19226
19697
|
// permanent failure, don't attempt reconnection
|
19227
19698
|
throw new UnexpectedConnectionState('could not reconnect, url or token not saved');
|
@@ -19254,7 +19725,13 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19254
19725
|
}
|
19255
19726
|
|
19256
19727
|
await this.waitForPCConnected();
|
19257
|
-
this.client.setReconnected(); //
|
19728
|
+
this.client.setReconnected(); // recreate publish datachannel if it's id is null
|
19729
|
+
// (for safari https://bugs.webkit.org/show_bug.cgi?id=184688)
|
19730
|
+
|
19731
|
+
if (((_a = this.reliableDC) === null || _a === void 0 ? void 0 : _a.readyState) === 'open' && this.reliableDC.id === null) {
|
19732
|
+
this.createDataChannels();
|
19733
|
+
} // resume success
|
19734
|
+
|
19258
19735
|
|
19259
19736
|
this.emit(EngineEvent.Resumed);
|
19260
19737
|
}
|
@@ -19624,11 +20101,15 @@ class Room extends events.exports.EventEmitter {
|
|
19624
20101
|
*/
|
19625
20102
|
|
19626
20103
|
|
19627
|
-
this.disconnect = function () {
|
20104
|
+
this.disconnect = async function () {
|
19628
20105
|
let stopTracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
19629
20106
|
|
19630
20107
|
var _a, _b;
|
19631
20108
|
|
20109
|
+
livekitLogger.info('disconnect from room', {
|
20110
|
+
identity: _this.localParticipant.identity
|
20111
|
+
});
|
20112
|
+
|
19632
20113
|
if (_this.state === ConnectionState.Connecting) {
|
19633
20114
|
// try aborting pending connection attempt
|
19634
20115
|
livekitLogger.warn('abort connection attempt');
|
@@ -19638,7 +20119,7 @@ class Room extends events.exports.EventEmitter {
|
|
19638
20119
|
|
19639
20120
|
|
19640
20121
|
if ((_b = _this.engine) === null || _b === void 0 ? void 0 : _b.client.isConnected) {
|
19641
|
-
_this.engine.client.sendLeave();
|
20122
|
+
await _this.engine.client.sendLeave();
|
19642
20123
|
} // close engine (also closes client)
|
19643
20124
|
|
19644
20125
|
|
@@ -19646,7 +20127,7 @@ class Room extends events.exports.EventEmitter {
|
|
19646
20127
|
_this.engine.close();
|
19647
20128
|
}
|
19648
20129
|
|
19649
|
-
_this.handleDisconnect(stopTracks);
|
20130
|
+
_this.handleDisconnect(stopTracks, DisconnectReason.CLIENT_INITIATED);
|
19650
20131
|
/* @ts-ignore */
|
19651
20132
|
|
19652
20133
|
|
@@ -19843,9 +20324,7 @@ class Room extends events.exports.EventEmitter {
|
|
19843
20324
|
return;
|
19844
20325
|
}
|
19845
20326
|
|
19846
|
-
pub.
|
19847
|
-
participant.emit(ParticipantEvent.TrackSubscriptionPermissionChanged, pub, pub.subscriptionStatus);
|
19848
|
-
this.emitWhenConnected(RoomEvent.TrackSubscriptionPermissionChanged, pub, pub.subscriptionStatus, participant);
|
20327
|
+
pub.setAllowed(update.allowed);
|
19849
20328
|
};
|
19850
20329
|
|
19851
20330
|
this.handleDataPacket = (userPacket, kind) => {
|
@@ -19925,8 +20404,8 @@ class Room extends events.exports.EventEmitter {
|
|
19925
20404
|
this.engine.client.onConnectionQuality = this.handleConnectionQualityUpdate;
|
19926
20405
|
this.engine.on(EngineEvent.MediaTrackAdded, (mediaTrack, stream, receiver) => {
|
19927
20406
|
this.onTrackAdded(mediaTrack, stream, receiver);
|
19928
|
-
}).on(EngineEvent.Disconnected,
|
19929
|
-
this.handleDisconnect(this.options.stopLocalTrackOnUnpublish);
|
20407
|
+
}).on(EngineEvent.Disconnected, reason => {
|
20408
|
+
this.handleDisconnect(this.options.stopLocalTrackOnUnpublish, reason);
|
19930
20409
|
}).on(EngineEvent.ActiveSpeakersUpdate, this.handleActiveSpeakersUpdate).on(EngineEvent.DataPacketReceived, this.handleDataPacket).on(EngineEvent.Resuming, () => {
|
19931
20410
|
if (this.setAndEmitConnectionState(ConnectionState.Reconnecting)) {
|
19932
20411
|
this.emit(RoomEvent.Reconnecting);
|
@@ -20146,15 +20625,16 @@ class Room extends events.exports.EventEmitter {
|
|
20146
20625
|
// at that time, ICE connectivity has not been established so the track is not
|
20147
20626
|
// technically subscribed.
|
20148
20627
|
// We'll defer these events until when the room is connected or eventually disconnected.
|
20149
|
-
if (this.
|
20150
|
-
|
20628
|
+
if (this.connectFuture) {
|
20629
|
+
this.connectFuture.promise.then(() => {
|
20151
20630
|
this.onTrackAdded(mediaTrack, stream, receiver);
|
20152
|
-
}
|
20631
|
+
});
|
20153
20632
|
return;
|
20154
20633
|
}
|
20155
20634
|
|
20156
20635
|
if (this.state === ConnectionState.Disconnected) {
|
20157
20636
|
livekitLogger.warn('skipping incoming track after Room disconnected');
|
20637
|
+
return;
|
20158
20638
|
}
|
20159
20639
|
|
20160
20640
|
const parts = unpackStreamId(stream.id);
|
@@ -20183,9 +20663,14 @@ class Room extends events.exports.EventEmitter {
|
|
20183
20663
|
|
20184
20664
|
handleDisconnect() {
|
20185
20665
|
let shouldStopTracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
20666
|
+
let reason = arguments.length > 1 ? arguments[1] : undefined;
|
20186
20667
|
|
20187
20668
|
var _a;
|
20188
20669
|
|
20670
|
+
if (this.state === ConnectionState.Disconnected) {
|
20671
|
+
return;
|
20672
|
+
}
|
20673
|
+
|
20189
20674
|
this.participants.forEach(p => {
|
20190
20675
|
p.tracks.forEach(pub => {
|
20191
20676
|
p.unpublishTrack(pub.trackSid);
|
@@ -20203,6 +20688,9 @@ class Room extends events.exports.EventEmitter {
|
|
20203
20688
|
(_b = pub.track) === null || _b === void 0 ? void 0 : _b.stop();
|
20204
20689
|
}
|
20205
20690
|
});
|
20691
|
+
this.localParticipant.tracks.clear();
|
20692
|
+
this.localParticipant.videoTracks.clear();
|
20693
|
+
this.localParticipant.audioTracks.clear();
|
20206
20694
|
this.participants.clear();
|
20207
20695
|
this.activeSpeakers = [];
|
20208
20696
|
|
@@ -20217,7 +20705,7 @@ class Room extends events.exports.EventEmitter {
|
|
20217
20705
|
}
|
20218
20706
|
|
20219
20707
|
this.setAndEmitConnectionState(ConnectionState.Disconnected);
|
20220
|
-
this.emit(RoomEvent.Disconnected);
|
20708
|
+
this.emit(RoomEvent.Disconnected, reason);
|
20221
20709
|
}
|
20222
20710
|
|
20223
20711
|
handleParticipantDisconnected(sid, participant) {
|
@@ -20304,6 +20792,8 @@ class Room extends events.exports.EventEmitter {
|
|
20304
20792
|
this.emitWhenConnected(RoomEvent.ConnectionQualityChanged, quality, participant);
|
20305
20793
|
}).on(ParticipantEvent.ParticipantPermissionsChanged, prevPermissions => {
|
20306
20794
|
this.emitWhenConnected(RoomEvent.ParticipantPermissionsChanged, prevPermissions, participant);
|
20795
|
+
}).on(ParticipantEvent.TrackSubscriptionPermissionChanged, (pub, status) => {
|
20796
|
+
this.emitWhenConnected(RoomEvent.TrackSubscriptionPermissionChanged, pub, status, participant);
|
20307
20797
|
}); // update info at the end after callbacks have been set up
|
20308
20798
|
|
20309
20799
|
if (info) {
|
@@ -20543,5 +21033,5 @@ async function createLocalScreenTracks(options) {
|
|
20543
21033
|
return localTracks;
|
20544
21034
|
}
|
20545
21035
|
|
20546
|
-
export { AudioPresets, ConnectionError, ConnectionQuality, ConnectionState, DataPacket_Kind, EngineEvent, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalVideoTrack, LogLevel, MediaDeviceFailure, Participant, ParticipantEvent, PublishDataError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, RoomState, ScreenSharePresets, Track, TrackEvent, TrackInvalidError, TrackPublication, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, attachToElement, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, detachTrack, protocolVersion, setLogExtension, setLogLevel, version };
|
21036
|
+
export { AudioPresets, ConnectionError, ConnectionQuality, ConnectionState, DataPacket_Kind, DisconnectReason, EngineEvent, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalVideoTrack, LogLevel, MediaDeviceFailure, Participant, ParticipantEvent, PublishDataError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, RoomState, ScreenSharePresets, Track, TrackEvent, TrackInvalidError, TrackPublication, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, attachToElement, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, detachTrack, getEmptyAudioStreamTrack, getEmptyVideoStreamTrack, protocolVersion, setLogExtension, setLogLevel, version };
|
20547
21037
|
//# sourceMappingURL=livekit-client.esm.mjs.map
|