livekit-client 1.15.3 → 1.15.5
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 +91 -50
- 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/proto/livekit_models_pb.d.ts +11 -1
- package/dist/src/proto/livekit_models_pb.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts +4 -1
- 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 +4 -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/Participant.d.ts +6 -0
- package/dist/src/room/participant/Participant.d.ts.map +1 -1
- package/dist/src/room/stats.d.ts +1 -0
- package/dist/src/room/stats.d.ts.map +1 -1
- package/dist/src/room/track/RemoteVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/Track.d.ts +0 -3
- package/dist/src/room/track/Track.d.ts.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/ts4.2/src/proto/livekit_models_pb.d.ts +11 -1
- package/dist/ts4.2/src/room/RTCEngine.d.ts +4 -0
- package/dist/ts4.2/src/room/events.d.ts +4 -1
- package/dist/ts4.2/src/room/participant/Participant.d.ts +6 -0
- package/dist/ts4.2/src/room/stats.d.ts +1 -0
- package/dist/ts4.2/src/room/track/Track.d.ts +0 -3
- package/dist/ts4.2/src/version.d.ts +1 -1
- package/package.json +2 -2
- package/src/proto/livekit_models_pb.ts +15 -1
- package/src/proto/livekit_rtc_pb.ts +1 -1
- package/src/room/RTCEngine.ts +13 -0
- package/src/room/Room.ts +26 -8
- package/src/room/events.ts +3 -0
- package/src/room/participant/LocalParticipant.ts +4 -6
- package/src/room/participant/Participant.ts +11 -0
- package/src/room/stats.ts +2 -0
- package/src/room/track/RemoteVideoTrack.ts +8 -0
- package/src/room/track/Track.ts +34 -48
- package/src/version.ts +1 -1
@@ -3761,6 +3761,10 @@ var ConnectionQuality$1;
|
|
3761
3761
|
* @generated from enum value: EXCELLENT = 2;
|
3762
3762
|
*/
|
3763
3763
|
ConnectionQuality[ConnectionQuality["EXCELLENT"] = 2] = "EXCELLENT";
|
3764
|
+
/**
|
3765
|
+
* @generated from enum value: LOST = 3;
|
3766
|
+
*/
|
3767
|
+
ConnectionQuality[ConnectionQuality["LOST"] = 3] = "LOST";
|
3764
3768
|
})(ConnectionQuality$1 || (ConnectionQuality$1 = {}));
|
3765
3769
|
// Retrieve enum metadata with: proto3.getEnumType(ConnectionQuality)
|
3766
3770
|
proto3.util.setEnumType(ConnectionQuality$1, "livekit.ConnectionQuality", [{
|
@@ -3772,6 +3776,9 @@ proto3.util.setEnumType(ConnectionQuality$1, "livekit.ConnectionQuality", [{
|
|
3772
3776
|
}, {
|
3773
3777
|
no: 2,
|
3774
3778
|
name: "EXCELLENT"
|
3779
|
+
}, {
|
3780
|
+
no: 3,
|
3781
|
+
name: "LOST"
|
3775
3782
|
}]);
|
3776
3783
|
/**
|
3777
3784
|
* @generated from enum livekit.ClientConfigSetting
|
@@ -4203,6 +4210,12 @@ class ParticipantPermission extends Message {
|
|
4203
4210
|
* @generated from field: bool can_update_metadata = 10;
|
4204
4211
|
*/
|
4205
4212
|
this.canUpdateMetadata = false;
|
4213
|
+
/**
|
4214
|
+
* indicates that participant is an agent
|
4215
|
+
*
|
4216
|
+
* @generated from field: bool agent = 11;
|
4217
|
+
*/
|
4218
|
+
this.agent = false;
|
4206
4219
|
proto3.util.initPartial(data, this);
|
4207
4220
|
}
|
4208
4221
|
static fromBinary(bytes, options) {
|
@@ -4256,6 +4269,11 @@ ParticipantPermission.fields = proto3.util.newFieldList(() => [{
|
|
4256
4269
|
name: "can_update_metadata",
|
4257
4270
|
kind: "scalar",
|
4258
4271
|
T: 8 /* ScalarType.BOOL */
|
4272
|
+
}, {
|
4273
|
+
no: 11,
|
4274
|
+
name: "agent",
|
4275
|
+
kind: "scalar",
|
4276
|
+
T: 8 /* ScalarType.BOOL */
|
4259
4277
|
}]);
|
4260
4278
|
/**
|
4261
4279
|
* @generated from message livekit.ParticipantInfo
|
@@ -10396,6 +10414,9 @@ var EngineEvent;
|
|
10396
10414
|
EngineEvent["ConnectionQualityUpdate"] = "connectionQualityUpdate";
|
10397
10415
|
EngineEvent["SubscriptionError"] = "subscriptionError";
|
10398
10416
|
EngineEvent["SubscriptionPermissionUpdate"] = "subscriptionPermissionUpdate";
|
10417
|
+
EngineEvent["RemoteMute"] = "remoteMute";
|
10418
|
+
EngineEvent["SubscribedQualityUpdate"] = "subscribedQualityUpdate";
|
10419
|
+
EngineEvent["LocalTrackUnpublished"] = "localTrackUnpublished";
|
10399
10420
|
})(EngineEvent || (EngineEvent = {}));
|
10400
10421
|
var TrackEvent;
|
10401
10422
|
(function (TrackEvent) {
|
@@ -10565,10 +10586,10 @@ function getMatch(exp, ua) {
|
|
10565
10586
|
return match && match.length >= id && match[id] || '';
|
10566
10587
|
}
|
10567
10588
|
|
10568
|
-
var version$1 = "1.15.
|
10589
|
+
var version$1 = "1.15.5";
|
10569
10590
|
|
10570
10591
|
const version = version$1;
|
10571
|
-
const protocolVersion =
|
10592
|
+
const protocolVersion = 11;
|
10572
10593
|
|
10573
10594
|
/**
|
10574
10595
|
* Timers that can be overridden with platform specific implementations
|
@@ -12957,21 +12978,6 @@ class Track extends eventsExports.EventEmitter {
|
|
12957
12978
|
this.handleAppVisibilityChanged();
|
12958
12979
|
}
|
12959
12980
|
};
|
12960
|
-
this.handleElementSuspended = () => {
|
12961
|
-
this.debouncedPlaybackStateChange(false);
|
12962
|
-
};
|
12963
|
-
this.handleElementPlay = () => {
|
12964
|
-
this.debouncedPlaybackStateChange(true);
|
12965
|
-
};
|
12966
|
-
this.debouncedPlaybackStateChange = r(allowed => {
|
12967
|
-
// we debounce this as Safari triggers both `playing` and `suspend` shortly after one another
|
12968
|
-
// in order not to raise the wrong event, we debounce the call to make sure we only emit the correct status
|
12969
|
-
if (this.kind === Track.Kind.Audio) {
|
12970
|
-
this.emit(allowed ? TrackEvent.AudioPlaybackStarted : TrackEvent.AudioPlaybackFailed);
|
12971
|
-
} else if (this.kind === Track.Kind.Video) {
|
12972
|
-
this.emit(allowed ? TrackEvent.VideoPlaybackStarted : TrackEvent.VideoPlaybackFailed);
|
12973
|
-
}
|
12974
|
-
}, 300);
|
12975
12981
|
this.setMaxListeners(100);
|
12976
12982
|
this.kind = kind;
|
12977
12983
|
this._mediaStreamTrack = mediaTrack;
|
@@ -13019,9 +13025,6 @@ class Track extends eventsExports.EventEmitter {
|
|
13019
13025
|
}
|
13020
13026
|
if (!this.attachedElements.includes(element)) {
|
13021
13027
|
this.attachedElements.push(element);
|
13022
|
-
// listen to suspend events in order to detect auto playback issues
|
13023
|
-
element.addEventListener('suspend', this.handleElementSuspended);
|
13024
|
-
element.addEventListener('playing', this.handleElementPlay);
|
13025
13028
|
}
|
13026
13029
|
// even if we believe it's already attached to the element, it's possible
|
13027
13030
|
// the element's srcObject was set to something else out of band.
|
@@ -13029,20 +13032,27 @@ class Track extends eventsExports.EventEmitter {
|
|
13029
13032
|
attachToElement(this.mediaStreamTrack, element);
|
13030
13033
|
// handle auto playback failures
|
13031
13034
|
const allMediaStreamTracks = element.srcObject.getTracks();
|
13032
|
-
|
13033
|
-
|
13034
|
-
|
13035
|
-
|
13036
|
-
|
13037
|
-
|
13038
|
-
|
13039
|
-
|
13040
|
-
|
13041
|
-
|
13042
|
-
|
13043
|
-
|
13044
|
-
}
|
13045
|
-
|
13035
|
+
const hasAudio = allMediaStreamTracks.some(tr => tr.kind === 'audio');
|
13036
|
+
// manually play media to detect auto playback status
|
13037
|
+
element.play().then(() => {
|
13038
|
+
this.emit(hasAudio ? TrackEvent.AudioPlaybackStarted : TrackEvent.VideoPlaybackStarted);
|
13039
|
+
}).catch(e => {
|
13040
|
+
if (e.name === 'NotAllowedError') {
|
13041
|
+
this.emit(hasAudio ? TrackEvent.AudioPlaybackFailed : TrackEvent.VideoPlaybackFailed, e);
|
13042
|
+
} else if (e.name === 'AbortError') {
|
13043
|
+
// commonly triggered by another `play` request, only log for debugging purposes
|
13044
|
+
livekitLogger.debug("".concat(hasAudio ? 'audio' : 'video', " playback aborted, likely due to new play request"));
|
13045
|
+
} else {
|
13046
|
+
livekitLogger.warn("could not playback ".concat(hasAudio ? 'audio' : 'video'), e);
|
13047
|
+
}
|
13048
|
+
// If audio playback isn't allowed make sure we still play back the video
|
13049
|
+
if (hasAudio && element && allMediaStreamTracks.some(tr => tr.kind === 'video') && e.name === 'NotAllowedError') {
|
13050
|
+
element.muted = true;
|
13051
|
+
element.play().catch(() => {
|
13052
|
+
// catch for Safari, exceeded options at this point to automatically play the media element
|
13053
|
+
});
|
13054
|
+
}
|
13055
|
+
});
|
13046
13056
|
this.emit(TrackEvent.ElementAttached, element);
|
13047
13057
|
return element;
|
13048
13058
|
}
|
@@ -13055,8 +13065,6 @@ class Track extends eventsExports.EventEmitter {
|
|
13055
13065
|
if (idx >= 0) {
|
13056
13066
|
this.attachedElements.splice(idx, 1);
|
13057
13067
|
this.recycleElement(element);
|
13058
|
-
element.removeEventListener('suspend', this.handleElementSuspended);
|
13059
|
-
element.removeEventListener('playing', this.handleElementPlay);
|
13060
13068
|
this.emit(TrackEvent.ElementDetached, element);
|
13061
13069
|
}
|
13062
13070
|
return element;
|
@@ -13066,8 +13074,6 @@ class Track extends eventsExports.EventEmitter {
|
|
13066
13074
|
detachTrack(this.mediaStreamTrack, elm);
|
13067
13075
|
detached.push(elm);
|
13068
13076
|
this.recycleElement(elm);
|
13069
|
-
elm.removeEventListener('suspend', this.handleElementSuspended);
|
13070
|
-
elm.removeEventListener('playing', this.handleElementPlay);
|
13071
13077
|
this.emit(TrackEvent.ElementDetached, elm);
|
13072
13078
|
});
|
13073
13079
|
// remove all tracks
|
@@ -13176,7 +13182,7 @@ function attachToElement(track, element) {
|
|
13176
13182
|
// when the window is backgrounded before the first frame is drawn
|
13177
13183
|
// manually calling play here seems to fix that
|
13178
13184
|
element.play().catch(() => {
|
13179
|
-
/** do nothing
|
13185
|
+
/** do nothing */
|
13180
13186
|
});
|
13181
13187
|
}, 0);
|
13182
13188
|
}
|
@@ -17242,6 +17248,12 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
17242
17248
|
this.client.onTokenRefresh = token => {
|
17243
17249
|
this.token = token;
|
17244
17250
|
};
|
17251
|
+
this.client.onRemoteMuteChanged = (trackSid, muted) => {
|
17252
|
+
this.emit(EngineEvent.RemoteMute, trackSid, muted);
|
17253
|
+
};
|
17254
|
+
this.client.onSubscribedQualityUpdate = update => {
|
17255
|
+
this.emit(EngineEvent.SubscribedQualityUpdate, update);
|
17256
|
+
};
|
17245
17257
|
this.client.onClose = () => {
|
17246
17258
|
this.handleDisconnect('signal', ReconnectReason.RR_SIGNAL_DISCONNECTED);
|
17247
17259
|
};
|
@@ -19369,8 +19381,11 @@ class RemoteVideoTrack extends RemoteTrack {
|
|
19369
19381
|
}
|
19370
19382
|
const stats = yield this.receiver.getStats();
|
19371
19383
|
let receiverStats;
|
19384
|
+
let codecID = '';
|
19385
|
+
let codecs = new Map();
|
19372
19386
|
stats.forEach(v => {
|
19373
19387
|
if (v.type === 'inbound-rtp') {
|
19388
|
+
codecID = v.codecId;
|
19374
19389
|
receiverStats = {
|
19375
19390
|
type: 'video',
|
19376
19391
|
framesDecoded: v.framesDecoded,
|
@@ -19388,8 +19403,13 @@ class RemoteVideoTrack extends RemoteTrack {
|
|
19388
19403
|
bytesReceived: v.bytesReceived,
|
19389
19404
|
decoderImplementation: v.decoderImplementation
|
19390
19405
|
};
|
19406
|
+
} else if (v.type === 'codec') {
|
19407
|
+
codecs.set(v.id, v);
|
19391
19408
|
}
|
19392
19409
|
});
|
19410
|
+
if (receiverStats && codecID !== '' && codecs.get(codecID)) {
|
19411
|
+
receiverStats.mimeType = codecs.get(codecID).mimeType;
|
19412
|
+
}
|
19393
19413
|
return receiverStats;
|
19394
19414
|
});
|
19395
19415
|
}
|
@@ -19727,6 +19747,11 @@ var ConnectionQuality;
|
|
19727
19747
|
ConnectionQuality["Excellent"] = "excellent";
|
19728
19748
|
ConnectionQuality["Good"] = "good";
|
19729
19749
|
ConnectionQuality["Poor"] = "poor";
|
19750
|
+
/**
|
19751
|
+
* Indicates that a participant has temporarily (or permanently) lost connection to LiveKit.
|
19752
|
+
* For permanent disconnection a `ParticipantDisconnected` event will be emitted after a timeout
|
19753
|
+
*/
|
19754
|
+
ConnectionQuality["Lost"] = "lost";
|
19730
19755
|
ConnectionQuality["Unknown"] = "unknown";
|
19731
19756
|
})(ConnectionQuality || (ConnectionQuality = {}));
|
19732
19757
|
function qualityFromProto(q) {
|
@@ -19737,6 +19762,8 @@ function qualityFromProto(q) {
|
|
19737
19762
|
return ConnectionQuality.Good;
|
19738
19763
|
case ConnectionQuality$1.POOR:
|
19739
19764
|
return ConnectionQuality.Poor;
|
19765
|
+
case ConnectionQuality$1.LOST:
|
19766
|
+
return ConnectionQuality.Lost;
|
19740
19767
|
default:
|
19741
19768
|
return ConnectionQuality.Unknown;
|
19742
19769
|
}
|
@@ -19745,6 +19772,10 @@ class Participant extends eventsExports.EventEmitter {
|
|
19745
19772
|
get isEncrypted() {
|
19746
19773
|
return this.tracks.size > 0 && Array.from(this.tracks.values()).every(tr => tr.isEncrypted);
|
19747
19774
|
}
|
19775
|
+
get isAgent() {
|
19776
|
+
var _a, _b;
|
19777
|
+
return (_b = (_a = this.permissions) === null || _a === void 0 ? void 0 : _a.agent) !== null && _b !== void 0 ? _b : false;
|
19778
|
+
}
|
19748
19779
|
/** @internal */
|
19749
19780
|
constructor(sid, identity, name, metadata) {
|
19750
19781
|
super();
|
@@ -20635,7 +20666,7 @@ class LocalParticipant extends Participant {
|
|
20635
20666
|
*/
|
20636
20667
|
setupEngine(engine) {
|
20637
20668
|
this.engine = engine;
|
20638
|
-
this.engine.
|
20669
|
+
this.engine.on(EngineEvent.RemoteMute, (trackSid, muted) => {
|
20639
20670
|
const pub = this.tracks.get(trackSid);
|
20640
20671
|
if (!pub || !pub.track) {
|
20641
20672
|
return;
|
@@ -20645,10 +20676,8 @@ class LocalParticipant extends Participant {
|
|
20645
20676
|
} else {
|
20646
20677
|
pub.unmute();
|
20647
20678
|
}
|
20648
|
-
};
|
20649
|
-
this.engine.
|
20650
|
-
this.engine.client.onLocalTrackUnpublished = this.handleLocalTrackUnpublished;
|
20651
|
-
this.engine.on(EngineEvent.Connected, this.handleReconnected).on(EngineEvent.SignalRestarted, this.handleReconnected).on(EngineEvent.SignalResumed, this.handleReconnected).on(EngineEvent.Restarting, this.handleReconnecting).on(EngineEvent.Resuming, this.handleReconnecting).on(EngineEvent.Disconnected, this.handleDisconnected);
|
20679
|
+
});
|
20680
|
+
this.engine.on(EngineEvent.Connected, this.handleReconnected).on(EngineEvent.SignalRestarted, this.handleReconnected).on(EngineEvent.SignalResumed, this.handleReconnected).on(EngineEvent.Restarting, this.handleReconnecting).on(EngineEvent.Resuming, this.handleReconnecting).on(EngineEvent.LocalTrackUnpublished, this.handleLocalTrackUnpublished).on(EngineEvent.SubscribedQualityUpdate, this.handleSubscribedQualityUpdate).on(EngineEvent.Disconnected, this.handleDisconnected);
|
20652
20681
|
}
|
20653
20682
|
/**
|
20654
20683
|
* Sets and updates the metadata of the local participant.
|
@@ -21808,18 +21837,26 @@ class Room extends eventsExports.EventEmitter {
|
|
21808
21837
|
}
|
21809
21838
|
});
|
21810
21839
|
this.startVideo = () => __awaiter(this, void 0, void 0, function* () {
|
21840
|
+
const elements = [];
|
21811
21841
|
for (const p of this.participants.values()) {
|
21812
21842
|
p.videoTracks.forEach(tr => {
|
21813
21843
|
var _a;
|
21814
21844
|
(_a = tr.track) === null || _a === void 0 ? void 0 : _a.attachedElements.forEach(el => {
|
21815
|
-
|
21816
|
-
|
21817
|
-
|
21818
|
-
}
|
21819
|
-
});
|
21845
|
+
if (!elements.includes(el)) {
|
21846
|
+
elements.push(el);
|
21847
|
+
}
|
21820
21848
|
});
|
21821
21849
|
});
|
21822
21850
|
}
|
21851
|
+
yield Promise.all(elements.map(el => el.play())).then(() => {
|
21852
|
+
this.handleVideoPlaybackStarted();
|
21853
|
+
}).catch(e => {
|
21854
|
+
if (e.name === 'NotAllowedError') {
|
21855
|
+
this.handleVideoPlaybackFailed();
|
21856
|
+
} else {
|
21857
|
+
livekitLogger.warn('Resuming video playback failed, make sure you call `startVideo` directly in a user gesture handler');
|
21858
|
+
}
|
21859
|
+
});
|
21823
21860
|
});
|
21824
21861
|
this.handleRestarting = () => {
|
21825
21862
|
this.clearConnectionReconcile();
|
@@ -22126,7 +22163,7 @@ class Room extends eventsExports.EventEmitter {
|
|
22126
22163
|
this.localParticipant.activeDeviceMap.set('audioinput', unwrapConstraint(this.options.audioCaptureDefaults.deviceId));
|
22127
22164
|
}
|
22128
22165
|
if ((_a = this.options.audioOutput) === null || _a === void 0 ? void 0 : _a.deviceId) {
|
22129
|
-
this.switchActiveDevice('audiooutput', unwrapConstraint(this.options.audioOutput.deviceId));
|
22166
|
+
this.switchActiveDevice('audiooutput', unwrapConstraint(this.options.audioOutput.deviceId)).catch(e => livekitLogger.warn("Could not set audio output: ".concat(e.message)));
|
22130
22167
|
}
|
22131
22168
|
if (this.options.e2ee) {
|
22132
22169
|
this.setupE2EE();
|
@@ -22643,6 +22680,7 @@ class Room extends eventsExports.EventEmitter {
|
|
22643
22680
|
});
|
22644
22681
|
}
|
22645
22682
|
createParticipant(id, info) {
|
22683
|
+
var _a;
|
22646
22684
|
let participant;
|
22647
22685
|
if (info) {
|
22648
22686
|
participant = RemoteParticipant.fromParticipantInfo(this.engine.client, info);
|
@@ -22652,6 +22690,9 @@ class Room extends eventsExports.EventEmitter {
|
|
22652
22690
|
if (this.options.expWebAudioMix) {
|
22653
22691
|
participant.setAudioContext(this.audioContext);
|
22654
22692
|
}
|
22693
|
+
if ((_a = this.options.audioOutput) === null || _a === void 0 ? void 0 : _a.deviceId) {
|
22694
|
+
participant.setAudioOutput(this.options.audioOutput).catch(e => livekitLogger.warn("Could not set audio output: ".concat(e.message)));
|
22695
|
+
}
|
22655
22696
|
return participant;
|
22656
22697
|
}
|
22657
22698
|
getOrCreateParticipant(id, info) {
|