livekit-client 1.12.3 → 1.13.1
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/livekit-client.e2ee.worker.js +1 -1
- package/dist/livekit-client.e2ee.worker.js.map +1 -1
- package/dist/livekit-client.e2ee.worker.mjs +198 -107
- package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
- package/dist/livekit-client.esm.mjs +515 -192
- 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 +2 -5
- package/dist/src/api/SignalClient.d.ts.map +1 -1
- package/dist/src/connectionHelper/checks/turn.d.ts.map +1 -1
- package/dist/src/connectionHelper/checks/webrtc.d.ts.map +1 -1
- package/dist/src/connectionHelper/checks/websocket.d.ts.map +1 -1
- package/dist/src/e2ee/E2eeManager.d.ts +9 -3
- package/dist/src/e2ee/E2eeManager.d.ts.map +1 -1
- package/dist/src/e2ee/KeyProvider.d.ts +10 -7
- package/dist/src/e2ee/KeyProvider.d.ts.map +1 -1
- package/dist/src/e2ee/constants.d.ts +2 -0
- package/dist/src/e2ee/constants.d.ts.map +1 -1
- package/dist/src/e2ee/events.d.ts +34 -0
- package/dist/src/e2ee/events.d.ts.map +1 -0
- package/dist/src/e2ee/index.d.ts +1 -0
- package/dist/src/e2ee/index.d.ts.map +1 -1
- package/dist/src/e2ee/types.d.ts +23 -33
- package/dist/src/e2ee/types.d.ts.map +1 -1
- package/dist/src/e2ee/utils.d.ts +1 -0
- package/dist/src/e2ee/utils.d.ts.map +1 -1
- package/dist/src/e2ee/worker/FrameCryptor.d.ts +18 -13
- package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
- package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts +6 -8
- package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts.map +1 -1
- package/dist/src/e2ee/worker/SifGuard.d.ts +11 -0
- package/dist/src/e2ee/worker/SifGuard.d.ts.map +1 -0
- package/dist/src/options.d.ts +5 -0
- package/dist/src/options.d.ts.map +1 -1
- package/dist/src/proto/livekit_models_pb.d.ts.map +1 -1
- package/dist/src/proto/livekit_rtc_pb.d.ts.map +1 -1
- package/dist/src/room/DeviceManager.d.ts +1 -0
- package/dist/src/room/DeviceManager.d.ts.map +1 -1
- package/dist/src/room/PCTransport.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts +1 -1
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/defaults.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts +1 -0
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/participant/Participant.d.ts +5 -0
- package/dist/src/room/participant/Participant.d.ts.map +1 -1
- package/dist/src/room/participant/RemoteParticipant.d.ts +0 -5
- package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
- package/dist/src/room/timers.d.ts +2 -2
- package/dist/src/room/timers.d.ts.map +1 -1
- package/dist/src/room/track/LocalAudioTrack.d.ts +9 -1
- package/dist/src/room/track/LocalAudioTrack.d.ts.map +1 -1
- package/dist/src/room/track/LocalTrack.d.ts +3 -3
- package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
- package/dist/src/room/track/LocalVideoTrack.d.ts +6 -0
- package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/RemoteAudioTrack.d.ts.map +1 -1
- package/dist/src/room/track/processor/types.d.ts +14 -2
- package/dist/src/room/track/processor/types.d.ts.map +1 -1
- package/dist/src/room/types.d.ts +1 -1
- package/dist/src/room/types.d.ts.map +1 -1
- package/dist/ts4.2/src/api/SignalClient.d.ts +2 -5
- package/dist/ts4.2/src/e2ee/E2eeManager.d.ts +9 -3
- package/dist/ts4.2/src/e2ee/KeyProvider.d.ts +10 -7
- package/dist/ts4.2/src/e2ee/constants.d.ts +2 -0
- package/dist/ts4.2/src/e2ee/events.d.ts +34 -0
- package/dist/ts4.2/src/e2ee/index.d.ts +1 -0
- package/dist/ts4.2/src/e2ee/types.d.ts +23 -33
- package/dist/ts4.2/src/e2ee/utils.d.ts +1 -0
- package/dist/ts4.2/src/e2ee/worker/FrameCryptor.d.ts +18 -13
- package/dist/ts4.2/src/e2ee/worker/ParticipantKeyHandler.d.ts +6 -8
- package/dist/ts4.2/src/e2ee/worker/SifGuard.d.ts +11 -0
- package/dist/ts4.2/src/options.d.ts +5 -0
- package/dist/ts4.2/src/room/DeviceManager.d.ts +1 -0
- package/dist/ts4.2/src/room/Room.d.ts +1 -1
- package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +1 -0
- package/dist/ts4.2/src/room/participant/Participant.d.ts +5 -0
- package/dist/ts4.2/src/room/participant/RemoteParticipant.d.ts +0 -5
- package/dist/ts4.2/src/room/timers.d.ts +2 -2
- package/dist/ts4.2/src/room/track/LocalAudioTrack.d.ts +9 -1
- package/dist/ts4.2/src/room/track/LocalTrack.d.ts +3 -3
- package/dist/ts4.2/src/room/track/LocalVideoTrack.d.ts +6 -0
- package/dist/ts4.2/src/room/track/processor/types.d.ts +14 -2
- package/dist/ts4.2/src/room/types.d.ts +1 -1
- package/package.json +15 -16
- package/src/api/SignalClient.ts +13 -9
- package/src/connectionHelper/checks/turn.ts +1 -0
- package/src/connectionHelper/checks/webrtc.ts +9 -7
- package/src/connectionHelper/checks/websocket.ts +1 -0
- package/src/e2ee/E2eeManager.ts +129 -76
- package/src/e2ee/KeyProvider.ts +31 -16
- package/src/e2ee/constants.ts +3 -0
- package/src/e2ee/events.ts +48 -0
- package/src/e2ee/index.ts +1 -0
- package/src/e2ee/types.ts +27 -41
- package/src/e2ee/utils.ts +9 -0
- package/src/e2ee/worker/FrameCryptor.ts +90 -47
- package/src/e2ee/worker/ParticipantKeyHandler.ts +25 -26
- package/src/e2ee/worker/SifGuard.ts +47 -0
- package/src/e2ee/worker/e2ee.worker.ts +75 -68
- package/src/options.ts +6 -0
- package/src/proto/livekit_models_pb.ts +14 -0
- package/src/proto/livekit_rtc_pb.ts +14 -0
- package/src/room/DeviceManager.ts +7 -2
- package/src/room/PCTransport.ts +12 -2
- package/src/room/RTCEngine.ts +3 -2
- package/src/room/Room.ts +47 -22
- package/src/room/defaults.ts +1 -0
- package/src/room/participant/LocalParticipant.ts +18 -2
- package/src/room/participant/Participant.ts +16 -0
- package/src/room/participant/RemoteParticipant.ts +0 -12
- package/src/room/track/LocalAudioTrack.ts +45 -0
- package/src/room/track/LocalTrack.ts +22 -14
- package/src/room/track/LocalVideoTrack.ts +39 -0
- package/src/room/track/RemoteAudioTrack.ts +9 -1
- package/src/room/track/RemoteTrackPublication.ts +2 -2
- package/src/room/track/facingMode.ts +1 -1
- package/src/room/track/processor/types.ts +18 -2
- package/src/room/types.ts +5 -1
@@ -285,7 +285,6 @@ var loglevel = {exports: {}};
|
|
285
285
|
});
|
286
286
|
})(loglevel);
|
287
287
|
var loglevelExports = loglevel.exports;
|
288
|
-
var log$1 = /*@__PURE__*/getDefaultExportFromCjs(loglevelExports);
|
289
288
|
|
290
289
|
var LogLevel;
|
291
290
|
(function (LogLevel) {
|
@@ -3465,10 +3464,19 @@ Timestamp.fields = proto3.util.newFieldList(() => [{
|
|
3465
3464
|
T: 5 /* ScalarType.INT32 */
|
3466
3465
|
}]);
|
3467
3466
|
|
3468
|
-
//
|
3469
|
-
//
|
3470
|
-
|
3471
|
-
//
|
3467
|
+
// Copyright 2023 LiveKit, Inc.
|
3468
|
+
//
|
3469
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
3470
|
+
// you may not use this file except in compliance with the License.
|
3471
|
+
// You may obtain a copy of the License at
|
3472
|
+
//
|
3473
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
3474
|
+
//
|
3475
|
+
// Unless required by applicable law or agreed to in writing, software
|
3476
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
3477
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
3478
|
+
// See the License for the specific language governing permissions and
|
3479
|
+
// limitations under the License.
|
3472
3480
|
/**
|
3473
3481
|
* @generated from enum livekit.AudioCodec
|
3474
3482
|
*/
|
@@ -6447,7 +6455,7 @@ function detectBrowser(window) {
|
|
6447
6455
|
};
|
6448
6456
|
|
6449
6457
|
// Fail early if it's not a browser
|
6450
|
-
if (typeof window === 'undefined' || !window.navigator) {
|
6458
|
+
if (typeof window === 'undefined' || !window.navigator || !window.navigator.userAgent) {
|
6451
6459
|
result.browser = 'Not a browser.';
|
6452
6460
|
return result;
|
6453
6461
|
}
|
@@ -9424,10 +9432,19 @@ adapterFactory({
|
|
9424
9432
|
window: typeof window === 'undefined' ? undefined : window
|
9425
9433
|
});
|
9426
9434
|
|
9427
|
-
//
|
9428
|
-
//
|
9429
|
-
|
9430
|
-
//
|
9435
|
+
// Copyright 2023 LiveKit, Inc.
|
9436
|
+
//
|
9437
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
9438
|
+
// you may not use this file except in compliance with the License.
|
9439
|
+
// You may obtain a copy of the License at
|
9440
|
+
//
|
9441
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
9442
|
+
//
|
9443
|
+
// Unless required by applicable law or agreed to in writing, software
|
9444
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
9445
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
9446
|
+
// See the License for the specific language governing permissions and
|
9447
|
+
// limitations under the License.
|
9431
9448
|
/**
|
9432
9449
|
* @generated from enum livekit.SignalTarget
|
9433
9450
|
*/
|
@@ -11823,7 +11840,7 @@ function getMatch(exp, ua) {
|
|
11823
11840
|
return match && match.length >= id && match[id] || '';
|
11824
11841
|
}
|
11825
11842
|
|
11826
|
-
var version$1 = "1.
|
11843
|
+
var version$1 = "1.13.1";
|
11827
11844
|
|
11828
11845
|
const version = version$1;
|
11829
11846
|
const protocolVersion = 9;
|
@@ -13380,8 +13397,13 @@ class SignalClient {
|
|
13380
13397
|
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
13381
13398
|
const abortHandler = () => __awaiter(this, void 0, void 0, function* () {
|
13382
13399
|
this.close();
|
13400
|
+
clearTimeout(wsTimeout);
|
13383
13401
|
reject(new ConnectionError('room connection has been cancelled (signal)'));
|
13384
13402
|
});
|
13403
|
+
const wsTimeout = setTimeout(() => {
|
13404
|
+
this.close();
|
13405
|
+
reject(new ConnectionError('room connection has timed out (signal)'));
|
13406
|
+
}, opts.websocketTimeout);
|
13385
13407
|
if (abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.aborted) {
|
13386
13408
|
abortHandler();
|
13387
13409
|
}
|
@@ -13392,8 +13414,12 @@ class SignalClient {
|
|
13392
13414
|
}
|
13393
13415
|
this.ws = new WebSocket(url + params);
|
13394
13416
|
this.ws.binaryType = 'arraybuffer';
|
13417
|
+
this.ws.onopen = () => {
|
13418
|
+
clearTimeout(wsTimeout);
|
13419
|
+
};
|
13395
13420
|
this.ws.onerror = ev => __awaiter(this, void 0, void 0, function* () {
|
13396
13421
|
if (!this.isConnected) {
|
13422
|
+
clearTimeout(wsTimeout);
|
13397
13423
|
try {
|
13398
13424
|
const resp = yield fetch("http".concat(url.substring(2), "/validate").concat(params));
|
13399
13425
|
if (resp.status.toFixed(0).startsWith('4')) {
|
@@ -13889,6 +13915,26 @@ const KEY_PROVIDER_DEFAULTS = {
|
|
13889
13915
|
failureTolerance: DECRYPTION_FAILURE_TOLERANCE
|
13890
13916
|
};
|
13891
13917
|
|
13918
|
+
var KeyProviderEvent;
|
13919
|
+
(function (KeyProviderEvent) {
|
13920
|
+
KeyProviderEvent["SetKey"] = "setKey";
|
13921
|
+
KeyProviderEvent["RatchetRequest"] = "ratchetRequest";
|
13922
|
+
KeyProviderEvent["KeyRatcheted"] = "keyRatcheted";
|
13923
|
+
})(KeyProviderEvent || (KeyProviderEvent = {}));
|
13924
|
+
var KeyHandlerEvent;
|
13925
|
+
(function (KeyHandlerEvent) {
|
13926
|
+
KeyHandlerEvent["KeyRatcheted"] = "keyRatcheted";
|
13927
|
+
})(KeyHandlerEvent || (KeyHandlerEvent = {}));
|
13928
|
+
var EncryptionEvent;
|
13929
|
+
(function (EncryptionEvent) {
|
13930
|
+
EncryptionEvent["ParticipantEncryptionStatusChanged"] = "participantEncryptionStatusChanged";
|
13931
|
+
EncryptionEvent["EncryptionError"] = "encryptionError";
|
13932
|
+
})(EncryptionEvent || (EncryptionEvent = {}));
|
13933
|
+
var CryptorEvent;
|
13934
|
+
(function (CryptorEvent) {
|
13935
|
+
CryptorEvent["Error"] = "cryptorError";
|
13936
|
+
})(CryptorEvent || (CryptorEvent = {}));
|
13937
|
+
|
13892
13938
|
function isE2EESupported() {
|
13893
13939
|
return isInsertableStreamSupported() || isScriptTransformSupported();
|
13894
13940
|
}
|
@@ -13923,6 +13969,12 @@ function createKeyMaterialFromString(password) {
|
|
13923
13969
|
return keyMaterial;
|
13924
13970
|
});
|
13925
13971
|
}
|
13972
|
+
function createKeyMaterialFromBuffer(cryptoBuffer) {
|
13973
|
+
return __awaiter(this, void 0, void 0, function* () {
|
13974
|
+
const keyMaterial = yield crypto.subtle.importKey('raw', cryptoBuffer, 'HKDF', false, ['deriveBits', 'deriveKey']);
|
13975
|
+
return keyMaterial;
|
13976
|
+
});
|
13977
|
+
}
|
13926
13978
|
function getAlgoOptions(algorithmName, salt) {
|
13927
13979
|
const textEncoder = new TextEncoder();
|
13928
13980
|
const encodedSalt = textEncoder.encode(salt);
|
@@ -13996,32 +14048,35 @@ class BaseKeyProvider extends eventsExports.EventEmitter {
|
|
13996
14048
|
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
13997
14049
|
super();
|
13998
14050
|
/**
|
13999
|
-
* callback being invoked after a ratchet request has been performed on
|
14051
|
+
* callback being invoked after a ratchet request has been performed on a participant
|
14000
14052
|
* that surfaces the new key material.
|
14001
14053
|
* @param material
|
14002
14054
|
* @param keyIndex
|
14003
14055
|
*/
|
14004
14056
|
this.onKeyRatcheted = (material, keyIndex) => {
|
14005
|
-
|
14057
|
+
livekitLogger.debug('key ratcheted event received', {
|
14058
|
+
material,
|
14059
|
+
keyIndex
|
14060
|
+
});
|
14006
14061
|
};
|
14007
14062
|
this.keyInfoMap = new Map();
|
14008
14063
|
this.options = Object.assign(Object.assign({}, KEY_PROVIDER_DEFAULTS), options);
|
14009
|
-
this.on(
|
14064
|
+
this.on(KeyProviderEvent.KeyRatcheted, this.onKeyRatcheted);
|
14010
14065
|
}
|
14011
14066
|
/**
|
14012
14067
|
* callback to invoke once a key has been set for a participant
|
14013
14068
|
* @param key
|
14014
|
-
* @param
|
14069
|
+
* @param participantIdentity
|
14015
14070
|
* @param keyIndex
|
14016
14071
|
*/
|
14017
|
-
onSetEncryptionKey(key,
|
14072
|
+
onSetEncryptionKey(key, participantIdentity, keyIndex) {
|
14018
14073
|
const keyInfo = {
|
14019
14074
|
key,
|
14020
|
-
|
14075
|
+
participantIdentity,
|
14021
14076
|
keyIndex
|
14022
14077
|
};
|
14023
|
-
this.keyInfoMap.set("".concat(
|
14024
|
-
this.emit(
|
14078
|
+
this.keyInfoMap.set("".concat(participantIdentity !== null && participantIdentity !== void 0 ? participantIdentity : 'shared', "-").concat(keyIndex !== null && keyIndex !== void 0 ? keyIndex : 0), keyInfo);
|
14079
|
+
this.emit(KeyProviderEvent.SetKey, keyInfo);
|
14025
14080
|
}
|
14026
14081
|
getKeys() {
|
14027
14082
|
return Array.from(this.keyInfoMap.values());
|
@@ -14029,8 +14084,8 @@ class BaseKeyProvider extends eventsExports.EventEmitter {
|
|
14029
14084
|
getOptions() {
|
14030
14085
|
return this.options;
|
14031
14086
|
}
|
14032
|
-
ratchetKey(
|
14033
|
-
this.emit(
|
14087
|
+
ratchetKey(participantIdentity, keyIndex) {
|
14088
|
+
this.emit(KeyProviderEvent.RatchetRequest, participantIdentity, keyIndex);
|
14034
14089
|
}
|
14035
14090
|
}
|
14036
14091
|
/**
|
@@ -14042,30 +14097,29 @@ class ExternalE2EEKeyProvider extends BaseKeyProvider {
|
|
14042
14097
|
constructor() {
|
14043
14098
|
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
14044
14099
|
const opts = Object.assign(Object.assign({}, options), {
|
14045
|
-
sharedKey: true
|
14100
|
+
sharedKey: true,
|
14101
|
+
// for a shared key provider failing to decrypt for a specific participant
|
14102
|
+
// should not mark the key as invalid, so we accept wrong keys forever
|
14103
|
+
// and won't try to auto-ratchet
|
14104
|
+
ratchetWindowSize: 0,
|
14105
|
+
failureTolerance: -1
|
14046
14106
|
});
|
14047
14107
|
super(opts);
|
14048
14108
|
}
|
14049
14109
|
/**
|
14050
|
-
* Accepts a passphrase that's used to create the crypto keys
|
14110
|
+
* Accepts a passphrase that's used to create the crypto keys.
|
14111
|
+
* When passing in a string, PBKDF2 is used.
|
14112
|
+
* When passing in an Array buffer of cryptographically random numbers, HKDF is being used. (recommended)
|
14051
14113
|
* @param key
|
14052
14114
|
*/
|
14053
14115
|
setKey(key) {
|
14054
14116
|
return __awaiter(this, void 0, void 0, function* () {
|
14055
|
-
const derivedKey = yield createKeyMaterialFromString(key);
|
14117
|
+
const derivedKey = typeof key === 'string' ? yield createKeyMaterialFromString(key) : yield createKeyMaterialFromBuffer(key);
|
14056
14118
|
this.onSetEncryptionKey(derivedKey);
|
14057
14119
|
});
|
14058
14120
|
}
|
14059
14121
|
}
|
14060
14122
|
|
14061
|
-
const EncryptionEvent = {
|
14062
|
-
ParticipantEncryptionStatusChanged: 'participantEncryptionStatusChanged',
|
14063
|
-
Error: 'encryptionError'
|
14064
|
-
};
|
14065
|
-
const CryptorEvent = {
|
14066
|
-
Error: 'cryptorError'
|
14067
|
-
};
|
14068
|
-
|
14069
14123
|
function r(r, e, n) {
|
14070
14124
|
var i, t, o;
|
14071
14125
|
void 0 === e && (e = 50), void 0 === n && (n = {});
|
@@ -14135,9 +14189,9 @@ class DeviceManager {
|
|
14135
14189
|
}
|
14136
14190
|
}
|
14137
14191
|
let devices = yield navigator.mediaDevices.enumerateDevices();
|
14138
|
-
if (requestPermissions &&
|
14192
|
+
if (requestPermissions &&
|
14139
14193
|
// for safari we need to skip this check, as otherwise it will re-acquire user media and fail on iOS https://bugs.webkit.org/show_bug.cgi?id=179363
|
14140
|
-
!
|
14194
|
+
!(isSafari() && this.hasDeviceInUse(kind))) {
|
14141
14195
|
const isDummyDeviceOrEmpty = devices.length === 0 || devices.some(device => {
|
14142
14196
|
const noLabel = device.label === '';
|
14143
14197
|
const isRelevant = kind ? device.kind === kind : true;
|
@@ -14173,6 +14227,9 @@ class DeviceManager {
|
|
14173
14227
|
return device === null || device === void 0 ? void 0 : device.deviceId;
|
14174
14228
|
});
|
14175
14229
|
}
|
14230
|
+
hasDeviceInUse(kind) {
|
14231
|
+
return kind ? DeviceManager.userMediaPromiseMap.has(kind) : DeviceManager.userMediaPromiseMap.size > 0;
|
14232
|
+
}
|
14176
14233
|
}
|
14177
14234
|
DeviceManager.mediaDeviceKinds = ['audioinput', 'audiooutput', 'videoinput'];
|
14178
14235
|
DeviceManager.userMediaPromiseMap = new Map();
|
@@ -14209,52 +14266,6 @@ class LocalTrack extends Track {
|
|
14209
14266
|
this._mediaStreamTrack.removeEventListener('unmute', this.handleTrackUnmuteEvent);
|
14210
14267
|
this.emit(TrackEvent.Ended, this);
|
14211
14268
|
};
|
14212
|
-
/**
|
14213
|
-
* pauses publishing to the server without disabling the local MediaStreamTrack
|
14214
|
-
* this is used to display a user's own video locally while pausing publishing to
|
14215
|
-
* the server.
|
14216
|
-
* this API is unsupported on Safari < 12 due to a bug
|
14217
|
-
**/
|
14218
|
-
this.pauseUpstream = () => __awaiter(this, void 0, void 0, function* () {
|
14219
|
-
const unlock = yield this.pauseUpstreamLock.lock();
|
14220
|
-
try {
|
14221
|
-
if (this._isUpstreamPaused === true) {
|
14222
|
-
return;
|
14223
|
-
}
|
14224
|
-
if (!this.sender) {
|
14225
|
-
livekitLogger.warn('unable to pause upstream for an unpublished track');
|
14226
|
-
return;
|
14227
|
-
}
|
14228
|
-
this._isUpstreamPaused = true;
|
14229
|
-
this.emit(TrackEvent.UpstreamPaused, this);
|
14230
|
-
const browser = getBrowser();
|
14231
|
-
if ((browser === null || browser === void 0 ? void 0 : browser.name) === 'Safari' && compareVersions(browser.version, '12.0') < 0) {
|
14232
|
-
// https://bugs.webkit.org/show_bug.cgi?id=184911
|
14233
|
-
throw new DeviceUnsupportedError('pauseUpstream is not supported on Safari < 12.');
|
14234
|
-
}
|
14235
|
-
yield this.sender.replaceTrack(null);
|
14236
|
-
} finally {
|
14237
|
-
unlock();
|
14238
|
-
}
|
14239
|
-
});
|
14240
|
-
this.resumeUpstream = () => __awaiter(this, void 0, void 0, function* () {
|
14241
|
-
const unlock = yield this.pauseUpstreamLock.lock();
|
14242
|
-
try {
|
14243
|
-
if (this._isUpstreamPaused === false) {
|
14244
|
-
return;
|
14245
|
-
}
|
14246
|
-
if (!this.sender) {
|
14247
|
-
livekitLogger.warn('unable to resume upstream for an unpublished track');
|
14248
|
-
return;
|
14249
|
-
}
|
14250
|
-
this._isUpstreamPaused = false;
|
14251
|
-
this.emit(TrackEvent.UpstreamResumed, this);
|
14252
|
-
// this operation is noop if mediastreamtrack is already being sent
|
14253
|
-
yield this.sender.replaceTrack(this._mediaStreamTrack);
|
14254
|
-
} finally {
|
14255
|
-
unlock();
|
14256
|
-
}
|
14257
|
-
});
|
14258
14269
|
this.reacquireTrack = false;
|
14259
14270
|
this.providedByUser = userProvidedTrack;
|
14260
14271
|
this.muteLock = new Mutex();
|
@@ -14325,8 +14336,22 @@ class LocalTrack extends Track {
|
|
14325
14336
|
newTrack.addEventListener('unmute', this.handleTrackUnmuteEvent);
|
14326
14337
|
this._constraints = newTrack.getConstraints();
|
14327
14338
|
}
|
14339
|
+
let processedTrack;
|
14340
|
+
if (this.processor && newTrack && this.processorElement) {
|
14341
|
+
livekitLogger.debug('restarting processor');
|
14342
|
+
if (this.kind === 'unknown') {
|
14343
|
+
throw TypeError('cannot set processor on track of unknown kind');
|
14344
|
+
}
|
14345
|
+
attachToElement(newTrack, this.processorElement);
|
14346
|
+
yield this.processor.restart({
|
14347
|
+
track: newTrack,
|
14348
|
+
kind: this.kind,
|
14349
|
+
element: this.processorElement
|
14350
|
+
});
|
14351
|
+
processedTrack = this.processor.processedTrack;
|
14352
|
+
}
|
14328
14353
|
if (this.sender) {
|
14329
|
-
yield this.sender.replaceTrack(newTrack);
|
14354
|
+
yield this.sender.replaceTrack(processedTrack !== null && processedTrack !== void 0 ? processedTrack : newTrack);
|
14330
14355
|
}
|
14331
14356
|
this._mediaStreamTrack = newTrack;
|
14332
14357
|
if (newTrack) {
|
@@ -14335,7 +14360,7 @@ class LocalTrack extends Track {
|
|
14335
14360
|
// when a valid track is replace, we'd want to start producing
|
14336
14361
|
yield this.resumeUpstream();
|
14337
14362
|
this.attachedElements.forEach(el => {
|
14338
|
-
attachToElement(newTrack, el);
|
14363
|
+
attachToElement(processedTrack !== null && processedTrack !== void 0 ? processedTrack : newTrack, el);
|
14339
14364
|
});
|
14340
14365
|
}
|
14341
14366
|
});
|
@@ -14435,14 +14460,6 @@ class LocalTrack extends Track {
|
|
14435
14460
|
livekitLogger.debug('re-acquired MediaStreamTrack');
|
14436
14461
|
yield this.setMediaStreamTrack(newTrack);
|
14437
14462
|
this._constraints = constraints;
|
14438
|
-
if (this.processor) {
|
14439
|
-
const processor = this.processor;
|
14440
|
-
yield this.setProcessor(processor);
|
14441
|
-
} else {
|
14442
|
-
this.attachedElements.forEach(el => {
|
14443
|
-
attachToElement(this._mediaStreamTrack, el);
|
14444
|
-
});
|
14445
|
-
}
|
14446
14463
|
this.emit(TrackEvent.Restarted, this);
|
14447
14464
|
return this;
|
14448
14465
|
});
|
@@ -14485,6 +14502,56 @@ class LocalTrack extends Track {
|
|
14485
14502
|
(_a = this.processor) === null || _a === void 0 ? void 0 : _a.destroy();
|
14486
14503
|
this.processor = undefined;
|
14487
14504
|
}
|
14505
|
+
/**
|
14506
|
+
* pauses publishing to the server without disabling the local MediaStreamTrack
|
14507
|
+
* this is used to display a user's own video locally while pausing publishing to
|
14508
|
+
* the server.
|
14509
|
+
* this API is unsupported on Safari < 12 due to a bug
|
14510
|
+
**/
|
14511
|
+
pauseUpstream() {
|
14512
|
+
return __awaiter(this, void 0, void 0, function* () {
|
14513
|
+
const unlock = yield this.pauseUpstreamLock.lock();
|
14514
|
+
try {
|
14515
|
+
if (this._isUpstreamPaused === true) {
|
14516
|
+
return;
|
14517
|
+
}
|
14518
|
+
if (!this.sender) {
|
14519
|
+
livekitLogger.warn('unable to pause upstream for an unpublished track');
|
14520
|
+
return;
|
14521
|
+
}
|
14522
|
+
this._isUpstreamPaused = true;
|
14523
|
+
this.emit(TrackEvent.UpstreamPaused, this);
|
14524
|
+
const browser = getBrowser();
|
14525
|
+
if ((browser === null || browser === void 0 ? void 0 : browser.name) === 'Safari' && compareVersions(browser.version, '12.0') < 0) {
|
14526
|
+
// https://bugs.webkit.org/show_bug.cgi?id=184911
|
14527
|
+
throw new DeviceUnsupportedError('pauseUpstream is not supported on Safari < 12.');
|
14528
|
+
}
|
14529
|
+
yield this.sender.replaceTrack(null);
|
14530
|
+
} finally {
|
14531
|
+
unlock();
|
14532
|
+
}
|
14533
|
+
});
|
14534
|
+
}
|
14535
|
+
resumeUpstream() {
|
14536
|
+
return __awaiter(this, void 0, void 0, function* () {
|
14537
|
+
const unlock = yield this.pauseUpstreamLock.lock();
|
14538
|
+
try {
|
14539
|
+
if (this._isUpstreamPaused === false) {
|
14540
|
+
return;
|
14541
|
+
}
|
14542
|
+
if (!this.sender) {
|
14543
|
+
livekitLogger.warn('unable to resume upstream for an unpublished track');
|
14544
|
+
return;
|
14545
|
+
}
|
14546
|
+
this._isUpstreamPaused = false;
|
14547
|
+
this.emit(TrackEvent.UpstreamResumed, this);
|
14548
|
+
// this operation is noop if mediastreamtrack is already being sent
|
14549
|
+
yield this.sender.replaceTrack(this._mediaStreamTrack);
|
14550
|
+
} finally {
|
14551
|
+
unlock();
|
14552
|
+
}
|
14553
|
+
});
|
14554
|
+
}
|
14488
14555
|
/**
|
14489
14556
|
* Sets a processor on this track.
|
14490
14557
|
* See https://github.com/livekit/track-processors-js for example usage
|
@@ -14564,9 +14631,6 @@ class LocalTrack extends Track {
|
|
14564
14631
|
* @experimental
|
14565
14632
|
*/
|
14566
14633
|
class E2EEManager extends eventsExports.EventEmitter {
|
14567
|
-
get isEnabled() {
|
14568
|
-
return this.encryptionEnabled;
|
14569
|
-
}
|
14570
14634
|
constructor(options) {
|
14571
14635
|
super();
|
14572
14636
|
this.onWorkerMessage = ev => {
|
@@ -14577,17 +14641,25 @@ class E2EEManager extends eventsExports.EventEmitter {
|
|
14577
14641
|
} = ev.data;
|
14578
14642
|
switch (kind) {
|
14579
14643
|
case 'error':
|
14580
|
-
|
14581
|
-
|
14582
|
-
|
14583
|
-
|
14644
|
+
livekitLogger.error(data.error.message);
|
14645
|
+
this.emit(EncryptionEvent.EncryptionError, data.error);
|
14646
|
+
break;
|
14647
|
+
case 'initAck':
|
14648
|
+
if (data.enabled) {
|
14649
|
+
this.keyProvider.getKeys().forEach(keyInfo => {
|
14650
|
+
this.postKey(keyInfo);
|
14651
|
+
});
|
14652
|
+
}
|
14584
14653
|
break;
|
14585
14654
|
case 'enable':
|
14586
|
-
if (this.encryptionEnabled !== data.enabled &&
|
14587
|
-
this.emit(EncryptionEvent.ParticipantEncryptionStatusChanged, data.enabled,
|
14655
|
+
if (this.encryptionEnabled !== data.enabled && data.participantIdentity === ((_a = this.room) === null || _a === void 0 ? void 0 : _a.localParticipant.identity)) {
|
14656
|
+
this.emit(EncryptionEvent.ParticipantEncryptionStatusChanged, data.enabled, this.room.localParticipant);
|
14588
14657
|
this.encryptionEnabled = data.enabled;
|
14589
|
-
} else if (data.
|
14590
|
-
const participant = (_b = this.room) === null || _b === void 0 ? void 0 : _b.getParticipantByIdentity(data.
|
14658
|
+
} else if (data.participantIdentity) {
|
14659
|
+
const participant = (_b = this.room) === null || _b === void 0 ? void 0 : _b.getParticipantByIdentity(data.participantIdentity);
|
14660
|
+
if (!participant) {
|
14661
|
+
throw TypeError("couldn't set encryption status, participant not found".concat(data.participantIdentity));
|
14662
|
+
}
|
14591
14663
|
this.emit(EncryptionEvent.ParticipantEncryptionStatusChanged, data.enabled, participant);
|
14592
14664
|
}
|
14593
14665
|
if (this.encryptionEnabled) {
|
@@ -14597,7 +14669,7 @@ class E2EEManager extends eventsExports.EventEmitter {
|
|
14597
14669
|
}
|
14598
14670
|
break;
|
14599
14671
|
case 'ratchetKey':
|
14600
|
-
this.keyProvider.emit(
|
14672
|
+
this.keyProvider.emit(KeyProviderEvent.KeyRatcheted, data.material, data.keyIndex);
|
14601
14673
|
break;
|
14602
14674
|
}
|
14603
14675
|
};
|
@@ -14605,7 +14677,7 @@ class E2EEManager extends eventsExports.EventEmitter {
|
|
14605
14677
|
livekitLogger.error('e2ee worker encountered an error:', {
|
14606
14678
|
error: ev.error
|
14607
14679
|
});
|
14608
|
-
this.emit(EncryptionEvent.
|
14680
|
+
this.emit(EncryptionEvent.EncryptionError, ev.error);
|
14609
14681
|
};
|
14610
14682
|
this.keyProvider = options.keyProvider;
|
14611
14683
|
this.worker = options.worker;
|
@@ -14642,22 +14714,19 @@ class E2EEManager extends eventsExports.EventEmitter {
|
|
14642
14714
|
/**
|
14643
14715
|
* @internal
|
14644
14716
|
*/
|
14645
|
-
setParticipantCryptorEnabled(enabled,
|
14646
|
-
|
14647
|
-
|
14648
|
-
|
14649
|
-
|
14650
|
-
|
14651
|
-
|
14652
|
-
|
14653
|
-
|
14654
|
-
|
14655
|
-
|
14656
|
-
|
14657
|
-
|
14658
|
-
throw new ReferenceError('failed to enable e2ee, worker is not ready');
|
14659
|
-
}
|
14660
|
-
});
|
14717
|
+
setParticipantCryptorEnabled(enabled, participantIdentity) {
|
14718
|
+
livekitLogger.debug("set e2ee to ".concat(enabled, " for participant ").concat(participantIdentity));
|
14719
|
+
this.postEnable(enabled, participantIdentity);
|
14720
|
+
}
|
14721
|
+
/**
|
14722
|
+
* @internal
|
14723
|
+
*/
|
14724
|
+
setSifTrailer(trailer) {
|
14725
|
+
if (!trailer || trailer.length === 0) {
|
14726
|
+
livekitLogger.warn("ignoring server sent trailer as it's empty");
|
14727
|
+
} else {
|
14728
|
+
this.postSifTrailer(trailer);
|
14729
|
+
}
|
14661
14730
|
}
|
14662
14731
|
setupEngine(engine) {
|
14663
14732
|
engine.on(EngineEvent.RTPVideoMapUpdate, rtpMap => {
|
@@ -14674,34 +14743,40 @@ class E2EEManager extends eventsExports.EventEmitter {
|
|
14674
14743
|
});
|
14675
14744
|
});
|
14676
14745
|
}
|
14677
|
-
})
|
14678
|
-
room.on(RoomEvent.TrackUnsubscribed, (track, _, participant) => {
|
14746
|
+
}).on(RoomEvent.TrackUnsubscribed, (track, _, participant) => {
|
14679
14747
|
var _a;
|
14680
14748
|
const msg = {
|
14681
14749
|
kind: 'removeTransform',
|
14682
14750
|
data: {
|
14683
|
-
|
14751
|
+
participantIdentity: participant.identity,
|
14684
14752
|
trackId: track.mediaStreamID
|
14685
14753
|
}
|
14686
14754
|
};
|
14687
14755
|
(_a = this.worker) === null || _a === void 0 ? void 0 : _a.postMessage(msg);
|
14688
|
-
})
|
14689
|
-
room.on(RoomEvent.TrackSubscribed, (track, pub, participant) => {
|
14756
|
+
}).on(RoomEvent.TrackSubscribed, (track, pub, participant) => {
|
14690
14757
|
this.setupE2EEReceiver(track, participant.identity, pub.trackInfo);
|
14758
|
+
}).on(RoomEvent.SignalConnected, () => {
|
14759
|
+
if (!this.room) {
|
14760
|
+
throw new TypeError("expected room to be present on signal connect");
|
14761
|
+
}
|
14762
|
+
this.setParticipantCryptorEnabled(this.room.localParticipant.isE2EEEnabled, this.room.localParticipant.identity);
|
14763
|
+
keyProvider.getKeys().forEach(keyInfo => {
|
14764
|
+
this.postKey(keyInfo);
|
14765
|
+
});
|
14691
14766
|
});
|
14692
14767
|
room.localParticipant.on(ParticipantEvent.LocalTrackPublished, publication => __awaiter(this, void 0, void 0, function* () {
|
14693
|
-
this.setupE2EESender(publication.track, publication.track.sender
|
14768
|
+
this.setupE2EESender(publication.track, publication.track.sender);
|
14694
14769
|
}));
|
14695
|
-
keyProvider.on(
|
14770
|
+
keyProvider.on(KeyProviderEvent.SetKey, keyInfo => this.postKey(keyInfo)).on(KeyProviderEvent.RatchetRequest, (participantId, keyIndex) => this.postRatchetRequest(participantId, keyIndex));
|
14696
14771
|
}
|
14697
|
-
postRatchetRequest(
|
14772
|
+
postRatchetRequest(participantIdentity, keyIndex) {
|
14698
14773
|
if (!this.worker) {
|
14699
14774
|
throw Error('could not ratchet key, worker is missing');
|
14700
14775
|
}
|
14701
14776
|
const msg = {
|
14702
14777
|
kind: 'ratchetRequest',
|
14703
14778
|
data: {
|
14704
|
-
|
14779
|
+
participantIdentity: participantIdentity,
|
14705
14780
|
keyIndex
|
14706
14781
|
}
|
14707
14782
|
};
|
@@ -14710,30 +14785,63 @@ class E2EEManager extends eventsExports.EventEmitter {
|
|
14710
14785
|
postKey(_ref) {
|
14711
14786
|
let {
|
14712
14787
|
key,
|
14713
|
-
|
14788
|
+
participantIdentity,
|
14714
14789
|
keyIndex
|
14715
14790
|
} = _ref;
|
14791
|
+
var _a;
|
14716
14792
|
if (!this.worker) {
|
14717
14793
|
throw Error('could not set key, worker is missing');
|
14718
14794
|
}
|
14719
14795
|
const msg = {
|
14720
14796
|
kind: 'setKey',
|
14721
14797
|
data: {
|
14722
|
-
|
14798
|
+
participantIdentity: participantIdentity,
|
14799
|
+
isPublisher: participantIdentity === ((_a = this.room) === null || _a === void 0 ? void 0 : _a.localParticipant.identity),
|
14723
14800
|
key,
|
14724
14801
|
keyIndex
|
14725
14802
|
}
|
14726
14803
|
};
|
14727
14804
|
this.worker.postMessage(msg);
|
14728
14805
|
}
|
14806
|
+
postEnable(enabled, participantIdentity) {
|
14807
|
+
if (this.worker) {
|
14808
|
+
const enableMsg = {
|
14809
|
+
kind: 'enable',
|
14810
|
+
data: {
|
14811
|
+
enabled,
|
14812
|
+
participantIdentity
|
14813
|
+
}
|
14814
|
+
};
|
14815
|
+
this.worker.postMessage(enableMsg);
|
14816
|
+
} else {
|
14817
|
+
throw new ReferenceError('failed to enable e2ee, worker is not ready');
|
14818
|
+
}
|
14819
|
+
}
|
14729
14820
|
postRTPMap(map) {
|
14821
|
+
var _a;
|
14730
14822
|
if (!this.worker) {
|
14731
|
-
throw
|
14823
|
+
throw TypeError('could not post rtp map, worker is missing');
|
14824
|
+
}
|
14825
|
+
if (!((_a = this.room) === null || _a === void 0 ? void 0 : _a.localParticipant.identity)) {
|
14826
|
+
throw TypeError('could not post rtp map, local participant identity is missing');
|
14732
14827
|
}
|
14733
14828
|
const msg = {
|
14734
14829
|
kind: 'setRTPMap',
|
14735
14830
|
data: {
|
14736
|
-
map
|
14831
|
+
map,
|
14832
|
+
participantIdentity: this.room.localParticipant.identity
|
14833
|
+
}
|
14834
|
+
};
|
14835
|
+
this.worker.postMessage(msg);
|
14836
|
+
}
|
14837
|
+
postSifTrailer(trailer) {
|
14838
|
+
if (!this.worker) {
|
14839
|
+
throw Error('could not post SIF trailer, worker is missing');
|
14840
|
+
}
|
14841
|
+
const msg = {
|
14842
|
+
kind: 'setSifTrailer',
|
14843
|
+
data: {
|
14844
|
+
trailer
|
14737
14845
|
}
|
14738
14846
|
};
|
14739
14847
|
this.worker.postMessage(msg);
|
@@ -14747,19 +14855,19 @@ class E2EEManager extends eventsExports.EventEmitter {
|
|
14747
14855
|
}
|
14748
14856
|
this.handleReceiver(track.receiver, track.mediaStreamID, remoteId, track.kind === 'video' ? mimeTypeToVideoCodecString(trackInfo.mimeType) : undefined);
|
14749
14857
|
}
|
14750
|
-
setupE2EESender(track, sender
|
14858
|
+
setupE2EESender(track, sender) {
|
14751
14859
|
if (!(track instanceof LocalTrack) || !sender) {
|
14752
14860
|
if (!sender) livekitLogger.warn('early return because sender is not ready');
|
14753
14861
|
return;
|
14754
14862
|
}
|
14755
|
-
this.handleSender(sender, track.mediaStreamID,
|
14863
|
+
this.handleSender(sender, track.mediaStreamID, undefined);
|
14756
14864
|
}
|
14757
14865
|
/**
|
14758
14866
|
* Handles the given {@code RTCRtpReceiver} by creating a {@code TransformStream} which will inject
|
14759
14867
|
* a frame decoder.
|
14760
14868
|
*
|
14761
14869
|
*/
|
14762
|
-
handleReceiver(receiver, trackId,
|
14870
|
+
handleReceiver(receiver, trackId, participantIdentity, codec) {
|
14763
14871
|
return __awaiter(this, void 0, void 0, function* () {
|
14764
14872
|
if (!this.worker) {
|
14765
14873
|
return;
|
@@ -14767,7 +14875,7 @@ class E2EEManager extends eventsExports.EventEmitter {
|
|
14767
14875
|
if (isScriptTransformSupported()) {
|
14768
14876
|
const options = {
|
14769
14877
|
kind: 'decode',
|
14770
|
-
|
14878
|
+
participantIdentity,
|
14771
14879
|
trackId,
|
14772
14880
|
codec
|
14773
14881
|
};
|
@@ -14781,7 +14889,7 @@ class E2EEManager extends eventsExports.EventEmitter {
|
|
14781
14889
|
data: {
|
14782
14890
|
trackId,
|
14783
14891
|
codec,
|
14784
|
-
|
14892
|
+
participantIdentity: participantIdentity
|
14785
14893
|
}
|
14786
14894
|
};
|
14787
14895
|
this.worker.postMessage(msg);
|
@@ -14808,7 +14916,7 @@ class E2EEManager extends eventsExports.EventEmitter {
|
|
14808
14916
|
writableStream: writable,
|
14809
14917
|
trackId: trackId,
|
14810
14918
|
codec,
|
14811
|
-
|
14919
|
+
participantIdentity: participantIdentity
|
14812
14920
|
}
|
14813
14921
|
};
|
14814
14922
|
this.worker.postMessage(msg, [readable, writable]);
|
@@ -14822,22 +14930,26 @@ class E2EEManager extends eventsExports.EventEmitter {
|
|
14822
14930
|
* a frame encoder.
|
14823
14931
|
*
|
14824
14932
|
*/
|
14825
|
-
handleSender(sender, trackId,
|
14933
|
+
handleSender(sender, trackId, codec) {
|
14934
|
+
var _a;
|
14826
14935
|
if (E2EE_FLAG in sender || !this.worker) {
|
14827
14936
|
return;
|
14828
14937
|
}
|
14938
|
+
if (!((_a = this.room) === null || _a === void 0 ? void 0 : _a.localParticipant.identity) || this.room.localParticipant.identity === '') {
|
14939
|
+
throw TypeError('local identity needs to be known in order to set up encrypted sender');
|
14940
|
+
}
|
14829
14941
|
if (isScriptTransformSupported()) {
|
14830
|
-
livekitLogger.
|
14942
|
+
livekitLogger.info('initialize script transform');
|
14831
14943
|
const options = {
|
14832
14944
|
kind: 'encode',
|
14833
|
-
|
14945
|
+
participantIdentity: this.room.localParticipant.identity,
|
14834
14946
|
trackId,
|
14835
14947
|
codec
|
14836
14948
|
};
|
14837
14949
|
// @ts-ignore
|
14838
14950
|
sender.transform = new RTCRtpScriptTransform(this.worker, options);
|
14839
14951
|
} else {
|
14840
|
-
livekitLogger.
|
14952
|
+
livekitLogger.info('initialize encoded streams');
|
14841
14953
|
// @ts-ignore
|
14842
14954
|
const senderStreams = sender.createEncodedStreams();
|
14843
14955
|
const msg = {
|
@@ -14847,7 +14959,7 @@ class E2EEManager extends eventsExports.EventEmitter {
|
|
14847
14959
|
writableStream: senderStreams.writable,
|
14848
14960
|
codec,
|
14849
14961
|
trackId,
|
14850
|
-
|
14962
|
+
participantIdentity: this.room.localParticipant.identity
|
14851
14963
|
}
|
14852
14964
|
};
|
14853
14965
|
this.worker.postMessage(msg, [senderStreams.readable, senderStreams.writable]);
|
@@ -15789,7 +15901,8 @@ class PCTransport extends eventsExports.EventEmitter {
|
|
15789
15901
|
return;
|
15790
15902
|
} catch (e) {
|
15791
15903
|
livekitLogger.warn("not able to set ".concat(sd.type, ", falling back to unmodified sdp"), {
|
15792
|
-
error: e
|
15904
|
+
error: e,
|
15905
|
+
sdp: munged
|
15793
15906
|
});
|
15794
15907
|
sd.sdp = originalSdp;
|
15795
15908
|
}
|
@@ -15809,6 +15922,14 @@ class PCTransport extends eventsExports.EventEmitter {
|
|
15809
15922
|
} else if (typeof e === 'string') {
|
15810
15923
|
msg = e;
|
15811
15924
|
}
|
15925
|
+
const fields = {
|
15926
|
+
error: msg,
|
15927
|
+
sdp: sd.sdp
|
15928
|
+
};
|
15929
|
+
if (!remote && this.pc.remoteDescription) {
|
15930
|
+
fields.remoteSdp = this.pc.remoteDescription;
|
15931
|
+
}
|
15932
|
+
livekitLogger.error("unable to set ".concat(sd.type), fields);
|
15812
15933
|
throw new NegotiationError(msg);
|
15813
15934
|
}
|
15814
15935
|
});
|
@@ -15941,7 +16062,8 @@ const roomOptionDefaults = {
|
|
15941
16062
|
const roomConnectOptionDefaults = {
|
15942
16063
|
autoSubscribe: true,
|
15943
16064
|
maxRetries: 1,
|
15944
|
-
peerConnectionTimeout: 15000
|
16065
|
+
peerConnectionTimeout: 15000,
|
16066
|
+
websocketTimeout: 15000
|
15945
16067
|
};
|
15946
16068
|
|
15947
16069
|
const lossyDataChannel = '_lossy';
|
@@ -16139,8 +16261,10 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
16139
16261
|
this.url = url;
|
16140
16262
|
this.token = token;
|
16141
16263
|
this.signalOpts = opts;
|
16264
|
+
this.maxJoinAttempts = opts.maxRetries;
|
16142
16265
|
try {
|
16143
16266
|
this.joinAttempts += 1;
|
16267
|
+
this.setupSignalClientCallbacks();
|
16144
16268
|
const joinResponse = yield this.client.join(url, token, opts, abortSignal);
|
16145
16269
|
this._isClosed = false;
|
16146
16270
|
this.latestJoinResponse = joinResponse;
|
@@ -16152,7 +16276,6 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
16152
16276
|
if (!this.subscriberPrimary) {
|
16153
16277
|
this.negotiate();
|
16154
16278
|
}
|
16155
|
-
this.setupSignalClientCallbacks();
|
16156
16279
|
this.clientConfiguration = joinResponse.clientConfiguration;
|
16157
16280
|
return joinResponse;
|
16158
16281
|
} catch (e) {
|
@@ -17157,6 +17280,7 @@ class LocalAudioTrack extends LocalTrack {
|
|
17157
17280
|
*/
|
17158
17281
|
constructor(mediaTrack, constraints) {
|
17159
17282
|
let userProvidedTrack = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
17283
|
+
let audioContext = arguments.length > 3 ? arguments[3] : undefined;
|
17160
17284
|
super(mediaTrack, Track.Kind.Audio, constraints, userProvidedTrack);
|
17161
17285
|
/** @internal */
|
17162
17286
|
this.stopOnMute = false;
|
@@ -17179,6 +17303,7 @@ class LocalAudioTrack extends LocalTrack {
|
|
17179
17303
|
}
|
17180
17304
|
this.prevStats = stats;
|
17181
17305
|
});
|
17306
|
+
this.audioContext = audioContext;
|
17182
17307
|
this.checkForSilence();
|
17183
17308
|
}
|
17184
17309
|
setDeviceId(deviceId) {
|
@@ -17274,6 +17399,43 @@ class LocalAudioTrack extends LocalTrack {
|
|
17274
17399
|
this.monitorSender();
|
17275
17400
|
}, monitorFrequency);
|
17276
17401
|
}
|
17402
|
+
setProcessor(processor) {
|
17403
|
+
var _a;
|
17404
|
+
return __awaiter(this, void 0, void 0, function* () {
|
17405
|
+
const unlock = yield this.processorLock.lock();
|
17406
|
+
try {
|
17407
|
+
if (!this.audioContext) {
|
17408
|
+
throw Error('Audio context needs to be set on LocalAudioTrack in order to enable processors');
|
17409
|
+
}
|
17410
|
+
if (this.processor) {
|
17411
|
+
yield this.stopProcessor();
|
17412
|
+
}
|
17413
|
+
if (this.kind === 'unknown') {
|
17414
|
+
throw TypeError('cannot set processor on track of unknown kind');
|
17415
|
+
}
|
17416
|
+
const processorOptions = {
|
17417
|
+
kind: this.kind,
|
17418
|
+
track: this._mediaStreamTrack,
|
17419
|
+
audioContext: this.audioContext
|
17420
|
+
};
|
17421
|
+
livekitLogger.debug("setting up audio processor ".concat(processor.name));
|
17422
|
+
yield processor.init(processorOptions);
|
17423
|
+
this.processor = processor;
|
17424
|
+
if (this.processor.processedTrack) {
|
17425
|
+
yield (_a = this.sender) === null || _a === void 0 ? void 0 : _a.replaceTrack(this.processor.processedTrack);
|
17426
|
+
}
|
17427
|
+
} finally {
|
17428
|
+
unlock();
|
17429
|
+
}
|
17430
|
+
});
|
17431
|
+
}
|
17432
|
+
/**
|
17433
|
+
* @internal
|
17434
|
+
* @experimental
|
17435
|
+
*/
|
17436
|
+
setAudioContext(audioContext) {
|
17437
|
+
this.audioContext = audioContext;
|
17438
|
+
}
|
17277
17439
|
getSenderStats() {
|
17278
17440
|
var _a;
|
17279
17441
|
return __awaiter(this, void 0, void 0, function* () {
|
@@ -17687,6 +17849,66 @@ class LocalVideoTrack extends LocalTrack {
|
|
17687
17849
|
});
|
17688
17850
|
super.stop();
|
17689
17851
|
}
|
17852
|
+
pauseUpstream() {
|
17853
|
+
const _super = Object.create(null, {
|
17854
|
+
pauseUpstream: {
|
17855
|
+
get: () => super.pauseUpstream
|
17856
|
+
}
|
17857
|
+
});
|
17858
|
+
var _a, e_1, _b, _c;
|
17859
|
+
var _d;
|
17860
|
+
return __awaiter(this, void 0, void 0, function* () {
|
17861
|
+
yield _super.pauseUpstream.call(this);
|
17862
|
+
try {
|
17863
|
+
for (var _e = true, _f = __asyncValues(this.simulcastCodecs.values()), _g; _g = yield _f.next(), _a = _g.done, !_a; _e = true) {
|
17864
|
+
_c = _g.value;
|
17865
|
+
_e = false;
|
17866
|
+
const sc = _c;
|
17867
|
+
yield (_d = sc.sender) === null || _d === void 0 ? void 0 : _d.replaceTrack(null);
|
17868
|
+
}
|
17869
|
+
} catch (e_1_1) {
|
17870
|
+
e_1 = {
|
17871
|
+
error: e_1_1
|
17872
|
+
};
|
17873
|
+
} finally {
|
17874
|
+
try {
|
17875
|
+
if (!_e && !_a && (_b = _f.return)) yield _b.call(_f);
|
17876
|
+
} finally {
|
17877
|
+
if (e_1) throw e_1.error;
|
17878
|
+
}
|
17879
|
+
}
|
17880
|
+
});
|
17881
|
+
}
|
17882
|
+
resumeUpstream() {
|
17883
|
+
const _super = Object.create(null, {
|
17884
|
+
resumeUpstream: {
|
17885
|
+
get: () => super.resumeUpstream
|
17886
|
+
}
|
17887
|
+
});
|
17888
|
+
var _a, e_2, _b, _c;
|
17889
|
+
var _d;
|
17890
|
+
return __awaiter(this, void 0, void 0, function* () {
|
17891
|
+
yield _super.resumeUpstream.call(this);
|
17892
|
+
try {
|
17893
|
+
for (var _e = true, _f = __asyncValues(this.simulcastCodecs.values()), _g; _g = yield _f.next(), _a = _g.done, !_a; _e = true) {
|
17894
|
+
_c = _g.value;
|
17895
|
+
_e = false;
|
17896
|
+
const sc = _c;
|
17897
|
+
yield (_d = sc.sender) === null || _d === void 0 ? void 0 : _d.replaceTrack(sc.mediaStreamTrack);
|
17898
|
+
}
|
17899
|
+
} catch (e_2_1) {
|
17900
|
+
e_2 = {
|
17901
|
+
error: e_2_1
|
17902
|
+
};
|
17903
|
+
} finally {
|
17904
|
+
try {
|
17905
|
+
if (!_e && !_a && (_b = _f.return)) yield _b.call(_f);
|
17906
|
+
} finally {
|
17907
|
+
if (e_2) throw e_2.error;
|
17908
|
+
}
|
17909
|
+
}
|
17910
|
+
});
|
17911
|
+
}
|
17690
17912
|
mute() {
|
17691
17913
|
const _super = Object.create(null, {
|
17692
17914
|
mute: {
|
@@ -17728,6 +17950,12 @@ class LocalVideoTrack extends LocalTrack {
|
|
17728
17950
|
}
|
17729
17951
|
});
|
17730
17952
|
}
|
17953
|
+
setTrackMuted(muted) {
|
17954
|
+
super.setTrackMuted(muted);
|
17955
|
+
for (const sc of this.simulcastCodecs.values()) {
|
17956
|
+
sc.mediaStreamTrack.enabled = !muted;
|
17957
|
+
}
|
17958
|
+
}
|
17731
17959
|
getSenderStats() {
|
17732
17960
|
var _a;
|
17733
17961
|
return __awaiter(this, void 0, void 0, function* () {
|
@@ -17795,6 +18023,7 @@ class LocalVideoTrack extends LocalTrack {
|
|
17795
18023
|
});
|
17796
18024
|
}
|
17797
18025
|
restartTrack(options) {
|
18026
|
+
var _a, e_3, _b, _c;
|
17798
18027
|
return __awaiter(this, void 0, void 0, function* () {
|
17799
18028
|
let constraints;
|
17800
18029
|
if (options) {
|
@@ -17806,6 +18035,60 @@ class LocalVideoTrack extends LocalTrack {
|
|
17806
18035
|
}
|
17807
18036
|
}
|
17808
18037
|
yield this.restart(constraints);
|
18038
|
+
try {
|
18039
|
+
for (var _d = true, _e = __asyncValues(this.simulcastCodecs.values()), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
|
18040
|
+
_c = _f.value;
|
18041
|
+
_d = false;
|
18042
|
+
const sc = _c;
|
18043
|
+
if (sc.sender) {
|
18044
|
+
sc.mediaStreamTrack = this.mediaStreamTrack.clone();
|
18045
|
+
yield sc.sender.replaceTrack(sc.mediaStreamTrack);
|
18046
|
+
}
|
18047
|
+
}
|
18048
|
+
} catch (e_3_1) {
|
18049
|
+
e_3 = {
|
18050
|
+
error: e_3_1
|
18051
|
+
};
|
18052
|
+
} finally {
|
18053
|
+
try {
|
18054
|
+
if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
|
18055
|
+
} finally {
|
18056
|
+
if (e_3) throw e_3.error;
|
18057
|
+
}
|
18058
|
+
}
|
18059
|
+
});
|
18060
|
+
}
|
18061
|
+
setProcessor(processor) {
|
18062
|
+
let showProcessedStreamLocally = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
18063
|
+
const _super = Object.create(null, {
|
18064
|
+
setProcessor: {
|
18065
|
+
get: () => super.setProcessor
|
18066
|
+
}
|
18067
|
+
});
|
18068
|
+
var _a, e_4, _b, _c;
|
18069
|
+
var _d, _e;
|
18070
|
+
return __awaiter(this, void 0, void 0, function* () {
|
18071
|
+
yield _super.setProcessor.call(this, processor, showProcessedStreamLocally);
|
18072
|
+
if ((_d = this.processor) === null || _d === void 0 ? void 0 : _d.processedTrack) {
|
18073
|
+
try {
|
18074
|
+
for (var _f = true, _g = __asyncValues(this.simulcastCodecs.values()), _h; _h = yield _g.next(), _a = _h.done, !_a; _f = true) {
|
18075
|
+
_c = _h.value;
|
18076
|
+
_f = false;
|
18077
|
+
const sc = _c;
|
18078
|
+
yield (_e = sc.sender) === null || _e === void 0 ? void 0 : _e.replaceTrack(this.processor.processedTrack);
|
18079
|
+
}
|
18080
|
+
} catch (e_4_1) {
|
18081
|
+
e_4 = {
|
18082
|
+
error: e_4_1
|
18083
|
+
};
|
18084
|
+
} finally {
|
18085
|
+
try {
|
18086
|
+
if (!_f && !_a && (_b = _g.return)) yield _b.call(_g);
|
18087
|
+
} finally {
|
18088
|
+
if (e_4) throw e_4.error;
|
18089
|
+
}
|
18090
|
+
}
|
18091
|
+
}
|
17809
18092
|
});
|
17810
18093
|
}
|
17811
18094
|
addSimulcastTrack(codec, encodings) {
|
@@ -17841,7 +18124,7 @@ class LocalVideoTrack extends LocalTrack {
|
|
17841
18124
|
*/
|
17842
18125
|
setPublishingCodecs(codecs) {
|
17843
18126
|
var _a, codecs_1, codecs_1_1;
|
17844
|
-
var _b,
|
18127
|
+
var _b, e_5, _c, _d;
|
17845
18128
|
return __awaiter(this, void 0, void 0, function* () {
|
17846
18129
|
livekitLogger.debug('setting publishing codecs', {
|
17847
18130
|
codecs,
|
@@ -17877,15 +18160,15 @@ class LocalVideoTrack extends LocalTrack {
|
|
17877
18160
|
}
|
17878
18161
|
}
|
17879
18162
|
}
|
17880
|
-
} catch (
|
17881
|
-
|
17882
|
-
error:
|
18163
|
+
} catch (e_5_1) {
|
18164
|
+
e_5 = {
|
18165
|
+
error: e_5_1
|
17883
18166
|
};
|
17884
18167
|
} finally {
|
17885
18168
|
try {
|
17886
18169
|
if (!_a && !_b && (_c = codecs_1.return)) yield _c.call(codecs_1);
|
17887
18170
|
} finally {
|
17888
|
-
if (
|
18171
|
+
if (e_5) throw e_5.error;
|
17889
18172
|
}
|
17890
18173
|
}
|
17891
18174
|
return newCodecs;
|
@@ -18121,6 +18404,10 @@ class RemoteAudioTrack extends RemoteTrack {
|
|
18121
18404
|
el.volume = volume;
|
18122
18405
|
}
|
18123
18406
|
}
|
18407
|
+
if (isReactNative()) {
|
18408
|
+
// @ts-ignore
|
18409
|
+
this._mediaStreamTrack._setVolume(volume);
|
18410
|
+
}
|
18124
18411
|
this.elementVolume = volume;
|
18125
18412
|
}
|
18126
18413
|
/**
|
@@ -18130,6 +18417,10 @@ class RemoteAudioTrack extends RemoteTrack {
|
|
18130
18417
|
if (this.elementVolume) {
|
18131
18418
|
return this.elementVolume;
|
18132
18419
|
}
|
18420
|
+
if (isReactNative()) {
|
18421
|
+
// RN volume value defaults to 1.0 if hasn't been changed.
|
18422
|
+
return 1.0;
|
18423
|
+
}
|
18133
18424
|
let highestVolume = 0;
|
18134
18425
|
this.attachedElements.forEach(element => {
|
18135
18426
|
if (element.volume > highestVolume) {
|
@@ -18923,6 +19214,13 @@ class Participant extends eventsExports.EventEmitter {
|
|
18923
19214
|
this.emit(ParticipantEvent.ConnectionQualityChanged, this._connectionQuality);
|
18924
19215
|
}
|
18925
19216
|
}
|
19217
|
+
/**
|
19218
|
+
* @internal
|
19219
|
+
*/
|
19220
|
+
setAudioContext(ctx) {
|
19221
|
+
this.audioContext = ctx;
|
19222
|
+
this.audioTracks.forEach(track => (track.track instanceof RemoteAudioTrack || track.track instanceof LocalAudioTrack) && track.track.setAudioContext(ctx));
|
19223
|
+
}
|
18926
19224
|
addTrackPublication(publication) {
|
18927
19225
|
// forward publication driven events
|
18928
19226
|
publication.on(TrackEvent.Muted, () => {
|
@@ -19192,8 +19490,8 @@ class RemoteTrackPublication extends TrackPublication {
|
|
19192
19490
|
fps: this.fps
|
19193
19491
|
});
|
19194
19492
|
if (this.videoDimensions) {
|
19195
|
-
settings.width = this.videoDimensions.width;
|
19196
|
-
settings.height = this.videoDimensions.height;
|
19493
|
+
settings.width = Math.ceil(this.videoDimensions.width);
|
19494
|
+
settings.height = Math.ceil(this.videoDimensions.height);
|
19197
19495
|
} else if (this.currentVideoQuality !== undefined) {
|
19198
19496
|
settings.quality = this.currentVideoQuality;
|
19199
19497
|
} else {
|
@@ -19436,13 +19734,6 @@ class RemoteParticipant extends Participant {
|
|
19436
19734
|
this.emit(ParticipantEvent.TrackUnpublished, publication);
|
19437
19735
|
}
|
19438
19736
|
}
|
19439
|
-
/**
|
19440
|
-
* @internal
|
19441
|
-
*/
|
19442
|
-
setAudioContext(ctx) {
|
19443
|
-
this.audioContext = ctx;
|
19444
|
-
this.audioTracks.forEach(track => track.track instanceof RemoteAudioTrack && track.track.setAudioContext(ctx));
|
19445
|
-
}
|
19446
19737
|
/**
|
19447
19738
|
* @internal
|
19448
19739
|
*/
|
@@ -19645,6 +19936,9 @@ class LocalParticipant extends Participant {
|
|
19645
19936
|
get lastMicrophoneError() {
|
19646
19937
|
return this.microphoneError;
|
19647
19938
|
}
|
19939
|
+
get isE2EEEnabled() {
|
19940
|
+
return this.encryptionType !== Encryption_Type.NONE;
|
19941
|
+
}
|
19648
19942
|
getTrack(source) {
|
19649
19943
|
const track = super.getTrack(source);
|
19650
19944
|
if (track) {
|
@@ -19914,7 +20208,7 @@ class LocalParticipant extends Participant {
|
|
19914
20208
|
screenVideo.source = Track.Source.ScreenShare;
|
19915
20209
|
const localTracks = [screenVideo];
|
19916
20210
|
if (stream.getAudioTracks().length > 0) {
|
19917
|
-
const screenAudio = new LocalAudioTrack(stream.getAudioTracks()[0], undefined, false);
|
20211
|
+
const screenAudio = new LocalAudioTrack(stream.getAudioTracks()[0], undefined, false, this.audioContext);
|
19918
20212
|
screenAudio.source = Track.Source.ScreenShareAudio;
|
19919
20213
|
localTracks.push(screenAudio);
|
19920
20214
|
}
|
@@ -19958,7 +20252,7 @@ class LocalParticipant extends Participant {
|
|
19958
20252
|
if (track instanceof MediaStreamTrack) {
|
19959
20253
|
switch (track.kind) {
|
19960
20254
|
case 'audio':
|
19961
|
-
track = new LocalAudioTrack(track, defaultConstraints, true);
|
20255
|
+
track = new LocalAudioTrack(track, defaultConstraints, true, this.audioContext);
|
19962
20256
|
break;
|
19963
20257
|
case 'video':
|
19964
20258
|
track = new LocalVideoTrack(track, defaultConstraints, true);
|
@@ -19967,6 +20261,9 @@ class LocalParticipant extends Participant {
|
|
19967
20261
|
throw new TrackInvalidError("unsupported MediaStreamTrack kind ".concat(track.kind));
|
19968
20262
|
}
|
19969
20263
|
}
|
20264
|
+
if (track instanceof LocalAudioTrack) {
|
20265
|
+
track.setAudioContext(this.audioContext);
|
20266
|
+
}
|
19970
20267
|
// is it already published? if so skip
|
19971
20268
|
let existingPublication;
|
19972
20269
|
this.tracks.forEach(publication => {
|
@@ -20104,6 +20401,9 @@ class LocalParticipant extends Participant {
|
|
20104
20401
|
}
|
20105
20402
|
// set up backup
|
20106
20403
|
if (opts.videoCodec && opts.backupCodec && opts.videoCodec !== opts.backupCodec.codec) {
|
20404
|
+
if (!this.roomOptions.dynacast) {
|
20405
|
+
this.roomOptions.dynacast = true;
|
20406
|
+
}
|
20107
20407
|
const simOpts = Object.assign({}, opts);
|
20108
20408
|
simOpts.simulcast = true;
|
20109
20409
|
simEncodings = computeTrackBackupEncodings(track, opts.backupCodec.codec, simOpts);
|
@@ -20602,11 +20902,13 @@ class Room extends eventsExports.EventEmitter {
|
|
20602
20902
|
if (this.abortController) {
|
20603
20903
|
this.abortController.abort();
|
20604
20904
|
}
|
20605
|
-
|
20905
|
+
// explicit creation as local var needed to satisfy TS compiler when passing it to `attemptConnection` further down
|
20906
|
+
const abortController = new AbortController();
|
20907
|
+
this.abortController = abortController;
|
20606
20908
|
// at this point the intention to connect has been signalled so we can allow cancelling of the connection via disconnect() again
|
20607
20909
|
unlockDisconnect === null || unlockDisconnect === void 0 ? void 0 : unlockDisconnect();
|
20608
20910
|
try {
|
20609
|
-
yield this.attemptConnection(regionUrl !== null && regionUrl !== void 0 ? regionUrl : url, token, opts,
|
20911
|
+
yield this.attemptConnection(regionUrl !== null && regionUrl !== void 0 ? regionUrl : url, token, opts, abortController);
|
20610
20912
|
this.abortController = undefined;
|
20611
20913
|
resolve();
|
20612
20914
|
} catch (e) {
|
@@ -20648,7 +20950,8 @@ class Room extends eventsExports.EventEmitter {
|
|
20648
20950
|
publishOnly: connectOptions.publishOnly,
|
20649
20951
|
adaptiveStream: typeof roomOptions.adaptiveStream === 'object' ? true : roomOptions.adaptiveStream,
|
20650
20952
|
maxRetries: connectOptions.maxRetries,
|
20651
|
-
e2eeEnabled: !!this.e2eeManager
|
20953
|
+
e2eeEnabled: !!this.e2eeManager,
|
20954
|
+
websocketTimeout: connectOptions.websocketTimeout
|
20652
20955
|
}, abortController.signal);
|
20653
20956
|
let serverInfo = joinResponse.serverInfo;
|
20654
20957
|
if (!serverInfo) {
|
@@ -20680,6 +20983,9 @@ class Room extends eventsExports.EventEmitter {
|
|
20680
20983
|
if (joinResponse.room) {
|
20681
20984
|
this.handleRoomUpdate(joinResponse.room);
|
20682
20985
|
}
|
20986
|
+
if (this.options.e2ee && this.e2eeManager) {
|
20987
|
+
this.e2eeManager.setSifTrailer(joinResponse.sifTrailer);
|
20988
|
+
}
|
20683
20989
|
};
|
20684
20990
|
this.attemptConnection = (url, token, opts, abortController) => __awaiter(this, void 0, void 0, function* () {
|
20685
20991
|
var _d, _e;
|
@@ -21098,7 +21404,10 @@ class Room extends eventsExports.EventEmitter {
|
|
21098
21404
|
setE2EEEnabled(enabled) {
|
21099
21405
|
return __awaiter(this, void 0, void 0, function* () {
|
21100
21406
|
if (this.e2eeManager) {
|
21101
|
-
yield Promise.all([this.localParticipant.setE2EEEnabled(enabled)
|
21407
|
+
yield Promise.all([this.localParticipant.setE2EEEnabled(enabled)]);
|
21408
|
+
if (this.localParticipant.identity !== '') {
|
21409
|
+
this.e2eeManager.setParticipantCryptorEnabled(enabled, this.localParticipant.identity);
|
21410
|
+
}
|
21102
21411
|
} else {
|
21103
21412
|
throw Error('e2ee not configured, please set e2ee settings within the room options');
|
21104
21413
|
}
|
@@ -21114,7 +21423,7 @@ class Room extends eventsExports.EventEmitter {
|
|
21114
21423
|
}
|
21115
21424
|
this.emit(RoomEvent.ParticipantEncryptionStatusChanged, enabled, participant);
|
21116
21425
|
});
|
21117
|
-
this.e2eeManager.on(EncryptionEvent.
|
21426
|
+
this.e2eeManager.on(EncryptionEvent.EncryptionError, error => this.emit(RoomEvent.EncryptionError, error));
|
21118
21427
|
(_a = this.e2eeManager) === null || _a === void 0 ? void 0 : _a.setup(this);
|
21119
21428
|
}
|
21120
21429
|
}
|
@@ -21258,7 +21567,7 @@ class Room extends eventsExports.EventEmitter {
|
|
21258
21567
|
/**
|
21259
21568
|
* @internal for testing
|
21260
21569
|
*/
|
21261
|
-
simulateScenario(scenario) {
|
21570
|
+
simulateScenario(scenario, arg) {
|
21262
21571
|
return __awaiter(this, void 0, void 0, function* () {
|
21263
21572
|
let postAction = () => {};
|
21264
21573
|
let req;
|
@@ -21327,6 +21636,17 @@ class Room extends eventsExports.EventEmitter {
|
|
21327
21636
|
}
|
21328
21637
|
});
|
21329
21638
|
break;
|
21639
|
+
case 'subscriber-bandwidth':
|
21640
|
+
if (arg === undefined || typeof arg !== 'number') {
|
21641
|
+
throw new Error('subscriber-bandwidth requires a number as argument');
|
21642
|
+
}
|
21643
|
+
req = new SimulateScenario({
|
21644
|
+
scenario: {
|
21645
|
+
case: 'subscriberBandwidth',
|
21646
|
+
value: BigInt(arg)
|
21647
|
+
}
|
21648
|
+
});
|
21649
|
+
break;
|
21330
21650
|
}
|
21331
21651
|
if (req) {
|
21332
21652
|
this.engine.client.sendSimulateScenario(req);
|
@@ -21343,7 +21663,6 @@ class Room extends eventsExports.EventEmitter {
|
|
21343
21663
|
*/
|
21344
21664
|
startAudio() {
|
21345
21665
|
return __awaiter(this, void 0, void 0, function* () {
|
21346
|
-
yield this.acquireAudioContext();
|
21347
21666
|
const elements = [];
|
21348
21667
|
const browser = getBrowser();
|
21349
21668
|
if (browser && browser.os === 'iOS') {
|
@@ -21390,10 +21709,10 @@ class Room extends eventsExports.EventEmitter {
|
|
21390
21709
|
});
|
21391
21710
|
});
|
21392
21711
|
try {
|
21393
|
-
yield Promise.all(elements.map(e => {
|
21712
|
+
yield Promise.all([this.acquireAudioContext(), ...elements.map(e => {
|
21394
21713
|
e.muted = false;
|
21395
21714
|
return e.play();
|
21396
|
-
}));
|
21715
|
+
})]);
|
21397
21716
|
this.handleAudioPlaybackStarted();
|
21398
21717
|
} catch (err) {
|
21399
21718
|
this.handleAudioPlaybackFailed(err);
|
@@ -21542,7 +21861,11 @@ class Room extends eventsExports.EventEmitter {
|
|
21542
21861
|
livekitLogger.warn('tried to create RemoteParticipant for local participant');
|
21543
21862
|
return;
|
21544
21863
|
}
|
21545
|
-
const participant = this.
|
21864
|
+
const participant = this.participants.get(participantId);
|
21865
|
+
if (!participant) {
|
21866
|
+
livekitLogger.error("Tried to add a track for a participant, that's not present. Sid: ".concat(participantId));
|
21867
|
+
return;
|
21868
|
+
}
|
21546
21869
|
let adaptiveStreamSettings;
|
21547
21870
|
if (this.options.adaptiveStream) {
|
21548
21871
|
if (typeof this.options.adaptiveStream === 'object') {
|
@@ -21634,6 +21957,7 @@ class Room extends eventsExports.EventEmitter {
|
|
21634
21957
|
if (this.options.expWebAudioMix) {
|
21635
21958
|
this.participants.forEach(participant => participant.setAudioContext(this.audioContext));
|
21636
21959
|
}
|
21960
|
+
this.localParticipant.setAudioContext(this.audioContext);
|
21637
21961
|
const newContextIsRunning = ((_b = this.audioContext) === null || _b === void 0 ? void 0 : _b.state) === 'running';
|
21638
21962
|
if (newContextIsRunning !== this.canPlaybackAudio) {
|
21639
21963
|
this.audioEnabled = newContextIsRunning;
|
@@ -21657,16 +21981,12 @@ class Room extends eventsExports.EventEmitter {
|
|
21657
21981
|
if (this.participants.has(id)) {
|
21658
21982
|
return this.participants.get(id);
|
21659
21983
|
}
|
21660
|
-
// it's possible for the RTC track to arrive before signaling data
|
21661
|
-
// when this happens, we'll create the participant and make the track work
|
21662
21984
|
const participant = this.createParticipant(id, info);
|
21663
21985
|
this.participants.set(id, participant);
|
21664
|
-
|
21665
|
-
|
21666
|
-
|
21667
|
-
|
21668
|
-
this.emitWhenConnected(RoomEvent.ParticipantConnected, participant);
|
21669
|
-
}
|
21986
|
+
this.identityToSid.set(info.identity, info.sid);
|
21987
|
+
// if we have valid info and the participant wasn't in the map before, we can assume the participant is new
|
21988
|
+
// firing here to make sure that `ParticipantConnected` fires before the initial track events
|
21989
|
+
this.emitWhenConnected(RoomEvent.ParticipantConnected, participant);
|
21670
21990
|
// also forward events
|
21671
21991
|
// trackPublished is only fired for tracks added after both local participant
|
21672
21992
|
// and remote participant joined the room
|
@@ -22262,7 +22582,8 @@ class TURNCheck extends Checker {
|
|
22262
22582
|
const joinRes = yield signalClient.join(this.url, this.token, {
|
22263
22583
|
autoSubscribe: true,
|
22264
22584
|
maxRetries: 0,
|
22265
|
-
e2eeEnabled: false
|
22585
|
+
e2eeEnabled: false,
|
22586
|
+
websocketTimeout: 15000
|
22266
22587
|
});
|
22267
22588
|
let hasTLS = false;
|
22268
22589
|
let hasTURN = false;
|
@@ -22314,18 +22635,19 @@ class WebRTCCheck extends Checker {
|
|
22314
22635
|
this.room.on(RoomEvent.SignalConnected, () => {
|
22315
22636
|
const prevTrickle = this.room.engine.client.onTrickle;
|
22316
22637
|
this.room.engine.client.onTrickle = (sd, target) => {
|
22317
|
-
console.log('got candidate', sd);
|
22318
22638
|
if (sd.candidate) {
|
22319
22639
|
const candidate = new RTCIceCandidate(sd);
|
22320
22640
|
let str = "".concat(candidate.protocol, " ").concat(candidate.address, ":").concat(candidate.port, " ").concat(candidate.type);
|
22321
|
-
if (candidate.
|
22322
|
-
hasTcp = true;
|
22323
|
-
str += ' (active)';
|
22324
|
-
} else if (candidate.protocol === 'udp' && candidate.address) {
|
22641
|
+
if (candidate.address) {
|
22325
22642
|
if (isIPPrivate(candidate.address)) {
|
22326
22643
|
str += ' (private)';
|
22327
22644
|
} else {
|
22328
|
-
|
22645
|
+
if (candidate.protocol === 'tcp' && candidate.tcpType === 'passive') {
|
22646
|
+
hasTcp = true;
|
22647
|
+
str += ' (passive)';
|
22648
|
+
} else if (candidate.protocol === 'udp') {
|
22649
|
+
hasIpv4Udp = true;
|
22650
|
+
}
|
22329
22651
|
}
|
22330
22652
|
}
|
22331
22653
|
this.appendMessage(str);
|
@@ -22344,7 +22666,7 @@ class WebRTCCheck extends Checker {
|
|
22344
22666
|
});
|
22345
22667
|
try {
|
22346
22668
|
yield this.connect();
|
22347
|
-
|
22669
|
+
livekitLogger.info('now the room is connected');
|
22348
22670
|
} catch (err) {
|
22349
22671
|
this.appendWarning('ports need to be open on firewall in order to connect.');
|
22350
22672
|
throw err;
|
@@ -22389,7 +22711,8 @@ class WebSocketCheck extends Checker {
|
|
22389
22711
|
const joinRes = yield signalClient.join(this.url, this.token, {
|
22390
22712
|
autoSubscribe: true,
|
22391
22713
|
maxRetries: 0,
|
22392
|
-
e2eeEnabled: false
|
22714
|
+
e2eeEnabled: false,
|
22715
|
+
websocketTimeout: 15000
|
22393
22716
|
});
|
22394
22717
|
this.appendMessage("Connected to server, version ".concat(joinRes.serverVersion, "."));
|
22395
22718
|
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)) {
|
@@ -22495,7 +22818,7 @@ function facingModeFromLocalTrack(localTrack) {
|
|
22495
22818
|
// 1. Try to get facingMode from track settings.
|
22496
22819
|
if ('facingMode' in trackSettings) {
|
22497
22820
|
const rawFacingMode = trackSettings.facingMode;
|
22498
|
-
|
22821
|
+
livekitLogger.debug('rawFacingMode', {
|
22499
22822
|
rawFacingMode
|
22500
22823
|
});
|
22501
22824
|
if (rawFacingMode && typeof rawFacingMode === 'string' && isFacingModeValue(rawFacingMode)) {
|
@@ -22507,7 +22830,7 @@ function facingModeFromLocalTrack(localTrack) {
|
|
22507
22830
|
}
|
22508
22831
|
// 2. If we don't have a high confidence we try to get the facing mode from the device label.
|
22509
22832
|
if (['low', 'medium'].includes(result.confidence)) {
|
22510
|
-
|
22833
|
+
livekitLogger.debug("Try to get facing mode from device label: (".concat(track.label, ")"));
|
22511
22834
|
const labelAnalysisResult = facingModeFromDeviceLabel(track.label);
|
22512
22835
|
if (labelAnalysisResult !== undefined) {
|
22513
22836
|
result = labelAnalysisResult;
|
@@ -22553,5 +22876,5 @@ function isFacingModeValue(item) {
|
|
22553
22876
|
return item === undefined || allowedValues.includes(item);
|
22554
22877
|
}
|
22555
22878
|
|
22556
|
-
export { AudioPresets, BaseKeyProvider, ConnectionCheck, ConnectionError, ConnectionQuality, ConnectionState, CriticalTimers, CryptorEvent, DataPacket_Kind, DefaultReconnectPolicy, DeviceUnsupportedError, DisconnectReason, EncryptionEvent, EngineEvent, ExternalE2EEKeyProvider, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalVideoTrack, LogLevel, MediaDeviceFailure, NegotiationError, Participant, ParticipantEvent, PublishDataError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, RoomState, ScreenSharePresets, Track, TrackEvent, TrackInvalidError, TrackPublication, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, attachToElement, createAudioAnalyser, createE2EEKey, createKeyMaterialFromString, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, deriveKeys, detachTrack, facingModeFromDeviceLabel, facingModeFromLocalTrack, getEmptyAudioStreamTrack, getEmptyVideoStreamTrack, importKey, isBackupCodec, isBrowserSupported, isCodecEqual, isE2EESupported, isInsertableStreamSupported, isScriptTransformSupported, isVideoFrame, mimeTypeToVideoCodecString, protocolVersion, ratchet, setLogExtension, setLogLevel, supportsAV1, supportsAdaptiveStream, supportsDynacast, supportsVP9, version, videoCodecs };
|
22879
|
+
export { AudioPresets, BaseKeyProvider, ConnectionCheck, ConnectionError, ConnectionQuality, ConnectionState, CriticalTimers, CryptorEvent, DataPacket_Kind, DefaultReconnectPolicy, DeviceUnsupportedError, DisconnectReason, EncryptionEvent, EngineEvent, ExternalE2EEKeyProvider, KeyHandlerEvent, KeyProviderEvent, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalVideoTrack, LogLevel, MediaDeviceFailure, NegotiationError, Participant, ParticipantEvent, PublishDataError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, RoomState, ScreenSharePresets, Track, TrackEvent, TrackInvalidError, TrackPublication, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, attachToElement, createAudioAnalyser, createE2EEKey, createKeyMaterialFromBuffer, createKeyMaterialFromString, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, deriveKeys, detachTrack, facingModeFromDeviceLabel, facingModeFromLocalTrack, getEmptyAudioStreamTrack, getEmptyVideoStreamTrack, importKey, isBackupCodec, isBrowserSupported, isCodecEqual, isE2EESupported, isInsertableStreamSupported, isScriptTransformSupported, isVideoFrame, mimeTypeToVideoCodecString, protocolVersion, ratchet, setLogExtension, setLogLevel, supportsAV1, supportsAdaptiveStream, supportsDynacast, supportsVP9, version, videoCodecs };
|
22557
22880
|
//# sourceMappingURL=livekit-client.esm.mjs.map
|