livekit-client 2.13.7 → 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.e2ee.worker.js +1 -1
- package/dist/livekit-client.e2ee.worker.js.map +1 -1
- package/dist/livekit-client.e2ee.worker.mjs +13 -7
- package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
- package/dist/livekit-client.esm.mjs +188 -90
- 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/e2ee/types.d.ts +7 -0
- package/dist/src/e2ee/types.d.ts.map +1 -1
- package/dist/src/e2ee/worker/FrameCryptor.d.ts +2 -1
- package/dist/src/e2ee/worker/FrameCryptor.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/e2ee/types.d.ts +7 -0
- package/dist/ts4.2/src/e2ee/worker/FrameCryptor.d.ts +2 -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 +8 -3
- package/src/e2ee/types.ts +8 -0
- package/src/e2ee/worker/FrameCryptor.ts +15 -0
- package/src/e2ee/worker/e2ee.worker.ts +8 -5
- 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
|
}
|
@@ -12951,7 +12973,8 @@ class E2EEManager extends eventsExports.EventEmitter {
|
|
12951
12973
|
writableStream: writable,
|
12952
12974
|
trackId: trackId,
|
12953
12975
|
codec,
|
12954
|
-
participantIdentity: participantIdentity
|
12976
|
+
participantIdentity: participantIdentity,
|
12977
|
+
isReuse: E2EE_FLAG in receiver
|
12955
12978
|
}
|
12956
12979
|
};
|
12957
12980
|
this.worker.postMessage(msg, [readable, writable]);
|
@@ -12994,7 +13017,8 @@ class E2EEManager extends eventsExports.EventEmitter {
|
|
12994
13017
|
writableStream: senderStreams.writable,
|
12995
13018
|
codec,
|
12996
13019
|
trackId,
|
12997
|
-
participantIdentity: this.room.localParticipant.identity
|
13020
|
+
participantIdentity: this.room.localParticipant.identity,
|
13021
|
+
isReuse: false
|
12998
13022
|
}
|
12999
13023
|
};
|
13000
13024
|
this.worker.postMessage(msg, [senderStreams.readable, senderStreams.writable]);
|
@@ -14787,6 +14811,7 @@ class PCTransport extends eventsExports.EventEmitter {
|
|
14787
14811
|
this.loggerOptions = loggerOptions;
|
14788
14812
|
this.config = config;
|
14789
14813
|
this._pc = this.createPC();
|
14814
|
+
this.offerLock = new _();
|
14790
14815
|
}
|
14791
14816
|
createPC() {
|
14792
14817
|
const pc = new RTCPeerConnection(this.config);
|
@@ -14925,92 +14950,97 @@ class PCTransport extends eventsExports.EventEmitter {
|
|
14925
14950
|
createAndSendOffer(options) {
|
14926
14951
|
return __awaiter(this, void 0, void 0, function* () {
|
14927
14952
|
var _a;
|
14928
|
-
|
14929
|
-
|
14930
|
-
|
14931
|
-
|
14932
|
-
|
14933
|
-
|
14934
|
-
if (options === null || options === void 0 ? void 0 : options.iceRestart) {
|
14935
|
-
this.log.debug('restarting ICE', this.logContext);
|
14936
|
-
this.restartingIce = true;
|
14937
|
-
}
|
14938
|
-
if (this._pc && this._pc.signalingState === 'have-local-offer') {
|
14939
|
-
// we're waiting for the peer to accept our offer, so we'll just wait
|
14940
|
-
// the only exception to this is when ICE restart is needed
|
14941
|
-
const currentSD = this._pc.remoteDescription;
|
14942
|
-
if ((options === null || options === void 0 ? void 0 : options.iceRestart) && currentSD) {
|
14943
|
-
// TODO: handle when ICE restart is needed but we don't have a remote description
|
14944
|
-
// the best thing to do is to recreate the peerconnection
|
14945
|
-
yield this._pc.setRemoteDescription(currentSD);
|
14946
|
-
} else {
|
14947
|
-
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) {
|
14948
14959
|
return;
|
14949
14960
|
}
|
14950
|
-
|
14951
|
-
|
14952
|
-
|
14953
|
-
|
14954
|
-
|
14955
|
-
|
14956
|
-
|
14957
|
-
|
14958
|
-
|
14959
|
-
|
14960
|
-
|
14961
|
-
|
14962
|
-
|
14963
|
-
|
14964
|
-
|
14965
|
-
|
14966
|
-
|
14967
|
-
|
14968
|
-
|
14969
|
-
|
14970
|
-
|
14971
|
-
|
14972
|
-
|
14973
|
-
|
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) {
|
14974
15006
|
return true;
|
14975
15007
|
}
|
14976
|
-
|
14977
|
-
|
14978
|
-
|
14979
|
-
|
14980
|
-
|
14981
|
-
|
14982
|
-
|
14983
|
-
|
14984
|
-
|
14985
|
-
|
14986
|
-
|
14987
|
-
|
14988
|
-
|
14989
|
-
|
14990
|
-
|
14991
|
-
|
14992
|
-
|
14993
|
-
|
14994
|
-
// initial track's bitrate for all tracks
|
14995
|
-
if (!fmtp.config.includes('x-google-start-bitrate')) {
|
14996
|
-
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;
|
14997
15026
|
}
|
14998
|
-
break;
|
14999
15027
|
}
|
15000
|
-
|
15001
|
-
|
15002
|
-
}
|
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;
|
15003
15038
|
}
|
15004
|
-
|
15005
|
-
|
15006
|
-
|
15007
|
-
|
15008
|
-
offerId
|
15009
|
-
}));
|
15010
|
-
return;
|
15039
|
+
yield this.setMungedSDP(offer, libExports.write(sdpParsed));
|
15040
|
+
this.onOffer(offer, this.latestOfferId);
|
15041
|
+
} finally {
|
15042
|
+
unlock();
|
15011
15043
|
}
|
15012
|
-
yield this.setMungedSDP(offer, libExports.write(sdpParsed));
|
15013
|
-
this.onOffer(offer, this.latestOfferId);
|
15014
15044
|
});
|
15015
15045
|
}
|
15016
15046
|
createAndSetAnswer() {
|
@@ -16675,7 +16705,7 @@ function computeVideoEncodings(isScreenShare, width, height, options) {
|
|
16675
16705
|
// before M113.
|
16676
16706
|
// Announced here: https://groups.google.com/g/discuss-webrtc/c/-QQ3pxrl-fw?pli=1
|
16677
16707
|
const browser = getBrowser();
|
16678
|
-
if (
|
16708
|
+
if (isSafariBased() ||
|
16679
16709
|
// Even tho RN runs M114, it does not produce SVC layers when a single encoding
|
16680
16710
|
// is provided. So we'll use the legacy SVC specification for now.
|
16681
16711
|
// TODO: when we upstream libwebrtc, this will need additional verification
|
@@ -16962,6 +16992,8 @@ class LocalVideoTrack extends LocalTrack {
|
|
16962
16992
|
/* @internal */
|
16963
16993
|
this.simulcastCodecs = new Map();
|
16964
16994
|
this.degradationPreference = 'balanced';
|
16995
|
+
this.isCpuConstrained = false;
|
16996
|
+
this.optimizeForPerformance = false;
|
16965
16997
|
this.monitorSender = () => __awaiter(this, void 0, void 0, function* () {
|
16966
16998
|
if (!this.sender) {
|
16967
16999
|
this._currentBitrate = 0;
|
@@ -16971,12 +17003,19 @@ class LocalVideoTrack extends LocalTrack {
|
|
16971
17003
|
try {
|
16972
17004
|
stats = yield this.getSenderStats();
|
16973
17005
|
} catch (e) {
|
16974
|
-
this.log.error('could not get
|
17006
|
+
this.log.error('could not get video sender stats', Object.assign(Object.assign({}, this.logContext), {
|
16975
17007
|
error: e
|
16976
17008
|
}));
|
16977
17009
|
return;
|
16978
17010
|
}
|
16979
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
|
+
}
|
16980
17019
|
if (this.prevStats) {
|
16981
17020
|
let totalBitrate = 0;
|
16982
17021
|
statsMap.forEach((s, key) => {
|
@@ -17212,6 +17251,8 @@ class LocalVideoTrack extends LocalTrack {
|
|
17212
17251
|
}
|
17213
17252
|
}
|
17214
17253
|
yield this.restart(constraints);
|
17254
|
+
// reset cpu constrained state after track is restarted
|
17255
|
+
this.isCpuConstrained = false;
|
17215
17256
|
try {
|
17216
17257
|
for (var _e = true, _f = __asyncValues(this.simulcastCodecs.values()), _g; _g = yield _f.next(), _a = _g.done, !_a; _e = true) {
|
17217
17258
|
_c = _g.value;
|
@@ -17381,6 +17422,12 @@ class LocalVideoTrack extends LocalTrack {
|
|
17381
17422
|
*/
|
17382
17423
|
setPublishingLayers(isSvc, qualities) {
|
17383
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
|
+
}
|
17384
17431
|
this.log.debug('setting publishing layers', Object.assign(Object.assign({}, this.logContext), {
|
17385
17432
|
qualities
|
17386
17433
|
}));
|
@@ -17390,6 +17437,44 @@ class LocalVideoTrack extends LocalTrack {
|
|
17390
17437
|
yield setPublishingLayersForSender(this.sender, this.encodings, qualities, this.senderLock, isSvc, this.log, this.logContext);
|
17391
17438
|
});
|
17392
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
|
+
}
|
17393
17478
|
handleAppVisibilityChanged() {
|
17394
17479
|
const _super = Object.create(null, {
|
17395
17480
|
handleAppVisibilityChanged: {
|
@@ -19816,16 +19901,23 @@ class LocalTrackPublication extends TrackPublication {
|
|
19816
19901
|
this.handleTrackEnded = () => {
|
19817
19902
|
this.emit(TrackEvent.Ended);
|
19818
19903
|
};
|
19904
|
+
this.handleCpuConstrained = () => {
|
19905
|
+
if (this.track && isVideoTrack(this.track)) {
|
19906
|
+
this.emit(TrackEvent.CpuConstrained, this.track);
|
19907
|
+
}
|
19908
|
+
};
|
19819
19909
|
this.updateInfo(ti);
|
19820
19910
|
this.setTrack(track);
|
19821
19911
|
}
|
19822
19912
|
setTrack(track) {
|
19823
19913
|
if (this.track) {
|
19824
19914
|
this.track.off(TrackEvent.Ended, this.handleTrackEnded);
|
19915
|
+
this.track.off(TrackEvent.CpuConstrained, this.handleCpuConstrained);
|
19825
19916
|
}
|
19826
19917
|
super.setTrack(track);
|
19827
19918
|
if (track) {
|
19828
19919
|
track.on(TrackEvent.Ended, this.handleTrackEnded);
|
19920
|
+
track.on(TrackEvent.CpuConstrained, this.handleCpuConstrained);
|
19829
19921
|
}
|
19830
19922
|
}
|
19831
19923
|
get isMuted() {
|
@@ -20063,7 +20155,7 @@ function createLocalScreenTracks(options) {
|
|
20063
20155
|
if (options === undefined) {
|
20064
20156
|
options = {};
|
20065
20157
|
}
|
20066
|
-
if (options.resolution === undefined && !
|
20158
|
+
if (options.resolution === undefined && !isSafari17Based()) {
|
20067
20159
|
options.resolution = ScreenSharePresets.h1080fps30.resolution;
|
20068
20160
|
}
|
20069
20161
|
if (navigator.mediaDevices.getDisplayMedia === undefined) {
|
@@ -20496,6 +20588,10 @@ class LocalParticipant extends Participant {
|
|
20496
20588
|
}
|
20497
20589
|
this.engine.client.sendUpdateLocalAudioTrack(pub.trackSid, pub.getTrackFeatures());
|
20498
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
|
+
};
|
20499
20595
|
this.handleSubscribedQualityUpdate = update => __awaiter(this, void 0, void 0, function* () {
|
20500
20596
|
var _a, e_1, _b, _c;
|
20501
20597
|
var _d;
|
@@ -20955,7 +21051,7 @@ class LocalParticipant extends Participant {
|
|
20955
21051
|
if (navigator.mediaDevices.getDisplayMedia === undefined) {
|
20956
21052
|
throw new DeviceUnsupportedError('getDisplayMedia not supported');
|
20957
21053
|
}
|
20958
|
-
if (options.resolution === undefined && !
|
21054
|
+
if (options.resolution === undefined && !isSafari17Based()) {
|
20959
21055
|
// we need to constrain the dimensions, otherwise it could lead to low bitrate
|
20960
21056
|
// due to encoding a huge video. Encoding such large surfaces is really expensive
|
20961
21057
|
// unfortunately Safari 17 has a but and cannot be constrained by default
|
@@ -21322,6 +21418,7 @@ class LocalParticipant extends Participant {
|
|
21322
21418
|
throw new UnexpectedConnectionState('pcManager is not ready');
|
21323
21419
|
}
|
21324
21420
|
track.sender = yield this.engine.createSender(track, opts, encodings);
|
21421
|
+
this.emit(ParticipantEvent.LocalSenderCreated, track.sender, track);
|
21325
21422
|
if (isLocalVideoTrack(track)) {
|
21326
21423
|
(_a = opts.degradationPreference) !== null && _a !== void 0 ? _a : opts.degradationPreference = getDefaultDegradationPreference(track);
|
21327
21424
|
track.setDegradationPreference(opts.degradationPreference);
|
@@ -21407,6 +21504,7 @@ class LocalParticipant extends Participant {
|
|
21407
21504
|
loggerName: this.roomOptions.loggerName,
|
21408
21505
|
loggerContextCb: () => this.logContext
|
21409
21506
|
});
|
21507
|
+
publication.on(TrackEvent.CpuConstrained, constrainedTrack => this.onTrackCpuConstrained(constrainedTrack, publication));
|
21410
21508
|
// save options for when it needs to be republished again
|
21411
21509
|
publication.options = opts;
|
21412
21510
|
track.sid = ti.sid;
|