livekit-client 2.13.8 → 2.14.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 +184 -88
- 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/e2ee/E2eeManager.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/events.d.ts +18 -0
- package/dist/src/room/events.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts +1 -0
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/participant/Participant.d.ts +3 -0
- package/dist/src/room/participant/Participant.d.ts.map +1 -1
- package/dist/src/room/track/LocalTrackPublication.d.ts +1 -0
- package/dist/src/room/track/LocalTrackPublication.d.ts.map +1 -1
- package/dist/src/room/track/LocalVideoTrack.d.ts +7 -0
- package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/Track.d.ts +1 -0
- package/dist/src/room/track/Track.d.ts.map +1 -1
- package/dist/src/room/track/TrackPublication.d.ts +1 -0
- package/dist/src/room/track/TrackPublication.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/utils.d.ts +1 -1
- package/dist/src/room/utils.d.ts.map +1 -1
- package/dist/ts4.2/src/room/PCTransport.d.ts +1 -0
- package/dist/ts4.2/src/room/events.d.ts +18 -0
- package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +1 -0
- package/dist/ts4.2/src/room/participant/Participant.d.ts +3 -0
- package/dist/ts4.2/src/room/track/LocalTrackPublication.d.ts +1 -0
- package/dist/ts4.2/src/room/track/LocalVideoTrack.d.ts +7 -0
- package/dist/ts4.2/src/room/track/Track.d.ts +1 -0
- package/dist/ts4.2/src/room/track/TrackPublication.d.ts +1 -0
- package/dist/ts4.2/src/room/track/options.d.ts +4 -0
- package/dist/ts4.2/src/room/utils.d.ts +1 -1
- package/package.json +1 -1
- package/src/e2ee/E2eeManager.ts +3 -2
- package/src/room/PCTransport.ts +88 -77
- package/src/room/events.ts +21 -0
- package/src/room/participant/LocalParticipant.ts +14 -2
- package/src/room/participant/Participant.ts +3 -0
- package/src/room/participant/publishUtils.ts +2 -2
- package/src/room/track/LocalTrackPublication.ts +9 -1
- package/src/room/track/LocalVideoTrack.ts +68 -1
- package/src/room/track/Track.ts +1 -0
- package/src/room/track/TrackPublication.ts +1 -0
- package/src/room/track/create.ts +2 -2
- package/src/room/track/options.ts +5 -0
- package/src/room/utils.ts +19 -3
@@ -11025,6 +11025,19 @@ var ParticipantEvent;
|
|
11025
11025
|
* args: ([[LocalTrackPublication]])
|
11026
11026
|
*/
|
11027
11027
|
ParticipantEvent["LocalTrackUnpublished"] = "localTrackUnpublished";
|
11028
|
+
/**
|
11029
|
+
* A local track has been constrained by cpu.
|
11030
|
+
* This event is useful to know when to reduce the capture resolution of the track.
|
11031
|
+
*
|
11032
|
+
* This event is emitted on the local participant.
|
11033
|
+
*
|
11034
|
+
* args: ([[LocalVideoTrack]], [[LocalTrackPublication]])
|
11035
|
+
*/
|
11036
|
+
ParticipantEvent["LocalTrackCpuConstrained"] = "localTrackCpuConstrained";
|
11037
|
+
/**
|
11038
|
+
* @internal
|
11039
|
+
*/
|
11040
|
+
ParticipantEvent["LocalSenderCreated"] = "localSenderCreated";
|
11028
11041
|
/**
|
11029
11042
|
* Participant metadata is a simple way for app-specific state to be pushed to
|
11030
11043
|
* all users.
|
@@ -11101,6 +11114,10 @@ var ParticipantEvent;
|
|
11101
11114
|
*
|
11102
11115
|
*/
|
11103
11116
|
ParticipantEvent["TrackSubscriptionStatusChanged"] = "trackSubscriptionStatusChanged";
|
11117
|
+
/**
|
11118
|
+
* a local track has been constrained by cpu
|
11119
|
+
*/
|
11120
|
+
ParticipantEvent["TrackCpuConstrained"] = "trackCpuConstrained";
|
11104
11121
|
// fired only on LocalParticipant
|
11105
11122
|
/** @internal */
|
11106
11123
|
ParticipantEvent["MediaDevicesError"] = "mediaDevicesError";
|
@@ -11178,6 +11195,7 @@ var TrackEvent;
|
|
11178
11195
|
TrackEvent["Ended"] = "ended";
|
11179
11196
|
TrackEvent["Subscribed"] = "subscribed";
|
11180
11197
|
TrackEvent["Unsubscribed"] = "unsubscribed";
|
11198
|
+
TrackEvent["CpuConstrained"] = "cpuConstrained";
|
11181
11199
|
/** @internal */
|
11182
11200
|
TrackEvent["UpdateSettings"] = "updateSettings";
|
11183
11201
|
/** @internal */
|
@@ -11331,7 +11349,7 @@ function getOSVersion(ua) {
|
|
11331
11349
|
return ua.includes('mac os') ? getMatch(/\(.+?(\d+_\d+(:?_\d+)?)/, ua, 1).replace(/_/g, '.') : undefined;
|
11332
11350
|
}
|
11333
11351
|
|
11334
|
-
var version$1 = "2.
|
11352
|
+
var version$1 = "2.14.0";
|
11335
11353
|
|
11336
11354
|
const version = version$1;
|
11337
11355
|
const protocolVersion = 16;
|
@@ -11902,6 +11920,10 @@ function supportsVP9() {
|
|
11902
11920
|
// Safari 16 and below does not support VP9
|
11903
11921
|
return false;
|
11904
11922
|
}
|
11923
|
+
if ((browser === null || browser === void 0 ? void 0 : browser.os) === 'iOS' && (browser === null || browser === void 0 ? void 0 : browser.osVersion) && compareVersions(browser.osVersion, '16') < 0) {
|
11924
|
+
// Safari 16 and below on iOS does not support VP9 we need the iOS check to account for other browsers running webkit under the hood
|
11925
|
+
return false;
|
11926
|
+
}
|
11905
11927
|
}
|
11906
11928
|
const capabilities = RTCRtpSender.getCapabilities('video');
|
11907
11929
|
let hasVP9 = false;
|
@@ -11945,16 +11967,16 @@ function isSafariBased() {
|
|
11945
11967
|
const b = getBrowser();
|
11946
11968
|
return (b === null || b === void 0 ? void 0 : b.name) === 'Safari' || (b === null || b === void 0 ? void 0 : b.os) === 'iOS';
|
11947
11969
|
}
|
11948
|
-
function
|
11970
|
+
function isSafari17Based() {
|
11949
11971
|
const b = getBrowser();
|
11950
|
-
return (b === null || b === void 0 ? void 0 : b.name) === 'Safari' && b.version.startsWith('17.');
|
11972
|
+
return (b === null || b === void 0 ? void 0 : b.name) === 'Safari' && b.version.startsWith('17.') || (b === null || b === void 0 ? void 0 : b.os) === 'iOS' && !!(b === null || b === void 0 ? void 0 : b.osVersion) && compareVersions(b.osVersion, '17') >= 0;
|
11951
11973
|
}
|
11952
11974
|
function isSafariSvcApi(browser) {
|
11953
11975
|
if (!browser) {
|
11954
11976
|
browser = getBrowser();
|
11955
11977
|
}
|
11956
11978
|
// Safari 18.4 requires legacy svc api and scaleResolutionDown to be set
|
11957
|
-
return (browser === null || browser === void 0 ? void 0 : browser.name) === 'Safari' && compareVersions(browser.version, '18.3') > 0;
|
11979
|
+
return (browser === null || browser === void 0 ? void 0 : browser.name) === 'Safari' && compareVersions(browser.version, '18.3') > 0 || (browser === null || browser === void 0 ? void 0 : browser.os) === 'iOS' && !!(browser === null || browser === void 0 ? void 0 : browser.osVersion) && compareVersions(browser.osVersion, '18.3') > 0;
|
11958
11980
|
}
|
11959
11981
|
function isMobile() {
|
11960
11982
|
var _a, _b;
|
@@ -12799,8 +12821,8 @@ class E2EEManager extends eventsExports.EventEmitter {
|
|
12799
12821
|
});
|
12800
12822
|
this.setParticipantCryptorEnabled(this.room.localParticipant.isE2EEEnabled, this.room.localParticipant.identity);
|
12801
12823
|
});
|
12802
|
-
room.localParticipant.on(ParticipantEvent.
|
12803
|
-
this.setupE2EESender(
|
12824
|
+
room.localParticipant.on(ParticipantEvent.LocalSenderCreated, (sender, track) => __awaiter(this, void 0, void 0, function* () {
|
12825
|
+
this.setupE2EESender(track, sender);
|
12804
12826
|
}));
|
12805
12827
|
keyProvider.on(KeyProviderEvent.SetKey, keyInfo => this.postKey(keyInfo)).on(KeyProviderEvent.RatchetRequest, (participantId, keyIndex) => this.postRatchetRequest(participantId, keyIndex));
|
12806
12828
|
}
|
@@ -14789,6 +14811,7 @@ class PCTransport extends eventsExports.EventEmitter {
|
|
14789
14811
|
this.loggerOptions = loggerOptions;
|
14790
14812
|
this.config = config;
|
14791
14813
|
this._pc = this.createPC();
|
14814
|
+
this.offerLock = new _();
|
14792
14815
|
}
|
14793
14816
|
createPC() {
|
14794
14817
|
const pc = new RTCPeerConnection(this.config);
|
@@ -14927,92 +14950,97 @@ class PCTransport extends eventsExports.EventEmitter {
|
|
14927
14950
|
createAndSendOffer(options) {
|
14928
14951
|
return __awaiter(this, void 0, void 0, function* () {
|
14929
14952
|
var _a;
|
14930
|
-
|
14931
|
-
|
14932
|
-
|
14933
|
-
|
14934
|
-
|
14935
|
-
|
14936
|
-
if (options === null || options === void 0 ? void 0 : options.iceRestart) {
|
14937
|
-
this.log.debug('restarting ICE', this.logContext);
|
14938
|
-
this.restartingIce = true;
|
14939
|
-
}
|
14940
|
-
if (this._pc && this._pc.signalingState === 'have-local-offer') {
|
14941
|
-
// we're waiting for the peer to accept our offer, so we'll just wait
|
14942
|
-
// the only exception to this is when ICE restart is needed
|
14943
|
-
const currentSD = this._pc.remoteDescription;
|
14944
|
-
if ((options === null || options === void 0 ? void 0 : options.iceRestart) && currentSD) {
|
14945
|
-
// TODO: handle when ICE restart is needed but we don't have a remote description
|
14946
|
-
// the best thing to do is to recreate the peerconnection
|
14947
|
-
yield this._pc.setRemoteDescription(currentSD);
|
14948
|
-
} else {
|
14949
|
-
this.renegotiate = true;
|
14953
|
+
const unlock = yield this.offerLock.lock();
|
14954
|
+
try {
|
14955
|
+
// increase the offer id at the start to ensure the offer is always > 0 so that we can use 0 as a default value for legacy behavior
|
14956
|
+
const offerId = this.latestOfferId + 1;
|
14957
|
+
this.latestOfferId = offerId;
|
14958
|
+
if (this.onOffer === undefined) {
|
14950
14959
|
return;
|
14951
14960
|
}
|
14952
|
-
|
14953
|
-
|
14954
|
-
|
14955
|
-
|
14956
|
-
|
14957
|
-
|
14958
|
-
|
14959
|
-
|
14960
|
-
|
14961
|
-
|
14962
|
-
|
14963
|
-
|
14964
|
-
|
14965
|
-
|
14966
|
-
|
14967
|
-
|
14968
|
-
|
14969
|
-
|
14970
|
-
|
14971
|
-
|
14972
|
-
|
14973
|
-
|
14974
|
-
|
14975
|
-
|
14961
|
+
if (options === null || options === void 0 ? void 0 : options.iceRestart) {
|
14962
|
+
this.log.debug('restarting ICE', this.logContext);
|
14963
|
+
this.restartingIce = true;
|
14964
|
+
}
|
14965
|
+
if (this._pc && this._pc.signalingState === 'have-local-offer') {
|
14966
|
+
// we're waiting for the peer to accept our offer, so we'll just wait
|
14967
|
+
// the only exception to this is when ICE restart is needed
|
14968
|
+
const currentSD = this._pc.remoteDescription;
|
14969
|
+
if ((options === null || options === void 0 ? void 0 : options.iceRestart) && currentSD) {
|
14970
|
+
// TODO: handle when ICE restart is needed but we don't have a remote description
|
14971
|
+
// the best thing to do is to recreate the peerconnection
|
14972
|
+
yield this._pc.setRemoteDescription(currentSD);
|
14973
|
+
} else {
|
14974
|
+
this.renegotiate = true;
|
14975
|
+
return;
|
14976
|
+
}
|
14977
|
+
} else if (!this._pc || this._pc.signalingState === 'closed') {
|
14978
|
+
this.log.warn('could not createOffer with closed peer connection', this.logContext);
|
14979
|
+
return;
|
14980
|
+
}
|
14981
|
+
// actually negotiate
|
14982
|
+
this.log.debug('starting to negotiate', this.logContext);
|
14983
|
+
const offer = yield this.pc.createOffer(options);
|
14984
|
+
this.log.debug('original offer', Object.assign({
|
14985
|
+
sdp: offer.sdp
|
14986
|
+
}, this.logContext));
|
14987
|
+
const sdpParsed = libExports.parse((_a = offer.sdp) !== null && _a !== void 0 ? _a : '');
|
14988
|
+
sdpParsed.media.forEach(media => {
|
14989
|
+
ensureIPAddrMatchVersion(media);
|
14990
|
+
if (media.type === 'audio') {
|
14991
|
+
ensureAudioNackAndStereo(media, [], []);
|
14992
|
+
} else if (media.type === 'video') {
|
14993
|
+
this.trackBitrates.some(trackbr => {
|
14994
|
+
if (!media.msid || !trackbr.cid || !media.msid.includes(trackbr.cid)) {
|
14995
|
+
return false;
|
14996
|
+
}
|
14997
|
+
let codecPayload = 0;
|
14998
|
+
media.rtp.some(rtp => {
|
14999
|
+
if (rtp.codec.toUpperCase() === trackbr.codec.toUpperCase()) {
|
15000
|
+
codecPayload = rtp.payload;
|
15001
|
+
return true;
|
15002
|
+
}
|
15003
|
+
return false;
|
15004
|
+
});
|
15005
|
+
if (codecPayload === 0) {
|
14976
15006
|
return true;
|
14977
15007
|
}
|
14978
|
-
|
14979
|
-
|
14980
|
-
|
14981
|
-
|
14982
|
-
|
14983
|
-
|
14984
|
-
|
14985
|
-
|
14986
|
-
|
14987
|
-
|
14988
|
-
|
14989
|
-
|
14990
|
-
|
14991
|
-
|
14992
|
-
|
14993
|
-
|
14994
|
-
|
14995
|
-
|
14996
|
-
// initial track's bitrate for all tracks
|
14997
|
-
if (!fmtp.config.includes('x-google-start-bitrate')) {
|
14998
|
-
fmtp.config += ";x-google-start-bitrate=".concat(startBitrate);
|
15008
|
+
if (isSVCCodec(trackbr.codec)) {
|
15009
|
+
this.ensureVideoDDExtensionForSVC(media, sdpParsed);
|
15010
|
+
}
|
15011
|
+
// TODO: av1 slow starting issue already fixed in chrome 124, clean this after some versions
|
15012
|
+
// mung sdp for av1 bitrate setting that can't apply by sendEncoding
|
15013
|
+
if (trackbr.codec !== 'av1') {
|
15014
|
+
return true;
|
15015
|
+
}
|
15016
|
+
const startBitrate = Math.round(trackbr.maxbr * startBitrateForSVC);
|
15017
|
+
for (const fmtp of media.fmtp) {
|
15018
|
+
if (fmtp.payload === codecPayload) {
|
15019
|
+
// if another track's fmtp already is set, we cannot override the bitrate
|
15020
|
+
// this has the unfortunate consequence of being forced to use the
|
15021
|
+
// initial track's bitrate for all tracks
|
15022
|
+
if (!fmtp.config.includes('x-google-start-bitrate')) {
|
15023
|
+
fmtp.config += ";x-google-start-bitrate=".concat(startBitrate);
|
15024
|
+
}
|
15025
|
+
break;
|
14999
15026
|
}
|
15000
|
-
break;
|
15001
15027
|
}
|
15002
|
-
|
15003
|
-
|
15004
|
-
}
|
15028
|
+
return true;
|
15029
|
+
});
|
15030
|
+
}
|
15031
|
+
});
|
15032
|
+
if (this.latestOfferId > offerId) {
|
15033
|
+
this.log.warn('latestOfferId mismatch', Object.assign(Object.assign({}, this.logContext), {
|
15034
|
+
latestOfferId: this.latestOfferId,
|
15035
|
+
offerId
|
15036
|
+
}));
|
15037
|
+
return;
|
15005
15038
|
}
|
15006
|
-
|
15007
|
-
|
15008
|
-
|
15009
|
-
|
15010
|
-
offerId
|
15011
|
-
}));
|
15012
|
-
return;
|
15039
|
+
yield this.setMungedSDP(offer, libExports.write(sdpParsed));
|
15040
|
+
this.onOffer(offer, this.latestOfferId);
|
15041
|
+
} finally {
|
15042
|
+
unlock();
|
15013
15043
|
}
|
15014
|
-
yield this.setMungedSDP(offer, libExports.write(sdpParsed));
|
15015
|
-
this.onOffer(offer, this.latestOfferId);
|
15016
15044
|
});
|
15017
15045
|
}
|
15018
15046
|
createAndSetAnswer() {
|
@@ -16677,7 +16705,7 @@ function computeVideoEncodings(isScreenShare, width, height, options) {
|
|
16677
16705
|
// before M113.
|
16678
16706
|
// Announced here: https://groups.google.com/g/discuss-webrtc/c/-QQ3pxrl-fw?pli=1
|
16679
16707
|
const browser = getBrowser();
|
16680
|
-
if (
|
16708
|
+
if (isSafariBased() ||
|
16681
16709
|
// Even tho RN runs M114, it does not produce SVC layers when a single encoding
|
16682
16710
|
// is provided. So we'll use the legacy SVC specification for now.
|
16683
16711
|
// TODO: when we upstream libwebrtc, this will need additional verification
|
@@ -16964,6 +16992,8 @@ class LocalVideoTrack extends LocalTrack {
|
|
16964
16992
|
/* @internal */
|
16965
16993
|
this.simulcastCodecs = new Map();
|
16966
16994
|
this.degradationPreference = 'balanced';
|
16995
|
+
this.isCpuConstrained = false;
|
16996
|
+
this.optimizeForPerformance = false;
|
16967
16997
|
this.monitorSender = () => __awaiter(this, void 0, void 0, function* () {
|
16968
16998
|
if (!this.sender) {
|
16969
16999
|
this._currentBitrate = 0;
|
@@ -16973,12 +17003,19 @@ class LocalVideoTrack extends LocalTrack {
|
|
16973
17003
|
try {
|
16974
17004
|
stats = yield this.getSenderStats();
|
16975
17005
|
} catch (e) {
|
16976
|
-
this.log.error('could not get
|
17006
|
+
this.log.error('could not get video sender stats', Object.assign(Object.assign({}, this.logContext), {
|
16977
17007
|
error: e
|
16978
17008
|
}));
|
16979
17009
|
return;
|
16980
17010
|
}
|
16981
17011
|
const statsMap = new Map(stats.map(s => [s.rid, s]));
|
17012
|
+
const isCpuConstrained = stats.some(s => s.qualityLimitationReason === 'cpu');
|
17013
|
+
if (isCpuConstrained !== this.isCpuConstrained) {
|
17014
|
+
this.isCpuConstrained = isCpuConstrained;
|
17015
|
+
if (this.isCpuConstrained) {
|
17016
|
+
this.emit(TrackEvent.CpuConstrained);
|
17017
|
+
}
|
17018
|
+
}
|
16982
17019
|
if (this.prevStats) {
|
16983
17020
|
let totalBitrate = 0;
|
16984
17021
|
statsMap.forEach((s, key) => {
|
@@ -17214,6 +17251,8 @@ class LocalVideoTrack extends LocalTrack {
|
|
17214
17251
|
}
|
17215
17252
|
}
|
17216
17253
|
yield this.restart(constraints);
|
17254
|
+
// reset cpu constrained state after track is restarted
|
17255
|
+
this.isCpuConstrained = false;
|
17217
17256
|
try {
|
17218
17257
|
for (var _e = true, _f = __asyncValues(this.simulcastCodecs.values()), _g; _g = yield _f.next(), _a = _g.done, !_a; _e = true) {
|
17219
17258
|
_c = _g.value;
|
@@ -17383,6 +17422,12 @@ class LocalVideoTrack extends LocalTrack {
|
|
17383
17422
|
*/
|
17384
17423
|
setPublishingLayers(isSvc, qualities) {
|
17385
17424
|
return __awaiter(this, void 0, void 0, function* () {
|
17425
|
+
if (this.optimizeForPerformance) {
|
17426
|
+
this.log.info('skipping setPublishingLayers due to optimized publishing performance', Object.assign(Object.assign({}, this.logContext), {
|
17427
|
+
qualities
|
17428
|
+
}));
|
17429
|
+
return;
|
17430
|
+
}
|
17386
17431
|
this.log.debug('setting publishing layers', Object.assign(Object.assign({}, this.logContext), {
|
17387
17432
|
qualities
|
17388
17433
|
}));
|
@@ -17392,6 +17437,44 @@ class LocalVideoTrack extends LocalTrack {
|
|
17392
17437
|
yield setPublishingLayersForSender(this.sender, this.encodings, qualities, this.senderLock, isSvc, this.log, this.logContext);
|
17393
17438
|
});
|
17394
17439
|
}
|
17440
|
+
/**
|
17441
|
+
* Designed for lower powered devices, reduces video publishing quality and disables simulcast.
|
17442
|
+
* @experimental
|
17443
|
+
*/
|
17444
|
+
prioritizePerformance() {
|
17445
|
+
return __awaiter(this, void 0, void 0, function* () {
|
17446
|
+
if (!this.sender) {
|
17447
|
+
throw new Error('sender not found');
|
17448
|
+
}
|
17449
|
+
const unlock = yield this.senderLock.lock();
|
17450
|
+
try {
|
17451
|
+
this.optimizeForPerformance = true;
|
17452
|
+
const params = this.sender.getParameters();
|
17453
|
+
params.encodings = params.encodings.map((e, idx) => {
|
17454
|
+
var _a;
|
17455
|
+
return Object.assign(Object.assign({}, e), {
|
17456
|
+
active: idx === 0,
|
17457
|
+
scaleResolutionDownBy: Math.max(1, Math.ceil(((_a = this.mediaStreamTrack.getSettings().height) !== null && _a !== void 0 ? _a : 360) / 360)),
|
17458
|
+
scalabilityMode: idx === 0 && isSVCCodec(this.codec) ? 'L1T3' : undefined,
|
17459
|
+
maxFramerate: idx === 0 ? 15 : 0,
|
17460
|
+
maxBitrate: idx === 0 ? e.maxBitrate : 0
|
17461
|
+
});
|
17462
|
+
});
|
17463
|
+
this.log.debug('setting performance optimised encodings', Object.assign(Object.assign({}, this.logContext), {
|
17464
|
+
encodings: params.encodings
|
17465
|
+
}));
|
17466
|
+
this.encodings = params.encodings;
|
17467
|
+
yield this.sender.setParameters(params);
|
17468
|
+
} catch (e) {
|
17469
|
+
this.log.error('failed to set performance optimised encodings', Object.assign(Object.assign({}, this.logContext), {
|
17470
|
+
error: e
|
17471
|
+
}));
|
17472
|
+
this.optimizeForPerformance = false;
|
17473
|
+
} finally {
|
17474
|
+
unlock();
|
17475
|
+
}
|
17476
|
+
});
|
17477
|
+
}
|
17395
17478
|
handleAppVisibilityChanged() {
|
17396
17479
|
const _super = Object.create(null, {
|
17397
17480
|
handleAppVisibilityChanged: {
|
@@ -19818,16 +19901,23 @@ class LocalTrackPublication extends TrackPublication {
|
|
19818
19901
|
this.handleTrackEnded = () => {
|
19819
19902
|
this.emit(TrackEvent.Ended);
|
19820
19903
|
};
|
19904
|
+
this.handleCpuConstrained = () => {
|
19905
|
+
if (this.track && isVideoTrack(this.track)) {
|
19906
|
+
this.emit(TrackEvent.CpuConstrained, this.track);
|
19907
|
+
}
|
19908
|
+
};
|
19821
19909
|
this.updateInfo(ti);
|
19822
19910
|
this.setTrack(track);
|
19823
19911
|
}
|
19824
19912
|
setTrack(track) {
|
19825
19913
|
if (this.track) {
|
19826
19914
|
this.track.off(TrackEvent.Ended, this.handleTrackEnded);
|
19915
|
+
this.track.off(TrackEvent.CpuConstrained, this.handleCpuConstrained);
|
19827
19916
|
}
|
19828
19917
|
super.setTrack(track);
|
19829
19918
|
if (track) {
|
19830
19919
|
track.on(TrackEvent.Ended, this.handleTrackEnded);
|
19920
|
+
track.on(TrackEvent.CpuConstrained, this.handleCpuConstrained);
|
19831
19921
|
}
|
19832
19922
|
}
|
19833
19923
|
get isMuted() {
|
@@ -20065,7 +20155,7 @@ function createLocalScreenTracks(options) {
|
|
20065
20155
|
if (options === undefined) {
|
20066
20156
|
options = {};
|
20067
20157
|
}
|
20068
|
-
if (options.resolution === undefined && !
|
20158
|
+
if (options.resolution === undefined && !isSafari17Based()) {
|
20069
20159
|
options.resolution = ScreenSharePresets.h1080fps30.resolution;
|
20070
20160
|
}
|
20071
20161
|
if (navigator.mediaDevices.getDisplayMedia === undefined) {
|
@@ -20498,6 +20588,10 @@ class LocalParticipant extends Participant {
|
|
20498
20588
|
}
|
20499
20589
|
this.engine.client.sendUpdateLocalAudioTrack(pub.trackSid, pub.getTrackFeatures());
|
20500
20590
|
};
|
20591
|
+
this.onTrackCpuConstrained = (track, publication) => {
|
20592
|
+
this.log.debug('track cpu constrained', Object.assign(Object.assign({}, this.logContext), getLogContextFromTrack(publication)));
|
20593
|
+
this.emit(ParticipantEvent.LocalTrackCpuConstrained, track, publication);
|
20594
|
+
};
|
20501
20595
|
this.handleSubscribedQualityUpdate = update => __awaiter(this, void 0, void 0, function* () {
|
20502
20596
|
var _a, e_1, _b, _c;
|
20503
20597
|
var _d;
|
@@ -20957,7 +21051,7 @@ class LocalParticipant extends Participant {
|
|
20957
21051
|
if (navigator.mediaDevices.getDisplayMedia === undefined) {
|
20958
21052
|
throw new DeviceUnsupportedError('getDisplayMedia not supported');
|
20959
21053
|
}
|
20960
|
-
if (options.resolution === undefined && !
|
21054
|
+
if (options.resolution === undefined && !isSafari17Based()) {
|
20961
21055
|
// we need to constrain the dimensions, otherwise it could lead to low bitrate
|
20962
21056
|
// due to encoding a huge video. Encoding such large surfaces is really expensive
|
20963
21057
|
// unfortunately Safari 17 has a but and cannot be constrained by default
|
@@ -21324,6 +21418,7 @@ class LocalParticipant extends Participant {
|
|
21324
21418
|
throw new UnexpectedConnectionState('pcManager is not ready');
|
21325
21419
|
}
|
21326
21420
|
track.sender = yield this.engine.createSender(track, opts, encodings);
|
21421
|
+
this.emit(ParticipantEvent.LocalSenderCreated, track.sender, track);
|
21327
21422
|
if (isLocalVideoTrack(track)) {
|
21328
21423
|
(_a = opts.degradationPreference) !== null && _a !== void 0 ? _a : opts.degradationPreference = getDefaultDegradationPreference(track);
|
21329
21424
|
track.setDegradationPreference(opts.degradationPreference);
|
@@ -21409,6 +21504,7 @@ class LocalParticipant extends Participant {
|
|
21409
21504
|
loggerName: this.roomOptions.loggerName,
|
21410
21505
|
loggerContextCb: () => this.logContext
|
21411
21506
|
});
|
21507
|
+
publication.on(TrackEvent.CpuConstrained, constrainedTrack => this.onTrackCpuConstrained(constrainedTrack, publication));
|
21412
21508
|
// save options for when it needs to be republished again
|
21413
21509
|
publication.options = opts;
|
21414
21510
|
track.sid = ti.sid;
|