fix(voice): stop clamping stored video quality preferences (#2415)

This commit is contained in:
Hampus authored and GitHub committed 2026-09-03 04:36:04 +02:00
1 parent 6c08813f9b
commit 3e15b97c8c
47 files changed
+3725 -3732

No files matched your search

@@ -1,7 +1,5 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {LimitResolver} from '@app/features/app/utils/LimitResolverAdapter';
import {isLimitToggleEnabled} from '@app/features/app/utils/LimitUtils';
import {Logger} from '@app/features/platform/utils/AppLogger';
import * as PremiumModalCommands from '@app/features/premium/commands/PremiumModalCommands';
import {shouldShowPremiumFeatures} from '@app/features/premium/utils/PremiumUtils';
@@ -52,6 +50,7 @@ import {
type StreamSettingsShareContext,
shouldReconfigureLinuxAudioForActiveStreamSettings,
} from '@app/features/voice/utils/StreamSettingsUpdatePolicy';
import {hasHigherVideoQuality as resolveHigherVideoQuality} from '@app/features/voice/utils/VideoQualityEntitlement';
import {formatVoiceAudioDeviceLabel} from '@app/features/voice/utils/VoiceMessageDescriptors';
import type {NativeAudioAvailability} from '@app/types/electron.d';
import {msg} from '@lingui/core/macro';
@@ -83,8 +82,8 @@ const RAZOR_SHARP_TEXT_AT_NATIVE_SOURCE_15_FPS_DESCRIPTOR = msg({
comment:
'Description for the high-tier Screen share streaming preset (Plutonium). Source resolution and frame rate are technical tokens.',
});
const SHARPER_TEXT_AT_720P_15_FPS_DESCRIPTOR = msg({
message: 'Sharper text at 720p, 15 FPS',
const SHARPER_TEXT_AT_720P_30_FPS_DESCRIPTOR = msg({
message: 'Sharper text at 720p, 30 FPS',
comment:
'Description for the free-tier Screen share streaming preset. Resolution and frame rate are technical tokens.',
});
@@ -187,19 +186,7 @@ const PremiumBadge = () => (
);
export function useHasHigherVideoQuality(): boolean {
return useMemo(
() =>
isLimitToggleEnabled(
{
feature_higher_video_quality: LimitResolver.resolve({
key: 'feature_higher_video_quality',
fallback: 0,
}),
},
'feature_higher_video_quality',
),
[],
);
return resolveHigherVideoQuality();
}
function supportsStreamAudioCapture(shareContext: StreamSettingsShareContext): boolean {
@@ -437,7 +424,7 @@ export const StreamSettingsMenuContent = observer(
label: i18n._(SCREENSHARE_DESCRIPTOR),
description: hasHigherVideoQuality
? i18n._(RAZOR_SHARP_TEXT_AT_NATIVE_SOURCE_15_FPS_DESCRIPTOR)
: i18n._(SHARPER_TEXT_AT_720P_15_FPS_DESCRIPTOR),
: i18n._(SHARPER_TEXT_AT_720P_30_FPS_DESCRIPTOR),
isPremium: false,
});
}
@@ -451,7 +438,6 @@ export const StreamSettingsMenuContent = observer(
}, [isDeviceShare, hasHigherVideoQuality, i18n.locale]);
const resolutionOptions: Array<Option<ScreenshareResolution>> = useMemo(() => {
const options: Array<Option<ScreenshareResolution>> = [
{value: 'low_240p', label: '240p', isPremium: false},
{value: 'low_480p', label: '480p', isPremium: false},
{value: 'medium', label: '720p', isPremium: false},
];
@@ -575,6 +561,10 @@ export const StreamSettingsMenuContent = observer(
? formatVoiceAudioDeviceLabel(i18n, selectedAudioDevice, i18n._(UNNAMED_INPUT_DESCRIPTOR))
: i18n._(SYSTEM_DEFAULT_DESCRIPTOR);
if (variant === 'compactLive') {
const presetQuality =
currentMode === 'custom'
? null
: resolveStreamingModeSettings(effectiveMode, currentResolution, currentFrameRate, true);
const selectCompactResolution = (option: Option<ScreenshareResolution>) => {
if (option.isPremium && !hasHigherVideoQuality) {
if (showPremiumFeatures) PremiumModalCommands.open();
@@ -584,7 +574,7 @@ export const StreamSettingsMenuContent = observer(
VoiceSettingsCommands.update({
streamingMode: 'custom',
screenshareResolution: option.value,
videoFrameRate: effectiveQuality.frameRate,
...(presetQuality ? {videoFrameRate: presetQuality.frameRate} : {}),
});
runApply();
};
@@ -596,7 +586,7 @@ export const StreamSettingsMenuContent = observer(
if (currentMode === 'custom' && effectiveQuality.frameRate === option.value) return;
VoiceSettingsCommands.update({
streamingMode: 'custom',
screenshareResolution: effectiveQuality.resolution,
...(presetQuality ? {screenshareResolution: presetQuality.resolution} : {}),
videoFrameRate: option.value,
});
runApply();
@@ -87,7 +87,6 @@ import {
resolveStreamingModeSettings,
} from '@app/features/voice/utils/ScreenShareOptions';
import {
normaliseDeviceScreenShareSettings,
startConfiguredDeviceScreenShare,
startConfiguredDisplayScreenShare,
switchConfiguredDeviceScreenShare,
@@ -1268,12 +1267,6 @@ const ScreenSharePickerModalLoadedContent = observer(
if (deviceCards.some((card) => card.id === selectedDeviceId)) return;
setSelectedDeviceId(null);
}, [deviceCards, selectedDeviceId]);
useEffect(() => {
if (activeTab !== 'devices') {
return;
}
normaliseDeviceScreenShareSettings();
}, [activeTab]);
const handleStartSelection = useCallback(
async (cardId: string) => {
if (pendingSelectionIdRef.current) return;
@@ -2,8 +2,6 @@
import assert from 'node:assert/strict';
import Config from '@app/features/app/config/Config';
import {LimitResolver} from '@app/features/app/utils/LimitResolverAdapter';
import {isLimitToggleEnabled} from '@app/features/app/utils/LimitUtils';
import {getCachedDesktopTroubleshootingSettings} from '@app/features/devtools/utils/DesktopTroubleshootingUtils';
import type {AppMetricsSnapshot, DesktopInfo, GpuInfo} from '@app/features/platform/types/Electron';
import {getElectronAPI} from '@app/features/ui/utils/NativeUtils';
@@ -17,6 +15,7 @@ import {getPublishedScreenShareMaxBitrateBps} from '@app/features/voice/engine/v
import VoiceSettings from '@app/features/voice/state/VoiceSettings';
import {getNativeAudioCaptureDiagnosticState} from '@app/features/voice/utils/NativeAudioCaptureBridge';
import {getScreenShareBitrateBps, resolveStreamingModeSettings} from '@app/features/voice/utils/ScreenShareOptions';
import {hasHigherVideoQuality} from '@app/features/voice/utils/VideoQualityEntitlement';
import {
buildVoiceStatsForNerdsPresentation,
type StatsForNerdsData,
@@ -105,18 +104,6 @@ function getSystemInfo(): StatsForNerdsData['system'] {
};
}
function hasHigherVideoQuality(): boolean {
return isLimitToggleEnabled(
{
feature_higher_video_quality: LimitResolver.resolve({
key: 'feature_higher_video_quality',
fallback: 0,
}),
},
'feature_higher_video_quality',
);
}
export function useStatsForNerds({enabled = true}: UseStatsForNerdsOptions = {}): StatsForNerdsData {
useMediaEngineVersion();
const [gpuInfo, setGpuInfo] = useState<GpuInfo | null>(null);
@@ -20,6 +20,7 @@ import {
} from '@app/features/voice/utils/ScreenShareOptions';
import {ScreenShareRollbackIncompleteError} from '@app/features/voice/utils/ScreenShareRollbackIncompleteError';
import {classifyVideoEncoderAcceleration} from '@app/features/voice/utils/VideoAccelerationClassification';
import {hasHigherVideoQuality} from '@app/features/voice/utils/VideoQualityEntitlement';
import {
BackupCodecPolicy,
type LocalParticipant,
@@ -199,6 +200,7 @@ export function getEffectiveScreenShareEncoding(publishOptions?: TrackPublishOpt
VoiceSettings.getStreamingMode(),
VoiceSettings.getScreenshareResolution(),
VoiceSettings.getVideoFrameRate(),
hasHigherVideoQuality(),
);
screenShareEncoding = getScreenShareEncoding(settings.resolution, settings.frameRate);
}
@@ -1,7 +1,5 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {LimitResolver} from '@app/features/app/utils/LimitResolverAdapter';
import {isLimitToggleEnabled} from '@app/features/app/utils/LimitUtils';
import AppStorage from '@app/features/platform/state/PersistentStorage';
import {Logger} from '@app/features/platform/utils/AppLogger';
import {makePersistent} from '@app/features/platform/utils/MobXPersistence';
@@ -13,6 +11,7 @@ import type {
ScreenShareScalabilityModePreference,
ScreenShareSoftwareQuality,
} from '@app/features/voice/utils/CodecCapabilityDetector';
import {hasHigherVideoQuality} from '@app/features/voice/utils/VideoQualityEntitlement';
import {areVoiceBackgroundsAvailable} from '@app/features/voice/utils/VoiceBackgroundAvailability';
import {
DEFAULT_VOICE_PROCESSING_MODE,
@@ -53,6 +52,7 @@ const VIDEO_FRAME_RATE_DEFAULT = 30;
const DEFAULT_BROWSER_NOISE_SUPPRESSION = true;
const DEFAULT_DEEP_FILTER_NOISE_SUPPRESSION = false;
const FREE_VIDEO_FRAME_RATE_MAX = 30;
const RETIRED_SCREENSHARE_RESOLUTION_REPLACEMENT: ScreenshareResolution = 'low_480p';
const PREMIUM_SCREENSHARE_RESOLUTIONS: ReadonlySet<ScreenshareResolution> = new Set(['high', 'ultra', 'source']);
export const CAMERA_EFFECT_STRENGTH_MIN = 0;
export const CAMERA_EFFECT_STRENGTH_MAX = 100;
@@ -293,6 +293,32 @@ function applyScreenShareHevcOptOutMigrationV1(parsed: Record<string, unknown>):
return true;
}
function applyVideoQualityNormalisationMigration(parsed: Record<string, unknown>): boolean {
let changed = false;
if (parsed.screenshareResolution !== undefined) {
const resolution = validateScreenshareResolution(parsed.screenshareResolution);
if (resolution !== parsed.screenshareResolution) {
parsed.screenshareResolution = resolution;
changed = true;
}
}
if (parsed.cameraResolution !== undefined) {
const resolution = validateCameraResolution(parsed.cameraResolution);
if (resolution !== parsed.cameraResolution) {
parsed.cameraResolution = resolution;
changed = true;
}
}
if (parsed.videoFrameRate !== undefined) {
const frameRate = clampVideoFrameRate(parsed.videoFrameRate);
if (frameRate !== parsed.videoFrameRate) {
parsed.videoFrameRate = frameRate;
changed = true;
}
}
return changed;
}
function applyNoiseSuppressionStandardDefaultMigrationV1(parsed: Record<string, unknown>): boolean {
if (parsed.noiseSuppressionStandardDefaultMigratedV1 === true) {
return false;
@@ -398,11 +424,10 @@ class VoiceSettings {
private listeners = new Set<() => void>();
constructor() {
makeAutoObservable<this, 'hasHigherVideoQuality' | 'listeners' | 'notifyListeners'>(
makeAutoObservable<this, 'listeners' | 'notifyListeners'>(
this,
{
listeners: false,
hasHigherVideoQuality: false,
getInputDeviceId: false,
getOutputDeviceId: false,
getVideoDeviceId: false,
@@ -494,6 +519,7 @@ class VoiceSettings {
changed = applyScreenShareContentHintDefaultMigrationV1(parsed) || changed;
changed = applyOutputVolumeRecalibrationMigrationV1(parsed) || changed;
changed = applyNoiseSuppressionStandardDefaultMigrationV1(parsed) || changed;
changed = applyVideoQualityNormalisationMigration(parsed) || changed;
changed = applyScreenShareAv1OptOutMigrationV1(parsed) || changed;
changed = applyScreenShareHevcOptOutMigrationV1(parsed) || changed;
if (changed) {
@@ -664,19 +690,6 @@ class VoiceSettings {
this.adaptiveScreenShareQualityPrefV2 = value;
}
private hasHigherVideoQuality(): boolean {
const featureFlag = isLimitToggleEnabled(
{
feature_higher_video_quality: LimitResolver.resolve({
key: 'feature_higher_video_quality',
fallback: 0,
}),
},
'feature_higher_video_quality',
);
return featureFlag;
}
getInputDeviceId(): string {
return this.inputDeviceId;
}
@@ -757,7 +770,7 @@ class VoiceSettings {
}
getCameraResolution(): CameraResolution {
if (this.cameraResolution === 'high' && !this.hasHigherVideoQuality()) {
if (this.cameraResolution === 'high' && !hasHigherVideoQuality()) {
return 'medium';
}
return this.cameraResolution;
@@ -768,14 +781,14 @@ class VoiceSettings {
}
getScreenshareResolution(): ScreenshareResolution {
if (PREMIUM_SCREENSHARE_RESOLUTIONS.has(this.screenshareResolution) && !this.hasHigherVideoQuality()) {
if (PREMIUM_SCREENSHARE_RESOLUTIONS.has(this.screenshareResolution) && !hasHigherVideoQuality()) {
return 'medium';
}
return this.screenshareResolution;
}
getVideoFrameRate(): number {
if (this.videoFrameRate > FREE_VIDEO_FRAME_RATE_MAX && !this.hasHigherVideoQuality()) {
if (this.videoFrameRate > FREE_VIDEO_FRAME_RATE_MAX && !hasHigherVideoQuality()) {
return FREE_VIDEO_FRAME_RATE_MAX;
}
return this.videoFrameRate;
@@ -1126,11 +1139,13 @@ class VoiceSettings {
if (!validVoiceProcessingModes.includes(voiceProcessingMode)) {
voiceProcessingMode = DEFAULT_VOICE_PROCESSING_MODE;
}
let cameraResolution = data.cameraResolution ?? this.cameraResolution;
let screenshareResolution = data.screenshareResolution ?? this.screenshareResolution;
let videoFrameRate = clampVideoFrameRate(data.videoFrameRate ?? this.videoFrameRate);
const cameraResolution =
data.cameraResolution === undefined ? undefined : validateCameraResolution(data.cameraResolution);
const screenshareResolution =
data.screenshareResolution === undefined ? undefined : validateScreenshareResolution(data.screenshareResolution);
const videoFrameRate = data.videoFrameRate === undefined ? undefined : clampVideoFrameRate(data.videoFrameRate);
const streamingMode = validateStreamingMode(data.streamingMode ?? this.streamingMode);
let backgroundImages = validateBackgroundImages(data.backgroundImages ?? this.backgroundImages);
const backgroundImages = validateBackgroundImages(data.backgroundImages ?? this.backgroundImages);
let backgroundImageId = data.backgroundImageId ?? this.backgroundImageId;
const screenShareEncoderMode = validateScreenShareEncoderMode(
data.screenShareEncoderMode ?? this.screenShareEncoderMode,
@@ -1146,34 +1161,6 @@ class VoiceSettings {
);
const screenShareAv1OptIn = data.screenShareAv1OptIn ?? this.screenShareAv1OptIn;
const screenShareHevcOptIn = data.screenShareHevcOptIn ?? this.screenShareHevcOptIn;
const validCameraResolutions: Array<CameraResolution> = ['low', 'medium', 'high'];
if (!validCameraResolutions.includes(cameraResolution)) {
cameraResolution = 'medium';
}
const hasHigherQuality = this.hasHigherVideoQuality();
const validScreenshareResolutions: Array<ScreenshareResolution> = [
'low_240p',
'low_480p',
'medium',
'high',
'ultra',
'source',
];
if (!validScreenshareResolutions.includes(screenshareResolution)) {
screenshareResolution = 'medium';
}
if (!hasHigherQuality) {
if (screenshareResolution === 'high' || screenshareResolution === 'ultra' || screenshareResolution === 'source') {
screenshareResolution = 'medium';
}
if (cameraResolution === 'high') {
cameraResolution = 'medium';
}
videoFrameRate = Math.min(30, videoFrameRate);
if (backgroundImages.length > 3) {
backgroundImages = backgroundImages.slice(0, 3);
}
}
if (backgroundImageId !== NONE_BACKGROUND_ID && backgroundImageId !== BLUR_BACKGROUND_ID) {
const imageExists = backgroundImages.some((img: BackgroundImage) => img.id === backgroundImageId);
if (!imageExists) {
@@ -1198,7 +1185,7 @@ class VoiceSettings {
cameraResolution,
mirrorCamera: data.mirrorCamera ?? this.mirrorCamera,
screenshareResolution,
videoFrameRate: clampVideoFrameRate(videoFrameRate),
videoFrameRate,
streamingMode,
hideStreamPreview: data.hideStreamPreview ?? this.hideStreamPreview,
muteStreamAudio: data.muteStreamAudio ?? this.muteStreamAudio,
@@ -1321,6 +1308,17 @@ function validateScreenShareContentHint(hint: unknown): ScreenShareContentHint {
: DEFAULT_SCREEN_SHARE_CONTENT_HINT;
}
function validateCameraResolution(value: unknown): CameraResolution {
return value === 'low' || value === 'medium' || value === 'high' ? value : 'medium';
}
function validateScreenshareResolution(value: unknown): ScreenshareResolution {
if (value === 'low_240p') return RETIRED_SCREENSHARE_RESOLUTION_REPLACEMENT;
return value === 'low_480p' || value === 'medium' || value === 'high' || value === 'ultra' || value === 'source'
? value
: 'medium';
}
function validateStreamingMode(mode: unknown): StreamingMode {
return mode === 'gaming' || mode === 'screenshare' || mode === 'custom' ? mode : 'screenshare';
}
@@ -20,7 +20,12 @@ const AppStorage = (await import('@app/features/platform/state/PersistentStorage
AppStorage.setItem(
'VoiceSettings',
JSON.stringify({preferredScreenShareCodec: 'av1', screenShareContentHintPrefV2: 'auto'}),
JSON.stringify({
preferredScreenShareCodec: 'av1',
screenShareContentHintPrefV2: 'auto',
screenshareResolution: 'low_240p',
__mps__: {version: 1},
}),
);
const storageWrites: Array<string> = [];
@@ -151,3 +156,42 @@ describe('screen share content hint default', () => {
expect(VoiceSettings.getScreenShareContentHintOverride()).toBeUndefined();
});
});
describe('stored video quality preferences', () => {
it('retires a stored 240p screen share preference to 480p on first launch', () => {
const migrated = JSON.parse(storageWrites[0]);
expect(migrated.screenshareResolution).toBe('low_480p');
expect(VoiceSettings.screenshareResolution).toBe('low_480p');
});
it('upgrades a retired 240p patch to 480p', () => {
VoiceSettings.updateSettings({screenshareResolution: 'low_240p'});
expect(VoiceSettings.screenshareResolution).toBe('low_480p');
});
it('keeps premium video quality choices stored while the entitlement is missing', () => {
VoiceSettings.updateSettings({screenshareResolution: 'ultra', cameraResolution: 'high', videoFrameRate: 60});
VoiceSettings.updateSettings({outputDeviceId: 'default'});
expect(VoiceSettings.screenshareResolution).toBe('ultra');
expect(VoiceSettings.cameraResolution).toBe('high');
expect(VoiceSettings.videoFrameRate).toBe(60);
});
it('still hands out free-tier video quality while the entitlement is missing', () => {
VoiceSettings.updateSettings({screenshareResolution: 'ultra', cameraResolution: 'high', videoFrameRate: 60});
expect(VoiceSettings.getScreenshareResolution()).toBe('medium');
expect(VoiceSettings.getCameraResolution()).toBe('medium');
expect(VoiceSettings.getVideoFrameRate()).toBe(30);
});
it('keeps every stored background image while the entitlement is missing', () => {
const images = [1, 2, 3, 4, 5].map((index) => ({id: `background-${index}`, createdAt: index}));
runInAction(() => {
VoiceSettings.backgroundImages = images;
});
VoiceSettings.updateSettings({outputDeviceId: 'default'});
expect(VoiceSettings.backgroundImages).toHaveLength(5);
VoiceSettings.updateSettings({backgroundImages: images.slice(0, 4)});
expect(VoiceSettings.backgroundImages).toHaveLength(4);
});
});
@@ -179,6 +179,24 @@ describe('buildScreenShareOptions', () => {
frameRate: 30,
});
});
it('starts the free-tier screenshare preset at 720p 30 fps', () => {
expect(resolveStreamingModeSettings('screenshare', 'medium', 15, false)).toEqual({
resolution: 'medium',
frameRate: 30,
});
});
it('lifts a retired free-tier 240p custom choice back to 720p', () => {
expect(resolveStreamingModeSettings('custom', 'low_240p', 30, false)).toEqual({
resolution: 'medium',
frameRate: 30,
});
});
it('keeps 480p as the lowest free-tier rung', () => {
expect(resolveStreamingModeSettings('custom', 'low_480p', 30, false)).toEqual({
resolution: 'low_480p',
frameRate: 30,
});
});
it('offers the browser picker system audio for every surface when audio is requested', () => {
const {captureOptions} = buildScreenShareOptions({
resolution: 'medium',
@@ -136,7 +136,7 @@ const FREE_STREAMING_MODE_PRESETS: Record<
}
> = {
gaming: {resolution: 'medium', frameRate: 30},
screenshare: {resolution: 'medium', frameRate: 15},
screenshare: {resolution: 'medium', frameRate: 30},
};
export interface BuiltScreenShareOptions {
@@ -222,7 +222,7 @@ export function buildScreenShareOptions(
}
const FREE_TIER_FALLBACK_RESOLUTION: ScreenshareResolution = 'medium';
const FREE_TIER_RESOLUTIONS: ReadonlyArray<ScreenshareResolution> = ['low_240p', 'low_480p', 'medium'];
const FREE_TIER_RESOLUTIONS: ReadonlyArray<ScreenshareResolution> = ['low_480p', 'medium'];
const FREE_TIER_MAX_FRAME_RATE: SupportedScreenShareFrameRate = 30;
function isFreeTierResolution(resolution: ScreenshareResolution): boolean {
@@ -248,7 +248,7 @@ export function resolveStreamingModeSettings(
mode: StreamingMode,
customResolution: ScreenshareResolution,
customFrameRate: number,
hasHigherQuality: boolean = true,
hasHigherQuality: boolean,
): {
resolution: ScreenshareResolution;
frameRate: SupportedScreenShareFrameRate;
@@ -1,10 +1,7 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {LimitResolver} from '@app/features/app/utils/LimitResolverAdapter';
import {isLimitToggleEnabled} from '@app/features/app/utils/LimitUtils';
import {Logger} from '@app/features/platform/utils/AppLogger';
import {getElectronAPI, supportsDesktopScreenShareAudioCapture} from '@app/features/ui/utils/NativeUtils';
import * as VoiceSettingsCommands from '@app/features/voice/commands/VoiceSettingsCommands';
import MediaEngine from '@app/features/voice/engine/MediaEngineFacade';
import ScreenShareCodecNegotiation from '@app/features/voice/engine/ScreenShareCodecNegotiation';
import ActiveScreenShareSource from '@app/features/voice/state/ActiveScreenShareSource';
@@ -49,6 +46,7 @@ import {
ScreenSharePortalUnavailableError,
} from '@app/features/voice/utils/ScreenSharePortalUnavailableError';
import {executeScreenShareOperation} from '@app/features/voice/utils/ScreenShareUtils';
import {hasHigherVideoQuality} from '@app/features/voice/utils/VideoQualityEntitlement';
import type {NativeAudioStartOptions, VirtmicNode} from '@app/types/electron.d';
import type {ScreenShareCaptureOptions, VideoCodec} from 'livekit-client';
@@ -152,18 +150,6 @@ export async function stopActiveLinuxScreenShareAudioLink(): Promise<boolean> {
return true;
}
function hasHigherVideoQuality(): boolean {
return isLimitToggleEnabled(
{
feature_higher_video_quality: LimitResolver.resolve({
key: 'feature_higher_video_quality',
fallback: 0,
}),
},
'feature_higher_video_quality',
);
}
function didScreenShareStart(): boolean {
return Boolean(MediaEngine.room?.localParticipant?.isScreenShareEnabled || LocalVoiceState.getSelfStream());
}
@@ -177,25 +163,6 @@ function getScreenShareContentSource(
return 'display';
}
export function normaliseDeviceScreenShareSettings(): void {
const nextStreamingMode = normaliseStreamingModeForContext(VoiceSettings.getStreamingMode(), 'device');
const nextResolution = normaliseResolutionForContext(
VoiceSettings.getScreenshareResolution(),
'device',
hasHigherVideoQuality(),
);
if (
nextStreamingMode === VoiceSettings.getStreamingMode() &&
nextResolution === VoiceSettings.getScreenshareResolution()
) {
return;
}
VoiceSettingsCommands.update({
streamingMode: nextStreamingMode,
screenshareResolution: nextResolution,
});
}
function shouldIncludeAudioForShare(
shareContext: ScreenShareContext,
displayShareEnvironment: DisplayShareEnvironment,
@@ -695,7 +662,6 @@ export async function switchConfiguredDisplayScreenShare(
export async function startConfiguredDeviceScreenShare(videoDeviceId: string): Promise<boolean> {
return scheduleConfiguredScreenShareMutation(async () => {
normaliseDeviceScreenShareSettings();
const {captureOptions, publishOptions, includeAudio, audioDeviceId} = getConfiguredScreenShareOptions(
'device',
'desktop-custom',
@@ -723,7 +689,6 @@ export async function startConfiguredDeviceScreenShare(videoDeviceId: string): P
export async function switchConfiguredDeviceScreenShare(videoDeviceId: string): Promise<boolean> {
return scheduleConfiguredScreenShareMutation(async () => {
normaliseDeviceScreenShareSettings();
const {captureOptions, publishOptions, includeAudio, audioDeviceId} = getConfiguredScreenShareOptions(
'device',
'desktop-custom',
@@ -1,8 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import Config from '@app/features/app/config/Config';
import {LimitResolver} from '@app/features/app/utils/LimitResolverAdapter';
import {isLimitToggleEnabled} from '@app/features/app/utils/LimitUtils';
import {
getCachedDesktopTroubleshootingSettings,
getDesktopTroubleshootingSettings,
@@ -36,6 +34,7 @@ import {
} from '@app/features/voice/utils/NativeAudioCaptureBridge';
import {getDisplayShareEnvironment} from '@app/features/voice/utils/ScreenShareEnvironment';
import {getScreenShareBitrateBps, resolveStreamingModeSettings} from '@app/features/voice/utils/ScreenShareOptions';
import {hasHigherVideoQuality} from '@app/features/voice/utils/VideoQualityEntitlement';
import {
buildVoiceStatsForNerdsPresentation,
type StatsForNerdsData,
@@ -461,18 +460,6 @@ async function collectDesktopMetadata(): Promise<Record<string, unknown>> {
};
}
function hasHigherVideoQuality(): boolean {
return isLimitToggleEnabled(
{
feature_higher_video_quality: LimitResolver.resolve({
key: 'feature_higher_video_quality',
fallback: 0,
}),
},
'feature_higher_video_quality',
);
}
export function collectStatsForNerdsSnapshot(): StatsForNerdsData {
const adaptiveQualitySnapshot = AdaptiveScreenShareEngine.qualitySnapshot;
const effectiveScreenShareSettings = resolveStreamingModeSettings(
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {LimitResolver} from '@app/features/app/utils/LimitResolverAdapter';
import {isLimitToggleEnabled} from '@app/features/app/utils/LimitUtils';
export function hasHigherVideoQuality(): boolean {
return isLimitToggleEnabled(
{
feature_higher_video_quality: LimitResolver.resolve({
key: 'feature_higher_video_quality',
fallback: 0,
}),
},
'feature_higher_video_quality',
);
}