livekit-client 2.15.8 → 2.15.10
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 +589 -205
- 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 +769 -0
- package/src/api/SignalClient.ts +319 -162
- 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 +59 -17
- package/src/room/Room.ts +5 -2
- package/src/room/defaults.ts +1 -0
- package/src/room/participant/LocalParticipant.ts +2 -2
- 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.10";
|
|
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,149 @@ 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
|
-
|
|
14544
|
-
|
|
14545
|
-
|
|
14546
|
-
|
|
14547
|
-
|
|
14548
|
-
|
|
14549
|
-
|
|
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;
|
|
14563
|
-
clearTimeout(wsTimeout);
|
|
14564
|
-
try {
|
|
14565
|
-
const resp = yield fetch(validateUrl);
|
|
14566
|
-
if (resp.status.toFixed(0).startsWith('4')) {
|
|
14567
|
-
const msg = yield resp.text();
|
|
14568
|
-
reject(new ConnectionError(msg, ConnectionErrorReason.NotAllowed, resp.status));
|
|
14569
|
-
} else {
|
|
14570
|
-
reject(new ConnectionError("Encountered unknown websocket error during connection: ".concat(ev.toString()), ConnectionErrorReason.InternalError, resp.status));
|
|
14571
|
-
}
|
|
14572
|
-
} catch (e) {
|
|
14573
|
-
reject(new ConnectionError(e instanceof Error ? e.message : 'server was not reachable', ConnectionErrorReason.ServerUnreachable));
|
|
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
|
+
// send leave if we have an active stream writer (connection is open)
|
|
14759
|
+
if (this.streamWriter) {
|
|
14760
|
+
this.sendLeave().then(() => this.close()).catch(e => {
|
|
14761
|
+
this.log.error(e);
|
|
14762
|
+
this.close();
|
|
14763
|
+
});
|
|
14764
|
+
} else {
|
|
14765
|
+
this.close();
|
|
14574
14766
|
}
|
|
14575
|
-
|
|
14767
|
+
clearTimeout(wsTimeout);
|
|
14768
|
+
const target = event.currentTarget;
|
|
14769
|
+
reject(target instanceof AbortSignal ? target.reason : target);
|
|
14770
|
+
});
|
|
14771
|
+
combinedAbort.addEventListener('abort', abortHandler);
|
|
14772
|
+
const wsTimeout = setTimeout(() => {
|
|
14773
|
+
timeoutAbortController.abort(new ConnectionError('room connection has timed out (signal)', ConnectionErrorReason.ServerUnreachable));
|
|
14774
|
+
}, opts.websocketTimeout);
|
|
14775
|
+
const handleSignalConnected = (connection, firstMessage) => {
|
|
14776
|
+
this.handleSignalConnected(connection, wsTimeout, firstMessage);
|
|
14777
|
+
};
|
|
14778
|
+
const redactedUrl = new URL(rtcUrl);
|
|
14779
|
+
if (redactedUrl.searchParams.has('access_token')) {
|
|
14780
|
+
redactedUrl.searchParams.set('access_token', '<redacted>');
|
|
14576
14781
|
}
|
|
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;
|
|
14782
|
+
this.log.debug("connecting to ".concat(redactedUrl), Object.assign({
|
|
14783
|
+
reconnect: opts.reconnect,
|
|
14784
|
+
reconnectReason: opts.reconnectReason
|
|
14785
|
+
}, this.logContext));
|
|
14786
|
+
if (this.ws) {
|
|
14787
|
+
yield this.close(false);
|
|
14594
14788
|
}
|
|
14595
|
-
|
|
14596
|
-
|
|
14597
|
-
|
|
14598
|
-
|
|
14599
|
-
|
|
14600
|
-
|
|
14601
|
-
|
|
14602
|
-
|
|
14789
|
+
this.ws = new WebSocketStream(rtcUrl, {
|
|
14790
|
+
signal: combinedAbort
|
|
14791
|
+
});
|
|
14792
|
+
try {
|
|
14793
|
+
this.ws.closed.then(closeInfo => {
|
|
14794
|
+
if (this.isEstablishingConnection) {
|
|
14795
|
+
reject(new ConnectionError("Websocket got closed during a (re)connection attempt: ".concat(closeInfo.reason), ConnectionErrorReason.InternalError));
|
|
14796
|
+
}
|
|
14797
|
+
if (closeInfo.closeCode !== 1000) {
|
|
14798
|
+
this.log.warn("websocket closed", Object.assign(Object.assign({}, this.logContext), {
|
|
14799
|
+
reason: closeInfo.reason,
|
|
14800
|
+
code: closeInfo.closeCode,
|
|
14801
|
+
wasClean: closeInfo.closeCode === 1000,
|
|
14802
|
+
state: this.state
|
|
14803
|
+
}));
|
|
14804
|
+
}
|
|
14805
|
+
return;
|
|
14806
|
+
}).catch(reason => {
|
|
14807
|
+
if (this.isEstablishingConnection) {
|
|
14808
|
+
reject(new ConnectionError("Websocket error during a (re)connection attempt: ".concat(reason), ConnectionErrorReason.InternalError));
|
|
14809
|
+
}
|
|
14810
|
+
});
|
|
14811
|
+
const connection = yield this.ws.opened.catch(reason => __awaiter(this, void 0, void 0, function* () {
|
|
14812
|
+
if (this.state !== SignalConnectionState.CONNECTED) {
|
|
14813
|
+
this.state = SignalConnectionState.DISCONNECTED;
|
|
14814
|
+
clearTimeout(wsTimeout);
|
|
14815
|
+
const error = yield this.handleConnectionError(reason, validateUrl);
|
|
14816
|
+
reject(error);
|
|
14817
|
+
return;
|
|
14818
|
+
}
|
|
14819
|
+
// other errors, handle
|
|
14820
|
+
this.handleWSError(reason);
|
|
14821
|
+
reject(reason);
|
|
14822
|
+
return;
|
|
14823
|
+
}));
|
|
14824
|
+
clearTimeout(wsTimeout);
|
|
14825
|
+
if (!connection) {
|
|
14826
|
+
return;
|
|
14827
|
+
}
|
|
14828
|
+
const signalReader = connection.readable.getReader();
|
|
14829
|
+
this.streamWriter = connection.writable.getWriter();
|
|
14830
|
+
const firstMessage = yield signalReader.read();
|
|
14831
|
+
signalReader.releaseLock();
|
|
14832
|
+
if (!firstMessage.value) {
|
|
14833
|
+
throw new ConnectionError('no message received as first message', ConnectionErrorReason.InternalError);
|
|
14834
|
+
}
|
|
14835
|
+
const firstSignalResponse = parseSignalResponse(firstMessage.value);
|
|
14836
|
+
// Validate the first message
|
|
14837
|
+
const validation = this.validateFirstMessage(firstSignalResponse, (_a = opts.reconnect) !== null && _a !== void 0 ? _a : false);
|
|
14838
|
+
if (!validation.isValid) {
|
|
14839
|
+
reject(validation.error);
|
|
14840
|
+
return;
|
|
14841
|
+
}
|
|
14842
|
+
// Handle join response - set up ping configuration
|
|
14843
|
+
if (((_b = firstSignalResponse.message) === null || _b === void 0 ? void 0 : _b.case) === 'join') {
|
|
14844
|
+
this.pingTimeoutDuration = firstSignalResponse.message.value.pingTimeout;
|
|
14845
|
+
this.pingIntervalDuration = firstSignalResponse.message.value.pingInterval;
|
|
14603
14846
|
if (this.pingTimeoutDuration && this.pingTimeoutDuration > 0) {
|
|
14604
14847
|
this.log.debug('ping config', Object.assign(Object.assign({}, this.logContext), {
|
|
14605
14848
|
timeout: this.pingTimeoutDuration,
|
|
14606
14849
|
interval: this.pingIntervalDuration
|
|
14607
14850
|
}));
|
|
14608
|
-
this.startPingInterval();
|
|
14609
14851
|
}
|
|
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
14852
|
}
|
|
14853
|
+
// Handle successful connection
|
|
14854
|
+
const firstMessageToProcess = validation.shouldProcessFirstMessage ? firstSignalResponse : undefined;
|
|
14855
|
+
handleSignalConnected(connection, firstMessageToProcess);
|
|
14856
|
+
resolve(validation.response);
|
|
14857
|
+
} catch (e) {
|
|
14858
|
+
clearTimeout(wsTimeout);
|
|
14859
|
+
reject(e);
|
|
14632
14860
|
}
|
|
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();
|
|
14861
|
+
} finally {
|
|
14862
|
+
unlock();
|
|
14863
|
+
}
|
|
14864
|
+
}));
|
|
14865
|
+
});
|
|
14866
|
+
}
|
|
14867
|
+
startReadingLoop(signalReader, firstMessage) {
|
|
14868
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
14869
|
+
if (firstMessage) {
|
|
14870
|
+
this.handleSignalResponse(firstMessage);
|
|
14652
14871
|
}
|
|
14653
|
-
|
|
14872
|
+
while (true) {
|
|
14873
|
+
if (this.signalLatency) {
|
|
14874
|
+
yield sleep(this.signalLatency);
|
|
14875
|
+
}
|
|
14876
|
+
const {
|
|
14877
|
+
done,
|
|
14878
|
+
value
|
|
14879
|
+
} = yield signalReader.read();
|
|
14880
|
+
if (done) {
|
|
14881
|
+
break;
|
|
14882
|
+
}
|
|
14883
|
+
const resp = parseSignalResponse(value);
|
|
14884
|
+
this.handleSignalResponse(resp);
|
|
14885
|
+
}
|
|
14886
|
+
});
|
|
14654
14887
|
}
|
|
14655
14888
|
close() {
|
|
14656
14889
|
return __awaiter(this, arguments, void 0, function () {
|
|
@@ -14664,26 +14897,20 @@ class SignalClient {
|
|
|
14664
14897
|
_this.state = SignalConnectionState.DISCONNECTING;
|
|
14665
14898
|
}
|
|
14666
14899
|
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
|
-
}
|
|
14900
|
+
_this.ws.close({
|
|
14901
|
+
closeCode: 1000,
|
|
14902
|
+
reason: 'Close method called on signal client'
|
|
14679
14903
|
});
|
|
14680
|
-
|
|
14681
|
-
|
|
14682
|
-
// 250ms grace period for ws to close gracefully
|
|
14683
|
-
yield Promise.race([closePromise, sleep(250)]);
|
|
14684
|
-
}
|
|
14904
|
+
// calling `ws.close()` only starts the closing handshake (CLOSING state), prefer to wait until state is actually CLOSED
|
|
14905
|
+
const closePromise = _this.ws.closed;
|
|
14685
14906
|
_this.ws = undefined;
|
|
14907
|
+
_this.streamWriter = undefined;
|
|
14908
|
+
yield Promise.race([closePromise, sleep(MAX_WS_CLOSE_TIME)]);
|
|
14686
14909
|
}
|
|
14910
|
+
} catch (e) {
|
|
14911
|
+
_this.log.debug('websocket error while closing', Object.assign(Object.assign({}, _this.logContext), {
|
|
14912
|
+
error: e
|
|
14913
|
+
}));
|
|
14687
14914
|
} finally {
|
|
14688
14915
|
if (updateState) {
|
|
14689
14916
|
_this.state = SignalConnectionState.DISCONNECTED;
|
|
@@ -14860,7 +15087,7 @@ class SignalClient {
|
|
|
14860
15087
|
_this3.log.debug("skipping signal request (type: ".concat(message.case, ") - SignalClient disconnected"));
|
|
14861
15088
|
return;
|
|
14862
15089
|
}
|
|
14863
|
-
if (!_this3.
|
|
15090
|
+
if (!_this3.streamWriter) {
|
|
14864
15091
|
_this3.log.error("cannot send signal request before connected, type: ".concat(message === null || message === void 0 ? void 0 : message.case), _this3.logContext);
|
|
14865
15092
|
return;
|
|
14866
15093
|
}
|
|
@@ -14869,9 +15096,9 @@ class SignalClient {
|
|
|
14869
15096
|
});
|
|
14870
15097
|
try {
|
|
14871
15098
|
if (_this3.useJSON) {
|
|
14872
|
-
_this3.
|
|
15099
|
+
yield _this3.streamWriter.write(req.toJsonString());
|
|
14873
15100
|
} else {
|
|
14874
|
-
_this3.
|
|
15101
|
+
yield _this3.streamWriter.write(req.toBinary());
|
|
14875
15102
|
}
|
|
14876
15103
|
} catch (e) {
|
|
14877
15104
|
_this3.log.error('error sending signal message', Object.assign(Object.assign({}, _this3.logContext), {
|
|
@@ -14975,6 +15202,10 @@ class SignalClient {
|
|
|
14975
15202
|
if (this.onRoomMoved) {
|
|
14976
15203
|
this.onRoomMoved(msg.value);
|
|
14977
15204
|
}
|
|
15205
|
+
} else if (msg.case === 'mediaSectionsRequirement') {
|
|
15206
|
+
if (this.onMediaSectionsRequirement) {
|
|
15207
|
+
this.onMediaSectionsRequirement(msg.value);
|
|
15208
|
+
}
|
|
14978
15209
|
} else {
|
|
14979
15210
|
this.log.debug('unsupported message', Object.assign(Object.assign({}, this.logContext), {
|
|
14980
15211
|
msgCase: msg.case
|
|
@@ -15005,9 +15236,9 @@ class SignalClient {
|
|
|
15005
15236
|
}
|
|
15006
15237
|
});
|
|
15007
15238
|
}
|
|
15008
|
-
handleWSError(
|
|
15239
|
+
handleWSError(error) {
|
|
15009
15240
|
this.log.error('websocket error', Object.assign(Object.assign({}, this.logContext), {
|
|
15010
|
-
error
|
|
15241
|
+
error
|
|
15011
15242
|
}));
|
|
15012
15243
|
}
|
|
15013
15244
|
/**
|
|
@@ -15052,6 +15283,89 @@ class SignalClient {
|
|
|
15052
15283
|
CriticalTimers.clearInterval(this.pingInterval);
|
|
15053
15284
|
}
|
|
15054
15285
|
}
|
|
15286
|
+
/**
|
|
15287
|
+
* Handles the successful connection to the signal server
|
|
15288
|
+
* @param connection The WebSocket connection
|
|
15289
|
+
* @param timeoutHandle The timeout handle to clear
|
|
15290
|
+
* @param firstMessage Optional first message to process
|
|
15291
|
+
* @internal
|
|
15292
|
+
*/
|
|
15293
|
+
handleSignalConnected(connection, timeoutHandle, firstMessage) {
|
|
15294
|
+
this.state = SignalConnectionState.CONNECTED;
|
|
15295
|
+
clearTimeout(timeoutHandle);
|
|
15296
|
+
this.startPingInterval();
|
|
15297
|
+
this.startReadingLoop(connection.readable.getReader(), firstMessage);
|
|
15298
|
+
}
|
|
15299
|
+
/**
|
|
15300
|
+
* Validates the first message received from the signal server
|
|
15301
|
+
* @param firstSignalResponse The first signal response received
|
|
15302
|
+
* @param isReconnect Whether this is a reconnection attempt
|
|
15303
|
+
* @returns Validation result with response or error
|
|
15304
|
+
* @internal
|
|
15305
|
+
*/
|
|
15306
|
+
validateFirstMessage(firstSignalResponse, isReconnect) {
|
|
15307
|
+
var _a, _b, _c, _d, _e;
|
|
15308
|
+
if (((_a = firstSignalResponse.message) === null || _a === void 0 ? void 0 : _a.case) === 'join') {
|
|
15309
|
+
return {
|
|
15310
|
+
isValid: true,
|
|
15311
|
+
response: firstSignalResponse.message.value
|
|
15312
|
+
};
|
|
15313
|
+
} else if (this.state === SignalConnectionState.RECONNECTING && ((_b = firstSignalResponse.message) === null || _b === void 0 ? void 0 : _b.case) !== 'leave') {
|
|
15314
|
+
if (((_c = firstSignalResponse.message) === null || _c === void 0 ? void 0 : _c.case) === 'reconnect') {
|
|
15315
|
+
return {
|
|
15316
|
+
isValid: true,
|
|
15317
|
+
response: firstSignalResponse.message.value
|
|
15318
|
+
};
|
|
15319
|
+
} else {
|
|
15320
|
+
// in reconnecting, any message received means signal reconnected and we still need to process it
|
|
15321
|
+
this.log.debug('declaring signal reconnected without reconnect response received', this.logContext);
|
|
15322
|
+
return {
|
|
15323
|
+
isValid: true,
|
|
15324
|
+
response: undefined,
|
|
15325
|
+
shouldProcessFirstMessage: true
|
|
15326
|
+
};
|
|
15327
|
+
}
|
|
15328
|
+
} else if (this.isEstablishingConnection && ((_d = firstSignalResponse.message) === null || _d === void 0 ? void 0 : _d.case) === 'leave') {
|
|
15329
|
+
return {
|
|
15330
|
+
isValid: false,
|
|
15331
|
+
error: new ConnectionError('Received leave request while trying to (re)connect', ConnectionErrorReason.LeaveRequest, undefined, firstSignalResponse.message.value.reason)
|
|
15332
|
+
};
|
|
15333
|
+
} else if (!isReconnect) {
|
|
15334
|
+
// non-reconnect case, should receive join response first
|
|
15335
|
+
return {
|
|
15336
|
+
isValid: false,
|
|
15337
|
+
error: new ConnectionError("did not receive join response, got ".concat((_e = firstSignalResponse.message) === null || _e === void 0 ? void 0 : _e.case, " instead"), ConnectionErrorReason.InternalError)
|
|
15338
|
+
};
|
|
15339
|
+
}
|
|
15340
|
+
return {
|
|
15341
|
+
isValid: false,
|
|
15342
|
+
error: new ConnectionError('Unexpected first message', ConnectionErrorReason.InternalError)
|
|
15343
|
+
};
|
|
15344
|
+
}
|
|
15345
|
+
/**
|
|
15346
|
+
* Handles WebSocket connection errors by validating with the server
|
|
15347
|
+
* @param reason The error that occurred
|
|
15348
|
+
* @param validateUrl The URL to validate the connection with
|
|
15349
|
+
* @returns A ConnectionError with appropriate reason and status
|
|
15350
|
+
* @internal
|
|
15351
|
+
*/
|
|
15352
|
+
handleConnectionError(reason, validateUrl) {
|
|
15353
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
15354
|
+
try {
|
|
15355
|
+
const resp = yield fetch(validateUrl);
|
|
15356
|
+
if (resp.status.toFixed(0).startsWith('4')) {
|
|
15357
|
+
const msg = yield resp.text();
|
|
15358
|
+
return new ConnectionError(msg, ConnectionErrorReason.NotAllowed, resp.status);
|
|
15359
|
+
} else if (reason instanceof ConnectionError) {
|
|
15360
|
+
return reason;
|
|
15361
|
+
} else {
|
|
15362
|
+
return new ConnectionError("Encountered unknown websocket error during connection: ".concat(reason), ConnectionErrorReason.InternalError, resp.status);
|
|
15363
|
+
}
|
|
15364
|
+
} catch (e) {
|
|
15365
|
+
return e instanceof ConnectionError ? e : new ConnectionError(e instanceof Error ? e.message : 'server was not reachable', ConnectionErrorReason.ServerUnreachable);
|
|
15366
|
+
}
|
|
15367
|
+
});
|
|
15368
|
+
}
|
|
15055
15369
|
}
|
|
15056
15370
|
function fromProtoSessionDescription(sd) {
|
|
15057
15371
|
const rsd = {
|
|
@@ -15120,6 +15434,27 @@ function createConnectionParams(token, info, opts) {
|
|
|
15120
15434
|
}
|
|
15121
15435
|
return params;
|
|
15122
15436
|
}
|
|
15437
|
+
function createJoinRequestConnectionParams(token, info, opts) {
|
|
15438
|
+
const params = new URLSearchParams();
|
|
15439
|
+
params.set('access_token', token);
|
|
15440
|
+
const joinRequest = new JoinRequest({
|
|
15441
|
+
clientInfo: info,
|
|
15442
|
+
connectionSettings: new ConnectionSettings({
|
|
15443
|
+
autoSubscribe: !!opts.autoSubscribe,
|
|
15444
|
+
adaptiveStream: !!opts.adaptiveStream
|
|
15445
|
+
}),
|
|
15446
|
+
reconnect: !!opts.reconnect,
|
|
15447
|
+
participantSid: opts.sid ? opts.sid : undefined
|
|
15448
|
+
});
|
|
15449
|
+
if (opts.reconnectReason) {
|
|
15450
|
+
joinRequest.reconnectReason = opts.reconnectReason;
|
|
15451
|
+
}
|
|
15452
|
+
const wrappedJoinRequest = new WrappedJoinRequest({
|
|
15453
|
+
joinRequest: joinRequest.toBinary()
|
|
15454
|
+
});
|
|
15455
|
+
params.set('join_request', btoa(new TextDecoder('utf-8').decode(wrappedJoinRequest.toBinary())));
|
|
15456
|
+
return params;
|
|
15457
|
+
}
|
|
15123
15458
|
|
|
15124
15459
|
class DataPacketBuffer {
|
|
15125
15460
|
constructor() {
|
|
@@ -16132,7 +16467,7 @@ class PCTransport extends eventsExports.EventEmitter {
|
|
|
16132
16467
|
sdpParsed.media.forEach(media => {
|
|
16133
16468
|
const mid = getMidString(media.mid);
|
|
16134
16469
|
if (media.type === 'audio') {
|
|
16135
|
-
//
|
|
16470
|
+
// munge sdp for opus bitrate settings
|
|
16136
16471
|
this.trackBitrates.some(trackbr => {
|
|
16137
16472
|
if (!trackbr.transceiver || mid != trackbr.transceiver.mid) {
|
|
16138
16473
|
return false;
|
|
@@ -16237,7 +16572,7 @@ class PCTransport extends eventsExports.EventEmitter {
|
|
|
16237
16572
|
sdpParsed.media.forEach(media => {
|
|
16238
16573
|
ensureIPAddrMatchVersion(media);
|
|
16239
16574
|
if (media.type === 'audio') {
|
|
16240
|
-
ensureAudioNackAndStereo(media, [], []);
|
|
16575
|
+
ensureAudioNackAndStereo(media, ['all'], []);
|
|
16241
16576
|
} else if (media.type === 'video') {
|
|
16242
16577
|
this.trackBitrates.some(trackbr => {
|
|
16243
16578
|
if (!media.msid || !trackbr.cid || !media.msid.includes(trackbr.cid)) {
|
|
@@ -16313,6 +16648,9 @@ class PCTransport extends eventsExports.EventEmitter {
|
|
|
16313
16648
|
addTransceiver(mediaStreamTrack, transceiverInit) {
|
|
16314
16649
|
return this.pc.addTransceiver(mediaStreamTrack, transceiverInit);
|
|
16315
16650
|
}
|
|
16651
|
+
addTransceiverOfKind(kind, transceiverInit) {
|
|
16652
|
+
return this.pc.addTransceiver(kind, transceiverInit);
|
|
16653
|
+
}
|
|
16316
16654
|
addTrack(track) {
|
|
16317
16655
|
if (!this._pc) {
|
|
16318
16656
|
throw new UnexpectedConnectionState('PC closed, cannot add track');
|
|
@@ -16507,7 +16845,7 @@ function ensureAudioNackAndStereo(media, stereoMids, nackMids) {
|
|
|
16507
16845
|
type: 'nack'
|
|
16508
16846
|
});
|
|
16509
16847
|
}
|
|
16510
|
-
if (stereoMids.includes(mid)) {
|
|
16848
|
+
if (stereoMids.includes(mid) || stereoMids.length === 1 && stereoMids[0] === 'all') {
|
|
16511
16849
|
media.fmtp.some(fmtp => {
|
|
16512
16850
|
if (fmtp.payload === opusPayload) {
|
|
16513
16851
|
if (!fmtp.config.includes('stereo=1')) {
|
|
@@ -16607,7 +16945,8 @@ const roomOptionDefaults = {
|
|
|
16607
16945
|
stopLocalTrackOnUnpublish: true,
|
|
16608
16946
|
reconnectPolicy: new DefaultReconnectPolicy(),
|
|
16609
16947
|
disconnectOnPageLeave: true,
|
|
16610
|
-
webAudioMix: false
|
|
16948
|
+
webAudioMix: false,
|
|
16949
|
+
singlePeerConnection: false
|
|
16611
16950
|
};
|
|
16612
16951
|
const roomConnectOptionDefaults = {
|
|
16613
16952
|
autoSubscribe: true,
|
|
@@ -16635,12 +16974,12 @@ class PCTransportManager {
|
|
|
16635
16974
|
get currentState() {
|
|
16636
16975
|
return this.state;
|
|
16637
16976
|
}
|
|
16638
|
-
constructor(rtcConfig,
|
|
16977
|
+
constructor(rtcConfig, mode, loggerOptions) {
|
|
16639
16978
|
var _a;
|
|
16640
16979
|
this.peerConnectionTimeout = roomConnectOptionDefaults.peerConnectionTimeout;
|
|
16641
16980
|
this.log = livekitLogger;
|
|
16642
16981
|
this.updateState = () => {
|
|
16643
|
-
var _a;
|
|
16982
|
+
var _a, _b;
|
|
16644
16983
|
const previousState = this.state;
|
|
16645
16984
|
const connectionStates = this.requiredTransports.map(tr => tr.getConnectionState());
|
|
16646
16985
|
if (connectionStates.every(st => st === 'connected')) {
|
|
@@ -16658,35 +16997,41 @@ class PCTransportManager {
|
|
|
16658
16997
|
}
|
|
16659
16998
|
if (previousState !== this.state) {
|
|
16660
16999
|
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());
|
|
17000
|
+
(_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
17001
|
}
|
|
16663
17002
|
};
|
|
16664
17003
|
this.log = getLogger((_a = loggerOptions.loggerName) !== null && _a !== void 0 ? _a : LoggerNames.PCManager);
|
|
16665
17004
|
this.loggerOptions = loggerOptions;
|
|
16666
|
-
this.isPublisherConnectionRequired =
|
|
16667
|
-
this.isSubscriberConnectionRequired =
|
|
17005
|
+
this.isPublisherConnectionRequired = mode !== 'subscriber-primary';
|
|
17006
|
+
this.isSubscriberConnectionRequired = mode === 'subscriber-primary';
|
|
16668
17007
|
this.publisher = new PCTransport(rtcConfig, loggerOptions);
|
|
16669
|
-
|
|
17008
|
+
if (mode !== 'publisher-only') {
|
|
17009
|
+
this.subscriber = new PCTransport(rtcConfig, loggerOptions);
|
|
17010
|
+
this.subscriber.onConnectionStateChange = this.updateState;
|
|
17011
|
+
this.subscriber.onIceConnectionStateChange = this.updateState;
|
|
17012
|
+
this.subscriber.onSignalingStatechange = this.updateState;
|
|
17013
|
+
this.subscriber.onIceCandidate = candidate => {
|
|
17014
|
+
var _a;
|
|
17015
|
+
(_a = this.onIceCandidate) === null || _a === void 0 ? void 0 : _a.call(this, candidate, SignalTarget.SUBSCRIBER);
|
|
17016
|
+
};
|
|
17017
|
+
// in subscriber primary mode, server side opens sub data channels.
|
|
17018
|
+
this.subscriber.onDataChannel = ev => {
|
|
17019
|
+
var _a;
|
|
17020
|
+
(_a = this.onDataChannel) === null || _a === void 0 ? void 0 : _a.call(this, ev);
|
|
17021
|
+
};
|
|
17022
|
+
this.subscriber.onTrack = ev => {
|
|
17023
|
+
var _a;
|
|
17024
|
+
(_a = this.onTrack) === null || _a === void 0 ? void 0 : _a.call(this, ev);
|
|
17025
|
+
};
|
|
17026
|
+
}
|
|
16670
17027
|
this.publisher.onConnectionStateChange = this.updateState;
|
|
16671
|
-
this.subscriber.onConnectionStateChange = this.updateState;
|
|
16672
17028
|
this.publisher.onIceConnectionStateChange = this.updateState;
|
|
16673
|
-
this.subscriber.onIceConnectionStateChange = this.updateState;
|
|
16674
17029
|
this.publisher.onSignalingStatechange = this.updateState;
|
|
16675
|
-
this.subscriber.onSignalingStatechange = this.updateState;
|
|
16676
17030
|
this.publisher.onIceCandidate = candidate => {
|
|
16677
17031
|
var _a;
|
|
16678
17032
|
(_a = this.onIceCandidate) === null || _a === void 0 ? void 0 : _a.call(this, candidate, SignalTarget.PUBLISHER);
|
|
16679
17033
|
};
|
|
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 => {
|
|
17034
|
+
this.publisher.onTrack = ev => {
|
|
16690
17035
|
var _a;
|
|
16691
17036
|
(_a = this.onTrack) === null || _a === void 0 ? void 0 : _a.call(this, ev);
|
|
16692
17037
|
};
|
|
@@ -16707,11 +17052,6 @@ class PCTransportManager {
|
|
|
16707
17052
|
this.isPublisherConnectionRequired = require;
|
|
16708
17053
|
this.updateState();
|
|
16709
17054
|
}
|
|
16710
|
-
requireSubscriber() {
|
|
16711
|
-
let require = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
16712
|
-
this.isSubscriberConnectionRequired = require;
|
|
16713
|
-
this.updateState();
|
|
16714
|
-
}
|
|
16715
17055
|
createAndSendPublisherOffer(options) {
|
|
16716
17056
|
return this.publisher.createAndSendOffer(options);
|
|
16717
17057
|
}
|
|
@@ -16723,6 +17063,7 @@ class PCTransportManager {
|
|
|
16723
17063
|
}
|
|
16724
17064
|
close() {
|
|
16725
17065
|
return __awaiter(this, void 0, void 0, function* () {
|
|
17066
|
+
var _a;
|
|
16726
17067
|
if (this.publisher && this.publisher.getSignallingState() !== 'closed') {
|
|
16727
17068
|
const publisher = this.publisher;
|
|
16728
17069
|
for (const sender of publisher.getSenders()) {
|
|
@@ -16738,13 +17079,15 @@ class PCTransportManager {
|
|
|
16738
17079
|
}
|
|
16739
17080
|
}
|
|
16740
17081
|
}
|
|
16741
|
-
yield Promise.all([this.publisher.close(), this.subscriber.close()]);
|
|
17082
|
+
yield Promise.all([this.publisher.close(), (_a = this.subscriber) === null || _a === void 0 ? void 0 : _a.close()]);
|
|
16742
17083
|
this.updateState();
|
|
16743
17084
|
});
|
|
16744
17085
|
}
|
|
16745
17086
|
triggerIceRestart() {
|
|
16746
17087
|
return __awaiter(this, void 0, void 0, function* () {
|
|
16747
|
-
this.subscriber
|
|
17088
|
+
if (this.subscriber) {
|
|
17089
|
+
this.subscriber.restartingIce = true;
|
|
17090
|
+
}
|
|
16748
17091
|
// only restart publisher if it's needed
|
|
16749
17092
|
if (this.needsPublisher) {
|
|
16750
17093
|
yield this.createAndSendPublisherOffer({
|
|
@@ -16755,28 +17098,30 @@ class PCTransportManager {
|
|
|
16755
17098
|
}
|
|
16756
17099
|
addIceCandidate(candidate, target) {
|
|
16757
17100
|
return __awaiter(this, void 0, void 0, function* () {
|
|
17101
|
+
var _a;
|
|
16758
17102
|
if (target === SignalTarget.PUBLISHER) {
|
|
16759
17103
|
yield this.publisher.addIceCandidate(candidate);
|
|
16760
17104
|
} else {
|
|
16761
|
-
yield this.subscriber.addIceCandidate(candidate);
|
|
17105
|
+
yield (_a = this.subscriber) === null || _a === void 0 ? void 0 : _a.addIceCandidate(candidate);
|
|
16762
17106
|
}
|
|
16763
17107
|
});
|
|
16764
17108
|
}
|
|
16765
17109
|
createSubscriberAnswerFromOffer(sd, offerId) {
|
|
16766
17110
|
return __awaiter(this, void 0, void 0, function* () {
|
|
17111
|
+
var _a, _b, _c;
|
|
16767
17112
|
this.log.debug('received server offer', Object.assign(Object.assign({}, this.logContext), {
|
|
16768
17113
|
RTCSdpType: sd.type,
|
|
16769
17114
|
sdp: sd.sdp,
|
|
16770
|
-
signalingState: this.subscriber.getSignallingState().toString()
|
|
17115
|
+
signalingState: (_a = this.subscriber) === null || _a === void 0 ? void 0 : _a.getSignallingState().toString()
|
|
16771
17116
|
}));
|
|
16772
17117
|
const unlock = yield this.remoteOfferLock.lock();
|
|
16773
17118
|
try {
|
|
16774
|
-
const success = yield this.subscriber.setRemoteDescription(sd, offerId);
|
|
17119
|
+
const success = yield (_b = this.subscriber) === null || _b === void 0 ? void 0 : _b.setRemoteDescription(sd, offerId);
|
|
16775
17120
|
if (!success) {
|
|
16776
17121
|
return undefined;
|
|
16777
17122
|
}
|
|
16778
17123
|
// answer the offer
|
|
16779
|
-
const answer = yield this.subscriber.createAndSetAnswer();
|
|
17124
|
+
const answer = yield (_c = this.subscriber) === null || _c === void 0 ? void 0 : _c.createAndSetAnswer();
|
|
16780
17125
|
return answer;
|
|
16781
17126
|
} finally {
|
|
16782
17127
|
unlock();
|
|
@@ -16784,8 +17129,9 @@ class PCTransportManager {
|
|
|
16784
17129
|
});
|
|
16785
17130
|
}
|
|
16786
17131
|
updateConfiguration(config, iceRestart) {
|
|
17132
|
+
var _a;
|
|
16787
17133
|
this.publisher.setConfiguration(config);
|
|
16788
|
-
this.subscriber.setConfiguration(config);
|
|
17134
|
+
(_a = this.subscriber) === null || _a === void 0 ? void 0 : _a.setConfiguration(config);
|
|
16789
17135
|
if (iceRestart) {
|
|
16790
17136
|
this.triggerIceRestart();
|
|
16791
17137
|
}
|
|
@@ -16835,6 +17181,9 @@ class PCTransportManager {
|
|
|
16835
17181
|
addPublisherTransceiver(track, transceiverInit) {
|
|
16836
17182
|
return this.publisher.addTransceiver(track, transceiverInit);
|
|
16837
17183
|
}
|
|
17184
|
+
addPublisherTransceiverOfKind(kind, transceiverInit) {
|
|
17185
|
+
return this.publisher.addTransceiverOfKind(kind, transceiverInit);
|
|
17186
|
+
}
|
|
16838
17187
|
addPublisherTrack(track) {
|
|
16839
17188
|
return this.publisher.addTrack(track);
|
|
16840
17189
|
}
|
|
@@ -16857,7 +17206,7 @@ class PCTransportManager {
|
|
|
16857
17206
|
if (this.isPublisherConnectionRequired) {
|
|
16858
17207
|
transports.push(this.publisher);
|
|
16859
17208
|
}
|
|
16860
|
-
if (this.isSubscriberConnectionRequired) {
|
|
17209
|
+
if (this.isSubscriberConnectionRequired && this.subscriber) {
|
|
16861
17210
|
transports.push(this.subscriber);
|
|
16862
17211
|
}
|
|
16863
17212
|
return transports;
|
|
@@ -19052,7 +19401,9 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
|
19052
19401
|
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
19402
|
const decryptedPacket = EncryptedPacketPayload.fromBinary(decryptedData.payload);
|
|
19054
19403
|
const newDp = new DataPacket({
|
|
19055
|
-
value: decryptedPacket.value
|
|
19404
|
+
value: decryptedPacket.value,
|
|
19405
|
+
participantIdentity: dp.participantIdentity,
|
|
19406
|
+
participantSid: dp.participantSid
|
|
19056
19407
|
});
|
|
19057
19408
|
if (((_d = newDp.value) === null || _d === void 0 ? void 0 : _d.case) === 'user') {
|
|
19058
19409
|
// compatibility
|
|
@@ -19367,7 +19718,7 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
|
19367
19718
|
}
|
|
19368
19719
|
this.participantSid = (_a = joinResponse.participant) === null || _a === void 0 ? void 0 : _a.sid;
|
|
19369
19720
|
const rtcConfig = this.makeRTCConfiguration(joinResponse);
|
|
19370
|
-
this.pcManager = new PCTransportManager(rtcConfig, joinResponse.subscriberPrimary, this.loggerOptions);
|
|
19721
|
+
this.pcManager = new PCTransportManager(rtcConfig, this.options.singlePeerConnection ? 'publisher-only' : joinResponse.subscriberPrimary ? 'subscriber-primary' : 'publisher-primary', this.loggerOptions);
|
|
19371
19722
|
this.emit(EngineEvent.TransportsCreated, this.pcManager.publisher, this.pcManager.subscriber);
|
|
19372
19723
|
this.pcManager.onIceCandidate = (candidate, target) => {
|
|
19373
19724
|
this.client.sendIceCandidate(candidate, target);
|
|
@@ -19403,6 +19754,9 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
|
19403
19754
|
}
|
|
19404
19755
|
});
|
|
19405
19756
|
this.pcManager.onTrack = ev => {
|
|
19757
|
+
// this fires after the underlying transceiver is stopped and potentially
|
|
19758
|
+
// peer connection closed, so do not bubble up if there are no streams
|
|
19759
|
+
if (ev.streams.length === 0) return;
|
|
19406
19760
|
this.emit(EngineEvent.MediaTrackAdded, ev.track, ev.streams[0], ev.receiver);
|
|
19407
19761
|
};
|
|
19408
19762
|
if (!supportOptionalDatachannel((_b = joinResponse.serverInfo) === null || _b === void 0 ? void 0 : _b.protocol)) {
|
|
@@ -19417,7 +19771,8 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
|
19417
19771
|
return;
|
|
19418
19772
|
}
|
|
19419
19773
|
this.log.debug('received server answer', Object.assign(Object.assign({}, this.logContext), {
|
|
19420
|
-
RTCSdpType: sd.type
|
|
19774
|
+
RTCSdpType: sd.type,
|
|
19775
|
+
sdp: sd.sdp
|
|
19421
19776
|
}));
|
|
19422
19777
|
yield this.pcManager.setPublisherAnswer(sd, offerId);
|
|
19423
19778
|
});
|
|
@@ -19484,6 +19839,19 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
|
19484
19839
|
}
|
|
19485
19840
|
this.emit(EngineEvent.RoomMoved, res);
|
|
19486
19841
|
};
|
|
19842
|
+
this.client.onMediaSectionsRequirement = requirement => {
|
|
19843
|
+
var _a, _b;
|
|
19844
|
+
const transceiverInit = {
|
|
19845
|
+
direction: 'recvonly'
|
|
19846
|
+
};
|
|
19847
|
+
for (let i = 0; i < requirement.numAudios; i++) {
|
|
19848
|
+
(_a = this.pcManager) === null || _a === void 0 ? void 0 : _a.addPublisherTransceiverOfKind('audio', transceiverInit);
|
|
19849
|
+
}
|
|
19850
|
+
for (let i = 0; i < requirement.numVideos; i++) {
|
|
19851
|
+
(_b = this.pcManager) === null || _b === void 0 ? void 0 : _b.addPublisherTransceiverOfKind('video', transceiverInit);
|
|
19852
|
+
}
|
|
19853
|
+
this.negotiate();
|
|
19854
|
+
};
|
|
19487
19855
|
this.client.onClose = () => {
|
|
19488
19856
|
this.handleDisconnect('signal', ReconnectReason.RR_SIGNAL_DISCONNECTED);
|
|
19489
19857
|
};
|
|
@@ -20113,19 +20481,21 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
|
20113
20481
|
}
|
|
20114
20482
|
/** @internal */
|
|
20115
20483
|
sendSyncState(remoteTracks, localTracks) {
|
|
20116
|
-
var _a, _b;
|
|
20484
|
+
var _a, _b, _c, _d;
|
|
20117
20485
|
if (!this.pcManager) {
|
|
20118
20486
|
this.log.warn('sync state cannot be sent without peer connection setup', this.logContext);
|
|
20119
20487
|
return;
|
|
20120
20488
|
}
|
|
20121
|
-
const
|
|
20122
|
-
const
|
|
20489
|
+
const previousPublisherOffer = this.pcManager.publisher.getLocalDescription();
|
|
20490
|
+
const previousPublisherAnswer = this.pcManager.publisher.getRemoteDescription();
|
|
20491
|
+
const previousSubscriberOffer = (_a = this.pcManager.subscriber) === null || _a === void 0 ? void 0 : _a.getRemoteDescription();
|
|
20492
|
+
const previousSubscriberAnswer = (_b = this.pcManager.subscriber) === null || _b === void 0 ? void 0 : _b.getLocalDescription();
|
|
20123
20493
|
/* 1. autosubscribe on, so subscribed tracks = all tracks - unsub tracks,
|
|
20124
20494
|
in this case, we send unsub tracks, so server add all tracks to this
|
|
20125
20495
|
subscribe pc and unsub special tracks from it.
|
|
20126
20496
|
2. autosubscribe off, we send subscribed tracks.
|
|
20127
20497
|
*/
|
|
20128
|
-
const autoSubscribe = (
|
|
20498
|
+
const autoSubscribe = (_d = (_c = this.signalOpts) === null || _c === void 0 ? void 0 : _c.autoSubscribe) !== null && _d !== void 0 ? _d : true;
|
|
20129
20499
|
const trackSids = new Array();
|
|
20130
20500
|
const trackSidsDisabled = new Array();
|
|
20131
20501
|
remoteTracks.forEach(track => {
|
|
@@ -20137,13 +20507,19 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
|
20137
20507
|
}
|
|
20138
20508
|
});
|
|
20139
20509
|
this.client.sendSyncState(new SyncState({
|
|
20140
|
-
answer:
|
|
20141
|
-
sdp:
|
|
20142
|
-
type:
|
|
20510
|
+
answer: this.options.singlePeerConnection ? previousPublisherAnswer ? toProtoSessionDescription({
|
|
20511
|
+
sdp: previousPublisherAnswer.sdp,
|
|
20512
|
+
type: previousPublisherAnswer.type
|
|
20513
|
+
}) : undefined : previousSubscriberAnswer ? toProtoSessionDescription({
|
|
20514
|
+
sdp: previousSubscriberAnswer.sdp,
|
|
20515
|
+
type: previousSubscriberAnswer.type
|
|
20143
20516
|
}) : undefined,
|
|
20144
|
-
offer:
|
|
20145
|
-
sdp:
|
|
20146
|
-
type:
|
|
20517
|
+
offer: this.options.singlePeerConnection ? previousPublisherOffer ? toProtoSessionDescription({
|
|
20518
|
+
sdp: previousPublisherOffer.sdp,
|
|
20519
|
+
type: previousPublisherOffer.type
|
|
20520
|
+
}) : undefined : previousSubscriberOffer ? toProtoSessionDescription({
|
|
20521
|
+
sdp: previousSubscriberOffer.sdp,
|
|
20522
|
+
type: previousSubscriberOffer.type
|
|
20147
20523
|
}) : undefined,
|
|
20148
20524
|
subscription: new UpdateSubscription({
|
|
20149
20525
|
trackSids,
|
|
@@ -23879,10 +24255,10 @@ class LocalParticipant extends Participant {
|
|
|
23879
24255
|
destinationIdentity,
|
|
23880
24256
|
method,
|
|
23881
24257
|
payload,
|
|
23882
|
-
responseTimeout =
|
|
24258
|
+
responseTimeout = 15000
|
|
23883
24259
|
} = _ref3;
|
|
23884
24260
|
return function* () {
|
|
23885
|
-
const maxRoundTripLatency =
|
|
24261
|
+
const maxRoundTripLatency = 7000;
|
|
23886
24262
|
return new Promise((resolve, reject) => __awaiter(_this5, void 0, void 0, function* () {
|
|
23887
24263
|
var _a, _b, _c, _d;
|
|
23888
24264
|
if (byteLength(payload) > MAX_PAYLOAD_BYTES) {
|
|
@@ -24803,7 +25179,8 @@ class Room extends eventsExports.EventEmitter {
|
|
|
24803
25179
|
adaptiveStream: typeof roomOptions.adaptiveStream === 'object' ? true : roomOptions.adaptiveStream,
|
|
24804
25180
|
maxRetries: connectOptions.maxRetries,
|
|
24805
25181
|
e2eeEnabled: !!this.e2eeManager,
|
|
24806
|
-
websocketTimeout: connectOptions.websocketTimeout
|
|
25182
|
+
websocketTimeout: connectOptions.websocketTimeout,
|
|
25183
|
+
singlePeerConnection: roomOptions.singlePeerConnection
|
|
24807
25184
|
}, abortController.signal);
|
|
24808
25185
|
let serverInfo = joinResponse.serverInfo;
|
|
24809
25186
|
if (!serverInfo) {
|
|
@@ -24940,8 +25317,9 @@ class Room extends eventsExports.EventEmitter {
|
|
|
24940
25317
|
_this2.log.info('disconnect from room', Object.assign({}, _this2.logContext));
|
|
24941
25318
|
if (_this2.state === ConnectionState.Connecting || _this2.state === ConnectionState.Reconnecting || _this2.isResuming) {
|
|
24942
25319
|
// try aborting pending connection attempt
|
|
24943
|
-
|
|
24944
|
-
(
|
|
25320
|
+
const msg = 'Abort connection attempt due to user initiated disconnect';
|
|
25321
|
+
_this2.log.warn(msg, _this2.logContext);
|
|
25322
|
+
(_a = _this2.abortController) === null || _a === void 0 ? void 0 : _a.abort(msg);
|
|
24945
25323
|
// in case the abort controller didn't manage to cancel the connection attempt, reject the connect promise explicitly
|
|
24946
25324
|
(_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
25325
|
_this2.connectFuture = undefined;
|
|
@@ -25513,6 +25891,7 @@ class Room extends eventsExports.EventEmitter {
|
|
|
25513
25891
|
if (e2eeOptions) {
|
|
25514
25892
|
if ('e2eeManager' in e2eeOptions) {
|
|
25515
25893
|
this.e2eeManager = e2eeOptions.e2eeManager;
|
|
25894
|
+
this.e2eeManager.isDataChannelEncryptionEnabled = dcEncryptionEnabled;
|
|
25516
25895
|
} else {
|
|
25517
25896
|
this.e2eeManager = new E2EEManager(e2eeOptions, dcEncryptionEnabled);
|
|
25518
25897
|
}
|
|
@@ -27087,7 +27466,8 @@ class TURNCheck extends Checker {
|
|
|
27087
27466
|
autoSubscribe: true,
|
|
27088
27467
|
maxRetries: 0,
|
|
27089
27468
|
e2eeEnabled: false,
|
|
27090
|
-
websocketTimeout: 15000
|
|
27469
|
+
websocketTimeout: 15000,
|
|
27470
|
+
singlePeerConnection: false
|
|
27091
27471
|
});
|
|
27092
27472
|
let hasTLS = false;
|
|
27093
27473
|
let hasTURN = false;
|
|
@@ -27137,6 +27517,7 @@ class WebRTCCheck extends Checker {
|
|
|
27137
27517
|
let hasTcp = false;
|
|
27138
27518
|
let hasIpv4Udp = false;
|
|
27139
27519
|
this.room.on(RoomEvent.SignalConnected, () => {
|
|
27520
|
+
var _a;
|
|
27140
27521
|
const prevTrickle = this.room.engine.client.onTrickle;
|
|
27141
27522
|
this.room.engine.client.onTrickle = (sd, target) => {
|
|
27142
27523
|
if (sd.candidate) {
|
|
@@ -27160,7 +27541,7 @@ class WebRTCCheck extends Checker {
|
|
|
27160
27541
|
prevTrickle(sd, target);
|
|
27161
27542
|
}
|
|
27162
27543
|
};
|
|
27163
|
-
if (this.room.engine.pcManager) {
|
|
27544
|
+
if ((_a = this.room.engine.pcManager) === null || _a === void 0 ? void 0 : _a.subscriber) {
|
|
27164
27545
|
this.room.engine.pcManager.subscriber.onIceCandidateError = ev => {
|
|
27165
27546
|
if (ev instanceof RTCPeerConnectionIceErrorEvent) {
|
|
27166
27547
|
this.appendWarning("error with ICE candidate: ".concat(ev.errorCode, " ").concat(ev.errorText, " ").concat(ev.url));
|
|
@@ -27216,7 +27597,8 @@ class WebSocketCheck extends Checker {
|
|
|
27216
27597
|
autoSubscribe: true,
|
|
27217
27598
|
maxRetries: 0,
|
|
27218
27599
|
e2eeEnabled: false,
|
|
27219
|
-
websocketTimeout: 15000
|
|
27600
|
+
websocketTimeout: 15000,
|
|
27601
|
+
singlePeerConnection: false
|
|
27220
27602
|
});
|
|
27221
27603
|
this.appendMessage("Connected to server, version ".concat(joinRes.serverVersion, "."));
|
|
27222
27604
|
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 +27966,17 @@ function decodeJwt(jwt) {
|
|
|
27584
27966
|
|
|
27585
27967
|
const ONE_SECOND_IN_MILLISECONDS = 1000;
|
|
27586
27968
|
const ONE_MINUTE_IN_MILLISECONDS = 60 * ONE_SECOND_IN_MILLISECONDS;
|
|
27587
|
-
function
|
|
27969
|
+
function isResponseTokenValid(response) {
|
|
27588
27970
|
const jwtPayload = decodeTokenPayload(response.participantToken);
|
|
27589
|
-
if (!(jwtPayload === null || jwtPayload === void 0 ? void 0 : jwtPayload.exp)) {
|
|
27971
|
+
if (!(jwtPayload === null || jwtPayload === void 0 ? void 0 : jwtPayload.nbf) || !(jwtPayload === null || jwtPayload === void 0 ? void 0 : jwtPayload.exp)) {
|
|
27590
27972
|
return true;
|
|
27591
27973
|
}
|
|
27592
|
-
const expInMilliseconds = jwtPayload.exp * ONE_SECOND_IN_MILLISECONDS;
|
|
27593
|
-
const expiresAt = new Date(expInMilliseconds - ONE_MINUTE_IN_MILLISECONDS);
|
|
27594
27974
|
const now = new Date();
|
|
27595
|
-
|
|
27975
|
+
const nbfInMilliseconds = jwtPayload.nbf * ONE_SECOND_IN_MILLISECONDS;
|
|
27976
|
+
const nbfDate = new Date(nbfInMilliseconds);
|
|
27977
|
+
const expInMilliseconds = jwtPayload.exp * ONE_SECOND_IN_MILLISECONDS;
|
|
27978
|
+
const expDate = new Date(expInMilliseconds - ONE_MINUTE_IN_MILLISECONDS);
|
|
27979
|
+
return nbfDate <= now && expDate > now;
|
|
27596
27980
|
}
|
|
27597
27981
|
function decodeTokenPayload(token) {
|
|
27598
27982
|
const payload = decodeJwt(token);
|
|
@@ -27644,7 +28028,7 @@ class TokenSourceCached extends TokenSourceConfigurable {
|
|
|
27644
28028
|
if (!this.cachedResponse) {
|
|
27645
28029
|
return false;
|
|
27646
28030
|
}
|
|
27647
|
-
if (
|
|
28031
|
+
if (!isResponseTokenValid(this.cachedResponse)) {
|
|
27648
28032
|
return false;
|
|
27649
28033
|
}
|
|
27650
28034
|
if (this.isSameAsCachedFetchOptions(fetchOptions)) {
|
|
@@ -27913,5 +28297,5 @@ function isFacingModeValue(item) {
|
|
|
27913
28297
|
return item === undefined || allowedValues.includes(item);
|
|
27914
28298
|
}
|
|
27915
28299
|
|
|
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 };
|
|
28300
|
+
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
28301
|
//# sourceMappingURL=livekit-client.esm.mjs.map
|