livekit-client 1.6.2 → 1.6.3
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 +312 -101
- 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 +3 -3
- package/dist/src/api/SignalClient.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/proto/livekit_models.d.ts +43 -1
- package/dist/src/proto/livekit_models.d.ts.map +1 -1
- package/dist/src/proto/livekit_rtc.d.ts +473 -4
- package/dist/src/proto/livekit_rtc.d.ts.map +1 -1
- package/dist/src/room/PCTransport.d.ts +1 -0
- package/dist/src/room/PCTransport.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts +2 -0
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/timers.d.ts +13 -0
- package/dist/src/room/timers.d.ts.map +1 -0
- package/dist/src/room/track/RemoteVideoTrack.d.ts.map +1 -1
- package/dist/ts4.2/src/api/SignalClient.d.ts +3 -3
- package/dist/ts4.2/src/index.d.ts +2 -1
- package/dist/ts4.2/src/proto/livekit_models.d.ts +45 -1
- package/dist/ts4.2/src/proto/livekit_rtc.d.ts +514 -3
- package/dist/ts4.2/src/room/PCTransport.d.ts +1 -0
- package/dist/ts4.2/src/room/RTCEngine.d.ts +2 -0
- package/dist/ts4.2/src/room/timers.d.ts +13 -0
- package/package.json +1 -1
- package/src/api/SignalClient.ts +28 -20
- package/src/index.ts +2 -0
- package/src/proto/livekit_models.ts +116 -1
- package/src/proto/livekit_rtc.ts +106 -2
- package/src/room/PCTransport.ts +22 -6
- package/src/room/RTCEngine.ts +56 -43
- package/src/room/Room.ts +4 -3
- package/src/room/timers.ts +16 -0
- package/src/room/track/RemoteVideoTrack.ts +2 -1
package/src/room/RTCEngine.ts
CHANGED
@@ -17,6 +17,7 @@ import {
|
|
17
17
|
AddTrackRequest,
|
18
18
|
JoinResponse,
|
19
19
|
LeaveRequest,
|
20
|
+
ReconnectResponse,
|
20
21
|
SignalTarget,
|
21
22
|
TrackPublishedResponse,
|
22
23
|
} from '../proto/livekit_rtc';
|
@@ -31,6 +32,7 @@ import {
|
|
31
32
|
import { EngineEvent } from './events';
|
32
33
|
import PCTransport, { PCEvents } from './PCTransport';
|
33
34
|
import type { ReconnectContext, ReconnectPolicy } from './ReconnectPolicy';
|
35
|
+
import CriticalTimers from './timers';
|
34
36
|
import type LocalTrack from './track/LocalTrack';
|
35
37
|
import type LocalVideoTrack from './track/LocalVideoTrack';
|
36
38
|
import type { SimulcastTrackInfo } from './track/LocalVideoTrack';
|
@@ -279,35 +281,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
279
281
|
|
280
282
|
this.participantSid = joinResponse.participant?.sid;
|
281
283
|
|
282
|
-
const rtcConfig =
|
283
|
-
|
284
|
-
// update ICE servers before creating PeerConnection
|
285
|
-
if (joinResponse.iceServers && !rtcConfig.iceServers) {
|
286
|
-
const rtcIceServers: RTCIceServer[] = [];
|
287
|
-
joinResponse.iceServers.forEach((iceServer) => {
|
288
|
-
const rtcIceServer: RTCIceServer = {
|
289
|
-
urls: iceServer.urls,
|
290
|
-
};
|
291
|
-
if (iceServer.username) rtcIceServer.username = iceServer.username;
|
292
|
-
if (iceServer.credential) {
|
293
|
-
rtcIceServer.credential = iceServer.credential;
|
294
|
-
}
|
295
|
-
rtcIceServers.push(rtcIceServer);
|
296
|
-
});
|
297
|
-
rtcConfig.iceServers = rtcIceServers;
|
298
|
-
}
|
299
|
-
|
300
|
-
if (
|
301
|
-
joinResponse.clientConfiguration &&
|
302
|
-
joinResponse.clientConfiguration.forceRelay === ClientConfigSetting.ENABLED
|
303
|
-
) {
|
304
|
-
rtcConfig.iceTransportPolicy = 'relay';
|
305
|
-
}
|
306
|
-
|
307
|
-
// @ts-ignore
|
308
|
-
rtcConfig.sdpSemantics = 'unified-plan';
|
309
|
-
// @ts-ignore
|
310
|
-
rtcConfig.continualGatheringPolicy = 'gather_continually';
|
284
|
+
const rtcConfig = this.makeRTCConfiguration(joinResponse);
|
311
285
|
|
312
286
|
this.publisher = new PCTransport(rtcConfig);
|
313
287
|
this.subscriber = new PCTransport(rtcConfig);
|
@@ -448,6 +422,40 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
448
422
|
};
|
449
423
|
}
|
450
424
|
|
425
|
+
private makeRTCConfiguration(serverResponse: JoinResponse | ReconnectResponse): RTCConfiguration {
|
426
|
+
const rtcConfig = { ...this.rtcConfig };
|
427
|
+
|
428
|
+
// update ICE servers before creating PeerConnection
|
429
|
+
if (serverResponse.iceServers && !rtcConfig.iceServers) {
|
430
|
+
const rtcIceServers: RTCIceServer[] = [];
|
431
|
+
serverResponse.iceServers.forEach((iceServer) => {
|
432
|
+
const rtcIceServer: RTCIceServer = {
|
433
|
+
urls: iceServer.urls,
|
434
|
+
};
|
435
|
+
if (iceServer.username) rtcIceServer.username = iceServer.username;
|
436
|
+
if (iceServer.credential) {
|
437
|
+
rtcIceServer.credential = iceServer.credential;
|
438
|
+
}
|
439
|
+
rtcIceServers.push(rtcIceServer);
|
440
|
+
});
|
441
|
+
rtcConfig.iceServers = rtcIceServers;
|
442
|
+
}
|
443
|
+
|
444
|
+
if (
|
445
|
+
serverResponse.clientConfiguration &&
|
446
|
+
serverResponse.clientConfiguration.forceRelay === ClientConfigSetting.ENABLED
|
447
|
+
) {
|
448
|
+
rtcConfig.iceTransportPolicy = 'relay';
|
449
|
+
}
|
450
|
+
|
451
|
+
// @ts-ignore
|
452
|
+
rtcConfig.sdpSemantics = 'unified-plan';
|
453
|
+
// @ts-ignore
|
454
|
+
rtcConfig.continualGatheringPolicy = 'gather_continually';
|
455
|
+
|
456
|
+
return rtcConfig;
|
457
|
+
}
|
458
|
+
|
451
459
|
private createDataChannels() {
|
452
460
|
if (!this.publisher) {
|
453
461
|
return;
|
@@ -703,10 +711,11 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
703
711
|
|
704
712
|
log.debug(`reconnecting in ${delay}ms`);
|
705
713
|
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
714
|
+
this.clearReconnectTimeout();
|
715
|
+
this.reconnectTimeout = CriticalTimers.setTimeout(
|
716
|
+
() => this.attemptReconnect(signalEvents),
|
717
|
+
delay,
|
718
|
+
);
|
710
719
|
};
|
711
720
|
|
712
721
|
private async attemptReconnect(signalEvents: boolean = false) {
|
@@ -733,11 +742,8 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
733
742
|
} else {
|
734
743
|
await this.resumeConnection(signalEvents);
|
735
744
|
}
|
736
|
-
this.
|
745
|
+
this.clearPendingReconnect();
|
737
746
|
this.fullReconnectOnNext = false;
|
738
|
-
if (this.reconnectTimeout) {
|
739
|
-
clearTimeout(this.reconnectTimeout);
|
740
|
-
}
|
741
747
|
} catch (e) {
|
742
748
|
this.reconnectAttempts += 1;
|
743
749
|
let reconnectRequired = false;
|
@@ -841,7 +847,12 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
841
847
|
}
|
842
848
|
|
843
849
|
try {
|
844
|
-
await this.client.reconnect(this.url, this.token, this.participantSid);
|
850
|
+
const res = await this.client.reconnect(this.url, this.token, this.participantSid);
|
851
|
+
if (res) {
|
852
|
+
const rtcConfig = this.makeRTCConfiguration(res);
|
853
|
+
this.publisher.pc.setConfiguration(rtcConfig);
|
854
|
+
this.subscriber.pc.setConfiguration(rtcConfig);
|
855
|
+
}
|
845
856
|
} catch (e) {
|
846
857
|
let message = '';
|
847
858
|
if (e instanceof Error) {
|
@@ -1034,19 +1045,21 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
1034
1045
|
}
|
1035
1046
|
}
|
1036
1047
|
|
1037
|
-
private
|
1048
|
+
private clearReconnectTimeout() {
|
1038
1049
|
if (this.reconnectTimeout) {
|
1039
|
-
clearTimeout(this.reconnectTimeout);
|
1050
|
+
CriticalTimers.clearTimeout(this.reconnectTimeout);
|
1040
1051
|
}
|
1052
|
+
}
|
1053
|
+
|
1054
|
+
private clearPendingReconnect() {
|
1055
|
+
this.clearReconnectTimeout();
|
1041
1056
|
this.reconnectAttempts = 0;
|
1042
1057
|
}
|
1043
1058
|
|
1044
1059
|
private handleBrowserOnLine = () => {
|
1045
1060
|
// in case the engine is currently reconnecting, attempt a reconnect immediately after the browser state has changed to 'onLine'
|
1046
1061
|
if (this.client.isReconnecting) {
|
1047
|
-
|
1048
|
-
clearTimeout(this.reconnectTimeout);
|
1049
|
-
}
|
1062
|
+
this.clearReconnectTimeout();
|
1050
1063
|
this.attemptReconnect(true);
|
1051
1064
|
}
|
1052
1065
|
};
|
package/src/room/Room.ts
CHANGED
@@ -44,6 +44,7 @@ import type Participant from './participant/Participant';
|
|
44
44
|
import type { ConnectionQuality } from './participant/Participant';
|
45
45
|
import RemoteParticipant from './participant/RemoteParticipant';
|
46
46
|
import RTCEngine from './RTCEngine';
|
47
|
+
import CriticalTimers from './timers';
|
47
48
|
import LocalAudioTrack from './track/LocalAudioTrack';
|
48
49
|
import LocalTrackPublication from './track/LocalTrackPublication';
|
49
50
|
import LocalVideoTrack from './track/LocalVideoTrack';
|
@@ -364,7 +365,7 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
364
365
|
}
|
365
366
|
|
366
367
|
// don't return until ICE connected
|
367
|
-
const connectTimeout = setTimeout(() => {
|
368
|
+
const connectTimeout = CriticalTimers.setTimeout(() => {
|
368
369
|
// timeout
|
369
370
|
this.recreateEngine();
|
370
371
|
this.handleDisconnect(this.options.stopLocalTrackOnUnpublish);
|
@@ -372,7 +373,7 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
372
373
|
}, this.connOptions.peerConnectionTimeout);
|
373
374
|
const abortHandler = () => {
|
374
375
|
log.warn('closing engine');
|
375
|
-
clearTimeout(connectTimeout);
|
376
|
+
CriticalTimers.clearTimeout(connectTimeout);
|
376
377
|
this.recreateEngine();
|
377
378
|
this.handleDisconnect(this.options.stopLocalTrackOnUnpublish);
|
378
379
|
reject(new ConnectionError('room connection has been cancelled'));
|
@@ -383,7 +384,7 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
383
384
|
this.abortController?.signal.addEventListener('abort', abortHandler);
|
384
385
|
|
385
386
|
this.engine.once(EngineEvent.Connected, () => {
|
386
|
-
clearTimeout(connectTimeout);
|
387
|
+
CriticalTimers.clearTimeout(connectTimeout);
|
387
388
|
this.abortController?.signal.removeEventListener('abort', abortHandler);
|
388
389
|
// also hook unload event
|
389
390
|
if (isWeb()) {
|
@@ -0,0 +1,16 @@
|
|
1
|
+
/**
|
2
|
+
* Timers that can be overridden with platform specific implementations
|
3
|
+
* that ensure that they are fired. These should be used when it is critical
|
4
|
+
* that the timer fires on time.
|
5
|
+
*/
|
6
|
+
export default class CriticalTimers {
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
8
|
+
static setTimeout = (...args: Parameters<typeof setTimeout>) => setTimeout(...args);
|
9
|
+
|
10
|
+
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
11
|
+
static setInterval = (...args: Parameters<typeof setInterval>) => setInterval(...args);
|
12
|
+
|
13
|
+
static clearTimeout = (...args: Parameters<typeof clearTimeout>) => clearTimeout(...args);
|
14
|
+
|
15
|
+
static clearInterval = (...args: Parameters<typeof clearInterval>) => clearInterval(...args);
|
16
|
+
}
|
@@ -2,6 +2,7 @@ import { debounce } from 'ts-debounce';
|
|
2
2
|
import log from '../../logger';
|
3
3
|
import { TrackEvent } from '../events';
|
4
4
|
import { computeBitrate, VideoReceiverStats } from '../stats';
|
5
|
+
import CriticalTimers from '../timers';
|
5
6
|
import { getIntersectionObserver, getResizeObserver, ObservableMediaElement } from '../utils';
|
6
7
|
import RemoteTrack from './RemoteTrack';
|
7
8
|
import { attachToElement, detachTrack, Track } from './Track';
|
@@ -233,7 +234,7 @@ export default class RemoteVideoTrack extends RemoteTrack {
|
|
233
234
|
|
234
235
|
if (!isVisible && Date.now() - lastVisibilityChange < REACTION_DELAY) {
|
235
236
|
// delay hidden events
|
236
|
-
setTimeout(() => {
|
237
|
+
CriticalTimers.setTimeout(() => {
|
237
238
|
this.updateVisibility();
|
238
239
|
}, REACTION_DELAY);
|
239
240
|
return;
|