diff --git a/fluxer_app/src/features/user/components/modals/tabs/AdvancedSettingDirectControls.tsx b/fluxer_app/src/features/user/components/modals/tabs/AdvancedSettingDirectControls.tsx
index 126dc858f..8836a224d 100644
--- a/fluxer_app/src/features/user/components/modals/tabs/AdvancedSettingDirectControls.tsx
+++ b/fluxer_app/src/features/user/components/modals/tabs/AdvancedSettingDirectControls.tsx
@@ -42,8 +42,10 @@ import {UnreadBadgeCustomizationControl} from '@app/features/user/components/mod
import {
EmulatedDecodeCodecCapControl,
OpenH264Control,
+ ScreenShareAv1OptInControl,
ScreenShareCodecControl,
ScreenShareEncoderControls,
+ ScreenShareHevcOptInControl,
ScreenSharePreviewBehaviorControl,
} from '@app/features/user/components/modals/tabs/advanced_settings_tab/AdvancedVideoControls';
import {
@@ -83,6 +85,8 @@ export const DIRECT_CONTROL_ITEM_IDS = new Set([
'voice-video-new-device-alerts',
'voice-video-connection-volume-controls',
'voice-video-screen-share-codec',
+ 'voice-video-screen-share-av1-opt-in',
+ 'voice-video-screen-share-hevc-opt-in',
'voice-video-emulated-decode-codec-cap',
'voice-video-openh264-codec',
'voice-video-screen-share-preview-behavior',
@@ -96,7 +100,6 @@ export const DIRECT_CONTROL_ITEM_IDS = new Set([
export const FULL_WIDTH_CONTROL_ITEM_IDS = new Set([
'appearance-voice-channel-join-behavior',
- 'voice-video-screen-share-codec',
'voice-video-screen-share-preview-behavior',
]);
@@ -122,6 +125,8 @@ export const COMPACT_SWITCH_CONTROL_ITEM_IDS = new Set([
'voice-video-new-device-alerts',
'voice-video-connection-volume-controls',
'voice-video-openh264-codec',
+ 'voice-video-screen-share-av1-opt-in',
+ 'voice-video-screen-share-hevc-opt-in',
'advanced-unread-badge-customization',
'client-developer-mode',
'accessibility-stay-interactive-unfocused',
@@ -268,6 +273,14 @@ export const AdvancedSettingControl = observer(({item}: {item: SearchableSetting
return (
);
+ case 'voice-video-screen-share-av1-opt-in':
+ return (
+
+ );
+ case 'voice-video-screen-share-hevc-opt-in':
+ return (
+
+ );
case 'voice-video-emulated-decode-codec-cap':
return (
diff --git a/fluxer_app/src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedVideoControls.tsx b/fluxer_app/src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedVideoControls.tsx
index 51ce13a5a..f6a732cf7 100644
--- a/fluxer_app/src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedVideoControls.tsx
+++ b/fluxer_app/src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedVideoControls.tsx
@@ -11,7 +11,6 @@ import {SwitchGroup, SwitchGroupItem} from '@app/features/ui/components/SwitchGr
import PiP from '@app/features/ui/state/PiP';
import {getElectronAPI, isDesktop} from '@app/features/ui/utils/NativeUtils';
import styles from '@app/features/user/components/modals/tabs/AdvancedSettingsTab.module.css';
-import {CodecSelectorSection} from '@app/features/user/components/modals/tabs/components/CodecSelectorSection';
import {CompactComboboxRow} from '@app/features/user/components/modals/tabs/components/CompactComboboxRow';
import PrivacyPreferences from '@app/features/user/state/PrivacyPreferences';
import * as VoiceSettingsCommands from '@app/features/voice/commands/VoiceSettingsCommands';
@@ -24,12 +23,18 @@ import type {
ScreenShareScalabilityModePreference,
ScreenShareSoftwareQuality,
} from '@app/features/voice/utils/CodecCapabilityDetector';
+import {
+ getCodecCapabilityReport,
+ selectAutomaticScreenShareCodec,
+} from '@app/features/voice/utils/CodecCapabilityDetector';
+import {getGpuEncoderReportSync, loadGpuEncoderReport} from '@app/features/voice/utils/GpuEncoderCapabilities';
import {setOpenH264Enabled} from '@app/features/voice/utils/OpenH264Status';
+import {CODEC_DISPLAY_LABEL} from '@app/features/voice/utils/ScreenShareCodecPolicy';
import {msg} from '@lingui/core/macro';
import {useLingui} from '@lingui/react/macro';
import {GearIcon} from '@phosphor-icons/react';
import {observer} from 'mobx-react-lite';
-import {useCallback, useEffect} from 'react';
+import {useCallback, useEffect, useState} from 'react';
const OPENH264_LABEL_DESCRIPTOR = msg({
message: 'OpenH264 Video Codec provided by Cisco Systems, Inc.',
@@ -210,9 +215,104 @@ const resolveScreenShareBitrateInput = (
return getNearestNumericOptionValue(valueInMbps, options);
};
-export const ScreenShareCodecControl = observer(() => (
-
-));
+const PREFERRED_SCREEN_SHARE_CODEC_DESCRIPTOR = msg({
+ message: 'Preferred screen share codec',
+ comment: 'Accessible label for the advanced screen-share codec preference select.',
+});
+const AUTOMATIC_CODEC_OPTION_DESCRIPTOR = msg({
+ message: 'Automatic ({codec})',
+ comment: 'Option label for the screen-share codec select. codec is the automatically selected codec label.',
+});
+const AV1_REQUIRES_OPT_IN_OPTION_DESCRIPTOR = msg({
+ message: 'AV1 (requires opt-in)',
+ comment:
+ 'Option label for the screen-share codec select while the AV1 opt-in is off and the option is disabled. AV1 is a codec name and should stay literal.',
+});
+const H265_REQUIRES_OPT_IN_OPTION_DESCRIPTOR = msg({
+ message: 'H.265 (requires opt-in)',
+ comment:
+ 'Option label for the screen-share codec select while the HEVC opt-in is off and the option is disabled. H.265 is a codec name and should stay literal.',
+});
+const AV1_SCREEN_SHARE_OPT_IN_DESCRIPTOR = msg({
+ message: 'Allow AV1 for screen sharing',
+ comment: 'Switch label for the AV1 screen-share opt-in. AV1 is a codec name and should stay literal.',
+});
+const HEVC_SCREEN_SHARE_OPT_IN_DESCRIPTOR = msg({
+ message: 'Allow H.265 (HEVC) for screen sharing',
+ comment:
+ 'Switch label for the H.265/HEVC screen-share opt-in. H.265 and HEVC are codec names and should stay literal.',
+});
+const SCREEN_SHARE_CODEC_OPTION_ORDER = ['av1', 'h265', 'h264', 'vp9', 'vp8'] as const;
+
+export const ScreenShareCodecControl = observer(() => {
+ const {i18n} = useLingui();
+ const encoderMode = VoiceSettings.getScreenShareEncoderMode();
+ const [gpuReport, setGpuReport] = useState(() => getGpuEncoderReportSync());
+ useEffect(() => {
+ if (gpuReport) return;
+ let cancelled = false;
+ void loadGpuEncoderReport().then((report) => {
+ if (!cancelled) setGpuReport(report);
+ });
+ return () => {
+ cancelled = true;
+ };
+ }, [gpuReport]);
+ const automaticCodec = selectAutomaticScreenShareCodec(encoderMode).codec;
+ const av1OptIn = VoiceSettings.getScreenShareAv1OptIn();
+ const hevcOptIn = VoiceSettings.getScreenShareHevcOptIn();
+ const codecCapabilities = getCodecCapabilityReport();
+ const options: ReadonlyArray> = [
+ {value: 'auto', label: i18n._(AUTOMATIC_CODEC_OPTION_DESCRIPTOR, {codec: CODEC_DISPLAY_LABEL[automaticCodec]})},
+ ...SCREEN_SHARE_CODEC_OPTION_ORDER.map((codec) => ({
+ value: codec,
+ label:
+ codec === 'av1' && !av1OptIn
+ ? i18n._(AV1_REQUIRES_OPT_IN_OPTION_DESCRIPTOR)
+ : codec === 'h265' && !hevcOptIn
+ ? i18n._(H265_REQUIRES_OPT_IN_OPTION_DESCRIPTOR)
+ : CODEC_DISPLAY_LABEL[codec],
+ isDisabled: !codecCapabilities[codec].supported,
+ })),
+ ];
+ return (
+
+ value={VoiceSettings.getPreferredScreenShareCodec()}
+ options={options}
+ onChange={(value) => VoiceSettingsCommands.update({preferredScreenShareCodec: value})}
+ density="compact"
+ isSearchable={false}
+ aria-label={i18n._(PREFERRED_SCREEN_SHARE_CODEC_DESCRIPTOR)}
+ data-flx="user.advanced-settings-tab.select.preferred-screen-share-codec"
+ />
+ );
+});
+
+export const ScreenShareAv1OptInControl = observer(() => {
+ const {i18n} = useLingui();
+ return (
+ VoiceSettingsCommands.update({screenShareAv1OptIn: value})}
+ compact
+ data-flx="user.advanced-settings-tab.switch.screen-share-av1-opt-in"
+ />
+ );
+});
+
+export const ScreenShareHevcOptInControl = observer(() => {
+ const {i18n} = useLingui();
+ return (
+ VoiceSettingsCommands.update({screenShareHevcOptIn: value})}
+ compact
+ data-flx="user.advanced-settings-tab.switch.screen-share-hevc-opt-in"
+ />
+ );
+});
export const EmulatedDecodeCodecCapControl = observer(() => {
const {i18n} = useLingui();
diff --git a/fluxer_app/src/features/user/components/modals/tabs/components/CodecSelectorDescription.ts b/fluxer_app/src/features/user/components/modals/tabs/components/CodecSelectorDescription.ts
deleted file mode 100644
index c646502fa..000000000
--- a/fluxer_app/src/features/user/components/modals/tabs/components/CodecSelectorDescription.ts
+++ /dev/null
@@ -1,167 +0,0 @@
-// SPDX-License-Identifier: AGPL-3.0-or-later
-
-import type {AutomaticScreenShareCodecSelection} from '@app/features/voice/utils/CodecCapabilityDetector';
-import {CODEC_DISPLAY_LABEL} from '@app/features/voice/utils/ScreenShareCodecPolicy';
-import type {I18n} from '@lingui/core';
-import {msg} from '@lingui/core/macro';
-
-const AUTO_DESCRIPTION_FIREFOX_VP8_DESCRIPTOR = msg({
- message: 'Automatic would use {codecName} because Firefox screen sharing works most reliably with it.',
- comment:
- 'Description shown under the Automatic option in the screen-share codec radio group. {codecName} is a codec label such as VP8 and should not be translated. Keep Firefox as a product name.',
-});
-const AUTO_DESCRIPTION_NON_CHROMIUM_H264_DESCRIPTOR = msg({
- message:
- 'Automatic would use {codecName} because this browser supports it and it is the best fallback outside Chromium.',
- comment:
- 'Description shown under the Automatic option in the screen-share codec radio group. {codecName} is a codec label such as H.264 and should not be translated. Keep Chromium as a product name.',
-});
-const AUTO_DESCRIPTION_DESKTOP_NON_CHROMIUM_H264_DESCRIPTOR = msg({
- message:
- 'Automatic would use {codecName} because your computer supports it and it is the best fallback outside Chromium.',
- comment:
- 'Desktop-client description shown under the Automatic option in the screen-share codec radio group. {codecName} is a codec label such as H.264 and should not be translated. Keep Chromium as a product name.',
-});
-const AUTO_DESCRIPTION_NON_CHROMIUM_VP8_DESCRIPTOR = msg({
- message: 'Automatic would use {codecName} because this browser does not expose H.264, so VP8 is the safest fallback.',
- comment:
- 'Description shown under the Automatic option in the screen-share codec radio group. {codecName} is a codec label such as VP8 and should not be translated. Keep codec names literal.',
-});
-const AUTO_DESCRIPTION_DESKTOP_NON_CHROMIUM_VP8_DESCRIPTOR = msg({
- message:
- 'Automatic would use {codecName} because your computer does not expose H.264, so VP8 is the safest fallback.',
- comment:
- 'Desktop-client description shown under the Automatic option in the screen-share codec radio group. {codecName} is a codec label such as VP8 and should not be translated. Keep codec names literal.',
-});
-const AUTO_DESCRIPTION_HARDWARE_AV1_DESCRIPTOR = msg({
- message:
- 'Automatic would use {codecName} because your GPU can encode it in hardware, with the best compression for screen sharing.',
- comment:
- 'Description shown under the Automatic option in the screen-share codec radio group. {codecName} is a codec label such as AV1 and should not be translated. Keep GPU as an acronym.',
-});
-const AUTO_DESCRIPTION_HARDWARE_H264_DESCRIPTOR = msg({
- message:
- 'Automatic would use {codecName} because your GPU can encode it in hardware and it is the most compatible screen-share default.',
- comment:
- 'Description shown under the Automatic option in the screen-share codec radio group. {codecName} is a codec label such as H.264 and should not be translated. Keep GPU as an acronym.',
-});
-const AUTO_DESCRIPTION_HARDWARE_H265_DESCRIPTOR = msg({
- message:
- 'Automatic would use {codecName} because your GPU can encode it in hardware, with excellent compression and low CPU usage.',
- comment:
- 'Description shown under the Automatic option in the screen-share codec radio group. {codecName} is a codec label such as H.265 and should not be translated. Keep GPU as an acronym.',
-});
-const AUTO_DESCRIPTION_HARDWARE_VP9_DESCRIPTOR = msg({
- message:
- 'Automatic would use {codecName} because your GPU can encode it in hardware and it gives strong screen-share quality.',
- comment:
- 'Description shown under the Automatic option in the screen-share codec radio group. {codecName} is a codec label such as VP9 and should not be translated. Keep GPU as an acronym.',
-});
-const AUTO_DESCRIPTION_SOFTWARE_AV1_DESCRIPTOR = msg({
- message: 'Automatic would use {codecName} because software encoding is preferred and this browser exposes AV1.',
- comment:
- 'Description shown under the Automatic option in the screen-share codec radio group. {codecName} is a codec label such as AV1 and should not be translated.',
-});
-const AUTO_DESCRIPTION_DESKTOP_SOFTWARE_AV1_DESCRIPTOR = msg({
- message: 'Automatic would use {codecName} because software encoding is preferred and your computer exposes AV1.',
- comment:
- 'Desktop-client description shown under the Automatic option in the screen-share codec radio group. {codecName} is a codec label such as AV1 and should not be translated.',
-});
-const AUTO_DESCRIPTION_SOFTWARE_H265_DESCRIPTOR = msg({
- message: 'Automatic would use {codecName} because no hardware encoder is available and this browser exposes H.265.',
- comment:
- 'Description shown under the Automatic option in the screen-share codec radio group. {codecName} is a codec label such as H.265 and should not be translated.',
-});
-const AUTO_DESCRIPTION_DESKTOP_SOFTWARE_H265_DESCRIPTOR = msg({
- message: 'Automatic would use {codecName} because no hardware encoder is available and your computer exposes H.265.',
- comment:
- 'Desktop-client description shown under the Automatic option in the screen-share codec radio group. {codecName} is a codec label such as H.265 and should not be translated.',
-});
-const AUTO_DESCRIPTION_SOFTWARE_VP9_DESCRIPTOR = msg({
- message: 'Automatic would use {codecName} because software encoding is preferred and this browser exposes VP9.',
- comment:
- 'Description shown under the Automatic option in the screen-share codec radio group. {codecName} is a codec label such as VP9 and should not be translated.',
-});
-const AUTO_DESCRIPTION_DESKTOP_SOFTWARE_VP9_DESCRIPTOR = msg({
- message: 'Automatic would use {codecName} because software encoding is preferred and your computer exposes VP9.',
- comment:
- 'Desktop-client description shown under the Automatic option in the screen-share codec radio group. {codecName} is a codec label such as VP9 and should not be translated.',
-});
-const AUTO_DESCRIPTION_SOFTWARE_H264_DESCRIPTOR = msg({
- message: 'Automatic would use {codecName} because no higher-quality encoder is available and H.264 is compatible.',
- comment:
- 'Description shown under the Automatic option in the screen-share codec radio group. {codecName} is a codec label such as H.264 and should not be translated.',
-});
-const AUTO_DESCRIPTION_SOFTWARE_VP8_DESCRIPTOR = msg({
- message:
- 'Automatic would use {codecName} because software encoding is preferred and VP8 is the safest software fallback.',
- comment:
- 'Description shown under the Automatic option in the screen-share codec radio group. {codecName} is a codec label such as VP8 and should not be translated.',
-});
-const AUTO_DESCRIPTION_OPENH264_REQUIRED_DESCRIPTOR = msg({
- message:
- 'Automatic would use {codecName} because no video encoder is exposed. On Linux, OpenH264 may need to be installed.',
- comment:
- 'Description shown under the Automatic option in the screen-share codec radio group. {codecName} is a codec label such as H.264 and should not be translated. Keep OpenH264 and Linux literal.',
-});
-
-export function getAutomaticDescription(
- i18n: I18n,
- selection: AutomaticScreenShareCodecSelection,
- options: {isDesktopClient?: boolean} = {},
-): string {
- const codecName = CODEC_DISPLAY_LABEL[selection.codec];
- switch (selection.reason) {
- case 'firefox-vp8':
- return i18n._(AUTO_DESCRIPTION_FIREFOX_VP8_DESCRIPTOR, {codecName});
- case 'non-chromium-h264':
- return i18n._(
- options.isDesktopClient
- ? AUTO_DESCRIPTION_DESKTOP_NON_CHROMIUM_H264_DESCRIPTOR
- : AUTO_DESCRIPTION_NON_CHROMIUM_H264_DESCRIPTOR,
- {codecName},
- );
- case 'non-chromium-vp8':
- return i18n._(
- options.isDesktopClient
- ? AUTO_DESCRIPTION_DESKTOP_NON_CHROMIUM_VP8_DESCRIPTOR
- : AUTO_DESCRIPTION_NON_CHROMIUM_VP8_DESCRIPTOR,
- {codecName},
- );
- case 'hardware-av1':
- return i18n._(AUTO_DESCRIPTION_HARDWARE_AV1_DESCRIPTOR, {codecName});
- case 'hardware-h265':
- return i18n._(AUTO_DESCRIPTION_HARDWARE_H265_DESCRIPTOR, {codecName});
- case 'hardware-h264':
- return i18n._(AUTO_DESCRIPTION_HARDWARE_H264_DESCRIPTOR, {codecName});
- case 'hardware-vp9':
- return i18n._(AUTO_DESCRIPTION_HARDWARE_VP9_DESCRIPTOR, {codecName});
- case 'software-av1':
- return i18n._(
- options.isDesktopClient
- ? AUTO_DESCRIPTION_DESKTOP_SOFTWARE_AV1_DESCRIPTOR
- : AUTO_DESCRIPTION_SOFTWARE_AV1_DESCRIPTOR,
- {codecName},
- );
- case 'software-h265':
- return i18n._(
- options.isDesktopClient
- ? AUTO_DESCRIPTION_DESKTOP_SOFTWARE_H265_DESCRIPTOR
- : AUTO_DESCRIPTION_SOFTWARE_H265_DESCRIPTOR,
- {codecName},
- );
- case 'software-vp9':
- return i18n._(
- options.isDesktopClient
- ? AUTO_DESCRIPTION_DESKTOP_SOFTWARE_VP9_DESCRIPTOR
- : AUTO_DESCRIPTION_SOFTWARE_VP9_DESCRIPTOR,
- {codecName},
- );
- case 'software-h264':
- return i18n._(AUTO_DESCRIPTION_SOFTWARE_H264_DESCRIPTOR, {codecName});
- case 'software-vp8':
- return i18n._(AUTO_DESCRIPTION_SOFTWARE_VP8_DESCRIPTOR, {codecName});
- case 'openh264-required':
- return i18n._(AUTO_DESCRIPTION_OPENH264_REQUIRED_DESCRIPTOR, {codecName});
- }
-}
diff --git a/fluxer_app/src/features/user/components/modals/tabs/components/CodecSelectorSection.module.css b/fluxer_app/src/features/user/components/modals/tabs/components/CodecSelectorSection.module.css
deleted file mode 100644
index 1cafbe124..000000000
--- a/fluxer_app/src/features/user/components/modals/tabs/components/CodecSelectorSection.module.css
+++ /dev/null
@@ -1,62 +0,0 @@
-/* SPDX-License-Identifier: AGPL-3.0-or-later */
-
-.codecPicker {
- display: flex;
- flex-direction: column;
- gap: 0.5rem;
-}
-
-.codecRadioGroup {
- gap: 0.25rem;
-}
-
-.codecLabelRow {
- display: flex;
- align-items: center;
- gap: 0.5rem;
- min-width: 0;
-}
-
-.codecLabel {
- color: var(--text-primary);
- font-size: 0.9375rem;
- font-weight: 500;
- line-height: 1.4;
-}
-
-.codecBadge {
- flex: 0 0 auto;
- border-radius: 62.4375rem;
- padding: 0.0625rem 0.5rem;
- background-color: var(--background-modifier-accent);
- color: var(--text-primary-muted);
- font-size: 0.6875rem;
- font-weight: 600;
- line-height: 1.1rem;
- text-transform: uppercase;
- letter-spacing: 0.04em;
- border: 0.0625rem solid transparent;
-}
-
-.codecBadgeRecommended {
- background-color: var(--brand-primary);
- color: white;
- border-color: var(--brand-primary);
-}
-
-.codecHint {
- margin: 0;
- color: var(--status-warning);
- font-size: 0.8125rem;
- line-height: 1.35;
-}
-
-.codecAdvancedLink {
- padding: 0;
- border: 0;
- background: transparent;
- color: inherit;
- cursor: pointer;
- font: inherit;
- text-decoration: underline;
-}
diff --git a/fluxer_app/src/features/user/components/modals/tabs/components/CodecSelectorSection.tsx b/fluxer_app/src/features/user/components/modals/tabs/components/CodecSelectorSection.tsx
deleted file mode 100644
index 75d8f63c8..000000000
--- a/fluxer_app/src/features/user/components/modals/tabs/components/CodecSelectorSection.tsx
+++ /dev/null
@@ -1,148 +0,0 @@
-// SPDX-License-Identifier: AGPL-3.0-or-later
-
-import {
- getCachedDesktopTroubleshootingSettings,
- getDesktopTroubleshootingSettings,
-} from '@app/features/devtools/utils/DesktopTroubleshootingUtils';
-import {ComponentBus} from '@app/features/platform/utils/ComponentBus';
-import type {RadioOption} from '@app/features/ui/radio_group/RadioGroup';
-import {RadioGroup} from '@app/features/ui/radio_group/RadioGroup';
-import {isDesktop} from '@app/features/ui/utils/NativeUtils';
-import styles from '@app/features/user/components/modals/tabs/components/CodecSelectorSection.module.css';
-import {getUserSettingsTabLabel} from '@app/features/user/components/settings_utils/SettingsConstants';
-import * as VoiceSettingsCommands from '@app/features/voice/commands/VoiceSettingsCommands';
-import VoiceSettings from '@app/features/voice/state/VoiceSettings';
-import {
- type CodecPreference,
- getCodecCapabilityReport,
- getLiveKitSupportedCodecs,
- selectAutomaticScreenShareCodec,
-} from '@app/features/voice/utils/CodecCapabilityDetector';
-import {
- getGpuEncoderReportSync,
- type HardwareEncodeReport,
- loadGpuEncoderReport,
-} from '@app/features/voice/utils/GpuEncoderCapabilities';
-import {CODEC_DISPLAY_LABEL} from '@app/features/voice/utils/ScreenShareCodecPolicy';
-import {msg} from '@lingui/core/macro';
-import {Trans, useLingui} from '@lingui/react/macro';
-import {clsx} from 'clsx';
-import {observer} from 'mobx-react-lite';
-import {useCallback, useEffect, useMemo, useState} from 'react';
-import {getAutomaticDescription} from './CodecSelectorDescription';
-
-const AUTO_DESCRIPTOR = msg({
- message: 'Automatic',
- comment: 'Label for the auto codec option in the screen-share codec radio group. Keep it concise.',
-});
-const RECOMMENDED_DESCRIPTOR = msg({
- message: 'Recommended',
- comment: 'Badge shown next to the auto codec option in the screen-share codec radio group. Keep it concise.',
-});
-const SCREEN_SHARE_VIDEO_CODEC_DESCRIPTOR = msg({
- message: 'Screen share video codec',
- comment: 'Accessible label for the screen-share codec radio group.',
-});
-
-interface CodecRadioOption extends RadioOption {
- value: CodecPreference;
-}
-
-export const CodecSelectorSection = observer(() => {
- const {i18n} = useLingui();
- const isDesktopClient = isDesktop();
- const advancedSettingsLabel = getUserSettingsTabLabel(i18n, 'advanced_settings');
- const preference = VoiceSettings.getPreferredScreenShareCodec();
- const encoderMode = VoiceSettings.getScreenShareEncoderMode();
- const [gpuReport, setGpuReport] = useState(() => getGpuEncoderReportSync());
- const [hardwareAccelDisabled, setHardwareAccelDisabled] = useState(
- () => getCachedDesktopTroubleshootingSettings()?.disableHardwareAcceleration ?? null,
- );
- useEffect(() => {
- if (gpuReport) return;
- let cancelled = false;
- void loadGpuEncoderReport().then((report) => {
- if (!cancelled) setGpuReport(report);
- });
- return () => {
- cancelled = true;
- };
- }, [gpuReport]);
- useEffect(() => {
- if (!isDesktopClient || hardwareAccelDisabled !== null) return;
- let cancelled = false;
- void getDesktopTroubleshootingSettings().then((settings) => {
- if (!cancelled && settings) setHardwareAccelDisabled(settings.disableHardwareAcceleration);
- });
- return () => {
- cancelled = true;
- };
- }, [hardwareAccelDisabled, isDesktopClient]);
- const report = useMemo(() => getCodecCapabilityReport(), [gpuReport, hardwareAccelDisabled]);
- const liveKitCodecs = useMemo(() => getLiveKitSupportedCodecs(), []);
- const automaticSelection = useMemo(
- () => selectAutomaticScreenShareCodec(encoderMode),
- [encoderMode, gpuReport, hardwareAccelDisabled],
- );
- const options = useMemo>(() => {
- const autoOption: CodecRadioOption = {
- value: 'auto',
- name: (
-