livekit-client 1.6.5 → 1.6.7
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 +149 -130
- 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/room/PCTransport.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts +10 -3
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/events.d.ts +2 -1
- package/dist/src/room/events.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
- package/dist/src/room/track/LocalVideoTrack.d.ts +1 -0
- package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/RemoteTrackPublication.d.ts +1 -1
- package/dist/src/room/track/RemoteTrackPublication.d.ts.map +1 -1
- package/dist/src/room/track/RemoteVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/Track.d.ts +2 -1
- package/dist/src/room/track/Track.d.ts.map +1 -1
- package/dist/src/room/track/options.d.ts +2 -2
- package/dist/ts4.2/src/room/RTCEngine.d.ts +10 -3
- package/dist/ts4.2/src/room/events.d.ts +2 -1
- package/dist/ts4.2/src/room/track/LocalVideoTrack.d.ts +1 -0
- package/dist/ts4.2/src/room/track/RemoteTrackPublication.d.ts +1 -1
- package/dist/ts4.2/src/room/track/Track.d.ts +2 -1
- package/dist/ts4.2/src/room/track/options.d.ts +2 -2
- package/package.json +13 -13
- package/src/room/PCTransport.ts +2 -0
- package/src/room/RTCEngine.ts +46 -51
- package/src/room/Room.ts +13 -3
- package/src/room/events.ts +2 -1
- package/src/room/participant/LocalParticipant.ts +20 -8
- package/src/room/participant/RemoteParticipant.ts +2 -3
- package/src/room/track/LocalVideoTrack.ts +62 -46
- package/src/room/track/RemoteTrackPublication.ts +3 -2
- package/src/room/track/RemoteVideoTrack.ts +0 -3
- package/src/room/track/Track.ts +2 -1
- package/src/room/track/options.ts +2 -2
@@ -12877,7 +12877,8 @@ var RoomEvent;
|
|
12877
12877
|
*/
|
12878
12878
|
RoomEvent["SignalConnected"] = "signalConnected";
|
12879
12879
|
/**
|
12880
|
-
* Recording of a room has started/stopped.
|
12880
|
+
* Recording of a room has started/stopped. Room.isRecording will be updated too.
|
12881
|
+
* args: (isRecording: boolean)
|
12881
12882
|
*/
|
12882
12883
|
RoomEvent["RecordingStatusChanged"] = "recordingStatusChanged";
|
12883
12884
|
})(RoomEvent || (RoomEvent = {}));
|
@@ -13799,7 +13800,7 @@ var uaParser = {
|
|
13799
13800
|
})(uaParser, uaParserExports);
|
13800
13801
|
var UAParser = uaParserExports;
|
13801
13802
|
|
13802
|
-
var version$1 = "1.6.
|
13803
|
+
var version$1 = "1.6.7";
|
13803
13804
|
|
13804
13805
|
const version = version$1;
|
13805
13806
|
const protocolVersion = 8;
|
@@ -14780,7 +14781,8 @@ class Track extends eventsExports.EventEmitter {
|
|
14780
14781
|
this.attachedElements = [];
|
14781
14782
|
this.isMuted = false;
|
14782
14783
|
/**
|
14783
|
-
* indicates current state of stream
|
14784
|
+
* indicates current state of stream, it'll indicate `paused` if the track
|
14785
|
+
* has been paused by congestion controller
|
14784
14786
|
*/
|
14785
14787
|
this.streamState = Track.StreamState.Active;
|
14786
14788
|
this._currentBitrate = 0;
|
@@ -15465,6 +15467,7 @@ class LocalVideoTrack extends LocalTrack {
|
|
15465
15467
|
}
|
15466
15468
|
this.prevStats = statsMap;
|
15467
15469
|
};
|
15470
|
+
this.senderLock = new Mutex();
|
15468
15471
|
}
|
15469
15472
|
get isSimulcast() {
|
15470
15473
|
if (this.sender && this.sender.getParameters().encodings.length > 1) {
|
@@ -15657,7 +15660,7 @@ class LocalVideoTrack extends LocalTrack {
|
|
15657
15660
|
}
|
15658
15661
|
} else if (simulcastCodecInfo.encodings) {
|
15659
15662
|
livekitLogger.debug("try setPublishingLayersForSender ".concat(codec.codec));
|
15660
|
-
await setPublishingLayersForSender(simulcastCodecInfo.sender, simulcastCodecInfo.encodings, codec.qualities);
|
15663
|
+
await setPublishingLayersForSender(simulcastCodecInfo.sender, simulcastCodecInfo.encodings, codec.qualities, this.senderLock);
|
15661
15664
|
}
|
15662
15665
|
}
|
15663
15666
|
}
|
@@ -15687,7 +15690,7 @@ class LocalVideoTrack extends LocalTrack {
|
|
15687
15690
|
if (!this.sender || !this.encodings) {
|
15688
15691
|
return;
|
15689
15692
|
}
|
15690
|
-
await setPublishingLayersForSender(this.sender, this.encodings, qualities);
|
15693
|
+
await setPublishingLayersForSender(this.sender, this.encodings, qualities, this.senderLock);
|
15691
15694
|
}
|
15692
15695
|
async handleAppVisibilityChanged() {
|
15693
15696
|
await super.handleAppVisibilityChanged();
|
@@ -15697,59 +15700,64 @@ class LocalVideoTrack extends LocalTrack {
|
|
15697
15700
|
}
|
15698
15701
|
}
|
15699
15702
|
}
|
15700
|
-
async function setPublishingLayersForSender(sender, senderEncodings, qualities) {
|
15703
|
+
async function setPublishingLayersForSender(sender, senderEncodings, qualities, senderLock) {
|
15704
|
+
const unlock = await senderLock.lock();
|
15701
15705
|
livekitLogger.debug('setPublishingLayersForSender', {
|
15702
15706
|
sender,
|
15703
15707
|
qualities,
|
15704
15708
|
senderEncodings
|
15705
15709
|
});
|
15706
|
-
|
15707
|
-
|
15708
|
-
|
15709
|
-
|
15710
|
-
|
15711
|
-
|
15712
|
-
|
15713
|
-
if (encodings.length !== senderEncodings.length) {
|
15714
|
-
livekitLogger.warn('cannot set publishing layers, encodings mismatch');
|
15715
|
-
return;
|
15716
|
-
}
|
15717
|
-
let hasChanged = false;
|
15718
|
-
encodings.forEach((encoding, idx) => {
|
15719
|
-
var _a;
|
15720
|
-
let rid = (_a = encoding.rid) !== null && _a !== void 0 ? _a : '';
|
15721
|
-
if (rid === '') {
|
15722
|
-
rid = 'q';
|
15710
|
+
try {
|
15711
|
+
const params = sender.getParameters();
|
15712
|
+
const {
|
15713
|
+
encodings
|
15714
|
+
} = params;
|
15715
|
+
if (!encodings) {
|
15716
|
+
return;
|
15723
15717
|
}
|
15724
|
-
|
15725
|
-
|
15726
|
-
if (!subscribedQuality) {
|
15718
|
+
if (encodings.length !== senderEncodings.length) {
|
15719
|
+
livekitLogger.warn('cannot set publishing layers, encodings mismatch');
|
15727
15720
|
return;
|
15728
15721
|
}
|
15729
|
-
|
15730
|
-
|
15731
|
-
|
15732
|
-
|
15733
|
-
|
15734
|
-
|
15735
|
-
|
15736
|
-
|
15737
|
-
|
15738
|
-
|
15739
|
-
|
15740
|
-
|
15741
|
-
|
15742
|
-
|
15743
|
-
|
15744
|
-
|
15745
|
-
|
15722
|
+
let hasChanged = false;
|
15723
|
+
encodings.forEach((encoding, idx) => {
|
15724
|
+
var _a;
|
15725
|
+
let rid = (_a = encoding.rid) !== null && _a !== void 0 ? _a : '';
|
15726
|
+
if (rid === '') {
|
15727
|
+
rid = 'q';
|
15728
|
+
}
|
15729
|
+
const quality = videoQualityForRid(rid);
|
15730
|
+
const subscribedQuality = qualities.find(q => q.quality === quality);
|
15731
|
+
if (!subscribedQuality) {
|
15732
|
+
return;
|
15733
|
+
}
|
15734
|
+
if (encoding.active !== subscribedQuality.enabled) {
|
15735
|
+
hasChanged = true;
|
15736
|
+
encoding.active = subscribedQuality.enabled;
|
15737
|
+
livekitLogger.debug("setting layer ".concat(subscribedQuality.quality, " to ").concat(encoding.active ? 'enabled' : 'disabled'));
|
15738
|
+
// FireFox does not support setting encoding.active to false, so we
|
15739
|
+
// have a workaround of lowering its bitrate and resolution to the min.
|
15740
|
+
if (isFireFox()) {
|
15741
|
+
if (subscribedQuality.enabled) {
|
15742
|
+
encoding.scaleResolutionDownBy = senderEncodings[idx].scaleResolutionDownBy;
|
15743
|
+
encoding.maxBitrate = senderEncodings[idx].maxBitrate;
|
15744
|
+
/* @ts-ignore */
|
15745
|
+
encoding.maxFrameRate = senderEncodings[idx].maxFrameRate;
|
15746
|
+
} else {
|
15747
|
+
encoding.scaleResolutionDownBy = 4;
|
15748
|
+
encoding.maxBitrate = 10;
|
15749
|
+
/* @ts-ignore */
|
15750
|
+
encoding.maxFrameRate = 2;
|
15751
|
+
}
|
15746
15752
|
}
|
15747
15753
|
}
|
15754
|
+
});
|
15755
|
+
if (hasChanged) {
|
15756
|
+
params.encodings = encodings;
|
15757
|
+
await sender.setParameters(params);
|
15748
15758
|
}
|
15749
|
-
}
|
15750
|
-
|
15751
|
-
params.encodings = encodings;
|
15752
|
-
await sender.setParameters(params);
|
15759
|
+
} finally {
|
15760
|
+
unlock();
|
15753
15761
|
}
|
15754
15762
|
}
|
15755
15763
|
function videoQualityForRid(rid) {
|
@@ -16108,9 +16116,6 @@ class RemoteVideoTrack extends RemoteTrack {
|
|
16108
16116
|
this.updateDimensions();
|
16109
16117
|
}, REACTION_DELAY);
|
16110
16118
|
this.adaptiveStreamSettings = adaptiveStreamSettings;
|
16111
|
-
if (this.isAdaptiveStream) {
|
16112
|
-
this.streamState = Track.StreamState.Paused;
|
16113
|
-
}
|
16114
16119
|
}
|
16115
16120
|
get isAdaptiveStream() {
|
16116
16121
|
return this.adaptiveStreamSettings !== undefined;
|
@@ -17016,8 +17021,8 @@ function sortPresets(presets) {
|
|
17016
17021
|
}
|
17017
17022
|
|
17018
17023
|
class RemoteTrackPublication extends TrackPublication {
|
17019
|
-
constructor(kind,
|
17020
|
-
super(kind,
|
17024
|
+
constructor(kind, ti, autoSubscribe) {
|
17025
|
+
super(kind, ti.sid, ti.name);
|
17021
17026
|
this.track = undefined;
|
17022
17027
|
/** @internal */
|
17023
17028
|
this.allowed = true;
|
@@ -17042,6 +17047,7 @@ class RemoteTrackPublication extends TrackPublication {
|
|
17042
17047
|
this.emitTrackUpdate();
|
17043
17048
|
};
|
17044
17049
|
this.subscribed = autoSubscribe;
|
17050
|
+
this.updateInfo(ti);
|
17045
17051
|
}
|
17046
17052
|
/**
|
17047
17053
|
* Subscribe or unsubscribe to this remote track
|
@@ -17408,12 +17414,12 @@ class RemoteParticipant extends Participant {
|
|
17408
17414
|
if (!kind) {
|
17409
17415
|
return;
|
17410
17416
|
}
|
17411
|
-
publication = new RemoteTrackPublication(kind, ti
|
17417
|
+
publication = new RemoteTrackPublication(kind, ti, (_a = this.signalClient.connectOptions) === null || _a === void 0 ? void 0 : _a.autoSubscribe);
|
17412
17418
|
publication.updateInfo(ti);
|
17413
17419
|
newTracks.set(ti.sid, publication);
|
17414
17420
|
const existingTrackOfSource = Array.from(this.tracks.values()).find(publishedTrack => publishedTrack.source === (publication === null || publication === void 0 ? void 0 : publication.source));
|
17415
17421
|
if (existingTrackOfSource && publication.source !== Track.Source.Unknown) {
|
17416
|
-
livekitLogger.
|
17422
|
+
livekitLogger.debug("received a second track publication for ".concat(this.identity, " with the same source: ").concat(publication.source), {
|
17417
17423
|
oldTrack: existingTrackOfSource,
|
17418
17424
|
newTrack: publication,
|
17419
17425
|
participant: this,
|
@@ -17588,7 +17594,7 @@ class LocalParticipant extends Participant {
|
|
17588
17594
|
}
|
17589
17595
|
}
|
17590
17596
|
} else if (update.subscribedQualities.length > 0) {
|
17591
|
-
(_b = pub.videoTrack) === null || _b === void 0 ? void 0 : _b.setPublishingLayers(update.subscribedQualities);
|
17597
|
+
await ((_b = pub.videoTrack) === null || _b === void 0 ? void 0 : _b.setPublishingLayers(update.subscribedQualities));
|
17592
17598
|
}
|
17593
17599
|
};
|
17594
17600
|
this.handleLocalTrackUnpublished = unpublished => {
|
@@ -17921,7 +17927,7 @@ class LocalParticipant extends Participant {
|
|
17921
17927
|
* @param options
|
17922
17928
|
*/
|
17923
17929
|
async publishTrack(track, options) {
|
17924
|
-
var _a, _b, _c, _d, _e;
|
17930
|
+
var _a, _b, _c, _d, _e, _f;
|
17925
17931
|
// convert raw media track into audio or video track
|
17926
17932
|
if (track instanceof MediaStreamTrack) {
|
17927
17933
|
switch (track.kind) {
|
@@ -17946,7 +17952,11 @@ class LocalParticipant extends Participant {
|
|
17946
17952
|
if (options.dtx === undefined) {
|
17947
17953
|
livekitLogger.info("Opus DTX will be disabled for stereo tracks by default. Enable them explicitly to make it work.");
|
17948
17954
|
}
|
17955
|
+
if (options.red === undefined) {
|
17956
|
+
livekitLogger.info("Opus RED will be disabled for stereo tracks by default. Enable them explicitly to make it work.");
|
17957
|
+
}
|
17949
17958
|
(_a = options.dtx) !== null && _a !== void 0 ? _a : options.dtx = false;
|
17959
|
+
(_b = options.red) !== null && _b !== void 0 ? _b : options.red = false;
|
17950
17960
|
}
|
17951
17961
|
const opts = _objectSpread2(_objectSpread2({}, this.roomOptions.publishDefaults), options);
|
17952
17962
|
// is it already published? if so skip
|
@@ -18004,9 +18014,9 @@ class LocalParticipant extends Participant {
|
|
18004
18014
|
type: Track.kindToProto(track.kind),
|
18005
18015
|
muted: track.isMuted,
|
18006
18016
|
source: Track.sourceToProto(track.source),
|
18007
|
-
disableDtx: !((
|
18017
|
+
disableDtx: !((_c = opts.dtx) !== null && _c !== void 0 ? _c : true),
|
18008
18018
|
stereo: isStereo,
|
18009
|
-
disableRed: !((
|
18019
|
+
disableRed: !((_d = opts.red) !== null && _d !== void 0 ? _d : true)
|
18010
18020
|
});
|
18011
18021
|
// compute encodings and layers for video
|
18012
18022
|
let encodings;
|
@@ -18029,7 +18039,7 @@ class LocalParticipant extends Participant {
|
|
18029
18039
|
if (track instanceof LocalVideoTrack) {
|
18030
18040
|
if ((opts === null || opts === void 0 ? void 0 : opts.videoCodec) === 'av1') {
|
18031
18041
|
// set scalabilityMode to 'L3T3' by default
|
18032
|
-
opts.scalabilityMode = (
|
18042
|
+
opts.scalabilityMode = (_e = opts.scalabilityMode) !== null && _e !== void 0 ? _e : 'L3T3';
|
18033
18043
|
}
|
18034
18044
|
// set up backup
|
18035
18045
|
if (opts.videoCodec && opts.backupCodec && opts.videoCodec !== opts.backupCodec.codec) {
|
@@ -18071,7 +18081,7 @@ class LocalParticipant extends Participant {
|
|
18071
18081
|
});
|
18072
18082
|
// store RTPSender
|
18073
18083
|
track.sender = await this.engine.createSender(track, opts, encodings);
|
18074
|
-
if (track.codec === 'av1' && encodings && ((
|
18084
|
+
if (track.codec === 'av1' && encodings && ((_f = encodings[0]) === null || _f === void 0 ? void 0 : _f.maxBitrate)) {
|
18075
18085
|
this.engine.publisher.setTrackCodecBitrate(req.cid, track.codec, encodings[0].maxBitrate / 1000);
|
18076
18086
|
}
|
18077
18087
|
this.engine.negotiate();
|
@@ -18167,13 +18177,20 @@ class LocalParticipant extends Participant {
|
|
18167
18177
|
if (stopOnUnpublish) {
|
18168
18178
|
track.stop();
|
18169
18179
|
}
|
18170
|
-
|
18180
|
+
let negotiationNeeded = false;
|
18181
|
+
const trackSender = track.sender;
|
18182
|
+
track.sender = undefined;
|
18183
|
+
if (this.engine.publisher && this.engine.publisher.pc.connectionState !== 'closed' && trackSender) {
|
18171
18184
|
try {
|
18172
|
-
this.engine.removeTrack(
|
18185
|
+
if (this.engine.removeTrack(trackSender)) {
|
18186
|
+
negotiationNeeded = true;
|
18187
|
+
}
|
18173
18188
|
if (track instanceof LocalVideoTrack) {
|
18174
18189
|
for (const [, trackInfo] of track.simulcastCodecs) {
|
18175
18190
|
if (trackInfo.sender) {
|
18176
|
-
this.engine.removeTrack(trackInfo.sender)
|
18191
|
+
if (this.engine.removeTrack(trackInfo.sender)) {
|
18192
|
+
negotiationNeeded = true;
|
18193
|
+
}
|
18177
18194
|
trackInfo.sender = undefined;
|
18178
18195
|
}
|
18179
18196
|
}
|
@@ -18184,11 +18201,8 @@ class LocalParticipant extends Participant {
|
|
18184
18201
|
error: e,
|
18185
18202
|
method: 'unpublishTrack'
|
18186
18203
|
});
|
18187
|
-
} finally {
|
18188
|
-
await this.engine.negotiate();
|
18189
18204
|
}
|
18190
18205
|
}
|
18191
|
-
track.sender = undefined;
|
18192
18206
|
// remove from our maps
|
18193
18207
|
this.tracks.delete(publication.trackSid);
|
18194
18208
|
switch (publication.kind) {
|
@@ -18201,6 +18215,9 @@ class LocalParticipant extends Participant {
|
|
18201
18215
|
}
|
18202
18216
|
this.emit(ParticipantEvent.LocalTrackUnpublished, publication);
|
18203
18217
|
publication.setTrack(undefined);
|
18218
|
+
if (negotiationNeeded) {
|
18219
|
+
await this.engine.negotiate();
|
18220
|
+
}
|
18204
18221
|
return publication;
|
18205
18222
|
}
|
18206
18223
|
async unpublishTracks(tracks) {
|
@@ -19750,6 +19767,8 @@ class PCTransport extends eventsExports {
|
|
19750
19767
|
});
|
19751
19768
|
}
|
19752
19769
|
close() {
|
19770
|
+
this.pc.onconnectionstatechange = null;
|
19771
|
+
this.pc.oniceconnectionstatechange = null;
|
19753
19772
|
this.pc.close();
|
19754
19773
|
}
|
19755
19774
|
async setMungedLocalDescription(sd, munged) {
|
@@ -19868,9 +19887,7 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
19868
19887
|
return this._isClosed;
|
19869
19888
|
}
|
19870
19889
|
constructor(options) {
|
19871
|
-
var _this;
|
19872
19890
|
super();
|
19873
|
-
_this = this;
|
19874
19891
|
this.options = options;
|
19875
19892
|
this.rtcConfig = {};
|
19876
19893
|
this.peerConnectionTimeout = roomConnectOptionDefaults.peerConnectionTimeout;
|
@@ -19889,6 +19906,7 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
19889
19906
|
this.joinAttempts = 0;
|
19890
19907
|
/** specifies how often an initial join connection is allowed to retry */
|
19891
19908
|
this.maxJoinAttempts = 1;
|
19909
|
+
this.shouldFailNext = false;
|
19892
19910
|
this.handleDataChannel = async _ref => {
|
19893
19911
|
let {
|
19894
19912
|
channel
|
@@ -19941,26 +19959,24 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
19941
19959
|
// websocket reconnect behavior. if websocket is interrupted, and the PeerConnection
|
19942
19960
|
// continues to work, we can reconnect to websocket to continue the session
|
19943
19961
|
// after a number of retries, we'll close and give up permanently
|
19944
|
-
this.handleDisconnect =
|
19945
|
-
|
19946
|
-
let disconnectReason = arguments.length > 2 ? arguments[2] : undefined;
|
19947
|
-
if (_this._isClosed) {
|
19962
|
+
this.handleDisconnect = (connection, disconnectReason) => {
|
19963
|
+
if (this._isClosed) {
|
19948
19964
|
return;
|
19949
19965
|
}
|
19950
19966
|
livekitLogger.warn("".concat(connection, " disconnected"));
|
19951
|
-
if (
|
19967
|
+
if (this.reconnectAttempts === 0) {
|
19952
19968
|
// only reset start time on the first try
|
19953
|
-
|
19969
|
+
this.reconnectStart = Date.now();
|
19954
19970
|
}
|
19955
19971
|
const disconnect = duration => {
|
19956
|
-
livekitLogger.warn("could not recover connection after ".concat(
|
19957
|
-
|
19958
|
-
|
19972
|
+
livekitLogger.warn("could not recover connection after ".concat(this.reconnectAttempts, " attempts, ").concat(duration, "ms. giving up"));
|
19973
|
+
this.emit(EngineEvent.Disconnected);
|
19974
|
+
this.close();
|
19959
19975
|
};
|
19960
|
-
const duration = Date.now() -
|
19961
|
-
let delay =
|
19976
|
+
const duration = Date.now() - this.reconnectStart;
|
19977
|
+
let delay = this.getNextRetryDelay({
|
19962
19978
|
elapsedMs: duration,
|
19963
|
-
retryCount:
|
19979
|
+
retryCount: this.reconnectAttempts
|
19964
19980
|
});
|
19965
19981
|
if (delay === null) {
|
19966
19982
|
disconnect(duration);
|
@@ -19970,14 +19986,14 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
19970
19986
|
delay = 0;
|
19971
19987
|
}
|
19972
19988
|
livekitLogger.debug("reconnecting in ".concat(delay, "ms"));
|
19973
|
-
|
19974
|
-
|
19989
|
+
this.clearReconnectTimeout();
|
19990
|
+
this.reconnectTimeout = CriticalTimers.setTimeout(() => this.attemptReconnect(disconnectReason), delay);
|
19975
19991
|
};
|
19976
19992
|
this.handleBrowserOnLine = () => {
|
19977
19993
|
// in case the engine is currently reconnecting, attempt a reconnect immediately after the browser state has changed to 'onLine'
|
19978
19994
|
if (this.client.isReconnecting) {
|
19979
19995
|
this.clearReconnectTimeout();
|
19980
|
-
this.attemptReconnect(
|
19996
|
+
this.attemptReconnect(ReconnectReason.REASON_SIGNAL_DISCONNECTED);
|
19981
19997
|
}
|
19982
19998
|
};
|
19983
19999
|
this.client = new SignalClient();
|
@@ -20076,6 +20092,12 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
20076
20092
|
this.client.sendAddTrack(req);
|
20077
20093
|
});
|
20078
20094
|
}
|
20095
|
+
/**
|
20096
|
+
* Removes sender from PeerConnection, returning true if it was removed successfully
|
20097
|
+
* and a negotiation is necessary
|
20098
|
+
* @param sender
|
20099
|
+
* @returns
|
20100
|
+
*/
|
20079
20101
|
removeTrack(sender) {
|
20080
20102
|
var _a;
|
20081
20103
|
if (sender.track && this.pendingTrackResolvers[sender.track.id]) {
|
@@ -20089,12 +20111,14 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
20089
20111
|
}
|
20090
20112
|
try {
|
20091
20113
|
(_a = this.publisher) === null || _a === void 0 ? void 0 : _a.pc.removeTrack(sender);
|
20114
|
+
return true;
|
20092
20115
|
} catch (e) {
|
20093
20116
|
livekitLogger.warn('failed to remove track', {
|
20094
20117
|
error: e,
|
20095
20118
|
method: 'removeTrack'
|
20096
20119
|
});
|
20097
20120
|
}
|
20121
|
+
return false;
|
20098
20122
|
}
|
20099
20123
|
updateMuteStatus(trackSid, muted) {
|
20100
20124
|
this.client.sendMuteTrack(trackSid, muted);
|
@@ -20103,8 +20127,11 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
20103
20127
|
var _a;
|
20104
20128
|
return (_a = this.reliableDCSub) === null || _a === void 0 ? void 0 : _a.readyState;
|
20105
20129
|
}
|
20106
|
-
|
20107
|
-
|
20130
|
+
async getConnectedServerAddress() {
|
20131
|
+
if (this.primaryPC === undefined) {
|
20132
|
+
return undefined;
|
20133
|
+
}
|
20134
|
+
return getConnectedAddress(this.primaryPC);
|
20108
20135
|
}
|
20109
20136
|
configure(joinResponse) {
|
20110
20137
|
var _a;
|
@@ -20142,13 +20169,6 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
20142
20169
|
primaryPC.onconnectionstatechange = async () => {
|
20143
20170
|
livekitLogger.debug("primary PC state changed ".concat(primaryPC.connectionState));
|
20144
20171
|
if (primaryPC.connectionState === 'connected') {
|
20145
|
-
try {
|
20146
|
-
this.connectedServerAddr = await getConnectedAddress(primaryPC);
|
20147
|
-
} catch (e) {
|
20148
|
-
livekitLogger.warn('could not get connected server address', {
|
20149
|
-
error: e
|
20150
|
-
});
|
20151
|
-
}
|
20152
20172
|
const shouldEmit = this.pcState === PCState.New;
|
20153
20173
|
this.pcState = PCState.Connected;
|
20154
20174
|
if (shouldEmit) {
|
@@ -20158,7 +20178,7 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
20158
20178
|
// on Safari, PeerConnection will switch to 'disconnected' during renegotiation
|
20159
20179
|
if (this.pcState === PCState.Connected) {
|
20160
20180
|
this.pcState = PCState.Disconnected;
|
20161
|
-
this.handleDisconnect('primary peerconnection',
|
20181
|
+
this.handleDisconnect('primary peerconnection', subscriberPrimary ? ReconnectReason.REASON_SUBSCRIBER_FAILED : ReconnectReason.REASON_PUBLISHER_FAILED);
|
20162
20182
|
}
|
20163
20183
|
}
|
20164
20184
|
};
|
@@ -20166,7 +20186,7 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
20166
20186
|
livekitLogger.debug("secondary PC state changed ".concat(secondaryPC.connectionState));
|
20167
20187
|
// also reconnect if secondary peerconnection fails
|
20168
20188
|
if (secondaryPC.connectionState === 'failed') {
|
20169
|
-
this.handleDisconnect('secondary peerconnection',
|
20189
|
+
this.handleDisconnect('secondary peerconnection', subscriberPrimary ? ReconnectReason.REASON_PUBLISHER_FAILED : ReconnectReason.REASON_SUBSCRIBER_FAILED);
|
20170
20190
|
}
|
20171
20191
|
};
|
20172
20192
|
this.subscriber.pc.ontrack = ev => {
|
@@ -20229,7 +20249,7 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
20229
20249
|
this.token = token;
|
20230
20250
|
};
|
20231
20251
|
this.client.onClose = () => {
|
20232
|
-
this.handleDisconnect('signal',
|
20252
|
+
this.handleDisconnect('signal', ReconnectReason.REASON_SIGNAL_DISCONNECTED);
|
20233
20253
|
};
|
20234
20254
|
this.client.onLeave = leave => {
|
20235
20255
|
if (leave === null || leave === void 0 ? void 0 : leave.canReconnect) {
|
@@ -20403,9 +20423,7 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
20403
20423
|
}
|
20404
20424
|
return this.publisher.pc.addTrack(track);
|
20405
20425
|
}
|
20406
|
-
async attemptReconnect() {
|
20407
|
-
let signalEvents = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
20408
|
-
let reason = arguments.length > 1 ? arguments[1] : undefined;
|
20426
|
+
async attemptReconnect(reason) {
|
20409
20427
|
var _a, _b, _c;
|
20410
20428
|
if (this._isClosed) {
|
20411
20429
|
return;
|
@@ -20423,17 +20441,15 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
20423
20441
|
try {
|
20424
20442
|
this.attemptingReconnect = true;
|
20425
20443
|
if (this.fullReconnectOnNext) {
|
20426
|
-
await this.restartConnection(
|
20444
|
+
await this.restartConnection();
|
20427
20445
|
} else {
|
20428
|
-
await this.resumeConnection(
|
20446
|
+
await this.resumeConnection(reason);
|
20429
20447
|
}
|
20430
20448
|
this.clearPendingReconnect();
|
20431
20449
|
this.fullReconnectOnNext = false;
|
20432
20450
|
} catch (e) {
|
20433
20451
|
this.reconnectAttempts += 1;
|
20434
|
-
let reconnectRequired = false;
|
20435
20452
|
let recoverable = true;
|
20436
|
-
let requireSignalEvents = false;
|
20437
20453
|
if (e instanceof UnexpectedConnectionState) {
|
20438
20454
|
livekitLogger.debug('received unrecoverable error', {
|
20439
20455
|
error: e
|
@@ -20442,16 +20458,10 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
20442
20458
|
recoverable = false;
|
20443
20459
|
} else if (!(e instanceof SignalReconnectError)) {
|
20444
20460
|
// cannot resume
|
20445
|
-
reconnectRequired = true;
|
20446
|
-
}
|
20447
|
-
// when we flip from resume to reconnect
|
20448
|
-
// we need to fire the right reconnecting events
|
20449
|
-
if (reconnectRequired && !this.fullReconnectOnNext) {
|
20450
20461
|
this.fullReconnectOnNext = true;
|
20451
|
-
requireSignalEvents = true;
|
20452
20462
|
}
|
20453
20463
|
if (recoverable) {
|
20454
|
-
this.handleDisconnect('reconnect',
|
20464
|
+
this.handleDisconnect('reconnect', ReconnectReason.REASON_UNKOWN);
|
20455
20465
|
} else {
|
20456
20466
|
livekitLogger.info("could not recover connection after ".concat(this.reconnectAttempts, " attempts, ").concat(Date.now() - this.reconnectStart, "ms. giving up"));
|
20457
20467
|
this.emit(EngineEvent.Disconnected);
|
@@ -20473,16 +20483,13 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
20473
20483
|
return null;
|
20474
20484
|
}
|
20475
20485
|
async restartConnection() {
|
20476
|
-
let emitRestarting = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
20477
20486
|
var _a, _b;
|
20478
20487
|
if (!this.url || !this.token) {
|
20479
20488
|
// permanent failure, don't attempt reconnection
|
20480
20489
|
throw new UnexpectedConnectionState('could not reconnect, url or token not saved');
|
20481
20490
|
}
|
20482
20491
|
livekitLogger.info("reconnecting, attempt: ".concat(this.reconnectAttempts));
|
20483
|
-
|
20484
|
-
this.emit(EngineEvent.Restarting);
|
20485
|
-
}
|
20492
|
+
this.emit(EngineEvent.Restarting);
|
20486
20493
|
if (this.client.isConnected) {
|
20487
20494
|
await this.client.sendLeave();
|
20488
20495
|
}
|
@@ -20502,14 +20509,16 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
20502
20509
|
} catch (e) {
|
20503
20510
|
throw new SignalReconnectError();
|
20504
20511
|
}
|
20512
|
+
if (this.shouldFailNext) {
|
20513
|
+
this.shouldFailNext = false;
|
20514
|
+
throw new Error('simulated failure');
|
20515
|
+
}
|
20505
20516
|
await this.waitForPCConnected();
|
20506
20517
|
this.client.setReconnected();
|
20507
20518
|
// reconnect success
|
20508
20519
|
this.emit(EngineEvent.Restarted, joinResponse);
|
20509
20520
|
}
|
20510
|
-
async resumeConnection() {
|
20511
|
-
let emitResuming = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
20512
|
-
let reason = arguments.length > 1 ? arguments[1] : undefined;
|
20521
|
+
async resumeConnection(reason) {
|
20513
20522
|
var _a;
|
20514
20523
|
if (!this.url || !this.token) {
|
20515
20524
|
// permanent failure, don't attempt reconnection
|
@@ -20520,9 +20529,7 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
20520
20529
|
throw new UnexpectedConnectionState('publisher and subscriber connections unset');
|
20521
20530
|
}
|
20522
20531
|
livekitLogger.info("resuming signal connection, attempt ".concat(this.reconnectAttempts));
|
20523
|
-
|
20524
|
-
this.emit(EngineEvent.Resuming);
|
20525
|
-
}
|
20532
|
+
this.emit(EngineEvent.Resuming);
|
20526
20533
|
try {
|
20527
20534
|
const res = await this.client.reconnect(this.url, this.token, this.participantSid, reason);
|
20528
20535
|
if (res) {
|
@@ -20538,6 +20545,10 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
20538
20545
|
throw new SignalReconnectError(message);
|
20539
20546
|
}
|
20540
20547
|
this.emit(EngineEvent.SignalResumed);
|
20548
|
+
if (this.shouldFailNext) {
|
20549
|
+
this.shouldFailNext = false;
|
20550
|
+
throw new Error('simulated failure');
|
20551
|
+
}
|
20541
20552
|
this.subscriber.restartingIce = true;
|
20542
20553
|
// only restart publisher if it's needed
|
20543
20554
|
if (this.hasPublished) {
|
@@ -20571,13 +20582,6 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
20571
20582
|
// manually
|
20572
20583
|
now - startTime > minReconnectWait && ((_a = this.primaryPC) === null || _a === void 0 ? void 0 : _a.connectionState) === 'connected') {
|
20573
20584
|
this.pcState = PCState.Connected;
|
20574
|
-
try {
|
20575
|
-
this.connectedServerAddr = await getConnectedAddress(this.primaryPC);
|
20576
|
-
} catch (e) {
|
20577
|
-
livekitLogger.warn('could not get connected server address', {
|
20578
|
-
error: e
|
20579
|
-
});
|
20580
|
-
}
|
20581
20585
|
}
|
20582
20586
|
if (this.pcState === PCState.Connected) {
|
20583
20587
|
return;
|
@@ -20649,7 +20653,7 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
20649
20653
|
this.on(EngineEvent.Closing, handleClosed);
|
20650
20654
|
const negotiationTimeout = setTimeout(() => {
|
20651
20655
|
reject('negotiation timed out');
|
20652
|
-
this.handleDisconnect('negotiation',
|
20656
|
+
this.handleDisconnect('negotiation', ReconnectReason.REASON_SIGNAL_DISCONNECTED);
|
20653
20657
|
}, this.peerConnectionTimeout);
|
20654
20658
|
const cleanup = () => {
|
20655
20659
|
clearTimeout(negotiationTimeout);
|
@@ -20668,7 +20672,7 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
20668
20672
|
if (e instanceof NegotiationError) {
|
20669
20673
|
this.fullReconnectOnNext = true;
|
20670
20674
|
}
|
20671
|
-
this.handleDisconnect('negotiation',
|
20675
|
+
this.handleDisconnect('negotiation', ReconnectReason.REASON_UNKOWN);
|
20672
20676
|
});
|
20673
20677
|
});
|
20674
20678
|
}
|
@@ -20689,6 +20693,11 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
20689
20693
|
}
|
20690
20694
|
}
|
20691
20695
|
}
|
20696
|
+
/* @internal */
|
20697
|
+
failNext() {
|
20698
|
+
// debugging method to fail the next reconnect/resume attempt
|
20699
|
+
this.shouldFailNext = true;
|
20700
|
+
}
|
20692
20701
|
clearReconnectTimeout() {
|
20693
20702
|
if (this.reconnectTimeout) {
|
20694
20703
|
CriticalTimers.clearTimeout(this.reconnectTimeout);
|
@@ -21008,6 +21017,9 @@ class Room extends eventsExports.EventEmitter {
|
|
21008
21017
|
});
|
21009
21018
|
await track.restartTrack();
|
21010
21019
|
}
|
21020
|
+
livekitLogger.debug('publishing new track', {
|
21021
|
+
track: pub.trackSid
|
21022
|
+
});
|
21011
21023
|
await this.localParticipant.publishTrack(track, pub.options);
|
21012
21024
|
}
|
21013
21025
|
}));
|
@@ -21330,6 +21342,13 @@ class Room extends eventsExports.EventEmitter {
|
|
21330
21342
|
}
|
21331
21343
|
});
|
21332
21344
|
break;
|
21345
|
+
case 'resume-reconnect':
|
21346
|
+
this.engine.failNext();
|
21347
|
+
await this.engine.client.close();
|
21348
|
+
if (this.engine.client.onClose) {
|
21349
|
+
this.engine.client.onClose('simulate resume-reconnect');
|
21350
|
+
}
|
21351
|
+
break;
|
21333
21352
|
case 'force-tcp':
|
21334
21353
|
case 'force-tls':
|
21335
21354
|
req = SimulateScenario.fromPartial({
|
@@ -21564,7 +21583,7 @@ class Room extends eventsExports.EventEmitter {
|
|
21564
21583
|
participant.tracks.forEach(publication => {
|
21565
21584
|
participant.unpublishTrack(publication.trackSid, true);
|
21566
21585
|
});
|
21567
|
-
this.
|
21586
|
+
this.emit(RoomEvent.ParticipantDisconnected, participant);
|
21568
21587
|
}
|
21569
21588
|
async acquireAudioContext() {
|
21570
21589
|
var _a, _b;
|
@@ -21625,7 +21644,7 @@ class Room extends eventsExports.EventEmitter {
|
|
21625
21644
|
}
|
21626
21645
|
this.emit(RoomEvent.TrackSubscribed, track, publication, participant);
|
21627
21646
|
}).on(ParticipantEvent.TrackUnpublished, publication => {
|
21628
|
-
this.
|
21647
|
+
this.emit(RoomEvent.TrackUnpublished, publication, participant);
|
21629
21648
|
}).on(ParticipantEvent.TrackUnsubscribed, (track, publication) => {
|
21630
21649
|
this.emit(RoomEvent.TrackUnsubscribed, track, publication, participant);
|
21631
21650
|
}).on(ParticipantEvent.TrackSubscriptionFailed, sid => {
|