livekit-client 2.15.8 → 2.15.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/livekit-client.esm.mjs +577 -202
- 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 +31 -2
- package/dist/src/api/SignalClient.d.ts.map +1 -1
- package/dist/src/api/WebSocketStream.d.ts +29 -0
- package/dist/src/api/WebSocketStream.d.ts.map +1 -0
- package/dist/src/api/utils.d.ts +2 -0
- package/dist/src/api/utils.d.ts.map +1 -1
- package/dist/src/connectionHelper/checks/turn.d.ts.map +1 -1
- package/dist/src/connectionHelper/checks/websocket.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/options.d.ts +6 -0
- package/dist/src/options.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/PCTransportManager.d.ts +6 -4
- package/dist/src/room/PCTransportManager.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts +1 -1
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/defaults.d.ts.map +1 -1
- package/dist/src/room/token-source/utils.d.ts +1 -1
- package/dist/src/room/token-source/utils.d.ts.map +1 -1
- package/dist/src/room/utils.d.ts +6 -0
- package/dist/src/room/utils.d.ts.map +1 -1
- package/dist/ts4.2/api/SignalClient.d.ts +31 -2
- package/dist/ts4.2/api/WebSocketStream.d.ts +29 -0
- package/dist/ts4.2/api/utils.d.ts +2 -0
- package/dist/ts4.2/index.d.ts +2 -2
- package/dist/ts4.2/options.d.ts +6 -0
- package/dist/ts4.2/room/PCTransport.d.ts +1 -0
- package/dist/ts4.2/room/PCTransportManager.d.ts +6 -4
- package/dist/ts4.2/room/RTCEngine.d.ts +1 -1
- package/dist/ts4.2/room/token-source/utils.d.ts +1 -1
- package/dist/ts4.2/room/utils.d.ts +6 -0
- package/package.json +1 -1
- package/src/api/SignalClient.test.ts +688 -0
- package/src/api/SignalClient.ts +308 -161
- package/src/api/WebSocketStream.test.ts +625 -0
- package/src/api/WebSocketStream.ts +118 -0
- package/src/api/utils.ts +10 -0
- package/src/connectionHelper/checks/turn.ts +1 -0
- package/src/connectionHelper/checks/webrtc.ts +1 -1
- package/src/connectionHelper/checks/websocket.ts +1 -0
- package/src/index.ts +2 -0
- package/src/options.ts +7 -0
- package/src/room/PCTransport.ts +7 -3
- package/src/room/PCTransportManager.ts +39 -35
- package/src/room/RTCEngine.ts +54 -16
- package/src/room/Room.ts +5 -2
- package/src/room/defaults.ts +1 -0
- package/src/room/token-source/TokenSource.ts +2 -2
- package/src/room/token-source/utils.test.ts +63 -0
- package/src/room/token-source/utils.ts +10 -5
- package/src/room/utils.ts +29 -0
|
@@ -7373,6 +7373,110 @@ const TrackSubscribed = /* @__PURE__ */proto3.makeMessageType("livekit.TrackSubs
|
|
|
7373
7373
|
T: 9
|
|
7374
7374
|
/* ScalarType.STRING */
|
|
7375
7375
|
}]);
|
|
7376
|
+
const ConnectionSettings = /* @__PURE__ */proto3.makeMessageType("livekit.ConnectionSettings", () => [{
|
|
7377
|
+
no: 1,
|
|
7378
|
+
name: "auto_subscribe",
|
|
7379
|
+
kind: "scalar",
|
|
7380
|
+
T: 8
|
|
7381
|
+
/* ScalarType.BOOL */
|
|
7382
|
+
}, {
|
|
7383
|
+
no: 2,
|
|
7384
|
+
name: "adaptive_stream",
|
|
7385
|
+
kind: "scalar",
|
|
7386
|
+
T: 8
|
|
7387
|
+
/* ScalarType.BOOL */
|
|
7388
|
+
}, {
|
|
7389
|
+
no: 3,
|
|
7390
|
+
name: "subscriber_allow_pause",
|
|
7391
|
+
kind: "scalar",
|
|
7392
|
+
T: 8,
|
|
7393
|
+
opt: true
|
|
7394
|
+
}, {
|
|
7395
|
+
no: 4,
|
|
7396
|
+
name: "disable_ice_lite",
|
|
7397
|
+
kind: "scalar",
|
|
7398
|
+
T: 8
|
|
7399
|
+
/* ScalarType.BOOL */
|
|
7400
|
+
}]);
|
|
7401
|
+
const JoinRequest = /* @__PURE__ */proto3.makeMessageType("livekit.JoinRequest", () => [{
|
|
7402
|
+
no: 1,
|
|
7403
|
+
name: "client_info",
|
|
7404
|
+
kind: "message",
|
|
7405
|
+
T: ClientInfo
|
|
7406
|
+
}, {
|
|
7407
|
+
no: 2,
|
|
7408
|
+
name: "connection_settings",
|
|
7409
|
+
kind: "message",
|
|
7410
|
+
T: ConnectionSettings
|
|
7411
|
+
}, {
|
|
7412
|
+
no: 3,
|
|
7413
|
+
name: "metadata",
|
|
7414
|
+
kind: "scalar",
|
|
7415
|
+
T: 9
|
|
7416
|
+
/* ScalarType.STRING */
|
|
7417
|
+
}, {
|
|
7418
|
+
no: 4,
|
|
7419
|
+
name: "participant_attributes",
|
|
7420
|
+
kind: "map",
|
|
7421
|
+
K: 9,
|
|
7422
|
+
V: {
|
|
7423
|
+
kind: "scalar",
|
|
7424
|
+
T: 9
|
|
7425
|
+
/* ScalarType.STRING */
|
|
7426
|
+
}
|
|
7427
|
+
}, {
|
|
7428
|
+
no: 5,
|
|
7429
|
+
name: "add_track_requests",
|
|
7430
|
+
kind: "message",
|
|
7431
|
+
T: AddTrackRequest,
|
|
7432
|
+
repeated: true
|
|
7433
|
+
}, {
|
|
7434
|
+
no: 6,
|
|
7435
|
+
name: "publisher_offer",
|
|
7436
|
+
kind: "message",
|
|
7437
|
+
T: SessionDescription
|
|
7438
|
+
}, {
|
|
7439
|
+
no: 7,
|
|
7440
|
+
name: "reconnect",
|
|
7441
|
+
kind: "scalar",
|
|
7442
|
+
T: 8
|
|
7443
|
+
/* ScalarType.BOOL */
|
|
7444
|
+
}, {
|
|
7445
|
+
no: 8,
|
|
7446
|
+
name: "reconnect_reason",
|
|
7447
|
+
kind: "enum",
|
|
7448
|
+
T: proto3.getEnumType(ReconnectReason)
|
|
7449
|
+
}, {
|
|
7450
|
+
no: 9,
|
|
7451
|
+
name: "participant_sid",
|
|
7452
|
+
kind: "scalar",
|
|
7453
|
+
T: 9
|
|
7454
|
+
/* ScalarType.STRING */
|
|
7455
|
+
}, {
|
|
7456
|
+
no: 10,
|
|
7457
|
+
name: "sync_state",
|
|
7458
|
+
kind: "message",
|
|
7459
|
+
T: SyncState
|
|
7460
|
+
}]);
|
|
7461
|
+
const WrappedJoinRequest = /* @__PURE__ */proto3.makeMessageType("livekit.WrappedJoinRequest", () => [{
|
|
7462
|
+
no: 1,
|
|
7463
|
+
name: "compression",
|
|
7464
|
+
kind: "enum",
|
|
7465
|
+
T: proto3.getEnumType(WrappedJoinRequest_Compression)
|
|
7466
|
+
}, {
|
|
7467
|
+
no: 2,
|
|
7468
|
+
name: "join_request",
|
|
7469
|
+
kind: "scalar",
|
|
7470
|
+
T: 12
|
|
7471
|
+
/* ScalarType.BYTES */
|
|
7472
|
+
}]);
|
|
7473
|
+
const WrappedJoinRequest_Compression = /* @__PURE__ */proto3.makeEnum("livekit.WrappedJoinRequest.Compression", [{
|
|
7474
|
+
no: 0,
|
|
7475
|
+
name: "NONE"
|
|
7476
|
+
}, {
|
|
7477
|
+
no: 1,
|
|
7478
|
+
name: "GZIP"
|
|
7479
|
+
}]);
|
|
7376
7480
|
const MediaSectionsRequirement = /* @__PURE__ */proto3.makeMessageType("livekit.MediaSectionsRequirement", () => [{
|
|
7377
7481
|
no: 1,
|
|
7378
7482
|
name: "num_audios",
|
|
@@ -12466,7 +12570,7 @@ function getOSVersion(ua) {
|
|
|
12466
12570
|
return ua.includes('mac os') ? getMatch(/\(.+?(\d+_\d+(:?_\d+)?)/, ua, 1).replace(/_/g, '.') : undefined;
|
|
12467
12571
|
}
|
|
12468
12572
|
|
|
12469
|
-
var version$1 = "2.15.
|
|
12573
|
+
var version$1 = "2.15.9";
|
|
12470
12574
|
|
|
12471
12575
|
const version = version$1;
|
|
12472
12576
|
const protocolVersion = 16;
|
|
@@ -13078,6 +13182,14 @@ function supportsSetSinkId(elm) {
|
|
|
13078
13182
|
}
|
|
13079
13183
|
return 'setSinkId' in elm;
|
|
13080
13184
|
}
|
|
13185
|
+
/**
|
|
13186
|
+
* Checks whether or not setting an audio output via {@link Room#setActiveDevice}
|
|
13187
|
+
* is supported for the current browser.
|
|
13188
|
+
*/
|
|
13189
|
+
function supportsAudioOutputSelection() {
|
|
13190
|
+
// Note: this is method publicly exported under a user friendly name and currently only proxying `supportsSetSinkId`
|
|
13191
|
+
return supportsSetSinkId();
|
|
13192
|
+
}
|
|
13081
13193
|
function isBrowserSupported() {
|
|
13082
13194
|
if (typeof RTCPeerConnection === 'undefined') {
|
|
13083
13195
|
return false;
|
|
@@ -14405,6 +14517,102 @@ class AsyncQueue {
|
|
|
14405
14517
|
}
|
|
14406
14518
|
}
|
|
14407
14519
|
|
|
14520
|
+
/**
|
|
14521
|
+
* [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) with [Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API)
|
|
14522
|
+
*
|
|
14523
|
+
* @see https://web.dev/websocketstream/
|
|
14524
|
+
*/
|
|
14525
|
+
class WebSocketStream {
|
|
14526
|
+
get readyState() {
|
|
14527
|
+
return this.ws.readyState;
|
|
14528
|
+
}
|
|
14529
|
+
constructor(url) {
|
|
14530
|
+
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
14531
|
+
var _a, _b;
|
|
14532
|
+
if ((_a = options.signal) === null || _a === void 0 ? void 0 : _a.aborted) {
|
|
14533
|
+
throw new DOMException('This operation was aborted', 'AbortError');
|
|
14534
|
+
}
|
|
14535
|
+
this.url = url;
|
|
14536
|
+
const ws = new WebSocket(url, (_b = options.protocols) !== null && _b !== void 0 ? _b : []);
|
|
14537
|
+
ws.binaryType = 'arraybuffer';
|
|
14538
|
+
this.ws = ws;
|
|
14539
|
+
const closeWithInfo = function () {
|
|
14540
|
+
let {
|
|
14541
|
+
closeCode: code,
|
|
14542
|
+
reason
|
|
14543
|
+
} = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
14544
|
+
return ws.close(code, reason);
|
|
14545
|
+
};
|
|
14546
|
+
this.opened = new Promise((resolve, reject) => {
|
|
14547
|
+
ws.onopen = () => {
|
|
14548
|
+
resolve({
|
|
14549
|
+
readable: new ReadableStream({
|
|
14550
|
+
start(controller) {
|
|
14551
|
+
ws.onmessage = _ref => {
|
|
14552
|
+
let {
|
|
14553
|
+
data
|
|
14554
|
+
} = _ref;
|
|
14555
|
+
return controller.enqueue(data);
|
|
14556
|
+
};
|
|
14557
|
+
ws.onerror = e => controller.error(e);
|
|
14558
|
+
},
|
|
14559
|
+
cancel: closeWithInfo
|
|
14560
|
+
}),
|
|
14561
|
+
writable: new WritableStream({
|
|
14562
|
+
write(chunk) {
|
|
14563
|
+
ws.send(chunk);
|
|
14564
|
+
},
|
|
14565
|
+
abort() {
|
|
14566
|
+
ws.close();
|
|
14567
|
+
},
|
|
14568
|
+
close: closeWithInfo
|
|
14569
|
+
}),
|
|
14570
|
+
protocol: ws.protocol,
|
|
14571
|
+
extensions: ws.extensions
|
|
14572
|
+
});
|
|
14573
|
+
ws.removeEventListener('error', reject);
|
|
14574
|
+
};
|
|
14575
|
+
ws.addEventListener('error', reject);
|
|
14576
|
+
});
|
|
14577
|
+
this.closed = new Promise((resolve, reject) => {
|
|
14578
|
+
const rejectHandler = () => __awaiter(this, void 0, void 0, function* () {
|
|
14579
|
+
const closePromise = new Promise(res => {
|
|
14580
|
+
if (ws.readyState === WebSocket.CLOSED) return;else {
|
|
14581
|
+
ws.addEventListener('close', closeEv => {
|
|
14582
|
+
res(closeEv);
|
|
14583
|
+
}, {
|
|
14584
|
+
once: true
|
|
14585
|
+
});
|
|
14586
|
+
}
|
|
14587
|
+
});
|
|
14588
|
+
const reason = yield Promise.race([sleep(250), closePromise]);
|
|
14589
|
+
if (!reason) {
|
|
14590
|
+
reject(new Error('Encountered unspecified websocket error without a timely close event'));
|
|
14591
|
+
} else {
|
|
14592
|
+
// if we can infer the close reason from the close event then resolve the promise, we don't need to throw
|
|
14593
|
+
resolve(reason);
|
|
14594
|
+
}
|
|
14595
|
+
});
|
|
14596
|
+
ws.onclose = _ref2 => {
|
|
14597
|
+
let {
|
|
14598
|
+
code,
|
|
14599
|
+
reason
|
|
14600
|
+
} = _ref2;
|
|
14601
|
+
resolve({
|
|
14602
|
+
closeCode: code,
|
|
14603
|
+
reason
|
|
14604
|
+
});
|
|
14605
|
+
ws.removeEventListener('error', rejectHandler);
|
|
14606
|
+
};
|
|
14607
|
+
ws.addEventListener('error', rejectHandler);
|
|
14608
|
+
});
|
|
14609
|
+
if (options.signal) {
|
|
14610
|
+
options.signal.onabort = () => ws.close();
|
|
14611
|
+
}
|
|
14612
|
+
this.close = closeWithInfo;
|
|
14613
|
+
}
|
|
14614
|
+
}
|
|
14615
|
+
|
|
14408
14616
|
function createRtcUrl(url, searchParams) {
|
|
14409
14617
|
const urlObj = new URL(toWebsocketUrl(url));
|
|
14410
14618
|
searchParams.forEach((value, key) => {
|
|
@@ -14423,6 +14631,16 @@ function appendUrlPath(urlObj, path) {
|
|
|
14423
14631
|
urlObj.pathname = "".concat(ensureTrailingSlash(urlObj.pathname)).concat(path);
|
|
14424
14632
|
return urlObj.toString();
|
|
14425
14633
|
}
|
|
14634
|
+
function parseSignalResponse(value) {
|
|
14635
|
+
if (typeof value === 'string') {
|
|
14636
|
+
return SignalResponse.fromJson(JSON.parse(value), {
|
|
14637
|
+
ignoreUnknownFields: true
|
|
14638
|
+
});
|
|
14639
|
+
} else if (value instanceof ArrayBuffer) {
|
|
14640
|
+
return SignalResponse.fromBinary(new Uint8Array(value));
|
|
14641
|
+
}
|
|
14642
|
+
throw new Error("could not decode websocket message: ".concat(typeof value));
|
|
14643
|
+
}
|
|
14426
14644
|
|
|
14427
14645
|
const passThroughQueueSignals = ['syncState', 'trickle', 'offer', 'answer', 'simulate', 'leave'];
|
|
14428
14646
|
function canPassThroughQueue(req) {
|
|
@@ -14441,6 +14659,8 @@ var SignalConnectionState;
|
|
|
14441
14659
|
SignalConnectionState[SignalConnectionState["DISCONNECTING"] = 3] = "DISCONNECTING";
|
|
14442
14660
|
SignalConnectionState[SignalConnectionState["DISCONNECTED"] = 4] = "DISCONNECTED";
|
|
14443
14661
|
})(SignalConnectionState || (SignalConnectionState = {}));
|
|
14662
|
+
/** specifies how much time (in ms) we allow for the ws to close its connection gracefully before continuing */
|
|
14663
|
+
const MAX_WS_CLOSE_TIME = 250;
|
|
14444
14664
|
/** @internal */
|
|
14445
14665
|
class SignalClient {
|
|
14446
14666
|
get currentState() {
|
|
@@ -14478,6 +14698,7 @@ class SignalClient {
|
|
|
14478
14698
|
this.onTokenRefresh = undefined;
|
|
14479
14699
|
this.onTrickle = undefined;
|
|
14480
14700
|
this.onClose = undefined;
|
|
14701
|
+
this.onMediaSectionsRequirement = undefined;
|
|
14481
14702
|
};
|
|
14482
14703
|
this.log = getLogger((_a = loggerOptions.loggerName) !== null && _a !== void 0 ? _a : LoggerNames.Signal);
|
|
14483
14704
|
this.loggerContextCb = loggerOptions.loggerContextCb;
|
|
@@ -14520,137 +14741,140 @@ class SignalClient {
|
|
|
14520
14741
|
});
|
|
14521
14742
|
}
|
|
14522
14743
|
connect(url, token, opts, abortSignal) {
|
|
14523
|
-
this
|
|
14524
|
-
const clientInfo = getClientInfo();
|
|
14525
|
-
const params = createConnectionParams(token, clientInfo, opts);
|
|
14526
|
-
const rtcUrl = createRtcUrl(url, params);
|
|
14527
|
-
const validateUrl = createValidateUrl(rtcUrl);
|
|
14528
|
-
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
14744
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
14529
14745
|
const unlock = yield this.connectionLock.lock();
|
|
14530
|
-
|
|
14531
|
-
|
|
14532
|
-
|
|
14533
|
-
|
|
14534
|
-
|
|
14535
|
-
|
|
14536
|
-
|
|
14537
|
-
|
|
14538
|
-
|
|
14539
|
-
|
|
14540
|
-
|
|
14541
|
-
abortHandler()
|
|
14542
|
-
|
|
14543
|
-
abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.addEventListener('abort', abortHandler);
|
|
14544
|
-
const redactedUrl = new URL(rtcUrl);
|
|
14545
|
-
if (redactedUrl.searchParams.has('access_token')) {
|
|
14546
|
-
redactedUrl.searchParams.set('access_token', '<redacted>');
|
|
14547
|
-
}
|
|
14548
|
-
this.log.debug("connecting to ".concat(redactedUrl), Object.assign({
|
|
14549
|
-
reconnect: opts.reconnect,
|
|
14550
|
-
reconnectReason: opts.reconnectReason
|
|
14551
|
-
}, this.logContext));
|
|
14552
|
-
if (this.ws) {
|
|
14553
|
-
yield this.close(false);
|
|
14554
|
-
}
|
|
14555
|
-
this.ws = new WebSocket(rtcUrl);
|
|
14556
|
-
this.ws.binaryType = 'arraybuffer';
|
|
14557
|
-
this.ws.onopen = () => {
|
|
14558
|
-
clearTimeout(wsTimeout);
|
|
14559
|
-
};
|
|
14560
|
-
this.ws.onerror = ev => __awaiter(this, void 0, void 0, function* () {
|
|
14561
|
-
if (this.state !== SignalConnectionState.CONNECTED) {
|
|
14562
|
-
this.state = SignalConnectionState.DISCONNECTED;
|
|
14746
|
+
this.connectOptions = opts;
|
|
14747
|
+
const clientInfo = getClientInfo();
|
|
14748
|
+
const params = opts.singlePeerConnection ? createJoinRequestConnectionParams(token, clientInfo, opts) : createConnectionParams(token, clientInfo, opts);
|
|
14749
|
+
const rtcUrl = createRtcUrl(url, params);
|
|
14750
|
+
const validateUrl = createValidateUrl(rtcUrl);
|
|
14751
|
+
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
14752
|
+
var _a, _b;
|
|
14753
|
+
try {
|
|
14754
|
+
const timeoutAbortController = new AbortController();
|
|
14755
|
+
const signals = abortSignal ? [timeoutAbortController.signal, abortSignal] : [timeoutAbortController.signal];
|
|
14756
|
+
const combinedAbort = AbortSignal.any(signals);
|
|
14757
|
+
const abortHandler = event => __awaiter(this, void 0, void 0, function* () {
|
|
14758
|
+
this.close();
|
|
14563
14759
|
clearTimeout(wsTimeout);
|
|
14564
|
-
|
|
14565
|
-
|
|
14566
|
-
|
|
14567
|
-
|
|
14568
|
-
|
|
14569
|
-
|
|
14570
|
-
|
|
14571
|
-
|
|
14572
|
-
|
|
14573
|
-
|
|
14574
|
-
|
|
14575
|
-
|
|
14760
|
+
const target = event.currentTarget;
|
|
14761
|
+
reject(target instanceof AbortSignal ? target.reason : target);
|
|
14762
|
+
});
|
|
14763
|
+
combinedAbort.addEventListener('abort', abortHandler);
|
|
14764
|
+
const wsTimeout = setTimeout(() => {
|
|
14765
|
+
timeoutAbortController.abort(new ConnectionError('room connection has timed out (signal)', ConnectionErrorReason.ServerUnreachable));
|
|
14766
|
+
}, opts.websocketTimeout);
|
|
14767
|
+
const handleSignalConnected = (connection, firstMessage) => {
|
|
14768
|
+
this.handleSignalConnected(connection, wsTimeout, firstMessage);
|
|
14769
|
+
};
|
|
14770
|
+
const redactedUrl = new URL(rtcUrl);
|
|
14771
|
+
if (redactedUrl.searchParams.has('access_token')) {
|
|
14772
|
+
redactedUrl.searchParams.set('access_token', '<redacted>');
|
|
14576
14773
|
}
|
|
14577
|
-
|
|
14578
|
-
|
|
14579
|
-
|
|
14580
|
-
|
|
14581
|
-
|
|
14582
|
-
|
|
14583
|
-
let resp;
|
|
14584
|
-
if (typeof ev.data === 'string') {
|
|
14585
|
-
const json = JSON.parse(ev.data);
|
|
14586
|
-
resp = SignalResponse.fromJson(json, {
|
|
14587
|
-
ignoreUnknownFields: true
|
|
14588
|
-
});
|
|
14589
|
-
} else if (ev.data instanceof ArrayBuffer) {
|
|
14590
|
-
resp = SignalResponse.fromBinary(new Uint8Array(ev.data));
|
|
14591
|
-
} else {
|
|
14592
|
-
this.log.error("could not decode websocket message: ".concat(typeof ev.data), this.logContext);
|
|
14593
|
-
return;
|
|
14774
|
+
this.log.debug("connecting to ".concat(redactedUrl), Object.assign({
|
|
14775
|
+
reconnect: opts.reconnect,
|
|
14776
|
+
reconnectReason: opts.reconnectReason
|
|
14777
|
+
}, this.logContext));
|
|
14778
|
+
if (this.ws) {
|
|
14779
|
+
yield this.close(false);
|
|
14594
14780
|
}
|
|
14595
|
-
|
|
14596
|
-
|
|
14597
|
-
|
|
14598
|
-
|
|
14599
|
-
|
|
14600
|
-
|
|
14601
|
-
|
|
14602
|
-
|
|
14781
|
+
this.ws = new WebSocketStream(rtcUrl, {
|
|
14782
|
+
signal: combinedAbort
|
|
14783
|
+
});
|
|
14784
|
+
try {
|
|
14785
|
+
this.ws.closed.then(closeInfo => {
|
|
14786
|
+
if (this.isEstablishingConnection) {
|
|
14787
|
+
reject(new ConnectionError("Websocket got closed during a (re)connection attempt: ".concat(closeInfo.reason), ConnectionErrorReason.InternalError));
|
|
14788
|
+
}
|
|
14789
|
+
if (closeInfo.closeCode !== 1000) {
|
|
14790
|
+
this.log.warn("websocket closed", Object.assign(Object.assign({}, this.logContext), {
|
|
14791
|
+
reason: closeInfo.reason,
|
|
14792
|
+
code: closeInfo.closeCode,
|
|
14793
|
+
wasClean: closeInfo.closeCode === 1000,
|
|
14794
|
+
state: this.state
|
|
14795
|
+
}));
|
|
14796
|
+
}
|
|
14797
|
+
return;
|
|
14798
|
+
}).catch(reason => {
|
|
14799
|
+
if (this.isEstablishingConnection) {
|
|
14800
|
+
reject(new ConnectionError("Websocket error during a (re)connection attempt: ".concat(reason), ConnectionErrorReason.InternalError));
|
|
14801
|
+
}
|
|
14802
|
+
});
|
|
14803
|
+
const connection = yield this.ws.opened.catch(reason => __awaiter(this, void 0, void 0, function* () {
|
|
14804
|
+
if (this.state !== SignalConnectionState.CONNECTED) {
|
|
14805
|
+
this.state = SignalConnectionState.DISCONNECTED;
|
|
14806
|
+
clearTimeout(wsTimeout);
|
|
14807
|
+
const error = yield this.handleConnectionError(reason, validateUrl);
|
|
14808
|
+
reject(error);
|
|
14809
|
+
return;
|
|
14810
|
+
}
|
|
14811
|
+
// other errors, handle
|
|
14812
|
+
this.handleWSError(reason);
|
|
14813
|
+
reject(reason);
|
|
14814
|
+
return;
|
|
14815
|
+
}));
|
|
14816
|
+
clearTimeout(wsTimeout);
|
|
14817
|
+
if (!connection) {
|
|
14818
|
+
return;
|
|
14819
|
+
}
|
|
14820
|
+
const signalReader = connection.readable.getReader();
|
|
14821
|
+
const firstMessage = yield signalReader.read();
|
|
14822
|
+
signalReader.releaseLock();
|
|
14823
|
+
if (!firstMessage.value) {
|
|
14824
|
+
throw new ConnectionError('no message received as first message', ConnectionErrorReason.InternalError);
|
|
14825
|
+
}
|
|
14826
|
+
const firstSignalResponse = parseSignalResponse(firstMessage.value);
|
|
14827
|
+
// Validate the first message
|
|
14828
|
+
const validation = this.validateFirstMessage(firstSignalResponse, (_a = opts.reconnect) !== null && _a !== void 0 ? _a : false);
|
|
14829
|
+
if (!validation.isValid) {
|
|
14830
|
+
reject(validation.error);
|
|
14831
|
+
return;
|
|
14832
|
+
}
|
|
14833
|
+
// Handle join response - set up ping configuration
|
|
14834
|
+
if (((_b = firstSignalResponse.message) === null || _b === void 0 ? void 0 : _b.case) === 'join') {
|
|
14835
|
+
this.pingTimeoutDuration = firstSignalResponse.message.value.pingTimeout;
|
|
14836
|
+
this.pingIntervalDuration = firstSignalResponse.message.value.pingInterval;
|
|
14603
14837
|
if (this.pingTimeoutDuration && this.pingTimeoutDuration > 0) {
|
|
14604
14838
|
this.log.debug('ping config', Object.assign(Object.assign({}, this.logContext), {
|
|
14605
14839
|
timeout: this.pingTimeoutDuration,
|
|
14606
14840
|
interval: this.pingIntervalDuration
|
|
14607
14841
|
}));
|
|
14608
|
-
this.startPingInterval();
|
|
14609
14842
|
}
|
|
14610
|
-
resolve(resp.message.value);
|
|
14611
|
-
} else if (this.state === SignalConnectionState.RECONNECTING && resp.message.case !== 'leave') {
|
|
14612
|
-
// in reconnecting, any message received means signal reconnected
|
|
14613
|
-
this.state = SignalConnectionState.CONNECTED;
|
|
14614
|
-
abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.removeEventListener('abort', abortHandler);
|
|
14615
|
-
this.startPingInterval();
|
|
14616
|
-
if (((_b = resp.message) === null || _b === void 0 ? void 0 : _b.case) === 'reconnect') {
|
|
14617
|
-
resolve(resp.message.value);
|
|
14618
|
-
} else {
|
|
14619
|
-
this.log.debug('declaring signal reconnected without reconnect response received', this.logContext);
|
|
14620
|
-
resolve(undefined);
|
|
14621
|
-
shouldProcessMessage = true;
|
|
14622
|
-
}
|
|
14623
|
-
} else if (this.isEstablishingConnection && resp.message.case === 'leave') {
|
|
14624
|
-
reject(new ConnectionError('Received leave request while trying to (re)connect', ConnectionErrorReason.LeaveRequest, undefined, resp.message.value.reason));
|
|
14625
|
-
} else if (!opts.reconnect) {
|
|
14626
|
-
// non-reconnect case, should receive join response first
|
|
14627
|
-
reject(new ConnectionError("did not receive join response, got ".concat((_c = resp.message) === null || _c === void 0 ? void 0 : _c.case, " instead"), ConnectionErrorReason.InternalError));
|
|
14628
|
-
}
|
|
14629
|
-
if (!shouldProcessMessage) {
|
|
14630
|
-
return;
|
|
14631
14843
|
}
|
|
14844
|
+
// Handle successful connection
|
|
14845
|
+
const firstMessageToProcess = validation.shouldProcessFirstMessage ? firstSignalResponse : undefined;
|
|
14846
|
+
handleSignalConnected(connection, firstMessageToProcess);
|
|
14847
|
+
resolve(validation.response);
|
|
14848
|
+
} catch (e) {
|
|
14849
|
+
clearTimeout(wsTimeout);
|
|
14850
|
+
reject(e);
|
|
14632
14851
|
}
|
|
14633
|
-
|
|
14634
|
-
|
|
14635
|
-
|
|
14636
|
-
|
|
14637
|
-
|
|
14638
|
-
|
|
14639
|
-
|
|
14640
|
-
|
|
14641
|
-
|
|
14642
|
-
|
|
14643
|
-
reason: ev.reason,
|
|
14644
|
-
code: ev.code,
|
|
14645
|
-
wasClean: ev.wasClean,
|
|
14646
|
-
state: this.state
|
|
14647
|
-
}));
|
|
14648
|
-
this.handleOnClose(ev.reason);
|
|
14649
|
-
};
|
|
14650
|
-
} finally {
|
|
14651
|
-
unlock();
|
|
14852
|
+
} finally {
|
|
14853
|
+
unlock();
|
|
14854
|
+
}
|
|
14855
|
+
}));
|
|
14856
|
+
});
|
|
14857
|
+
}
|
|
14858
|
+
startReadingLoop(signalReader, firstMessage) {
|
|
14859
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
14860
|
+
if (firstMessage) {
|
|
14861
|
+
this.handleSignalResponse(firstMessage);
|
|
14652
14862
|
}
|
|
14653
|
-
|
|
14863
|
+
while (true) {
|
|
14864
|
+
if (this.signalLatency) {
|
|
14865
|
+
yield sleep(this.signalLatency);
|
|
14866
|
+
}
|
|
14867
|
+
const {
|
|
14868
|
+
done,
|
|
14869
|
+
value
|
|
14870
|
+
} = yield signalReader.read();
|
|
14871
|
+
if (done) {
|
|
14872
|
+
break;
|
|
14873
|
+
}
|
|
14874
|
+
const resp = parseSignalResponse(value);
|
|
14875
|
+
this.handleSignalResponse(resp);
|
|
14876
|
+
}
|
|
14877
|
+
});
|
|
14654
14878
|
}
|
|
14655
14879
|
close() {
|
|
14656
14880
|
return __awaiter(this, arguments, void 0, function () {
|
|
@@ -14664,26 +14888,20 @@ class SignalClient {
|
|
|
14664
14888
|
_this.state = SignalConnectionState.DISCONNECTING;
|
|
14665
14889
|
}
|
|
14666
14890
|
if (_this.ws) {
|
|
14667
|
-
_this.ws.
|
|
14668
|
-
|
|
14669
|
-
|
|
14670
|
-
// calling `ws.close()` only starts the closing handshake (CLOSING state), prefer to wait until state is actually CLOSED
|
|
14671
|
-
const closePromise = new Promise(resolve => {
|
|
14672
|
-
if (_this.ws) {
|
|
14673
|
-
_this.ws.onclose = () => {
|
|
14674
|
-
resolve();
|
|
14675
|
-
};
|
|
14676
|
-
} else {
|
|
14677
|
-
resolve();
|
|
14678
|
-
}
|
|
14891
|
+
_this.ws.close({
|
|
14892
|
+
closeCode: 1000,
|
|
14893
|
+
reason: 'Close method called on signal client'
|
|
14679
14894
|
});
|
|
14680
|
-
|
|
14681
|
-
|
|
14682
|
-
// 250ms grace period for ws to close gracefully
|
|
14683
|
-
yield Promise.race([closePromise, sleep(250)]);
|
|
14684
|
-
}
|
|
14895
|
+
// calling `ws.close()` only starts the closing handshake (CLOSING state), prefer to wait until state is actually CLOSED
|
|
14896
|
+
const closePromise = _this.ws.closed;
|
|
14685
14897
|
_this.ws = undefined;
|
|
14898
|
+
_this.streamWriter = undefined;
|
|
14899
|
+
yield Promise.race([closePromise, sleep(MAX_WS_CLOSE_TIME)]);
|
|
14686
14900
|
}
|
|
14901
|
+
} catch (e) {
|
|
14902
|
+
_this.log.debug('websocket error while closing', Object.assign(Object.assign({}, _this.logContext), {
|
|
14903
|
+
error: e
|
|
14904
|
+
}));
|
|
14687
14905
|
} finally {
|
|
14688
14906
|
if (updateState) {
|
|
14689
14907
|
_this.state = SignalConnectionState.DISCONNECTED;
|
|
@@ -14860,7 +15078,7 @@ class SignalClient {
|
|
|
14860
15078
|
_this3.log.debug("skipping signal request (type: ".concat(message.case, ") - SignalClient disconnected"));
|
|
14861
15079
|
return;
|
|
14862
15080
|
}
|
|
14863
|
-
if (!_this3.
|
|
15081
|
+
if (!_this3.streamWriter) {
|
|
14864
15082
|
_this3.log.error("cannot send signal request before connected, type: ".concat(message === null || message === void 0 ? void 0 : message.case), _this3.logContext);
|
|
14865
15083
|
return;
|
|
14866
15084
|
}
|
|
@@ -14869,9 +15087,9 @@ class SignalClient {
|
|
|
14869
15087
|
});
|
|
14870
15088
|
try {
|
|
14871
15089
|
if (_this3.useJSON) {
|
|
14872
|
-
_this3.
|
|
15090
|
+
yield _this3.streamWriter.write(req.toJsonString());
|
|
14873
15091
|
} else {
|
|
14874
|
-
_this3.
|
|
15092
|
+
yield _this3.streamWriter.write(req.toBinary());
|
|
14875
15093
|
}
|
|
14876
15094
|
} catch (e) {
|
|
14877
15095
|
_this3.log.error('error sending signal message', Object.assign(Object.assign({}, _this3.logContext), {
|
|
@@ -14975,6 +15193,10 @@ class SignalClient {
|
|
|
14975
15193
|
if (this.onRoomMoved) {
|
|
14976
15194
|
this.onRoomMoved(msg.value);
|
|
14977
15195
|
}
|
|
15196
|
+
} else if (msg.case === 'mediaSectionsRequirement') {
|
|
15197
|
+
if (this.onMediaSectionsRequirement) {
|
|
15198
|
+
this.onMediaSectionsRequirement(msg.value);
|
|
15199
|
+
}
|
|
14978
15200
|
} else {
|
|
14979
15201
|
this.log.debug('unsupported message', Object.assign(Object.assign({}, this.logContext), {
|
|
14980
15202
|
msgCase: msg.case
|
|
@@ -15005,9 +15227,9 @@ class SignalClient {
|
|
|
15005
15227
|
}
|
|
15006
15228
|
});
|
|
15007
15229
|
}
|
|
15008
|
-
handleWSError(
|
|
15230
|
+
handleWSError(error) {
|
|
15009
15231
|
this.log.error('websocket error', Object.assign(Object.assign({}, this.logContext), {
|
|
15010
|
-
error
|
|
15232
|
+
error
|
|
15011
15233
|
}));
|
|
15012
15234
|
}
|
|
15013
15235
|
/**
|
|
@@ -15052,6 +15274,90 @@ class SignalClient {
|
|
|
15052
15274
|
CriticalTimers.clearInterval(this.pingInterval);
|
|
15053
15275
|
}
|
|
15054
15276
|
}
|
|
15277
|
+
/**
|
|
15278
|
+
* Handles the successful connection to the signal server
|
|
15279
|
+
* @param connection The WebSocket connection
|
|
15280
|
+
* @param timeoutHandle The timeout handle to clear
|
|
15281
|
+
* @param firstMessage Optional first message to process
|
|
15282
|
+
* @internal
|
|
15283
|
+
*/
|
|
15284
|
+
handleSignalConnected(connection, timeoutHandle, firstMessage) {
|
|
15285
|
+
this.state = SignalConnectionState.CONNECTED;
|
|
15286
|
+
clearTimeout(timeoutHandle);
|
|
15287
|
+
this.startPingInterval();
|
|
15288
|
+
this.startReadingLoop(connection.readable.getReader(), firstMessage);
|
|
15289
|
+
this.streamWriter = connection.writable.getWriter();
|
|
15290
|
+
}
|
|
15291
|
+
/**
|
|
15292
|
+
* Validates the first message received from the signal server
|
|
15293
|
+
* @param firstSignalResponse The first signal response received
|
|
15294
|
+
* @param isReconnect Whether this is a reconnection attempt
|
|
15295
|
+
* @returns Validation result with response or error
|
|
15296
|
+
* @internal
|
|
15297
|
+
*/
|
|
15298
|
+
validateFirstMessage(firstSignalResponse, isReconnect) {
|
|
15299
|
+
var _a, _b, _c, _d, _e;
|
|
15300
|
+
if (((_a = firstSignalResponse.message) === null || _a === void 0 ? void 0 : _a.case) === 'join') {
|
|
15301
|
+
return {
|
|
15302
|
+
isValid: true,
|
|
15303
|
+
response: firstSignalResponse.message.value
|
|
15304
|
+
};
|
|
15305
|
+
} else if (this.state === SignalConnectionState.RECONNECTING && ((_b = firstSignalResponse.message) === null || _b === void 0 ? void 0 : _b.case) !== 'leave') {
|
|
15306
|
+
if (((_c = firstSignalResponse.message) === null || _c === void 0 ? void 0 : _c.case) === 'reconnect') {
|
|
15307
|
+
return {
|
|
15308
|
+
isValid: true,
|
|
15309
|
+
response: firstSignalResponse.message.value
|
|
15310
|
+
};
|
|
15311
|
+
} else {
|
|
15312
|
+
// in reconnecting, any message received means signal reconnected and we still need to process it
|
|
15313
|
+
this.log.debug('declaring signal reconnected without reconnect response received', this.logContext);
|
|
15314
|
+
return {
|
|
15315
|
+
isValid: true,
|
|
15316
|
+
response: undefined,
|
|
15317
|
+
shouldProcessFirstMessage: true
|
|
15318
|
+
};
|
|
15319
|
+
}
|
|
15320
|
+
} else if (this.isEstablishingConnection && ((_d = firstSignalResponse.message) === null || _d === void 0 ? void 0 : _d.case) === 'leave') {
|
|
15321
|
+
return {
|
|
15322
|
+
isValid: false,
|
|
15323
|
+
error: new ConnectionError('Received leave request while trying to (re)connect', ConnectionErrorReason.LeaveRequest, undefined, firstSignalResponse.message.value.reason)
|
|
15324
|
+
};
|
|
15325
|
+
} else if (!isReconnect) {
|
|
15326
|
+
// non-reconnect case, should receive join response first
|
|
15327
|
+
return {
|
|
15328
|
+
isValid: false,
|
|
15329
|
+
error: new ConnectionError("did not receive join response, got ".concat((_e = firstSignalResponse.message) === null || _e === void 0 ? void 0 : _e.case, " instead"), ConnectionErrorReason.InternalError)
|
|
15330
|
+
};
|
|
15331
|
+
}
|
|
15332
|
+
return {
|
|
15333
|
+
isValid: false,
|
|
15334
|
+
error: new ConnectionError('Unexpected first message', ConnectionErrorReason.InternalError)
|
|
15335
|
+
};
|
|
15336
|
+
}
|
|
15337
|
+
/**
|
|
15338
|
+
* Handles WebSocket connection errors by validating with the server
|
|
15339
|
+
* @param reason The error that occurred
|
|
15340
|
+
* @param validateUrl The URL to validate the connection with
|
|
15341
|
+
* @returns A ConnectionError with appropriate reason and status
|
|
15342
|
+
* @internal
|
|
15343
|
+
*/
|
|
15344
|
+
handleConnectionError(reason, validateUrl) {
|
|
15345
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
15346
|
+
try {
|
|
15347
|
+
const resp = yield fetch(validateUrl);
|
|
15348
|
+
if (resp.status.toFixed(0).startsWith('4')) {
|
|
15349
|
+
const msg = yield resp.text();
|
|
15350
|
+
return new ConnectionError(msg, ConnectionErrorReason.NotAllowed, resp.status);
|
|
15351
|
+
} else if (reason instanceof ConnectionError) {
|
|
15352
|
+
return reason;
|
|
15353
|
+
} else {
|
|
15354
|
+
return new ConnectionError("Encountered unknown websocket error during connection: ".concat(reason), ConnectionErrorReason.InternalError, resp.status);
|
|
15355
|
+
}
|
|
15356
|
+
} catch (e) {
|
|
15357
|
+
return e instanceof ConnectionError ? e : new ConnectionError(e instanceof Error ? e.message : 'server was not reachable', ConnectionErrorReason.ServerUnreachable);
|
|
15358
|
+
}
|
|
15359
|
+
});
|
|
15360
|
+
}
|
|
15055
15361
|
}
|
|
15056
15362
|
function fromProtoSessionDescription(sd) {
|
|
15057
15363
|
const rsd = {
|
|
@@ -15120,6 +15426,27 @@ function createConnectionParams(token, info, opts) {
|
|
|
15120
15426
|
}
|
|
15121
15427
|
return params;
|
|
15122
15428
|
}
|
|
15429
|
+
function createJoinRequestConnectionParams(token, info, opts) {
|
|
15430
|
+
const params = new URLSearchParams();
|
|
15431
|
+
params.set('access_token', token);
|
|
15432
|
+
const joinRequest = new JoinRequest({
|
|
15433
|
+
clientInfo: info,
|
|
15434
|
+
connectionSettings: new ConnectionSettings({
|
|
15435
|
+
autoSubscribe: !!opts.autoSubscribe,
|
|
15436
|
+
adaptiveStream: !!opts.adaptiveStream
|
|
15437
|
+
}),
|
|
15438
|
+
reconnect: !!opts.reconnect,
|
|
15439
|
+
participantSid: opts.sid ? opts.sid : undefined
|
|
15440
|
+
});
|
|
15441
|
+
if (opts.reconnectReason) {
|
|
15442
|
+
joinRequest.reconnectReason = opts.reconnectReason;
|
|
15443
|
+
}
|
|
15444
|
+
const wrappedJoinRequest = new WrappedJoinRequest({
|
|
15445
|
+
joinRequest: joinRequest.toBinary()
|
|
15446
|
+
});
|
|
15447
|
+
params.set('join_request', btoa(new TextDecoder('utf-8').decode(wrappedJoinRequest.toBinary())));
|
|
15448
|
+
return params;
|
|
15449
|
+
}
|
|
15123
15450
|
|
|
15124
15451
|
class DataPacketBuffer {
|
|
15125
15452
|
constructor() {
|
|
@@ -16132,7 +16459,7 @@ class PCTransport extends eventsExports.EventEmitter {
|
|
|
16132
16459
|
sdpParsed.media.forEach(media => {
|
|
16133
16460
|
const mid = getMidString(media.mid);
|
|
16134
16461
|
if (media.type === 'audio') {
|
|
16135
|
-
//
|
|
16462
|
+
// munge sdp for opus bitrate settings
|
|
16136
16463
|
this.trackBitrates.some(trackbr => {
|
|
16137
16464
|
if (!trackbr.transceiver || mid != trackbr.transceiver.mid) {
|
|
16138
16465
|
return false;
|
|
@@ -16237,7 +16564,7 @@ class PCTransport extends eventsExports.EventEmitter {
|
|
|
16237
16564
|
sdpParsed.media.forEach(media => {
|
|
16238
16565
|
ensureIPAddrMatchVersion(media);
|
|
16239
16566
|
if (media.type === 'audio') {
|
|
16240
|
-
ensureAudioNackAndStereo(media, [], []);
|
|
16567
|
+
ensureAudioNackAndStereo(media, ['all'], []);
|
|
16241
16568
|
} else if (media.type === 'video') {
|
|
16242
16569
|
this.trackBitrates.some(trackbr => {
|
|
16243
16570
|
if (!media.msid || !trackbr.cid || !media.msid.includes(trackbr.cid)) {
|
|
@@ -16313,6 +16640,9 @@ class PCTransport extends eventsExports.EventEmitter {
|
|
|
16313
16640
|
addTransceiver(mediaStreamTrack, transceiverInit) {
|
|
16314
16641
|
return this.pc.addTransceiver(mediaStreamTrack, transceiverInit);
|
|
16315
16642
|
}
|
|
16643
|
+
addTransceiverOfKind(kind, transceiverInit) {
|
|
16644
|
+
return this.pc.addTransceiver(kind, transceiverInit);
|
|
16645
|
+
}
|
|
16316
16646
|
addTrack(track) {
|
|
16317
16647
|
if (!this._pc) {
|
|
16318
16648
|
throw new UnexpectedConnectionState('PC closed, cannot add track');
|
|
@@ -16507,7 +16837,7 @@ function ensureAudioNackAndStereo(media, stereoMids, nackMids) {
|
|
|
16507
16837
|
type: 'nack'
|
|
16508
16838
|
});
|
|
16509
16839
|
}
|
|
16510
|
-
if (stereoMids.includes(mid)) {
|
|
16840
|
+
if (stereoMids.includes(mid) || stereoMids.length === 1 && stereoMids[0] === 'all') {
|
|
16511
16841
|
media.fmtp.some(fmtp => {
|
|
16512
16842
|
if (fmtp.payload === opusPayload) {
|
|
16513
16843
|
if (!fmtp.config.includes('stereo=1')) {
|
|
@@ -16607,7 +16937,8 @@ const roomOptionDefaults = {
|
|
|
16607
16937
|
stopLocalTrackOnUnpublish: true,
|
|
16608
16938
|
reconnectPolicy: new DefaultReconnectPolicy(),
|
|
16609
16939
|
disconnectOnPageLeave: true,
|
|
16610
|
-
webAudioMix: false
|
|
16940
|
+
webAudioMix: false,
|
|
16941
|
+
singlePeerConnection: false
|
|
16611
16942
|
};
|
|
16612
16943
|
const roomConnectOptionDefaults = {
|
|
16613
16944
|
autoSubscribe: true,
|
|
@@ -16635,12 +16966,12 @@ class PCTransportManager {
|
|
|
16635
16966
|
get currentState() {
|
|
16636
16967
|
return this.state;
|
|
16637
16968
|
}
|
|
16638
|
-
constructor(rtcConfig,
|
|
16969
|
+
constructor(rtcConfig, mode, loggerOptions) {
|
|
16639
16970
|
var _a;
|
|
16640
16971
|
this.peerConnectionTimeout = roomConnectOptionDefaults.peerConnectionTimeout;
|
|
16641
16972
|
this.log = livekitLogger;
|
|
16642
16973
|
this.updateState = () => {
|
|
16643
|
-
var _a;
|
|
16974
|
+
var _a, _b;
|
|
16644
16975
|
const previousState = this.state;
|
|
16645
16976
|
const connectionStates = this.requiredTransports.map(tr => tr.getConnectionState());
|
|
16646
16977
|
if (connectionStates.every(st => st === 'connected')) {
|
|
@@ -16658,35 +16989,41 @@ class PCTransportManager {
|
|
|
16658
16989
|
}
|
|
16659
16990
|
if (previousState !== this.state) {
|
|
16660
16991
|
this.log.debug("pc state change: from ".concat(PCTransportState[previousState], " to ").concat(PCTransportState[this.state]), this.logContext);
|
|
16661
|
-
(_a = this.onStateChange) === null || _a === void 0 ? void 0 : _a.call(this, this.state, this.publisher.getConnectionState(), this.subscriber.getConnectionState());
|
|
16992
|
+
(_a = this.onStateChange) === null || _a === void 0 ? void 0 : _a.call(this, this.state, this.publisher.getConnectionState(), (_b = this.subscriber) === null || _b === void 0 ? void 0 : _b.getConnectionState());
|
|
16662
16993
|
}
|
|
16663
16994
|
};
|
|
16664
16995
|
this.log = getLogger((_a = loggerOptions.loggerName) !== null && _a !== void 0 ? _a : LoggerNames.PCManager);
|
|
16665
16996
|
this.loggerOptions = loggerOptions;
|
|
16666
|
-
this.isPublisherConnectionRequired =
|
|
16667
|
-
this.isSubscriberConnectionRequired =
|
|
16997
|
+
this.isPublisherConnectionRequired = mode !== 'subscriber-primary';
|
|
16998
|
+
this.isSubscriberConnectionRequired = mode === 'subscriber-primary';
|
|
16668
16999
|
this.publisher = new PCTransport(rtcConfig, loggerOptions);
|
|
16669
|
-
|
|
17000
|
+
if (mode !== 'publisher-only') {
|
|
17001
|
+
this.subscriber = new PCTransport(rtcConfig, loggerOptions);
|
|
17002
|
+
this.subscriber.onConnectionStateChange = this.updateState;
|
|
17003
|
+
this.subscriber.onIceConnectionStateChange = this.updateState;
|
|
17004
|
+
this.subscriber.onSignalingStatechange = this.updateState;
|
|
17005
|
+
this.subscriber.onIceCandidate = candidate => {
|
|
17006
|
+
var _a;
|
|
17007
|
+
(_a = this.onIceCandidate) === null || _a === void 0 ? void 0 : _a.call(this, candidate, SignalTarget.SUBSCRIBER);
|
|
17008
|
+
};
|
|
17009
|
+
// in subscriber primary mode, server side opens sub data channels.
|
|
17010
|
+
this.subscriber.onDataChannel = ev => {
|
|
17011
|
+
var _a;
|
|
17012
|
+
(_a = this.onDataChannel) === null || _a === void 0 ? void 0 : _a.call(this, ev);
|
|
17013
|
+
};
|
|
17014
|
+
this.subscriber.onTrack = ev => {
|
|
17015
|
+
var _a;
|
|
17016
|
+
(_a = this.onTrack) === null || _a === void 0 ? void 0 : _a.call(this, ev);
|
|
17017
|
+
};
|
|
17018
|
+
}
|
|
16670
17019
|
this.publisher.onConnectionStateChange = this.updateState;
|
|
16671
|
-
this.subscriber.onConnectionStateChange = this.updateState;
|
|
16672
17020
|
this.publisher.onIceConnectionStateChange = this.updateState;
|
|
16673
|
-
this.subscriber.onIceConnectionStateChange = this.updateState;
|
|
16674
17021
|
this.publisher.onSignalingStatechange = this.updateState;
|
|
16675
|
-
this.subscriber.onSignalingStatechange = this.updateState;
|
|
16676
17022
|
this.publisher.onIceCandidate = candidate => {
|
|
16677
17023
|
var _a;
|
|
16678
17024
|
(_a = this.onIceCandidate) === null || _a === void 0 ? void 0 : _a.call(this, candidate, SignalTarget.PUBLISHER);
|
|
16679
17025
|
};
|
|
16680
|
-
this.
|
|
16681
|
-
var _a;
|
|
16682
|
-
(_a = this.onIceCandidate) === null || _a === void 0 ? void 0 : _a.call(this, candidate, SignalTarget.SUBSCRIBER);
|
|
16683
|
-
};
|
|
16684
|
-
// in subscriber primary mode, server side opens sub data channels.
|
|
16685
|
-
this.subscriber.onDataChannel = ev => {
|
|
16686
|
-
var _a;
|
|
16687
|
-
(_a = this.onDataChannel) === null || _a === void 0 ? void 0 : _a.call(this, ev);
|
|
16688
|
-
};
|
|
16689
|
-
this.subscriber.onTrack = ev => {
|
|
17026
|
+
this.publisher.onTrack = ev => {
|
|
16690
17027
|
var _a;
|
|
16691
17028
|
(_a = this.onTrack) === null || _a === void 0 ? void 0 : _a.call(this, ev);
|
|
16692
17029
|
};
|
|
@@ -16707,11 +17044,6 @@ class PCTransportManager {
|
|
|
16707
17044
|
this.isPublisherConnectionRequired = require;
|
|
16708
17045
|
this.updateState();
|
|
16709
17046
|
}
|
|
16710
|
-
requireSubscriber() {
|
|
16711
|
-
let require = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
16712
|
-
this.isSubscriberConnectionRequired = require;
|
|
16713
|
-
this.updateState();
|
|
16714
|
-
}
|
|
16715
17047
|
createAndSendPublisherOffer(options) {
|
|
16716
17048
|
return this.publisher.createAndSendOffer(options);
|
|
16717
17049
|
}
|
|
@@ -16723,6 +17055,7 @@ class PCTransportManager {
|
|
|
16723
17055
|
}
|
|
16724
17056
|
close() {
|
|
16725
17057
|
return __awaiter(this, void 0, void 0, function* () {
|
|
17058
|
+
var _a;
|
|
16726
17059
|
if (this.publisher && this.publisher.getSignallingState() !== 'closed') {
|
|
16727
17060
|
const publisher = this.publisher;
|
|
16728
17061
|
for (const sender of publisher.getSenders()) {
|
|
@@ -16738,13 +17071,15 @@ class PCTransportManager {
|
|
|
16738
17071
|
}
|
|
16739
17072
|
}
|
|
16740
17073
|
}
|
|
16741
|
-
yield Promise.all([this.publisher.close(), this.subscriber.close()]);
|
|
17074
|
+
yield Promise.all([this.publisher.close(), (_a = this.subscriber) === null || _a === void 0 ? void 0 : _a.close()]);
|
|
16742
17075
|
this.updateState();
|
|
16743
17076
|
});
|
|
16744
17077
|
}
|
|
16745
17078
|
triggerIceRestart() {
|
|
16746
17079
|
return __awaiter(this, void 0, void 0, function* () {
|
|
16747
|
-
this.subscriber
|
|
17080
|
+
if (this.subscriber) {
|
|
17081
|
+
this.subscriber.restartingIce = true;
|
|
17082
|
+
}
|
|
16748
17083
|
// only restart publisher if it's needed
|
|
16749
17084
|
if (this.needsPublisher) {
|
|
16750
17085
|
yield this.createAndSendPublisherOffer({
|
|
@@ -16755,28 +17090,30 @@ class PCTransportManager {
|
|
|
16755
17090
|
}
|
|
16756
17091
|
addIceCandidate(candidate, target) {
|
|
16757
17092
|
return __awaiter(this, void 0, void 0, function* () {
|
|
17093
|
+
var _a;
|
|
16758
17094
|
if (target === SignalTarget.PUBLISHER) {
|
|
16759
17095
|
yield this.publisher.addIceCandidate(candidate);
|
|
16760
17096
|
} else {
|
|
16761
|
-
yield this.subscriber.addIceCandidate(candidate);
|
|
17097
|
+
yield (_a = this.subscriber) === null || _a === void 0 ? void 0 : _a.addIceCandidate(candidate);
|
|
16762
17098
|
}
|
|
16763
17099
|
});
|
|
16764
17100
|
}
|
|
16765
17101
|
createSubscriberAnswerFromOffer(sd, offerId) {
|
|
16766
17102
|
return __awaiter(this, void 0, void 0, function* () {
|
|
17103
|
+
var _a, _b, _c;
|
|
16767
17104
|
this.log.debug('received server offer', Object.assign(Object.assign({}, this.logContext), {
|
|
16768
17105
|
RTCSdpType: sd.type,
|
|
16769
17106
|
sdp: sd.sdp,
|
|
16770
|
-
signalingState: this.subscriber.getSignallingState().toString()
|
|
17107
|
+
signalingState: (_a = this.subscriber) === null || _a === void 0 ? void 0 : _a.getSignallingState().toString()
|
|
16771
17108
|
}));
|
|
16772
17109
|
const unlock = yield this.remoteOfferLock.lock();
|
|
16773
17110
|
try {
|
|
16774
|
-
const success = yield this.subscriber.setRemoteDescription(sd, offerId);
|
|
17111
|
+
const success = yield (_b = this.subscriber) === null || _b === void 0 ? void 0 : _b.setRemoteDescription(sd, offerId);
|
|
16775
17112
|
if (!success) {
|
|
16776
17113
|
return undefined;
|
|
16777
17114
|
}
|
|
16778
17115
|
// answer the offer
|
|
16779
|
-
const answer = yield this.subscriber.createAndSetAnswer();
|
|
17116
|
+
const answer = yield (_c = this.subscriber) === null || _c === void 0 ? void 0 : _c.createAndSetAnswer();
|
|
16780
17117
|
return answer;
|
|
16781
17118
|
} finally {
|
|
16782
17119
|
unlock();
|
|
@@ -16784,8 +17121,9 @@ class PCTransportManager {
|
|
|
16784
17121
|
});
|
|
16785
17122
|
}
|
|
16786
17123
|
updateConfiguration(config, iceRestart) {
|
|
17124
|
+
var _a;
|
|
16787
17125
|
this.publisher.setConfiguration(config);
|
|
16788
|
-
this.subscriber.setConfiguration(config);
|
|
17126
|
+
(_a = this.subscriber) === null || _a === void 0 ? void 0 : _a.setConfiguration(config);
|
|
16789
17127
|
if (iceRestart) {
|
|
16790
17128
|
this.triggerIceRestart();
|
|
16791
17129
|
}
|
|
@@ -16835,6 +17173,9 @@ class PCTransportManager {
|
|
|
16835
17173
|
addPublisherTransceiver(track, transceiverInit) {
|
|
16836
17174
|
return this.publisher.addTransceiver(track, transceiverInit);
|
|
16837
17175
|
}
|
|
17176
|
+
addPublisherTransceiverOfKind(kind, transceiverInit) {
|
|
17177
|
+
return this.publisher.addTransceiverOfKind(kind, transceiverInit);
|
|
17178
|
+
}
|
|
16838
17179
|
addPublisherTrack(track) {
|
|
16839
17180
|
return this.publisher.addTrack(track);
|
|
16840
17181
|
}
|
|
@@ -16857,7 +17198,7 @@ class PCTransportManager {
|
|
|
16857
17198
|
if (this.isPublisherConnectionRequired) {
|
|
16858
17199
|
transports.push(this.publisher);
|
|
16859
17200
|
}
|
|
16860
|
-
if (this.isSubscriberConnectionRequired) {
|
|
17201
|
+
if (this.isSubscriberConnectionRequired && this.subscriber) {
|
|
16861
17202
|
transports.push(this.subscriber);
|
|
16862
17203
|
}
|
|
16863
17204
|
return transports;
|
|
@@ -19052,7 +19393,9 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
|
19052
19393
|
const decryptedData = yield (_c = this.e2eeManager) === null || _c === void 0 ? void 0 : _c.handleEncryptedData(dp.value.value.encryptedValue, dp.value.value.iv, dp.participantIdentity, dp.value.value.keyIndex);
|
|
19053
19394
|
const decryptedPacket = EncryptedPacketPayload.fromBinary(decryptedData.payload);
|
|
19054
19395
|
const newDp = new DataPacket({
|
|
19055
|
-
value: decryptedPacket.value
|
|
19396
|
+
value: decryptedPacket.value,
|
|
19397
|
+
participantIdentity: dp.participantIdentity,
|
|
19398
|
+
participantSid: dp.participantSid
|
|
19056
19399
|
});
|
|
19057
19400
|
if (((_d = newDp.value) === null || _d === void 0 ? void 0 : _d.case) === 'user') {
|
|
19058
19401
|
// compatibility
|
|
@@ -19367,7 +19710,7 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
|
19367
19710
|
}
|
|
19368
19711
|
this.participantSid = (_a = joinResponse.participant) === null || _a === void 0 ? void 0 : _a.sid;
|
|
19369
19712
|
const rtcConfig = this.makeRTCConfiguration(joinResponse);
|
|
19370
|
-
this.pcManager = new PCTransportManager(rtcConfig, joinResponse.subscriberPrimary, this.loggerOptions);
|
|
19713
|
+
this.pcManager = new PCTransportManager(rtcConfig, this.options.singlePeerConnection ? 'publisher-only' : joinResponse.subscriberPrimary ? 'subscriber-primary' : 'publisher-primary', this.loggerOptions);
|
|
19371
19714
|
this.emit(EngineEvent.TransportsCreated, this.pcManager.publisher, this.pcManager.subscriber);
|
|
19372
19715
|
this.pcManager.onIceCandidate = (candidate, target) => {
|
|
19373
19716
|
this.client.sendIceCandidate(candidate, target);
|
|
@@ -19403,6 +19746,9 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
|
19403
19746
|
}
|
|
19404
19747
|
});
|
|
19405
19748
|
this.pcManager.onTrack = ev => {
|
|
19749
|
+
// this fires after the underlying transceiver is stopped and potentially
|
|
19750
|
+
// peer connection closed, so do not bubble up if there are no streams
|
|
19751
|
+
if (ev.streams.length === 0) return;
|
|
19406
19752
|
this.emit(EngineEvent.MediaTrackAdded, ev.track, ev.streams[0], ev.receiver);
|
|
19407
19753
|
};
|
|
19408
19754
|
if (!supportOptionalDatachannel((_b = joinResponse.serverInfo) === null || _b === void 0 ? void 0 : _b.protocol)) {
|
|
@@ -19484,6 +19830,19 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
|
19484
19830
|
}
|
|
19485
19831
|
this.emit(EngineEvent.RoomMoved, res);
|
|
19486
19832
|
};
|
|
19833
|
+
this.client.onMediaSectionsRequirement = requirement => {
|
|
19834
|
+
var _a, _b;
|
|
19835
|
+
const transceiverInit = {
|
|
19836
|
+
direction: 'recvonly'
|
|
19837
|
+
};
|
|
19838
|
+
for (let i = 0; i < requirement.numAudios; i++) {
|
|
19839
|
+
(_a = this.pcManager) === null || _a === void 0 ? void 0 : _a.addPublisherTransceiverOfKind('audio', transceiverInit);
|
|
19840
|
+
}
|
|
19841
|
+
for (let i = 0; i < requirement.numVideos; i++) {
|
|
19842
|
+
(_b = this.pcManager) === null || _b === void 0 ? void 0 : _b.addPublisherTransceiverOfKind('video', transceiverInit);
|
|
19843
|
+
}
|
|
19844
|
+
this.negotiate();
|
|
19845
|
+
};
|
|
19487
19846
|
this.client.onClose = () => {
|
|
19488
19847
|
this.handleDisconnect('signal', ReconnectReason.RR_SIGNAL_DISCONNECTED);
|
|
19489
19848
|
};
|
|
@@ -20113,19 +20472,21 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
|
20113
20472
|
}
|
|
20114
20473
|
/** @internal */
|
|
20115
20474
|
sendSyncState(remoteTracks, localTracks) {
|
|
20116
|
-
var _a, _b;
|
|
20475
|
+
var _a, _b, _c, _d;
|
|
20117
20476
|
if (!this.pcManager) {
|
|
20118
20477
|
this.log.warn('sync state cannot be sent without peer connection setup', this.logContext);
|
|
20119
20478
|
return;
|
|
20120
20479
|
}
|
|
20121
|
-
const
|
|
20122
|
-
const
|
|
20480
|
+
const previousPublisherOffer = this.pcManager.publisher.getLocalDescription();
|
|
20481
|
+
const previousPublisherAnswer = this.pcManager.publisher.getRemoteDescription();
|
|
20482
|
+
const previousSubscriberOffer = (_a = this.pcManager.subscriber) === null || _a === void 0 ? void 0 : _a.getRemoteDescription();
|
|
20483
|
+
const previousSubscriberAnswer = (_b = this.pcManager.subscriber) === null || _b === void 0 ? void 0 : _b.getLocalDescription();
|
|
20123
20484
|
/* 1. autosubscribe on, so subscribed tracks = all tracks - unsub tracks,
|
|
20124
20485
|
in this case, we send unsub tracks, so server add all tracks to this
|
|
20125
20486
|
subscribe pc and unsub special tracks from it.
|
|
20126
20487
|
2. autosubscribe off, we send subscribed tracks.
|
|
20127
20488
|
*/
|
|
20128
|
-
const autoSubscribe = (
|
|
20489
|
+
const autoSubscribe = (_d = (_c = this.signalOpts) === null || _c === void 0 ? void 0 : _c.autoSubscribe) !== null && _d !== void 0 ? _d : true;
|
|
20129
20490
|
const trackSids = new Array();
|
|
20130
20491
|
const trackSidsDisabled = new Array();
|
|
20131
20492
|
remoteTracks.forEach(track => {
|
|
@@ -20137,13 +20498,19 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
|
20137
20498
|
}
|
|
20138
20499
|
});
|
|
20139
20500
|
this.client.sendSyncState(new SyncState({
|
|
20140
|
-
answer:
|
|
20141
|
-
sdp:
|
|
20142
|
-
type:
|
|
20501
|
+
answer: this.options.singlePeerConnection ? previousPublisherAnswer ? toProtoSessionDescription({
|
|
20502
|
+
sdp: previousPublisherAnswer.sdp,
|
|
20503
|
+
type: previousPublisherAnswer.type
|
|
20504
|
+
}) : undefined : previousSubscriberAnswer ? toProtoSessionDescription({
|
|
20505
|
+
sdp: previousSubscriberAnswer.sdp,
|
|
20506
|
+
type: previousSubscriberAnswer.type
|
|
20143
20507
|
}) : undefined,
|
|
20144
|
-
offer:
|
|
20145
|
-
sdp:
|
|
20146
|
-
type:
|
|
20508
|
+
offer: this.options.singlePeerConnection ? previousPublisherOffer ? toProtoSessionDescription({
|
|
20509
|
+
sdp: previousPublisherOffer.sdp,
|
|
20510
|
+
type: previousPublisherOffer.type
|
|
20511
|
+
}) : undefined : previousSubscriberOffer ? toProtoSessionDescription({
|
|
20512
|
+
sdp: previousSubscriberOffer.sdp,
|
|
20513
|
+
type: previousSubscriberOffer.type
|
|
20147
20514
|
}) : undefined,
|
|
20148
20515
|
subscription: new UpdateSubscription({
|
|
20149
20516
|
trackSids,
|
|
@@ -24803,7 +25170,8 @@ class Room extends eventsExports.EventEmitter {
|
|
|
24803
25170
|
adaptiveStream: typeof roomOptions.adaptiveStream === 'object' ? true : roomOptions.adaptiveStream,
|
|
24804
25171
|
maxRetries: connectOptions.maxRetries,
|
|
24805
25172
|
e2eeEnabled: !!this.e2eeManager,
|
|
24806
|
-
websocketTimeout: connectOptions.websocketTimeout
|
|
25173
|
+
websocketTimeout: connectOptions.websocketTimeout,
|
|
25174
|
+
singlePeerConnection: roomOptions.singlePeerConnection
|
|
24807
25175
|
}, abortController.signal);
|
|
24808
25176
|
let serverInfo = joinResponse.serverInfo;
|
|
24809
25177
|
if (!serverInfo) {
|
|
@@ -24940,8 +25308,9 @@ class Room extends eventsExports.EventEmitter {
|
|
|
24940
25308
|
_this2.log.info('disconnect from room', Object.assign({}, _this2.logContext));
|
|
24941
25309
|
if (_this2.state === ConnectionState.Connecting || _this2.state === ConnectionState.Reconnecting || _this2.isResuming) {
|
|
24942
25310
|
// try aborting pending connection attempt
|
|
24943
|
-
|
|
24944
|
-
(
|
|
25311
|
+
const msg = 'Abort connection attempt due to user initiated disconnect';
|
|
25312
|
+
_this2.log.warn(msg, _this2.logContext);
|
|
25313
|
+
(_a = _this2.abortController) === null || _a === void 0 ? void 0 : _a.abort(msg);
|
|
24945
25314
|
// in case the abort controller didn't manage to cancel the connection attempt, reject the connect promise explicitly
|
|
24946
25315
|
(_c = (_b = _this2.connectFuture) === null || _b === void 0 ? void 0 : _b.reject) === null || _c === void 0 ? void 0 : _c.call(_b, new ConnectionError('Client initiated disconnect', ConnectionErrorReason.Cancelled));
|
|
24947
25316
|
_this2.connectFuture = undefined;
|
|
@@ -25513,6 +25882,7 @@ class Room extends eventsExports.EventEmitter {
|
|
|
25513
25882
|
if (e2eeOptions) {
|
|
25514
25883
|
if ('e2eeManager' in e2eeOptions) {
|
|
25515
25884
|
this.e2eeManager = e2eeOptions.e2eeManager;
|
|
25885
|
+
this.e2eeManager.isDataChannelEncryptionEnabled = dcEncryptionEnabled;
|
|
25516
25886
|
} else {
|
|
25517
25887
|
this.e2eeManager = new E2EEManager(e2eeOptions, dcEncryptionEnabled);
|
|
25518
25888
|
}
|
|
@@ -27087,7 +27457,8 @@ class TURNCheck extends Checker {
|
|
|
27087
27457
|
autoSubscribe: true,
|
|
27088
27458
|
maxRetries: 0,
|
|
27089
27459
|
e2eeEnabled: false,
|
|
27090
|
-
websocketTimeout: 15000
|
|
27460
|
+
websocketTimeout: 15000,
|
|
27461
|
+
singlePeerConnection: false
|
|
27091
27462
|
});
|
|
27092
27463
|
let hasTLS = false;
|
|
27093
27464
|
let hasTURN = false;
|
|
@@ -27137,6 +27508,7 @@ class WebRTCCheck extends Checker {
|
|
|
27137
27508
|
let hasTcp = false;
|
|
27138
27509
|
let hasIpv4Udp = false;
|
|
27139
27510
|
this.room.on(RoomEvent.SignalConnected, () => {
|
|
27511
|
+
var _a;
|
|
27140
27512
|
const prevTrickle = this.room.engine.client.onTrickle;
|
|
27141
27513
|
this.room.engine.client.onTrickle = (sd, target) => {
|
|
27142
27514
|
if (sd.candidate) {
|
|
@@ -27160,7 +27532,7 @@ class WebRTCCheck extends Checker {
|
|
|
27160
27532
|
prevTrickle(sd, target);
|
|
27161
27533
|
}
|
|
27162
27534
|
};
|
|
27163
|
-
if (this.room.engine.pcManager) {
|
|
27535
|
+
if ((_a = this.room.engine.pcManager) === null || _a === void 0 ? void 0 : _a.subscriber) {
|
|
27164
27536
|
this.room.engine.pcManager.subscriber.onIceCandidateError = ev => {
|
|
27165
27537
|
if (ev instanceof RTCPeerConnectionIceErrorEvent) {
|
|
27166
27538
|
this.appendWarning("error with ICE candidate: ".concat(ev.errorCode, " ").concat(ev.errorText, " ").concat(ev.url));
|
|
@@ -27216,7 +27588,8 @@ class WebSocketCheck extends Checker {
|
|
|
27216
27588
|
autoSubscribe: true,
|
|
27217
27589
|
maxRetries: 0,
|
|
27218
27590
|
e2eeEnabled: false,
|
|
27219
|
-
websocketTimeout: 15000
|
|
27591
|
+
websocketTimeout: 15000,
|
|
27592
|
+
singlePeerConnection: false
|
|
27220
27593
|
});
|
|
27221
27594
|
this.appendMessage("Connected to server, version ".concat(joinRes.serverVersion, "."));
|
|
27222
27595
|
if (((_a = joinRes.serverInfo) === null || _a === void 0 ? void 0 : _a.edition) === ServerInfo_Edition.Cloud && ((_b = joinRes.serverInfo) === null || _b === void 0 ? void 0 : _b.region)) {
|
|
@@ -27584,15 +27957,17 @@ function decodeJwt(jwt) {
|
|
|
27584
27957
|
|
|
27585
27958
|
const ONE_SECOND_IN_MILLISECONDS = 1000;
|
|
27586
27959
|
const ONE_MINUTE_IN_MILLISECONDS = 60 * ONE_SECOND_IN_MILLISECONDS;
|
|
27587
|
-
function
|
|
27960
|
+
function isResponseTokenValid(response) {
|
|
27588
27961
|
const jwtPayload = decodeTokenPayload(response.participantToken);
|
|
27589
|
-
if (!(jwtPayload === null || jwtPayload === void 0 ? void 0 : jwtPayload.exp)) {
|
|
27962
|
+
if (!(jwtPayload === null || jwtPayload === void 0 ? void 0 : jwtPayload.nbf) || !(jwtPayload === null || jwtPayload === void 0 ? void 0 : jwtPayload.exp)) {
|
|
27590
27963
|
return true;
|
|
27591
27964
|
}
|
|
27592
|
-
const expInMilliseconds = jwtPayload.exp * ONE_SECOND_IN_MILLISECONDS;
|
|
27593
|
-
const expiresAt = new Date(expInMilliseconds - ONE_MINUTE_IN_MILLISECONDS);
|
|
27594
27965
|
const now = new Date();
|
|
27595
|
-
|
|
27966
|
+
const nbfInMilliseconds = jwtPayload.nbf * ONE_SECOND_IN_MILLISECONDS;
|
|
27967
|
+
const nbfDate = new Date(nbfInMilliseconds);
|
|
27968
|
+
const expInMilliseconds = jwtPayload.exp * ONE_SECOND_IN_MILLISECONDS;
|
|
27969
|
+
const expDate = new Date(expInMilliseconds - ONE_MINUTE_IN_MILLISECONDS);
|
|
27970
|
+
return nbfDate <= now && expDate > now;
|
|
27596
27971
|
}
|
|
27597
27972
|
function decodeTokenPayload(token) {
|
|
27598
27973
|
const payload = decodeJwt(token);
|
|
@@ -27644,7 +28019,7 @@ class TokenSourceCached extends TokenSourceConfigurable {
|
|
|
27644
28019
|
if (!this.cachedResponse) {
|
|
27645
28020
|
return false;
|
|
27646
28021
|
}
|
|
27647
|
-
if (
|
|
28022
|
+
if (!isResponseTokenValid(this.cachedResponse)) {
|
|
27648
28023
|
return false;
|
|
27649
28024
|
}
|
|
27650
28025
|
if (this.isSameAsCachedFetchOptions(fetchOptions)) {
|
|
@@ -27913,5 +28288,5 @@ function isFacingModeValue(item) {
|
|
|
27913
28288
|
return item === undefined || allowedValues.includes(item);
|
|
27914
28289
|
}
|
|
27915
28290
|
|
|
27916
|
-
export { AudioPresets, BackupCodecPolicy, BaseKeyProvider, CheckStatus, Checker, ConnectionCheck, ConnectionError, ConnectionErrorReason, ConnectionQuality, ConnectionState, CriticalTimers, CryptorError, CryptorErrorReason, CryptorEvent, DataPacket_Kind, DataStreamError, DataStreamErrorReason, DefaultReconnectPolicy, DeviceUnsupportedError, DisconnectReason, EncryptionEvent, Encryption_Type, EngineEvent, ExternalE2EEKeyProvider, KeyHandlerEvent, KeyProviderEvent, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalTrackRecorder, LocalVideoTrack, LogLevel, LoggerNames, MediaDeviceFailure, _ as Mutex, NegotiationError, Participant, ParticipantEvent, ParticipantInfo_Kind as ParticipantKind, PublishDataError, PublishTrackError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, RpcError, ScreenSharePresets, SignalRequestError, SubscriptionError, TokenSource, TokenSourceConfigurable, TokenSourceCustom, TokenSourceEndpoint, TokenSourceFixed, TokenSourceLiteral, TokenSourceSandboxTokenServer, Track, TrackEvent, TrackInvalidError, TrackPublication, TrackType, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, asEncryptablePacket, attachToElement, attributeTypings as attributes, audioCodecs, compareVersions, createAudioAnalyser, createE2EEKey, createKeyMaterialFromBuffer, createKeyMaterialFromString, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, deriveKeys, detachTrack, facingModeFromDeviceLabel, facingModeFromLocalTrack, getBrowser, getEmptyAudioStreamTrack, getEmptyVideoStreamTrack, getLogger, importKey, isAudioCodec, isAudioTrack, isBackupCodec, isBackupVideoCodec, isBrowserSupported, isE2EESupported, isInsertableStreamSupported, isLocalParticipant, isLocalTrack, isRemoteParticipant, isRemoteTrack, isScriptTransformSupported, isVideoCodec, isVideoFrame, isVideoTrack, needsRbspUnescaping, parseRbsp, protocolVersion, ratchet, setLogExtension, setLogLevel, supportsAV1, supportsAdaptiveStream, supportsDynacast, supportsVP9, version, videoCodecs, writeRbsp };
|
|
28291
|
+
export { AudioPresets, BackupCodecPolicy, BaseKeyProvider, CheckStatus, Checker, ConnectionCheck, ConnectionError, ConnectionErrorReason, ConnectionQuality, ConnectionState, CriticalTimers, CryptorError, CryptorErrorReason, CryptorEvent, DataPacket_Kind, DataStreamError, DataStreamErrorReason, DefaultReconnectPolicy, DeviceUnsupportedError, DisconnectReason, EncryptionEvent, Encryption_Type, EngineEvent, ExternalE2EEKeyProvider, KeyHandlerEvent, KeyProviderEvent, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalTrackRecorder, LocalVideoTrack, LogLevel, LoggerNames, MediaDeviceFailure, _ as Mutex, NegotiationError, Participant, ParticipantEvent, ParticipantInfo_Kind as ParticipantKind, PublishDataError, PublishTrackError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, RpcError, ScreenSharePresets, SignalRequestError, SubscriptionError, TokenSource, TokenSourceConfigurable, TokenSourceCustom, TokenSourceEndpoint, TokenSourceFixed, TokenSourceLiteral, TokenSourceSandboxTokenServer, Track, TrackEvent, TrackInvalidError, TrackPublication, TrackType, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, asEncryptablePacket, attachToElement, attributeTypings as attributes, audioCodecs, compareVersions, createAudioAnalyser, createE2EEKey, createKeyMaterialFromBuffer, createKeyMaterialFromString, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, deriveKeys, detachTrack, facingModeFromDeviceLabel, facingModeFromLocalTrack, getBrowser, getEmptyAudioStreamTrack, getEmptyVideoStreamTrack, getLogger, importKey, isAudioCodec, isAudioTrack, isBackupCodec, isBackupVideoCodec, isBrowserSupported, isE2EESupported, isInsertableStreamSupported, isLocalParticipant, isLocalTrack, isRemoteParticipant, isRemoteTrack, isScriptTransformSupported, isVideoCodec, isVideoFrame, isVideoTrack, needsRbspUnescaping, parseRbsp, protocolVersion, ratchet, setLogExtension, setLogLevel, supportsAV1, supportsAdaptiveStream, supportsAudioOutputSelection, supportsDynacast, supportsVP9, version, videoCodecs, writeRbsp };
|
|
27917
28292
|
//# sourceMappingURL=livekit-client.esm.mjs.map
|