diff --git a/web/components/config/cpu-usage.tsx b/web/components/config/cpu-usage.tsx
deleted file mode 100644
index b75aa8bc4..000000000
--- a/web/components/config/cpu-usage.tsx
+++ /dev/null
@@ -1,76 +0,0 @@
-import React, { useContext, useState, useEffect } from 'react';
-import { Typography, Slider } from 'antd';
-import { ServerStatusContext } from '../../utils/server-status-context';
-
-const { Title } = Typography;
-
-const SLIDER_MARKS = {
- 1: 'lowest',
- 2: '',
- 3: '',
- 4: '',
- 5: 'highest',
-};
-
-const TOOLTIPS = {
- 1: 'Lowest CPU usage - lowest quality video',
- 2: 'Low CPU usage - low quality video',
- 3: 'Medium CPU usage - average quality video',
- 4: 'High CPU usage - high quality video',
- 5: 'Highest CPU usage - higher quality video',
-};
-interface Props {
- defaultValue: number;
- disabled: boolean;
- onChange: (arg: number) => void;
-}
-export default function CPUUsageSelector({ defaultValue, disabled, onChange }: Props) {
- const [selectedOption, setSelectedOption] = useState(null);
-
- const serverStatusData = useContext(ServerStatusContext);
- const { serverConfig } = serverStatusData || {};
- const { videoSettings } = serverConfig || {};
-
- if (!videoSettings) {
- return null;
- }
-
- useEffect(() => {
- setSelectedOption(defaultValue);
- }, [videoSettings]);
-
- const handleChange = value => {
- setSelectedOption(value);
- onChange(value);
- };
-
- const cpuUsageNote = () => {
- if (disabled) {
- return 'CPU usage selection is disabled when Video Passthrough is enabled.';
- }
-
- return TOOLTIPS[selectedOption];
- };
-
- return (
-
-
CPU Usage
-
- Reduce to improve server performance, or increase it to improve video quality.
-
-
-
TOOLTIPS[value]}
- onChange={handleChange}
- min={1}
- max={Object.keys(SLIDER_MARKS).length}
- marks={SLIDER_MARKS}
- defaultValue={selectedOption}
- value={selectedOption}
- disabled={disabled}
- />
- {cpuUsageNote()}
-
-
- );
-}
diff --git a/web/components/config/video-variant-form.tsx b/web/components/config/video-variant-form.tsx
index a8550f91e..4ead753be 100644
--- a/web/components/config/video-variant-form.tsx
+++ b/web/components/config/video-variant-form.tsx
@@ -1,62 +1,25 @@
-// This content populates the video variant modal, which is spawned from the variants table.
+// This content populates the video variant modal, which is spawned from the variants table. This relies on the `dataState` prop fed in by the table.
import React from 'react';
import { Popconfirm, Row, Col, Slider, Collapse, Typography } from 'antd';
import { ExclamationCircleFilled } from '@ant-design/icons';
+import classNames from 'classnames';
import { FieldUpdaterFunc, VideoVariant, UpdateArgs } from '../../types/config-section';
import TextField from './form-textfield';
-import { DEFAULT_VARIANT_STATE } from '../../utils/config-constants';
-import CPUUsageSelector from './cpu-usage';
+import {
+ DEFAULT_VARIANT_STATE,
+ VIDEO_VARIANT_SETTING_DEFAULTS,
+ ENCODER_PRESET_SLIDER_MARKS,
+ ENCODER_PRESET_TOOLTIPS,
+ VIDEO_BITRATE_DEFAULTS,
+ VIDEO_BITRATE_SLIDER_MARKS,
+ FRAMERATE_SLIDER_MARKS,
+ FRAMERATE_DEFAULTS,
+ FRAMERATE_TOOLTIPS,
+} from '../../utils/config-constants';
import ToggleSwitch from './form-toggleswitch';
const { Panel } = Collapse;
-const VIDEO_VARIANT_DEFAULTS = {
- framerate: {
- min: 24,
- max: 120,
- defaultValue: 24,
- unit: 'fps',
- incrementBy: null,
- tip:
- 'Reducing your framerate will decrease the amount of video that needs to be encoded and sent to your viewers, saving CPU and bandwidth at the expense of smoothness. A lower value is generally is fine for most content.',
- },
- videoBitrate: {
- min: 600,
- max: 6000,
- defaultValue: 1200,
- unit: 'kbps',
- incrementBy: 100,
- tip: 'The overall quality of your stream is generally impacted most by bitrate.',
- },
- audioBitrate: {
- min: 600,
- max: 1200,
- defaultValue: 800,
- unit: 'kbps',
- incrementBy: 100,
- tip: 'nothing to see here',
- },
- videoPassthrough: {
- tip: 'If enabled, all other settings will be disabled. Otherwise configure as desired.',
- },
- audioPassthrough: {
- tip: 'If No is selected, then you should set your desired Audio Bitrate.',
- },
- scaledWidth: {
- fieldName: 'scaledWidth',
- label: 'Resized Width',
- maxLength: 4,
- placeholder: '1080',
- tip: "Optionally resize this content's width.",
- },
- scaledHeight: {
- fieldName: 'scaledHeight',
- label: 'Resized Height',
- maxLength: 4,
- placeholder: '720',
- tip: "Optionally resize this content's height.",
- },
-};
interface VideoVariantFormProps {
dataState: VideoVariant;
onUpdateField: FieldUpdaterFunc;
@@ -66,6 +29,8 @@ export default function VideoVariantForm({
dataState = DEFAULT_VARIANT_STATE,
onUpdateField,
}: VideoVariantFormProps) {
+ const videoPassthroughEnabled = dataState.videoPassthrough;
+
const handleFramerateChange = (value: number) => {
onUpdateField({ fieldName: 'framerate', value });
};
@@ -99,40 +64,17 @@ export default function VideoVariantForm({
// If passthrough is currently on, set it back to false on toggle.
// Else let the Popconfirm turn it on.
const handleVideoPassthroughToggle = (value: boolean) => {
- if (dataState.videoPassthrough) {
+ if (videoPassthroughEnabled) {
onUpdateField({ fieldName: 'videoPassthrough', value });
}
};
- const framerateDefaults = VIDEO_VARIANT_DEFAULTS.framerate;
- const framerateMin = framerateDefaults.min;
- const framerateMax = framerateDefaults.max;
- const framerateUnit = framerateDefaults.unit;
- const framerateMarks = {
- [framerateMin]: `${framerateMin} ${framerateUnit}`,
- 30: '',
- 60: '',
- 90: '',
- [framerateMax]: `${framerateMax} ${framerateUnit}`,
- };
-
- const videoBitrateDefaults = VIDEO_VARIANT_DEFAULTS.videoBitrate;
- const videoBRMin = videoBitrateDefaults.min;
- const videoBRMax = videoBitrateDefaults.max;
- const videoBRUnit = videoBitrateDefaults.unit;
- const videoBRMarks = {
- [videoBRMin]: `${videoBRMin} ${videoBRUnit}`,
- 3000: 3000,
- 4500: 4500,
- [videoBRMax]: `${videoBRMax} ${videoBRUnit}`,
- };
-
+ // Slider notes
const selectedVideoBRnote = () => {
- if (dataState.videoPassthrough) {
+ if (videoPassthroughEnabled) {
return 'Bitrate selection is disabled when Video Passthrough is enabled.';
}
-
- let note = `${dataState.videoBitrate}${videoBRUnit}`;
+ let note = `${dataState.videoBitrate}${VIDEO_BITRATE_DEFAULTS.unit}`;
if (dataState.videoBitrate < 2000) {
note = `${note} - Good for low bandwidth environments.`;
} else if (dataState.videoBitrate < 3500) {
@@ -143,35 +85,24 @@ export default function VideoVariantForm({
return note;
};
const selectedFramerateNote = () => {
- if (dataState.videoPassthrough) {
+ if (videoPassthroughEnabled) {
return 'Framerate selection is disabled when Video Passthrough is enabled.';
}
-
- let note = `Selected: ${dataState.framerate}${framerateUnit}`;
- switch (dataState.framerate) {
- case 24:
- note = `${note} - Good for film, presentations, music, low power/bandwidth servers.`;
- break;
- case 30:
- note = `${note} - Good for slow/casual games, chat, general purpose.`;
- break;
- case 60:
- note = `${note} - Good for fast/action games, sports, HD video.`;
- break;
- case 90:
- note = `${note} - Good for newer fast games and hardware.`;
- break;
- case 120:
- note = `${note} - Experimental, use at your own risk!`;
- break;
- default:
- note = '';
+ return FRAMERATE_TOOLTIPS[dataState.framerate] || '';
+ };
+ const cpuUsageNote = () => {
+ if (videoPassthroughEnabled) {
+ return 'CPU usage selection is disabled when Video Passthrough is enabled.';
}
- return note;
+ return ENCODER_PRESET_TOOLTIPS[dataState.cpuUsageLevel] || '';
};
+ const classes = classNames({
+ 'config-variant-form': true,
+ 'video-passthrough-enabled': videoPassthroughEnabled,
+ });
return (
-
+
Learn more
@@ -179,15 +110,34 @@ export default function VideoVariantForm({
about how each of these settings can impact the performance of your server.
+ {videoPassthroughEnabled && (
+
+ NOTE: Video Passthrough for this output stream variant is enabled, disabling the
+ below video encoding settings.
+
+ )}
+
- {/* ENCODER PRESET FIELD */}
+ {/* ENCODER PRESET (CPU USAGE) FIELD */}
-
+
CPU Usage
+
+ Reduce to improve server performance, or increase it to improve video quality.
+
+
+
ENCODER_PRESET_TOOLTIPS[value]}
+ onChange={handleVideoCpuUsageLevelChange}
+ min={1}
+ max={Object.keys(ENCODER_PRESET_SLIDER_MARKS).length}
+ marks={ENCODER_PRESET_SLIDER_MARKS}
+ defaultValue={dataState.cpuUsageLevel}
+ value={dataState.cpuUsageLevel}
+ disabled={dataState.videoPassthrough}
+ />
+ {cpuUsageNote()}
+
Video Bitrate
- {VIDEO_VARIANT_DEFAULTS.videoBitrate.tip}
+ {VIDEO_BITRATE_DEFAULTS.tip}
`${value} ${videoBRUnit}`}
+ tipFormatter={value => `${value} ${VIDEO_BITRATE_DEFAULTS.unit}`}
disabled={dataState.videoPassthrough}
defaultValue={dataState.videoBitrate}
value={dataState.videoBitrate}
onChange={handleVideoBitrateChange}
- step={videoBitrateDefaults.incrementBy}
- min={videoBRMin}
- max={videoBRMax}
- marks={videoBRMarks}
+ step={VIDEO_BITRATE_DEFAULTS.incrementBy}
+ min={VIDEO_BITRATE_DEFAULTS.min}
+ max={VIDEO_BITRATE_DEFAULTS.max}
+ marks={VIDEO_BITRATE_SLIDER_MARKS}
/>
{selectedVideoBRnote()}
@@ -256,14 +206,14 @@ export default function VideoVariantForm({
{/* VIDEO PASSTHROUGH FIELD */}
-
+
Video Passthrough
@@ -307,7 +257,7 @@ export default function VideoVariantForm({
@@ -320,17 +270,17 @@ export default function VideoVariantForm({
{/* FRAME RATE FIELD */}
Frame rate
-
{VIDEO_VARIANT_DEFAULTS.framerate.tip}
+
{FRAMERATE_DEFAULTS.tip}
`${value} ${framerateUnit}`}
+ tipFormatter={value => `${value} ${FRAMERATE_DEFAULTS.unit}`}
defaultValue={dataState.framerate}
value={dataState.framerate}
onChange={handleFramerateChange}
- step={framerateDefaults.incrementBy}
- min={framerateMin}
- max={framerateMax}
- marks={framerateMarks}
+ step={FRAMERATE_DEFAULTS.incrementBy}
+ min={FRAMERATE_DEFAULTS.min}
+ max={FRAMERATE_DEFAULTS.max}
+ marks={FRAMERATE_SLIDER_MARKS}
disabled={dataState.videoPassthrough}
/>
{selectedFramerateNote()}
diff --git a/web/styles/config-video-variants.scss b/web/styles/config-video-variants.scss
index 340f6bb93..9d3e556c9 100644
--- a/web/styles/config-video-variants.scss
+++ b/web/styles/config-video-variants.scss
@@ -15,6 +15,15 @@
.description {
margin-top: 0;
}
+ .passthrough-warning {
+ text-align: center;
+ padding: 1em;
+ color: var(--ant-warning);
+ font-size: 0.88em;
+ font-weight: 500;
+ background-color: var(--black-50);
+ border-radius: var(--container-border-radius);
+ }
.cpu-usage-container,
.bitrate-container {
@@ -25,10 +34,17 @@
margin-top: 1em;
.resolution-module,
- .video-passthroug-module {
+ .video-passthrough-module {
min-height: 30em;
}
}
+ // make some things look disabled when passthrough is on
+ &.video-passthrough-enabled {
+ .form-module:not(.video-passthrough-module) {
+ opacity: 0.25;
+ cursor: not-allowed;
+ }
+ }
}
.variants-table {
diff --git a/web/utils/config-constants.tsx b/web/utils/config-constants.tsx
index 4bd3d636f..30f107785 100644
--- a/web/utils/config-constants.tsx
+++ b/web/utils/config-constants.tsx
@@ -144,8 +144,7 @@ export const FIELD_PROPS_YP = {
apiPath: API_YP_SWITCH,
configPath: 'yp',
label: 'Enable directory',
- tip:
- 'Turn this ON if you want to show up in the directory.',
+ tip: 'Turn this ON if you want to show up in the directory.',
};
export const DEFAULT_VARIANT_STATE: VideoVariant = {
@@ -159,6 +158,94 @@ export const DEFAULT_VARIANT_STATE: VideoVariant = {
scaledWidth: null,
};
+export const VIDEO_VARIANT_SETTING_DEFAULTS = {
+ // this one is currently unused
+ audioBitrate: {
+ min: 600,
+ max: 1200,
+ defaultValue: 800,
+ unit: 'kbps',
+ incrementBy: 100,
+ tip: 'nothing to see here',
+ },
+ videoPassthrough: {
+ tip: 'If enabled, all other settings will be disabled. Otherwise configure as desired.',
+ },
+ audioPassthrough: {
+ tip: 'If No is selected, then you should set your desired Audio Bitrate.',
+ },
+ scaledWidth: {
+ fieldName: 'scaledWidth',
+ label: 'Resized Width',
+ maxLength: 4,
+ placeholder: '1080',
+ tip: "Optionally resize this content's width.",
+ },
+ scaledHeight: {
+ fieldName: 'scaledHeight',
+ label: 'Resized Height',
+ maxLength: 4,
+ placeholder: '720',
+ tip: "Optionally resize this content's height.",
+ },
+};
+
+// VIDEO VARIANT FORM - framerate
+export const FRAMERATE_DEFAULTS = {
+ min: 24,
+ max: 120,
+ defaultValue: 24,
+ unit: 'fps',
+ incrementBy: null,
+ tip:
+ 'Reducing your framerate will decrease the amount of video that needs to be encoded and sent to your viewers, saving CPU and bandwidth at the expense of smoothness. A lower value is generally is fine for most content.',
+};
+export const FRAMERATE_SLIDER_MARKS = {
+ [FRAMERATE_DEFAULTS.min]: `${FRAMERATE_DEFAULTS.min} ${FRAMERATE_DEFAULTS.unit}`,
+ 30: '',
+ 60: '',
+ 90: '',
+ [FRAMERATE_DEFAULTS.max]: `${FRAMERATE_DEFAULTS.max} ${FRAMERATE_DEFAULTS.unit}`,
+};
+export const FRAMERATE_TOOLTIPS = {
+ [FRAMERATE_DEFAULTS.min]: `${FRAMERATE_DEFAULTS.min}fps - Good for film, presentations, music, low power/bandwidth servers.`,
+ 30: '30fps - Good for slow/casual games, chat, general purpose.',
+ 60: '60fps - Good for fast/action games, sports, HD video.',
+ 90: '90fps - Good for newer fast games and hardware.',
+ [FRAMERATE_DEFAULTS.max]: `${FRAMERATE_DEFAULTS.max}fps - Experimental, use at your own risk!`,
+};
+// VIDEO VARIANT FORM - bitrate
+export const VIDEO_BITRATE_DEFAULTS = {
+ min: 600,
+ max: 6000,
+ defaultValue: 1200,
+ unit: 'kbps',
+ incrementBy: 100,
+ tip: 'The overall quality of your stream is generally impacted most by bitrate.',
+};
+export const VIDEO_BITRATE_SLIDER_MARKS = {
+ [VIDEO_BITRATE_DEFAULTS.min]: `${VIDEO_BITRATE_DEFAULTS.min} ${VIDEO_BITRATE_DEFAULTS.unit}`,
+ 3000: 3000,
+ 4500: 4500,
+ [VIDEO_BITRATE_DEFAULTS.max]: `${VIDEO_BITRATE_DEFAULTS.max} ${VIDEO_BITRATE_DEFAULTS.unit}`,
+};
+// VIDEO VARIANT FORM - encoder preset
+// CPU
+export const ENCODER_PRESET_SLIDER_MARKS = {
+ 1: 'lowest',
+ 2: '',
+ 3: '',
+ 4: '',
+ 5: 'highest',
+};
+export const ENCODER_PRESET_TOOLTIPS = {
+ 1: 'Lowest CPU usage - lowest quality video',
+ 2: 'Low CPU usage - low quality video',
+ 3: 'Medium CPU usage - average quality video',
+ 4: 'High CPU usage - high quality video',
+ 5: 'Highest CPU usage - higher quality video',
+};
+
export const DEFAULT_SOCIAL_HANDLE: SocialHandle = {
url: '',
platform: '',