mirror of
https://github.com/vector-im/element-call.git
synced 2026-08-20 20:49:20 +00:00
feat: add user-configurable screen share quality settings UI
Adds a "Screen sharing" section to Settings > Video with controls for: - Resolution (576p to 4K) - Framerate (5-60 fps slider) - Bitrate (0.5-15 Mbps slider) - Codec (VP8/VP9/H.264/AV1) Gated behind an "Advanced screen share settings" toggle. When enabled, settings are passed to LiveKit's setScreenShareEnabled as both capture constraints and publish options. When disabled, falls back to config.json media_quality defaults. Settings are persisted in localStorage via the existing Setting<T> system. The Slider component is extended with a tooltipFormatter prop for custom tooltip display. Inspired by pirosuki's advanced-screen-share-settings branch, but reimplemented cleanly: settings are read directly in LocalMember.ts (no signature changes), the existing Slider is extended (no component duplication), and proper form components are used throughout. Signed-off-by: Ryan Emmick <ryanemmick4@gmail.com>
This commit is contained in:
@@ -24,6 +24,12 @@ import {
|
||||
soundEffectVolume as soundEffectVolumeSetting,
|
||||
backgroundBlur as backgroundBlurSetting,
|
||||
developerMode,
|
||||
advancedScreenShare as advancedScreenShareSetting,
|
||||
screenShareResolution as screenShareResolutionSetting,
|
||||
screenShareFramerate as screenShareFramerateSetting,
|
||||
screenShareBitrate as screenShareBitrateSetting,
|
||||
screenShareCodec as screenShareCodecSetting,
|
||||
type VideoCodec,
|
||||
} from "./settings";
|
||||
import { PreferencesSettingsTab } from "./PreferencesSettingsTab";
|
||||
import { Slider } from "../Slider";
|
||||
@@ -98,6 +104,110 @@ export const SettingsModal: FC<Props> = ({
|
||||
);
|
||||
};
|
||||
|
||||
const ScreenShareSettings: React.FC = (): ReactNode => {
|
||||
const [advancedEnabled, setAdvancedEnabled] = useSetting(
|
||||
advancedScreenShareSetting,
|
||||
);
|
||||
const [resolution, setResolution] = useSetting(
|
||||
screenShareResolutionSetting,
|
||||
);
|
||||
const [framerate, setFramerate] = useSetting(screenShareFramerateSetting);
|
||||
const [framerateRaw, setFramerateRaw] = useState(framerate);
|
||||
const [bitrate, setBitrate] = useSetting(screenShareBitrateSetting);
|
||||
const [bitrateRaw, setBitrateRaw] = useState(bitrate);
|
||||
const [codec, setCodec] = useSetting(screenShareCodecSetting);
|
||||
|
||||
return (
|
||||
<>
|
||||
<h4>{t("settings.screen_share_header", "Screen sharing")}</h4>
|
||||
<FieldRow>
|
||||
<InputField
|
||||
id="advancedScreenShare"
|
||||
label={t(
|
||||
"settings.advanced_screen_share_label",
|
||||
"Advanced screen share settings",
|
||||
)}
|
||||
description={t(
|
||||
"settings.advanced_screen_share_description",
|
||||
"Configure resolution, framerate, bitrate, and codec for screen sharing",
|
||||
)}
|
||||
type="checkbox"
|
||||
checked={advancedEnabled}
|
||||
onChange={(e): void => setAdvancedEnabled(e.target.checked)}
|
||||
/>
|
||||
</FieldRow>
|
||||
{advancedEnabled && (
|
||||
<>
|
||||
<FieldRow>
|
||||
<InputField
|
||||
id="screenShareResolution"
|
||||
label={t(
|
||||
"settings.screen_share_resolution_label",
|
||||
"Resolution",
|
||||
)}
|
||||
type="select"
|
||||
value={resolution}
|
||||
onChange={(e): void => setResolution(e.target.value)}
|
||||
>
|
||||
<option value="1024x576">576p</option>
|
||||
<option value="1280x720">720p</option>
|
||||
<option value="1920x1080">1080p</option>
|
||||
<option value="2560x1440">1440p</option>
|
||||
<option value="3840x2160">4K</option>
|
||||
</InputField>
|
||||
</FieldRow>
|
||||
<div className={styles.volumeSlider}>
|
||||
<label>
|
||||
{t("settings.screen_share_framerate_label", "Framerate")}
|
||||
</label>
|
||||
<Slider
|
||||
label={t("settings.screen_share_framerate_label", "Framerate")}
|
||||
value={framerateRaw}
|
||||
onValueChange={setFramerateRaw}
|
||||
onValueCommit={setFramerate}
|
||||
min={5}
|
||||
max={60}
|
||||
step={5}
|
||||
tooltipFormatter={(v): string => `${v} fps`}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.volumeSlider}>
|
||||
<label>
|
||||
{t("settings.screen_share_bitrate_label", "Bitrate")}
|
||||
</label>
|
||||
<Slider
|
||||
label={t("settings.screen_share_bitrate_label", "Bitrate")}
|
||||
value={bitrateRaw}
|
||||
onValueChange={setBitrateRaw}
|
||||
onValueCommit={setBitrate}
|
||||
min={500_000}
|
||||
max={15_000_000}
|
||||
step={500_000}
|
||||
tooltipFormatter={(v): string =>
|
||||
`${(v / 1_000_000).toFixed(1)} Mbps`
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<FieldRow>
|
||||
<InputField
|
||||
id="screenShareCodec"
|
||||
label={t("settings.screen_share_codec_label", "Codec")}
|
||||
type="select"
|
||||
value={codec}
|
||||
onChange={(e): void => setCodec(e.target.value as VideoCodec)}
|
||||
>
|
||||
<option value="vp8">VP8</option>
|
||||
<option value="vp9">VP9</option>
|
||||
<option value="h264">H.264</option>
|
||||
<option value="av1">AV1</option>
|
||||
</InputField>
|
||||
</FieldRow>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const devices = useMediaDevices();
|
||||
useEffect(() => {
|
||||
if (open) devices.requestDeviceNames();
|
||||
@@ -183,6 +293,8 @@ export const SettingsModal: FC<Props> = ({
|
||||
</Form>
|
||||
<Separator />
|
||||
<BlurCheckbox />
|
||||
<Separator />
|
||||
<ScreenShareSettings />
|
||||
</>
|
||||
),
|
||||
};
|
||||
|
||||
@@ -150,3 +150,30 @@ export const customLivekitUrl = new Setting<string | null>(
|
||||
"custom-livekit-url",
|
||||
null,
|
||||
);
|
||||
|
||||
export type VideoCodec = "vp8" | "vp9" | "h264" | "av1";
|
||||
|
||||
export const advancedScreenShare = new Setting<boolean>(
|
||||
"advanced-screen-share",
|
||||
false,
|
||||
);
|
||||
|
||||
export const screenShareResolution = new Setting<string>(
|
||||
"screen-share-resolution",
|
||||
"1920x1080",
|
||||
);
|
||||
|
||||
export const screenShareFramerate = new Setting<number>(
|
||||
"screen-share-framerate",
|
||||
30,
|
||||
);
|
||||
|
||||
export const screenShareBitrate = new Setting<number>(
|
||||
"screen-share-bitrate",
|
||||
5_000_000,
|
||||
);
|
||||
|
||||
export const screenShareCodec = new Setting<VideoCodec>(
|
||||
"screen-share-codec",
|
||||
"vp9",
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user