livekit-client 1.7.0 → 1.7.1
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/livekit-client.esm.mjs +83 -28
- 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/options.d.ts +5 -0
- package/dist/src/options.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts +1 -0
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts +2 -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/events.d.ts +7 -0
- package/dist/src/room/events.d.ts.map +1 -1
- package/dist/src/room/track/LocalAudioTrack.d.ts +1 -1
- package/dist/src/room/track/LocalAudioTrack.d.ts.map +1 -1
- package/dist/src/room/track/RemoteTrackPublication.d.ts.map +1 -1
- package/dist/src/room/track/RemoteVideoTrack.d.ts +1 -0
- package/dist/src/room/track/RemoteVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/utils.d.ts.map +1 -1
- package/dist/ts4.2/src/options.d.ts +5 -0
- package/dist/ts4.2/src/room/RTCEngine.d.ts +1 -0
- package/dist/ts4.2/src/room/Room.d.ts +2 -1
- package/dist/ts4.2/src/room/events.d.ts +7 -0
- package/dist/ts4.2/src/room/track/LocalAudioTrack.d.ts +1 -1
- package/dist/ts4.2/src/room/track/RemoteVideoTrack.d.ts +1 -0
- package/package.json +1 -1
- package/src/options.ts +6 -0
- package/src/room/RTCEngine.ts +25 -16
- package/src/room/Room.ts +15 -5
- package/src/room/defaults.ts +1 -0
- package/src/room/events.ts +8 -0
- package/src/room/track/LocalAudioTrack.ts +1 -0
- package/src/room/track/RemoteTrackPublication.ts +6 -1
- package/src/room/track/RemoteVideoTrack.test.ts +2 -0
- package/src/room/track/RemoteVideoTrack.ts +48 -5
- package/src/room/track/utils.ts +3 -2
@@ -12916,6 +12916,13 @@ var RoomEvent;
|
|
12916
12916
|
* args: ([[LocalTrackPublication]], [[LocalParticipant]])
|
12917
12917
|
*/
|
12918
12918
|
RoomEvent["LocalTrackUnpublished"] = "localTrackUnpublished";
|
12919
|
+
/**
|
12920
|
+
* When a local audio track is published the SDK checks whether there is complete silence
|
12921
|
+
* on that track and emits the LocalAudioSilenceDetected event in that case.
|
12922
|
+
* This allows for applications to show UI informing users that they might have to
|
12923
|
+
* reset their audio hardware or check for proper device connectivity.
|
12924
|
+
*/
|
12925
|
+
RoomEvent["LocalAudioSilenceDetected"] = "localAudioSilenceDetected";
|
12919
12926
|
/**
|
12920
12927
|
* Active speakers changed. List of speakers are ordered by their audio level.
|
12921
12928
|
* loudest speakers first. This will include the LocalParticipant too.
|
@@ -13940,7 +13947,7 @@ var uaParser = {
|
|
13940
13947
|
})(uaParser, uaParserExports);
|
13941
13948
|
var UAParser = uaParserExports;
|
13942
13949
|
|
13943
|
-
var version$1 = "1.7.
|
13950
|
+
var version$1 = "1.7.1";
|
13944
13951
|
|
13945
13952
|
const version = version$1;
|
13946
13953
|
const protocolVersion = 9;
|
@@ -14026,8 +14033,9 @@ async function detectSilence(track) {
|
|
14026
14033
|
* @internal
|
14027
14034
|
*/
|
14028
14035
|
function getNewAudioContext() {
|
14036
|
+
const AudioContext =
|
14029
14037
|
// @ts-ignore
|
14030
|
-
|
14038
|
+
typeof window !== 'undefined' && (window.AudioContext || window.webkitAudioContext);
|
14031
14039
|
if (AudioContext) {
|
14032
14040
|
return new AudioContext({
|
14033
14041
|
latencyHint: 'interactive'
|
@@ -15569,6 +15577,7 @@ class LocalAudioTrack extends LocalTrack {
|
|
15569
15577
|
}
|
15570
15578
|
this.emit(TrackEvent.AudioSilenceDetected);
|
15571
15579
|
}
|
15580
|
+
return trackIsSilent;
|
15572
15581
|
}
|
15573
15582
|
}
|
15574
15583
|
|
@@ -16401,7 +16410,8 @@ class RemoteVideoTrack extends RemoteTrack {
|
|
16401
16410
|
const lastVisibilityChange = this.elementInfos.reduce((prev, info) => Math.max(prev, info.visibilityChangedAt || 0), 0);
|
16402
16411
|
const backgroundPause = ((_b = (_a = this.adaptiveStreamSettings) === null || _a === void 0 ? void 0 : _a.pauseVideoInBackground) !== null && _b !== void 0 ? _b : true // default to true
|
16403
16412
|
) ? this.isInBackground : false;
|
16404
|
-
const
|
16413
|
+
const isPiPMode = this.elementInfos.some(info => info.pictureInPicture);
|
16414
|
+
const isVisible = this.elementInfos.some(info => info.visible) && !backgroundPause || isPiPMode;
|
16405
16415
|
if (this.lastVisible === isVisible) {
|
16406
16416
|
return;
|
16407
16417
|
}
|
@@ -16440,6 +16450,12 @@ class RemoteVideoTrack extends RemoteTrack {
|
|
16440
16450
|
}
|
16441
16451
|
}
|
16442
16452
|
class HTMLElementInfo {
|
16453
|
+
get visible() {
|
16454
|
+
return this.isPiP || this.isIntersecting;
|
16455
|
+
}
|
16456
|
+
get pictureInPicture() {
|
16457
|
+
return this.isPiP;
|
16458
|
+
}
|
16443
16459
|
constructor(element, visible) {
|
16444
16460
|
this.onVisibilityChanged = entry => {
|
16445
16461
|
var _a;
|
@@ -16448,13 +16464,24 @@ class HTMLElementInfo {
|
|
16448
16464
|
isIntersecting
|
16449
16465
|
} = entry;
|
16450
16466
|
if (target === this.element) {
|
16451
|
-
this.
|
16467
|
+
this.isIntersecting = isIntersecting;
|
16452
16468
|
this.visibilityChangedAt = Date.now();
|
16453
16469
|
(_a = this.handleVisibilityChanged) === null || _a === void 0 ? void 0 : _a.call(this);
|
16454
16470
|
}
|
16455
16471
|
};
|
16472
|
+
this.onEnterPiP = () => {
|
16473
|
+
var _a;
|
16474
|
+
this.isPiP = true;
|
16475
|
+
(_a = this.handleVisibilityChanged) === null || _a === void 0 ? void 0 : _a.call(this);
|
16476
|
+
};
|
16477
|
+
this.onLeavePiP = () => {
|
16478
|
+
var _a;
|
16479
|
+
this.isPiP = false;
|
16480
|
+
(_a = this.handleVisibilityChanged) === null || _a === void 0 ? void 0 : _a.call(this);
|
16481
|
+
};
|
16456
16482
|
this.element = element;
|
16457
|
-
this.
|
16483
|
+
this.isIntersecting = visible !== null && visible !== void 0 ? visible : isElementInViewport(element);
|
16484
|
+
this.isPiP = isWeb() && document.pictureInPictureElement === element;
|
16458
16485
|
this.visibilityChangedAt = 0;
|
16459
16486
|
}
|
16460
16487
|
width() {
|
@@ -16464,6 +16491,9 @@ class HTMLElementInfo {
|
|
16464
16491
|
return this.element.clientHeight;
|
16465
16492
|
}
|
16466
16493
|
observe() {
|
16494
|
+
// make sure we update the current visible state once we start to observe
|
16495
|
+
this.isIntersecting = isElementInViewport(this.element);
|
16496
|
+
this.isPiP = document.pictureInPictureElement === this.element;
|
16467
16497
|
this.element.handleResize = () => {
|
16468
16498
|
var _a;
|
16469
16499
|
(_a = this.handleResize) === null || _a === void 0 ? void 0 : _a.call(this);
|
@@ -16471,11 +16501,15 @@ class HTMLElementInfo {
|
|
16471
16501
|
this.element.handleVisibilityChanged = this.onVisibilityChanged;
|
16472
16502
|
getIntersectionObserver().observe(this.element);
|
16473
16503
|
getResizeObserver().observe(this.element);
|
16504
|
+
this.element.addEventListener('enterpictureinpicture', this.onEnterPiP);
|
16505
|
+
this.element.addEventListener('leavepictureinpicture', this.onLeavePiP);
|
16474
16506
|
}
|
16475
16507
|
stopObserving() {
|
16476
16508
|
var _a, _b;
|
16477
16509
|
(_a = getIntersectionObserver()) === null || _a === void 0 ? void 0 : _a.unobserve(this.element);
|
16478
16510
|
(_b = getResizeObserver()) === null || _b === void 0 ? void 0 : _b.unobserve(this.element);
|
16511
|
+
this.element.removeEventListener('enterpictureinpicture', this.onEnterPiP);
|
16512
|
+
this.element.removeEventListener('leavepictureinpicture', this.onLeavePiP);
|
16479
16513
|
}
|
16480
16514
|
}
|
16481
16515
|
// does not account for occlusion by other elements
|
@@ -17340,10 +17374,14 @@ class RemoteTrackPublication extends TrackPublication {
|
|
17340
17374
|
}
|
17341
17375
|
/** @internal */
|
17342
17376
|
updateInfo(info) {
|
17343
|
-
var _a;
|
17344
17377
|
super.updateInfo(info);
|
17378
|
+
const prevMetadataMuted = this.metadataMuted;
|
17345
17379
|
this.metadataMuted = info.muted;
|
17346
|
-
(
|
17380
|
+
if (this.track) {
|
17381
|
+
this.track.setMuted(info.muted);
|
17382
|
+
} else if (prevMetadataMuted !== info.muted) {
|
17383
|
+
this.emit(info.muted ? TrackEvent.Muted : TrackEvent.Unmuted);
|
17384
|
+
}
|
17347
17385
|
}
|
17348
17386
|
emitSubscriptionUpdateIfChanged(previousStatus) {
|
17349
17387
|
const currentStatus = this.subscriptionStatus;
|
@@ -19110,6 +19148,7 @@ const roomOptionDefaults = {
|
|
19110
19148
|
dynacast: false,
|
19111
19149
|
stopLocalTrackOnUnpublish: true,
|
19112
19150
|
reconnectPolicy: new DefaultReconnectPolicy(),
|
19151
|
+
disconnectOnPageLeave: true,
|
19113
19152
|
expWebAudioMix: false
|
19114
19153
|
};
|
19115
19154
|
const roomConnectOptionDefaults = {
|
@@ -20102,22 +20141,28 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
20102
20141
|
};
|
20103
20142
|
this.handleDataMessage = async message => {
|
20104
20143
|
var _a, _b;
|
20105
|
-
//
|
20106
|
-
|
20107
|
-
|
20108
|
-
|
20109
|
-
|
20110
|
-
|
20111
|
-
|
20112
|
-
|
20113
|
-
|
20114
|
-
|
20115
|
-
|
20116
|
-
|
20117
|
-
|
20118
|
-
|
20119
|
-
|
20120
|
-
|
20144
|
+
// make sure to respect incoming data message order by processing message events one after the other
|
20145
|
+
const unlock = await this.dataProcessLock.lock();
|
20146
|
+
try {
|
20147
|
+
// decode
|
20148
|
+
let buffer;
|
20149
|
+
if (message.data instanceof ArrayBuffer) {
|
20150
|
+
buffer = message.data;
|
20151
|
+
} else if (message.data instanceof Blob) {
|
20152
|
+
buffer = await message.data.arrayBuffer();
|
20153
|
+
} else {
|
20154
|
+
livekitLogger.error('unsupported data type', message.data);
|
20155
|
+
return;
|
20156
|
+
}
|
20157
|
+
const dp = DataPacket.decode(new Uint8Array(buffer));
|
20158
|
+
if (((_a = dp.value) === null || _a === void 0 ? void 0 : _a.$case) === 'speaker') {
|
20159
|
+
// dispatch speaker updates
|
20160
|
+
this.emit(EngineEvent.ActiveSpeakersUpdate, dp.value.speaker.speakers);
|
20161
|
+
} else if (((_b = dp.value) === null || _b === void 0 ? void 0 : _b.$case) === 'user') {
|
20162
|
+
this.emit(EngineEvent.DataPacketReceived, dp.value.user, dp.kind);
|
20163
|
+
}
|
20164
|
+
} finally {
|
20165
|
+
unlock();
|
20121
20166
|
}
|
20122
20167
|
};
|
20123
20168
|
this.handleDataError = event => {
|
@@ -20177,6 +20222,7 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
20177
20222
|
this.reconnectPolicy = this.options.reconnectPolicy;
|
20178
20223
|
this.registerOnLineListener();
|
20179
20224
|
this.closingLock = new Mutex();
|
20225
|
+
this.dataProcessLock = new Mutex();
|
20180
20226
|
}
|
20181
20227
|
async join(url, token, opts, abortSignal) {
|
20182
20228
|
this.url = url;
|
@@ -21097,8 +21143,10 @@ class Room extends eventsExports.EventEmitter {
|
|
21097
21143
|
CriticalTimers.clearTimeout(connectTimeout);
|
21098
21144
|
(_a = this.abortController) === null || _a === void 0 ? void 0 : _a.signal.removeEventListener('abort', abortHandler);
|
21099
21145
|
// also hook unload event
|
21100
|
-
if (isWeb()) {
|
21101
|
-
|
21146
|
+
if (isWeb() && this.options.disconnectOnPageLeave) {
|
21147
|
+
// capturing both 'pagehide' and 'beforeunload' to capture broadest set of browser behaviors
|
21148
|
+
window.addEventListener('pagehide', this.onPageLeave);
|
21149
|
+
window.addEventListener('beforeunload', this.onPageLeave);
|
21102
21150
|
(_b = navigator.mediaDevices) === null || _b === void 0 ? void 0 : _b.addEventListener('devicechange', this.handleDeviceChange);
|
21103
21151
|
}
|
21104
21152
|
this.setAndEmitConnectionState(ConnectionState.Connected);
|
@@ -21149,7 +21197,7 @@ class Room extends eventsExports.EventEmitter {
|
|
21149
21197
|
unlock();
|
21150
21198
|
}
|
21151
21199
|
};
|
21152
|
-
this.
|
21200
|
+
this.onPageLeave = async () => {
|
21153
21201
|
await this.disconnect();
|
21154
21202
|
};
|
21155
21203
|
this.handleRestarting = () => {
|
@@ -21376,8 +21424,14 @@ class Room extends eventsExports.EventEmitter {
|
|
21376
21424
|
this.onLocalTrackUnmuted = pub => {
|
21377
21425
|
this.emit(RoomEvent.TrackUnmuted, pub, this.localParticipant);
|
21378
21426
|
};
|
21379
|
-
this.onLocalTrackPublished = pub => {
|
21427
|
+
this.onLocalTrackPublished = async pub => {
|
21380
21428
|
this.emit(RoomEvent.LocalTrackPublished, pub, this.localParticipant);
|
21429
|
+
if (pub.track instanceof LocalAudioTrack) {
|
21430
|
+
const trackIsSilent = await pub.track.checkForSilence();
|
21431
|
+
if (trackIsSilent) {
|
21432
|
+
this.emit(RoomEvent.LocalAudioSilenceDetected, pub);
|
21433
|
+
}
|
21434
|
+
}
|
21381
21435
|
};
|
21382
21436
|
this.onLocalTrackUnpublished = pub => {
|
21383
21437
|
this.emit(RoomEvent.LocalTrackUnpublished, pub, this.localParticipant);
|
@@ -21756,7 +21810,8 @@ class Room extends eventsExports.EventEmitter {
|
|
21756
21810
|
this.audioContext = undefined;
|
21757
21811
|
}
|
21758
21812
|
if (isWeb()) {
|
21759
|
-
window.removeEventListener('beforeunload', this.
|
21813
|
+
window.removeEventListener('beforeunload', this.onPageLeave);
|
21814
|
+
window.removeEventListener('pagehide', this.onPageLeave);
|
21760
21815
|
(_a = navigator.mediaDevices) === null || _a === void 0 ? void 0 : _a.removeEventListener('devicechange', this.handleDeviceChange);
|
21761
21816
|
}
|
21762
21817
|
this.setAndEmitConnectionState(ConnectionState.Disconnected);
|