livekit-client 1.1.9 → 1.2.0
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 +168 -57
- 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 -1
- package/dist/src/api/SignalClient.d.ts.map +1 -1
- package/dist/src/options.d.ts +1 -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 +1 -1
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/events.d.ts +8 -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/LocalTrack.d.ts.map +1 -1
- package/dist/src/room/track/RemoteTrackPublication.d.ts +4 -1
- package/dist/src/room/track/RemoteTrackPublication.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/api/SignalClient.ts +3 -1
- package/src/options.ts +1 -0
- package/src/room/RTCEngine.ts +41 -16
- package/src/room/Room.ts +20 -16
- package/src/room/events.ts +7 -0
- package/src/room/participant/LocalParticipant.ts +44 -6
- package/src/room/participant/RemoteParticipant.ts +12 -10
- package/src/room/track/LocalTrack.ts +4 -0
- package/src/room/track/RemoteTrackPublication.ts +37 -11
@@ -10189,6 +10189,8 @@ var TrackEvent;
|
|
10189
10189
|
TrackEvent["Muted"] = "muted";
|
10190
10190
|
TrackEvent["Unmuted"] = "unmuted";
|
10191
10191
|
TrackEvent["Ended"] = "ended";
|
10192
|
+
TrackEvent["Subscribed"] = "subscribed";
|
10193
|
+
TrackEvent["Unsubscribed"] = "unsubscribed";
|
10192
10194
|
/** @internal */
|
10193
10195
|
|
10194
10196
|
TrackEvent["UpdateSettings"] = "updateSettings";
|
@@ -10231,6 +10233,12 @@ var TrackEvent;
|
|
10231
10233
|
*/
|
10232
10234
|
|
10233
10235
|
TrackEvent["UpstreamResumed"] = "upstreamResumed";
|
10236
|
+
/**
|
10237
|
+
* @internal
|
10238
|
+
* Fires on RemoteTrackPublication
|
10239
|
+
*/
|
10240
|
+
|
10241
|
+
TrackEvent["SubscriptionPermissionChanged"] = "subscriptionPermissionChanged";
|
10234
10242
|
})(TrackEvent || (TrackEvent = {}));
|
10235
10243
|
|
10236
10244
|
const monitorFrequency = 2000;
|
@@ -10257,7 +10265,7 @@ function computeBitrate(currentStats, prevStats) {
|
|
10257
10265
|
return (bytesNow - bytesPrev) * 8 * 1000 / (currentStats.timestamp - prevStats.timestamp);
|
10258
10266
|
}
|
10259
10267
|
|
10260
|
-
var version$1 = "1.
|
10268
|
+
var version$1 = "1.2.0";
|
10261
10269
|
|
10262
10270
|
const version = version$1;
|
10263
10271
|
const protocolVersion = 8;
|
@@ -11550,6 +11558,7 @@ class LocalTrack extends Track {
|
|
11550
11558
|
}
|
11551
11559
|
|
11552
11560
|
this._mediaStreamTrack = track;
|
11561
|
+
await this.resumeUpstream();
|
11553
11562
|
this.attachedElements.forEach(el => {
|
11554
11563
|
attachToElement(track, el);
|
11555
11564
|
});
|
@@ -11599,6 +11608,7 @@ class LocalTrack extends Track {
|
|
11599
11608
|
}
|
11600
11609
|
|
11601
11610
|
this._mediaStreamTrack = newTrack;
|
11611
|
+
await this.resumeUpstream();
|
11602
11612
|
this.attachedElements.forEach(el => {
|
11603
11613
|
attachToElement(newTrack, el);
|
11604
11614
|
});
|
@@ -13612,7 +13622,7 @@ class RemoteTrackPublication extends TrackPublication {
|
|
13612
13622
|
super(...arguments);
|
13613
13623
|
/** @internal */
|
13614
13624
|
|
13615
|
-
this.
|
13625
|
+
this.allowed = true;
|
13616
13626
|
this.disabled = false;
|
13617
13627
|
this.currentVideoQuality = VideoQuality.HIGH;
|
13618
13628
|
|
@@ -13644,7 +13654,10 @@ class RemoteTrackPublication extends TrackPublication {
|
|
13644
13654
|
|
13645
13655
|
|
13646
13656
|
setSubscribed(subscribed) {
|
13647
|
-
this.subscribed = subscribed;
|
13657
|
+
this.subscribed = subscribed; // reset allowed status when desired subscription state changes
|
13658
|
+
// server will notify client via signal message if it's not allowed
|
13659
|
+
|
13660
|
+
this.allowed = true;
|
13648
13661
|
const sub = {
|
13649
13662
|
trackSids: [this.trackSid],
|
13650
13663
|
subscribe: this.subscribed,
|
@@ -13660,11 +13673,11 @@ class RemoteTrackPublication extends TrackPublication {
|
|
13660
13673
|
|
13661
13674
|
get subscriptionStatus() {
|
13662
13675
|
if (this.subscribed === false || !super.isSubscribed) {
|
13663
|
-
|
13664
|
-
|
13676
|
+
if (!this.allowed) {
|
13677
|
+
return TrackPublication.SubscriptionStatus.NotAllowed;
|
13678
|
+
}
|
13665
13679
|
|
13666
|
-
|
13667
|
-
return TrackPublication.SubscriptionStatus.NotAllowed;
|
13680
|
+
return TrackPublication.SubscriptionStatus.Unsubscribed;
|
13668
13681
|
}
|
13669
13682
|
|
13670
13683
|
return TrackPublication.SubscriptionStatus.Subscribed;
|
@@ -13679,10 +13692,6 @@ class RemoteTrackPublication extends TrackPublication {
|
|
13679
13692
|
return false;
|
13680
13693
|
}
|
13681
13694
|
|
13682
|
-
if (!this._allowed) {
|
13683
|
-
return false;
|
13684
|
-
}
|
13685
|
-
|
13686
13695
|
return super.isSubscribed;
|
13687
13696
|
}
|
13688
13697
|
|
@@ -13750,11 +13759,14 @@ class RemoteTrackPublication extends TrackPublication {
|
|
13750
13759
|
|
13751
13760
|
|
13752
13761
|
setTrack(track) {
|
13753
|
-
|
13762
|
+
const prevStatus = this.subscriptionStatus;
|
13763
|
+
const prevTrack = this.track;
|
13764
|
+
|
13765
|
+
if (prevTrack) {
|
13754
13766
|
// unregister listener
|
13755
|
-
|
13756
|
-
|
13757
|
-
|
13767
|
+
prevTrack.off(TrackEvent.VideoDimensionsChanged, this.handleVideoDimensionsChange);
|
13768
|
+
prevTrack.off(TrackEvent.VisibilityChanged, this.handleVisibilityChange);
|
13769
|
+
prevTrack.off(TrackEvent.Ended, this.handleEnded);
|
13758
13770
|
}
|
13759
13771
|
|
13760
13772
|
super.setTrack(track);
|
@@ -13765,6 +13777,25 @@ class RemoteTrackPublication extends TrackPublication {
|
|
13765
13777
|
track.on(TrackEvent.VisibilityChanged, this.handleVisibilityChange);
|
13766
13778
|
track.on(TrackEvent.Ended, this.handleEnded);
|
13767
13779
|
}
|
13780
|
+
|
13781
|
+
this.emitSubscriptionUpdateIfChanged(prevStatus);
|
13782
|
+
|
13783
|
+
if (!!track !== !!prevTrack) {
|
13784
|
+
// when undefined status changes, there's a subscription changed event
|
13785
|
+
if (track) {
|
13786
|
+
this.emit(TrackEvent.Subscribed, track);
|
13787
|
+
} else {
|
13788
|
+
this.emit(TrackEvent.Unsubscribed, prevTrack);
|
13789
|
+
}
|
13790
|
+
}
|
13791
|
+
}
|
13792
|
+
/** @internal */
|
13793
|
+
|
13794
|
+
|
13795
|
+
setAllowed(allowed) {
|
13796
|
+
const prevStatus = this.subscriptionStatus;
|
13797
|
+
this.allowed = allowed;
|
13798
|
+
this.emitSubscriptionUpdateIfChanged(prevStatus);
|
13768
13799
|
}
|
13769
13800
|
/** @internal */
|
13770
13801
|
|
@@ -13777,6 +13808,16 @@ class RemoteTrackPublication extends TrackPublication {
|
|
13777
13808
|
(_a = this.track) === null || _a === void 0 ? void 0 : _a.setMuted(info.muted);
|
13778
13809
|
}
|
13779
13810
|
|
13811
|
+
emitSubscriptionUpdateIfChanged(previousStatus) {
|
13812
|
+
const currentStatus = this.subscriptionStatus;
|
13813
|
+
|
13814
|
+
if (previousStatus === currentStatus) {
|
13815
|
+
return;
|
13816
|
+
}
|
13817
|
+
|
13818
|
+
this.emit(TrackEvent.SubscriptionPermissionChanged, currentStatus, previousStatus);
|
13819
|
+
}
|
13820
|
+
|
13780
13821
|
isManualOperationAllowed() {
|
13781
13822
|
if (this.isAdaptiveStream) {
|
13782
13823
|
livekitLogger.warn('adaptive stream is enabled, cannot change track settings', {
|
@@ -13851,8 +13892,14 @@ class RemoteParticipant extends Participant {
|
|
13851
13892
|
});
|
13852
13893
|
this.signalClient.sendUpdateSubscription(sub);
|
13853
13894
|
});
|
13854
|
-
publication.on(TrackEvent.
|
13855
|
-
this.emit(ParticipantEvent.
|
13895
|
+
publication.on(TrackEvent.SubscriptionPermissionChanged, status => {
|
13896
|
+
this.emit(ParticipantEvent.TrackSubscriptionPermissionChanged, publication, status);
|
13897
|
+
});
|
13898
|
+
publication.on(TrackEvent.Subscribed, track => {
|
13899
|
+
this.emit(ParticipantEvent.TrackSubscribed, track, publication);
|
13900
|
+
});
|
13901
|
+
publication.on(TrackEvent.Unsubscribed, previousTrack => {
|
13902
|
+
this.emit(ParticipantEvent.TrackUnsubscribed, previousTrack, publication);
|
13856
13903
|
});
|
13857
13904
|
}
|
13858
13905
|
|
@@ -13953,15 +14000,12 @@ class RemoteParticipant extends Participant {
|
|
13953
14000
|
track.isMuted = publication.isMuted;
|
13954
14001
|
track.setMediaStream(mediaStream);
|
13955
14002
|
track.start();
|
13956
|
-
publication.setTrack(track); //
|
13957
|
-
|
13958
|
-
publication._allowed = true; // set participant volume on new microphone tracks
|
14003
|
+
publication.setTrack(track); // set participant volume on new microphone tracks
|
13959
14004
|
|
13960
14005
|
if (this.volume !== undefined && track instanceof RemoteAudioTrack && track.source === Track.Source.Microphone) {
|
13961
14006
|
track.setVolume(this.volume);
|
13962
14007
|
}
|
13963
14008
|
|
13964
|
-
this.emit(ParticipantEvent.TrackSubscribed, track, publication);
|
13965
14009
|
return publication;
|
13966
14010
|
}
|
13967
14011
|
/** @internal */
|
@@ -14049,15 +14093,8 @@ class RemoteParticipant extends Participant {
|
|
14049
14093
|
} = publication;
|
14050
14094
|
|
14051
14095
|
if (track) {
|
14052
|
-
const {
|
14053
|
-
isSubscribed
|
14054
|
-
} = publication;
|
14055
14096
|
track.stop();
|
14056
|
-
publication.setTrack(undefined);
|
14057
|
-
|
14058
|
-
if (isSubscribed) {
|
14059
|
-
this.emit(ParticipantEvent.TrackUnsubscribed, track, publication);
|
14060
|
-
}
|
14097
|
+
publication.setTrack(undefined);
|
14061
14098
|
}
|
14062
14099
|
|
14063
14100
|
if (sendUnpublish) {
|
@@ -14178,11 +14215,47 @@ class LocalParticipant extends Participant {
|
|
14178
14215
|
this.unpublishTrack(track.track);
|
14179
14216
|
};
|
14180
14217
|
|
14181
|
-
this.handleTrackEnded = track => {
|
14182
|
-
|
14183
|
-
track
|
14184
|
-
|
14185
|
-
|
14218
|
+
this.handleTrackEnded = async track => {
|
14219
|
+
if (track.source === Track.Source.ScreenShare || track.source === Track.Source.ScreenShareAudio) {
|
14220
|
+
livekitLogger.debug('unpublishing local track due to TrackEnded', {
|
14221
|
+
track: track.sid
|
14222
|
+
});
|
14223
|
+
this.unpublishTrack(track);
|
14224
|
+
} else if (track.isUserProvided) {
|
14225
|
+
await track.pauseUpstream();
|
14226
|
+
} else if (track instanceof LocalAudioTrack || track instanceof LocalVideoTrack) {
|
14227
|
+
try {
|
14228
|
+
if (isWeb()) {
|
14229
|
+
try {
|
14230
|
+
const currentPermissions = await (navigator === null || navigator === void 0 ? void 0 : navigator.permissions.query({
|
14231
|
+
// the permission query for camera and microphone currently not supported in Safari and Firefox
|
14232
|
+
// @ts-ignore
|
14233
|
+
name: track.source === Track.Source.Camera ? 'camera' : 'microphone'
|
14234
|
+
}));
|
14235
|
+
|
14236
|
+
if (currentPermissions && currentPermissions.state === 'denied') {
|
14237
|
+
livekitLogger.warn("user has revoked access to ".concat(track.source)); // detect granted change after permissions were denied to try and resume then
|
14238
|
+
|
14239
|
+
currentPermissions.onchange = () => {
|
14240
|
+
if (currentPermissions.state !== 'denied') {
|
14241
|
+
track.restartTrack();
|
14242
|
+
currentPermissions.onchange = null;
|
14243
|
+
}
|
14244
|
+
};
|
14245
|
+
|
14246
|
+
throw new Error('GetUserMedia Permission denied');
|
14247
|
+
}
|
14248
|
+
} catch (e) {// permissions query fails for firefox, we continue and try to restart the track
|
14249
|
+
}
|
14250
|
+
}
|
14251
|
+
|
14252
|
+
livekitLogger.debug('track ended, attempting to use a different device');
|
14253
|
+
await track.restartTrack();
|
14254
|
+
} catch (e) {
|
14255
|
+
livekitLogger.warn("could not restart track, pausing upstream instead");
|
14256
|
+
await track.pauseUpstream();
|
14257
|
+
}
|
14258
|
+
}
|
14186
14259
|
};
|
14187
14260
|
|
14188
14261
|
this.audioTracks = new Map();
|
@@ -19422,23 +19495,9 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19422
19495
|
const track = ev.stream.getTracks()[0];
|
19423
19496
|
this.emit(EngineEvent.MediaTrackAdded, track, ev.stream);
|
19424
19497
|
};
|
19425
|
-
}
|
19426
|
-
|
19427
|
-
|
19428
|
-
this.lossyDC = this.publisher.pc.createDataChannel(lossyDataChannel, {
|
19429
|
-
// will drop older packets that arrive
|
19430
|
-
ordered: true,
|
19431
|
-
maxRetransmits: 0
|
19432
|
-
});
|
19433
|
-
this.reliableDC = this.publisher.pc.createDataChannel(reliableDataChannel, {
|
19434
|
-
ordered: true
|
19435
|
-
}); // also handle messages over the pub channel, for backwards compatibility
|
19498
|
+
}
|
19436
19499
|
|
19437
|
-
this.
|
19438
|
-
this.reliableDC.onmessage = this.handleDataMessage; // handle datachannel errors
|
19439
|
-
|
19440
|
-
this.lossyDC.onerror = this.handleDataError;
|
19441
|
-
this.reliableDC.onerror = this.handleDataError; // configure signaling client
|
19500
|
+
this.createDataChannels(); // configure signaling client
|
19442
19501
|
|
19443
19502
|
this.client.onAnswer = async sd => {
|
19444
19503
|
if (!this.publisher) {
|
@@ -19523,6 +19582,39 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19523
19582
|
};
|
19524
19583
|
}
|
19525
19584
|
|
19585
|
+
createDataChannels() {
|
19586
|
+
if (!this.publisher) {
|
19587
|
+
return;
|
19588
|
+
} // clear old data channel callbacks if recreate
|
19589
|
+
|
19590
|
+
|
19591
|
+
if (this.lossyDC) {
|
19592
|
+
this.lossyDC.onmessage = null;
|
19593
|
+
this.lossyDC.onerror = null;
|
19594
|
+
}
|
19595
|
+
|
19596
|
+
if (this.reliableDC) {
|
19597
|
+
this.reliableDC.onmessage = null;
|
19598
|
+
this.reliableDC.onerror = null;
|
19599
|
+
} // create data channels
|
19600
|
+
|
19601
|
+
|
19602
|
+
this.lossyDC = this.publisher.pc.createDataChannel(lossyDataChannel, {
|
19603
|
+
// will drop older packets that arrive
|
19604
|
+
ordered: true,
|
19605
|
+
maxRetransmits: 0
|
19606
|
+
});
|
19607
|
+
this.reliableDC = this.publisher.pc.createDataChannel(reliableDataChannel, {
|
19608
|
+
ordered: true
|
19609
|
+
}); // also handle messages over the pub channel, for backwards compatibility
|
19610
|
+
|
19611
|
+
this.lossyDC.onmessage = this.handleDataMessage;
|
19612
|
+
this.reliableDC.onmessage = this.handleDataMessage; // handle datachannel errors
|
19613
|
+
|
19614
|
+
this.lossyDC.onerror = this.handleDataError;
|
19615
|
+
this.reliableDC.onerror = this.handleDataError;
|
19616
|
+
}
|
19617
|
+
|
19526
19618
|
async restartConnection() {
|
19527
19619
|
var _a, _b;
|
19528
19620
|
|
@@ -19562,6 +19654,8 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19562
19654
|
}
|
19563
19655
|
|
19564
19656
|
async resumeConnection() {
|
19657
|
+
var _a;
|
19658
|
+
|
19565
19659
|
if (!this.url || !this.token) {
|
19566
19660
|
// permanent failure, don't attempt reconnection
|
19567
19661
|
throw new UnexpectedConnectionState('could not reconnect, url or token not saved');
|
@@ -19594,7 +19688,13 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19594
19688
|
}
|
19595
19689
|
|
19596
19690
|
await this.waitForPCConnected();
|
19597
|
-
this.client.setReconnected(); //
|
19691
|
+
this.client.setReconnected(); // recreate publish datachannel if it's id is null
|
19692
|
+
// (for safari https://bugs.webkit.org/show_bug.cgi?id=184688)
|
19693
|
+
|
19694
|
+
if (((_a = this.reliableDC) === null || _a === void 0 ? void 0 : _a.readyState) === 'open' && this.reliableDC.id === null) {
|
19695
|
+
this.createDataChannels();
|
19696
|
+
} // resume success
|
19697
|
+
|
19598
19698
|
|
19599
19699
|
this.emit(EngineEvent.Resumed);
|
19600
19700
|
}
|
@@ -19964,11 +20064,15 @@ class Room extends events.exports.EventEmitter {
|
|
19964
20064
|
*/
|
19965
20065
|
|
19966
20066
|
|
19967
|
-
this.disconnect = function () {
|
20067
|
+
this.disconnect = async function () {
|
19968
20068
|
let stopTracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
19969
20069
|
|
19970
20070
|
var _a, _b;
|
19971
20071
|
|
20072
|
+
livekitLogger.info('disconnect from room', {
|
20073
|
+
identity: _this.localParticipant.identity
|
20074
|
+
});
|
20075
|
+
|
19972
20076
|
if (_this.state === ConnectionState.Connecting) {
|
19973
20077
|
// try aborting pending connection attempt
|
19974
20078
|
livekitLogger.warn('abort connection attempt');
|
@@ -19978,7 +20082,7 @@ class Room extends events.exports.EventEmitter {
|
|
19978
20082
|
|
19979
20083
|
|
19980
20084
|
if ((_b = _this.engine) === null || _b === void 0 ? void 0 : _b.client.isConnected) {
|
19981
|
-
_this.engine.client.sendLeave();
|
20085
|
+
await _this.engine.client.sendLeave();
|
19982
20086
|
} // close engine (also closes client)
|
19983
20087
|
|
19984
20088
|
|
@@ -19986,7 +20090,7 @@ class Room extends events.exports.EventEmitter {
|
|
19986
20090
|
_this.engine.close();
|
19987
20091
|
}
|
19988
20092
|
|
19989
|
-
_this.handleDisconnect(stopTracks);
|
20093
|
+
_this.handleDisconnect(stopTracks, DisconnectReason.CLIENT_INITIATED);
|
19990
20094
|
/* @ts-ignore */
|
19991
20095
|
|
19992
20096
|
|
@@ -20183,9 +20287,7 @@ class Room extends events.exports.EventEmitter {
|
|
20183
20287
|
return;
|
20184
20288
|
}
|
20185
20289
|
|
20186
|
-
pub.
|
20187
|
-
participant.emit(ParticipantEvent.TrackSubscriptionPermissionChanged, pub, pub.subscriptionStatus);
|
20188
|
-
this.emitWhenConnected(RoomEvent.TrackSubscriptionPermissionChanged, pub, pub.subscriptionStatus, participant);
|
20290
|
+
pub.setAllowed(update.allowed);
|
20189
20291
|
};
|
20190
20292
|
|
20191
20293
|
this.handleDataPacket = (userPacket, kind) => {
|
@@ -20528,6 +20630,10 @@ class Room extends events.exports.EventEmitter {
|
|
20528
20630
|
|
20529
20631
|
var _a;
|
20530
20632
|
|
20633
|
+
if (this.state === ConnectionState.Disconnected) {
|
20634
|
+
return;
|
20635
|
+
}
|
20636
|
+
|
20531
20637
|
this.participants.forEach(p => {
|
20532
20638
|
p.tracks.forEach(pub => {
|
20533
20639
|
p.unpublishTrack(pub.trackSid);
|
@@ -20545,6 +20651,9 @@ class Room extends events.exports.EventEmitter {
|
|
20545
20651
|
(_b = pub.track) === null || _b === void 0 ? void 0 : _b.stop();
|
20546
20652
|
}
|
20547
20653
|
});
|
20654
|
+
this.localParticipant.tracks.clear();
|
20655
|
+
this.localParticipant.videoTracks.clear();
|
20656
|
+
this.localParticipant.audioTracks.clear();
|
20548
20657
|
this.participants.clear();
|
20549
20658
|
this.activeSpeakers = [];
|
20550
20659
|
|
@@ -20646,6 +20755,8 @@ class Room extends events.exports.EventEmitter {
|
|
20646
20755
|
this.emitWhenConnected(RoomEvent.ConnectionQualityChanged, quality, participant);
|
20647
20756
|
}).on(ParticipantEvent.ParticipantPermissionsChanged, prevPermissions => {
|
20648
20757
|
this.emitWhenConnected(RoomEvent.ParticipantPermissionsChanged, prevPermissions, participant);
|
20758
|
+
}).on(ParticipantEvent.TrackSubscriptionPermissionChanged, (pub, status) => {
|
20759
|
+
this.emitWhenConnected(RoomEvent.TrackSubscriptionPermissionChanged, pub, status, participant);
|
20649
20760
|
}); // update info at the end after callbacks have been set up
|
20650
20761
|
|
20651
20762
|
if (info) {
|