livekit-client 1.6.9 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/livekit-client.esm.mjs +83 -31
- 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/participant/Participant.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/participant/Participant.ts +0 -3
- 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.
|
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
|
@@ -16778,9 +16812,6 @@ class Participant extends eventsExports.EventEmitter {
|
|
16778
16812
|
* @returns
|
16779
16813
|
*/
|
16780
16814
|
getTrack(source) {
|
16781
|
-
if (source === Track.Source.Unknown) {
|
16782
|
-
return;
|
16783
|
-
}
|
16784
16815
|
for (const [, pub] of this.tracks) {
|
16785
16816
|
if (pub.source === source) {
|
16786
16817
|
return pub;
|
@@ -17343,10 +17374,14 @@ class RemoteTrackPublication extends TrackPublication {
|
|
17343
17374
|
}
|
17344
17375
|
/** @internal */
|
17345
17376
|
updateInfo(info) {
|
17346
|
-
var _a;
|
17347
17377
|
super.updateInfo(info);
|
17378
|
+
const prevMetadataMuted = this.metadataMuted;
|
17348
17379
|
this.metadataMuted = info.muted;
|
17349
|
-
(
|
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
|
+
}
|
17350
17385
|
}
|
17351
17386
|
emitSubscriptionUpdateIfChanged(previousStatus) {
|
17352
17387
|
const currentStatus = this.subscriptionStatus;
|
@@ -19113,6 +19148,7 @@ const roomOptionDefaults = {
|
|
19113
19148
|
dynacast: false,
|
19114
19149
|
stopLocalTrackOnUnpublish: true,
|
19115
19150
|
reconnectPolicy: new DefaultReconnectPolicy(),
|
19151
|
+
disconnectOnPageLeave: true,
|
19116
19152
|
expWebAudioMix: false
|
19117
19153
|
};
|
19118
19154
|
const roomConnectOptionDefaults = {
|
@@ -20105,22 +20141,28 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
20105
20141
|
};
|
20106
20142
|
this.handleDataMessage = async message => {
|
20107
20143
|
var _a, _b;
|
20108
|
-
//
|
20109
|
-
|
20110
|
-
|
20111
|
-
|
20112
|
-
|
20113
|
-
|
20114
|
-
|
20115
|
-
|
20116
|
-
|
20117
|
-
|
20118
|
-
|
20119
|
-
|
20120
|
-
|
20121
|
-
|
20122
|
-
|
20123
|
-
|
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();
|
20124
20166
|
}
|
20125
20167
|
};
|
20126
20168
|
this.handleDataError = event => {
|
@@ -20180,6 +20222,7 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
20180
20222
|
this.reconnectPolicy = this.options.reconnectPolicy;
|
20181
20223
|
this.registerOnLineListener();
|
20182
20224
|
this.closingLock = new Mutex();
|
20225
|
+
this.dataProcessLock = new Mutex();
|
20183
20226
|
}
|
20184
20227
|
async join(url, token, opts, abortSignal) {
|
20185
20228
|
this.url = url;
|
@@ -21100,8 +21143,10 @@ class Room extends eventsExports.EventEmitter {
|
|
21100
21143
|
CriticalTimers.clearTimeout(connectTimeout);
|
21101
21144
|
(_a = this.abortController) === null || _a === void 0 ? void 0 : _a.signal.removeEventListener('abort', abortHandler);
|
21102
21145
|
// also hook unload event
|
21103
|
-
if (isWeb()) {
|
21104
|
-
|
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);
|
21105
21150
|
(_b = navigator.mediaDevices) === null || _b === void 0 ? void 0 : _b.addEventListener('devicechange', this.handleDeviceChange);
|
21106
21151
|
}
|
21107
21152
|
this.setAndEmitConnectionState(ConnectionState.Connected);
|
@@ -21152,7 +21197,7 @@ class Room extends eventsExports.EventEmitter {
|
|
21152
21197
|
unlock();
|
21153
21198
|
}
|
21154
21199
|
};
|
21155
|
-
this.
|
21200
|
+
this.onPageLeave = async () => {
|
21156
21201
|
await this.disconnect();
|
21157
21202
|
};
|
21158
21203
|
this.handleRestarting = () => {
|
@@ -21379,8 +21424,14 @@ class Room extends eventsExports.EventEmitter {
|
|
21379
21424
|
this.onLocalTrackUnmuted = pub => {
|
21380
21425
|
this.emit(RoomEvent.TrackUnmuted, pub, this.localParticipant);
|
21381
21426
|
};
|
21382
|
-
this.onLocalTrackPublished = pub => {
|
21427
|
+
this.onLocalTrackPublished = async pub => {
|
21383
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
|
+
}
|
21384
21435
|
};
|
21385
21436
|
this.onLocalTrackUnpublished = pub => {
|
21386
21437
|
this.emit(RoomEvent.LocalTrackUnpublished, pub, this.localParticipant);
|
@@ -21759,7 +21810,8 @@ class Room extends eventsExports.EventEmitter {
|
|
21759
21810
|
this.audioContext = undefined;
|
21760
21811
|
}
|
21761
21812
|
if (isWeb()) {
|
21762
|
-
window.removeEventListener('beforeunload', this.
|
21813
|
+
window.removeEventListener('beforeunload', this.onPageLeave);
|
21814
|
+
window.removeEventListener('pagehide', this.onPageLeave);
|
21763
21815
|
(_a = navigator.mediaDevices) === null || _a === void 0 ? void 0 : _a.removeEventListener('devicechange', this.handleDeviceChange);
|
21764
21816
|
}
|
21765
21817
|
this.setAndEmitConnectionState(ConnectionState.Disconnected);
|