livekit-client 2.1.3 → 2.1.4
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 +92 -29
- 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/Room.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/participant/publishUtils.d.ts +1 -0
- package/dist/src/room/participant/publishUtils.d.ts.map +1 -1
- package/dist/src/room/track/LocalTrack.d.ts +5 -1
- package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
- package/dist/src/room/track/LocalVideoTrack.d.ts +3 -0
- package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/RemoteTrack.d.ts.map +1 -1
- package/dist/src/room/track/options.d.ts +4 -0
- package/dist/src/room/track/options.d.ts.map +1 -1
- package/dist/src/room/track/utils.d.ts +1 -0
- package/dist/src/room/track/utils.d.ts.map +1 -1
- package/dist/src/room/types.d.ts +1 -1
- package/dist/src/room/types.d.ts.map +1 -1
- package/dist/src/room/utils.d.ts +1 -0
- package/dist/src/room/utils.d.ts.map +1 -1
- package/dist/ts4.2/src/room/participant/publishUtils.d.ts +1 -0
- package/dist/ts4.2/src/room/track/LocalTrack.d.ts +5 -1
- package/dist/ts4.2/src/room/track/LocalVideoTrack.d.ts +3 -0
- package/dist/ts4.2/src/room/track/options.d.ts +4 -0
- package/dist/ts4.2/src/room/track/utils.d.ts +1 -0
- package/dist/ts4.2/src/room/types.d.ts +1 -1
- package/dist/ts4.2/src/room/utils.d.ts +1 -0
- package/package.json +2 -2
- package/src/room/PCTransport.ts +10 -7
- package/src/room/Room.ts +7 -1
- package/src/room/participant/LocalParticipant.ts +7 -16
- package/src/room/participant/publishUtils.ts +20 -0
- package/src/room/track/LocalTrack.ts +21 -2
- package/src/room/track/LocalVideoTrack.ts +23 -0
- package/src/room/track/RemoteTrack.ts +4 -1
- package/src/room/track/options.ts +5 -0
- package/src/room/track/utils.ts +4 -0
- package/src/room/types.ts +3 -1
- package/src/room/utils.ts +4 -2
@@ -5494,6 +5494,12 @@ const SimulateScenario = /*@__PURE__*/proto3.makeMessageType("livekit.SimulateSc
|
|
5494
5494
|
kind: "scalar",
|
5495
5495
|
T: 8 /* ScalarType.BOOL */,
|
5496
5496
|
oneof: "scenario"
|
5497
|
+
}, {
|
5498
|
+
no: 9,
|
5499
|
+
name: "leave_request_full_reconnect",
|
5500
|
+
kind: "scalar",
|
5501
|
+
T: 8 /* ScalarType.BOOL */,
|
5502
|
+
oneof: "scenario"
|
5497
5503
|
}]);
|
5498
5504
|
|
5499
5505
|
/**
|
@@ -10499,7 +10505,7 @@ function getOSVersion(ua) {
|
|
10499
10505
|
return ua.includes('mac os') ? getMatch(/\(.+?(\d+_\d+(:?_\d+)?)/, ua, 1).replace(/_/g, '.') : undefined;
|
10500
10506
|
}
|
10501
10507
|
|
10502
|
-
var version$1 = "2.1.
|
10508
|
+
var version$1 = "2.1.4";
|
10503
10509
|
|
10504
10510
|
const version = version$1;
|
10505
10511
|
const protocolVersion = 13;
|
@@ -11203,6 +11209,9 @@ function getLogContextFromTrack(track) {
|
|
11203
11209
|
};
|
11204
11210
|
}
|
11205
11211
|
}
|
11212
|
+
function supportsSynchronizationSources() {
|
11213
|
+
return typeof RTCRtpReceiver !== 'undefined' && 'getSynchronizationSources' in RTCRtpReceiver;
|
11214
|
+
}
|
11206
11215
|
|
11207
11216
|
const separator = '|';
|
11208
11217
|
const ddExtensionURI = 'https://aomediacodec.github.io/av1-rtp-spec/#dependency-descriptor-rtp-header-extension';
|
@@ -11575,7 +11584,7 @@ function isVideoCodec(maybeCodec) {
|
|
11575
11584
|
return videoCodecs.includes(maybeCodec);
|
11576
11585
|
}
|
11577
11586
|
function unwrapConstraint(constraint) {
|
11578
|
-
if (typeof constraint === 'string') {
|
11587
|
+
if (typeof constraint === 'string' || typeof constraint === 'number') {
|
11579
11588
|
return constraint;
|
11580
11589
|
}
|
11581
11590
|
if (Array.isArray(constraint)) {
|
@@ -11712,6 +11721,14 @@ DeviceManager.userMediaPromiseMap = new Map();
|
|
11712
11721
|
|
11713
11722
|
const defaultDimensionsTimeout = 1000;
|
11714
11723
|
class LocalTrack extends Track {
|
11724
|
+
/** @internal */
|
11725
|
+
get sender() {
|
11726
|
+
return this._sender;
|
11727
|
+
}
|
11728
|
+
/** @internal */
|
11729
|
+
set sender(sender) {
|
11730
|
+
this._sender = sender;
|
11731
|
+
}
|
11715
11732
|
get constraints() {
|
11716
11733
|
return this._constraints;
|
11717
11734
|
}
|
@@ -11726,6 +11743,7 @@ class LocalTrack extends Track {
|
|
11726
11743
|
let userProvidedTrack = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
11727
11744
|
let loggerOptions = arguments.length > 4 ? arguments[4] : undefined;
|
11728
11745
|
super(mediaTrack, kind, loggerOptions);
|
11746
|
+
this.manuallyStopped = false;
|
11729
11747
|
this._isUpstreamPaused = false;
|
11730
11748
|
this.handleTrackMuteEvent = () => this.debouncedTrackMuteHandler().catch(() => this.log.debug('track mute bounce got cancelled by an unmute event', this.logContext));
|
11731
11749
|
this.debouncedTrackMuteHandler = r(() => __awaiter(this, void 0, void 0, function* () {
|
@@ -11936,6 +11954,7 @@ class LocalTrack extends Track {
|
|
11936
11954
|
}
|
11937
11955
|
restart(constraints) {
|
11938
11956
|
return __awaiter(this, void 0, void 0, function* () {
|
11957
|
+
this.manuallyStopped = false;
|
11939
11958
|
const unlock = yield this.restartLock.lock();
|
11940
11959
|
try {
|
11941
11960
|
if (!constraints) {
|
@@ -11971,6 +11990,10 @@ class LocalTrack extends Track {
|
|
11971
11990
|
yield this.setMediaStreamTrack(newTrack);
|
11972
11991
|
this._constraints = constraints;
|
11973
11992
|
this.emit(TrackEvent.Restarted, this);
|
11993
|
+
if (this.manuallyStopped) {
|
11994
|
+
this.log.warn('track was stopped during a restart, stopping restarted track', this.logContext);
|
11995
|
+
this.stop();
|
11996
|
+
}
|
11974
11997
|
return this;
|
11975
11998
|
} finally {
|
11976
11999
|
unlock();
|
@@ -12008,6 +12031,7 @@ class LocalTrack extends Track {
|
|
12008
12031
|
}
|
12009
12032
|
stop() {
|
12010
12033
|
var _a;
|
12034
|
+
this.manuallyStopped = true;
|
12011
12035
|
super.stop();
|
12012
12036
|
this._mediaStreamTrack.removeEventListener('ended', this.handleEnded);
|
12013
12037
|
this._mediaStreamTrack.removeEventListener('mute', this.handleTrackMuteEvent);
|
@@ -14098,8 +14122,6 @@ class PCTransport extends eventsExports.EventEmitter {
|
|
14098
14122
|
if (media.type === 'audio') {
|
14099
14123
|
ensureAudioNackAndStereo(media, [], []);
|
14100
14124
|
} else if (media.type === 'video') {
|
14101
|
-
ensureVideoDDExtensionForSVC(media);
|
14102
|
-
// mung sdp for codec bitrate setting that can't apply by sendEncoding
|
14103
14125
|
this.trackBitrates.some(trackbr => {
|
14104
14126
|
if (!media.msid || !trackbr.cid || !media.msid.includes(trackbr.cid)) {
|
14105
14127
|
return false;
|
@@ -14115,6 +14137,14 @@ class PCTransport extends eventsExports.EventEmitter {
|
|
14115
14137
|
if (codecPayload === 0) {
|
14116
14138
|
return true;
|
14117
14139
|
}
|
14140
|
+
if (isSVCCodec(trackbr.codec)) {
|
14141
|
+
ensureVideoDDExtensionForSVC(media);
|
14142
|
+
}
|
14143
|
+
// TODO: av1 slow starting issue already fixed in chrome 124, clean this after some versions
|
14144
|
+
// mung sdp for av1 bitrate setting that can't apply by sendEncoding
|
14145
|
+
if (trackbr.codec !== 'av1') {
|
14146
|
+
return true;
|
14147
|
+
}
|
14118
14148
|
const startBitrate = Math.round(trackbr.maxbr * startBitrateForSVC);
|
14119
14149
|
for (const fmtp of media.fmtp) {
|
14120
14150
|
if (fmtp.payload === codecPayload) {
|
@@ -14331,13 +14361,9 @@ function ensureAudioNackAndStereo(media, stereoMids, nackMids) {
|
|
14331
14361
|
}
|
14332
14362
|
}
|
14333
14363
|
function ensureVideoDDExtensionForSVC(media) {
|
14334
|
-
var _a, _b
|
14335
|
-
const codec = (_b = (_a = media.rtp[0]) === null || _a === void 0 ? void 0 : _a.codec) === null || _b === void 0 ? void 0 : _b.toLowerCase();
|
14336
|
-
if (!isSVCCodec(codec)) {
|
14337
|
-
return;
|
14338
|
-
}
|
14364
|
+
var _a, _b;
|
14339
14365
|
let maxID = 0;
|
14340
|
-
const ddFound = (
|
14366
|
+
const ddFound = (_a = media.ext) === null || _a === void 0 ? void 0 : _a.some(ext => {
|
14341
14367
|
if (ext.uri === ddExtensionURI) {
|
14342
14368
|
return true;
|
14343
14369
|
}
|
@@ -14347,7 +14373,7 @@ function ensureVideoDDExtensionForSVC(media) {
|
|
14347
14373
|
return false;
|
14348
14374
|
});
|
14349
14375
|
if (!ddFound) {
|
14350
|
-
(
|
14376
|
+
(_b = media.ext) === null || _b === void 0 ? void 0 : _b.push({
|
14351
14377
|
value: maxID + 1,
|
14352
14378
|
uri: ddExtensionURI
|
14353
14379
|
});
|
@@ -15055,6 +15081,10 @@ function computeVideoEncodings(isScreenShare, width, height, options) {
|
|
15055
15081
|
scalabilityMode: scalabilityMode
|
15056
15082
|
});
|
15057
15083
|
}
|
15084
|
+
if (original.encoding.priority) {
|
15085
|
+
encodings[0].priority = original.encoding.priority;
|
15086
|
+
encodings[0].networkPriority = original.encoding.priority;
|
15087
|
+
}
|
15058
15088
|
livekitLogger.debug("using svc encoding", {
|
15059
15089
|
encodings
|
15060
15090
|
});
|
@@ -15268,9 +15298,25 @@ class ScalabilityMode {
|
|
15268
15298
|
return "L".concat(this.spatial, "T").concat(this.temporal).concat((_a = this.suffix) !== null && _a !== void 0 ? _a : '');
|
15269
15299
|
}
|
15270
15300
|
}
|
15301
|
+
function getDefaultDegradationPreference(track) {
|
15302
|
+
// a few of reasons we have different default paths:
|
15303
|
+
// 1. without this, Chrome seems to aggressively resize the SVC video stating `quality-limitation: bandwidth` even when BW isn't an issue
|
15304
|
+
// 2. since we are overriding contentHint to motion (to workaround L1T3 publishing), it overrides the default degradationPreference to `balanced`
|
15305
|
+
if (track.source === Track.Source.ScreenShare || track.constraints.height && unwrapConstraint(track.constraints.height) >= 1080) {
|
15306
|
+
return 'maintain-resolution';
|
15307
|
+
} else {
|
15308
|
+
return 'balanced';
|
15309
|
+
}
|
15310
|
+
}
|
15271
15311
|
|
15272
15312
|
const refreshSubscribedCodecAfterNewCodec = 5000;
|
15273
15313
|
class LocalVideoTrack extends LocalTrack {
|
15314
|
+
set sender(sender) {
|
15315
|
+
this._sender = sender;
|
15316
|
+
if (this.degradationPreference) {
|
15317
|
+
this.setDegradationPreference(this.degradationPreference);
|
15318
|
+
}
|
15319
|
+
}
|
15274
15320
|
/**
|
15275
15321
|
*
|
15276
15322
|
* @param mediaTrack
|
@@ -15283,6 +15329,7 @@ class LocalVideoTrack extends LocalTrack {
|
|
15283
15329
|
super(mediaTrack, Track.Kind.Video, constraints, userProvidedTrack, loggerOptions);
|
15284
15330
|
/* @internal */
|
15285
15331
|
this.simulcastCodecs = new Map();
|
15332
|
+
this.degradationPreference = 'balanced';
|
15286
15333
|
this.monitorSender = () => __awaiter(this, void 0, void 0, function* () {
|
15287
15334
|
if (!this.sender) {
|
15288
15335
|
this._currentBitrate = 0;
|
@@ -15605,6 +15652,23 @@ class LocalVideoTrack extends LocalTrack {
|
|
15605
15652
|
}();
|
15606
15653
|
});
|
15607
15654
|
}
|
15655
|
+
setDegradationPreference(preference) {
|
15656
|
+
return __awaiter(this, void 0, void 0, function* () {
|
15657
|
+
this.degradationPreference = preference;
|
15658
|
+
if (this.sender) {
|
15659
|
+
try {
|
15660
|
+
this.log.debug("setting degradationPreference to ".concat(preference), this.logContext);
|
15661
|
+
const params = this.sender.getParameters();
|
15662
|
+
params.degradationPreference = preference;
|
15663
|
+
this.sender.setParameters(params);
|
15664
|
+
} catch (e) {
|
15665
|
+
this.log.warn("failed to set degradationPreference", Object.assign({
|
15666
|
+
error: e
|
15667
|
+
}, this.logContext));
|
15668
|
+
}
|
15669
|
+
}
|
15670
|
+
});
|
15671
|
+
}
|
15608
15672
|
addSimulcastTrack(codec, encodings) {
|
15609
15673
|
if (this.simulcastCodecs.has(codec)) {
|
15610
15674
|
this.log.error("".concat(codec, " already added, skipping adding simulcast codec"), this.logContext);
|
@@ -17076,7 +17140,9 @@ class RemoteTrack extends Track {
|
|
17076
17140
|
if (!this.monitorInterval) {
|
17077
17141
|
this.monitorInterval = setInterval(() => this.monitorReceiver(), monitorFrequency);
|
17078
17142
|
}
|
17079
|
-
|
17143
|
+
if (supportsSynchronizationSources()) {
|
17144
|
+
this.registerTimeSyncUpdate();
|
17145
|
+
}
|
17080
17146
|
}
|
17081
17147
|
registerTimeSyncUpdate() {
|
17082
17148
|
const loop = () => {
|
@@ -18634,7 +18700,7 @@ class LocalParticipant extends Participant {
|
|
18634
18700
|
}
|
18635
18701
|
publish(track, opts, isStereo) {
|
18636
18702
|
return __awaiter(this, void 0, void 0, function* () {
|
18637
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
18703
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
18638
18704
|
const existingTrackOfSource = Array.from(this.trackPublications.values()).find(publishedTrack => track instanceof LocalTrack && publishedTrack.source === track.source);
|
18639
18705
|
if (existingTrackOfSource && track.source !== Track.Source.Unknown) {
|
18640
18706
|
this.log.info("publishing a second track with the same source: ".concat(track.source), Object.assign(Object.assign({}, this.logContext), getLogContextFromTrack(track)));
|
@@ -18794,6 +18860,10 @@ class LocalParticipant extends Participant {
|
|
18794
18860
|
trackInfo: ti
|
18795
18861
|
}));
|
18796
18862
|
track.sender = yield this.engine.createSender(track, opts, encodings);
|
18863
|
+
if (track instanceof LocalVideoTrack) {
|
18864
|
+
(_l = opts.degradationPreference) !== null && _l !== void 0 ? _l : opts.degradationPreference = getDefaultDegradationPreference(track);
|
18865
|
+
track.setDegradationPreference(opts.degradationPreference);
|
18866
|
+
}
|
18797
18867
|
if (encodings) {
|
18798
18868
|
if (isFireFox() && track.kind === Track.Kind.Audio) {
|
18799
18869
|
/* Refer to RFC https://datatracker.ietf.org/doc/html/rfc7587#section-6.1,
|
@@ -18814,11 +18884,10 @@ class LocalParticipant extends Participant {
|
|
18814
18884
|
this.engine.pcManager.publisher.setTrackCodecBitrate({
|
18815
18885
|
transceiver: trackTransceiver,
|
18816
18886
|
codec: 'opus',
|
18817
|
-
maxbr: ((
|
18887
|
+
maxbr: ((_m = encodings[0]) === null || _m === void 0 ? void 0 : _m.maxBitrate) ? encodings[0].maxBitrate / 1000 : 0
|
18818
18888
|
});
|
18819
18889
|
}
|
18820
|
-
} else if (track.codec && track.codec
|
18821
|
-
// AV1 requires setting x-start-bitrate in SDP
|
18890
|
+
} else if (track.codec && isSVCCodec(track.codec) && ((_o = encodings[0]) === null || _o === void 0 ? void 0 : _o.maxBitrate)) {
|
18822
18891
|
this.engine.pcManager.publisher.setTrackCodecBitrate({
|
18823
18892
|
cid: req.cid,
|
18824
18893
|
codec: track.codec,
|
@@ -18826,19 +18895,6 @@ class LocalParticipant extends Participant {
|
|
18826
18895
|
});
|
18827
18896
|
}
|
18828
18897
|
}
|
18829
|
-
if (track.kind === Track.Kind.Video && track.source === Track.Source.ScreenShare) {
|
18830
|
-
// a few of reasons we are forcing this setting without allowing overrides:
|
18831
|
-
// 1. without this, Chrome seems to aggressively resize the SVC video stating `quality-limitation: bandwidth` even when BW isn't an issue
|
18832
|
-
// 2. since we are overriding contentHint to motion (to workaround L1T3 publishing), it overrides the default degradationPreference to `balanced`
|
18833
|
-
try {
|
18834
|
-
this.log.debug("setting degradationPreference to maintain-resolution");
|
18835
|
-
const params = track.sender.getParameters();
|
18836
|
-
params.degradationPreference = 'maintain-resolution';
|
18837
|
-
yield track.sender.setParameters(params);
|
18838
|
-
} catch (e) {
|
18839
|
-
this.log.warn("failed to set degradationPreference: ".concat(e));
|
18840
|
-
}
|
18841
|
-
}
|
18842
18898
|
yield this.engine.negotiate();
|
18843
18899
|
if (track instanceof LocalVideoTrack) {
|
18844
18900
|
track.startMonitor(this.engine.client);
|
@@ -20626,6 +20682,13 @@ class Room extends eventsExports.EventEmitter {
|
|
20626
20682
|
}
|
20627
20683
|
});
|
20628
20684
|
break;
|
20685
|
+
case 'leave-full-reconnect':
|
20686
|
+
req = new SimulateScenario({
|
20687
|
+
scenario: {
|
20688
|
+
case: 'leaveRequestFullReconnect',
|
20689
|
+
value: true
|
20690
|
+
}
|
20691
|
+
});
|
20629
20692
|
}
|
20630
20693
|
if (req) {
|
20631
20694
|
yield this.engine.client.sendSimulateScenario(req);
|