Increases the max bandwidth selectable in the admin UI (#4550)
* feat(admin): Closes #1462. Increases the max bandwidth selectable in the UI + localization for the strings * chore: update extracted translations * Javascript formatting autofixes --------- Co-authored-by: Owncast default web localizations <owncast@owncast.online>
This commit is contained in:
co-authored by
Owncast default web localizations
parent
14189420c5
commit
e66b0444ad
@@ -3,6 +3,8 @@ import React, { FC } from 'react';
|
|||||||
import { Popconfirm, Row, Col, Slider, Collapse, Typography, Alert, Button } from 'antd';
|
import { Popconfirm, Row, Col, Slider, Collapse, Typography, Alert, Button } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
|
import { useTranslation } from 'next-export-i18n';
|
||||||
|
import { Localization } from '../../types/localization';
|
||||||
import { FieldUpdaterFunc, VideoVariant, UpdateArgs } from '../../types/config-section';
|
import { FieldUpdaterFunc, VideoVariant, UpdateArgs } from '../../types/config-section';
|
||||||
import { TextField } from './TextField';
|
import { TextField } from './TextField';
|
||||||
import {
|
import {
|
||||||
@@ -36,6 +38,7 @@ export const VideoVariantForm: FC<VideoVariantFormProps> = ({
|
|||||||
dataState = DEFAULT_VARIANT_STATE,
|
dataState = DEFAULT_VARIANT_STATE,
|
||||||
onUpdateField,
|
onUpdateField,
|
||||||
}) => {
|
}) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const videoPassthroughEnabled = dataState.videoPassthrough;
|
const videoPassthroughEnabled = dataState.videoPassthrough;
|
||||||
|
|
||||||
const handleFramerateChange = (value: number) => {
|
const handleFramerateChange = (value: number) => {
|
||||||
@@ -80,18 +83,40 @@ export const VideoVariantForm: FC<VideoVariantFormProps> = ({
|
|||||||
onUpdateField({ fieldName: 'name', value: args.value });
|
onUpdateField({ fieldName: 'name', value: args.value });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Extract threshold values dynamically from slider marks
|
||||||
|
const getBitrateThresholds = () => {
|
||||||
|
// Get all numeric keys from slider marks and sort them
|
||||||
|
const marks = Object.keys(VIDEO_BITRATE_SLIDER_MARKS)
|
||||||
|
.map(key => parseInt(key, 10))
|
||||||
|
.filter(value => !Number.isNaN(value))
|
||||||
|
.sort((a, b) => a - b);
|
||||||
|
|
||||||
|
// Current marks: [400, 3000, 6000, 9000, 13000]
|
||||||
|
// Use the second mark (3000) as low threshold and second-to-last (9000) as high threshold
|
||||||
|
// This excludes min/max values and uses intermediate marks for quality categories
|
||||||
|
const lowThreshold = marks.length >= 3 ? marks[1] : marks[0];
|
||||||
|
const highThreshold = marks.length >= 4 ? marks[marks.length - 2] : marks[marks.length - 1];
|
||||||
|
|
||||||
|
return { lowThreshold, highThreshold };
|
||||||
|
};
|
||||||
|
|
||||||
// Slider notes
|
// Slider notes
|
||||||
const selectedVideoBRnote = () => {
|
const selectedVideoBRnote = () => {
|
||||||
if (videoPassthroughEnabled) {
|
if (videoPassthroughEnabled) {
|
||||||
return 'Bitrate selection is disabled when Video Passthrough is enabled.';
|
return t(Localization.Admin.VideoVariantForm.bitrateDisabledPassthrough);
|
||||||
}
|
}
|
||||||
let note = `${dataState.videoBitrate}${VIDEO_BITRATE_DEFAULTS.unit}`;
|
|
||||||
if (dataState.videoBitrate < 2000) {
|
const { lowThreshold, highThreshold } = getBitrateThresholds();
|
||||||
note = `${note} - Good for low bandwidth environments.`;
|
|
||||||
} else if (dataState.videoBitrate < 3500) {
|
let note = t(Localization.Admin.VideoVariantForm.bitrateValueKbps, {
|
||||||
note = `${note} - Good for most bandwidth environments.`;
|
bitrate: dataState.videoBitrate,
|
||||||
|
});
|
||||||
|
if (dataState.videoBitrate < lowThreshold) {
|
||||||
|
note = `${note} - ${t(Localization.Admin.VideoVariantForm.bitrateGoodForSlow)}`;
|
||||||
|
} else if (dataState.videoBitrate < highThreshold) {
|
||||||
|
note = `${note} - ${t(Localization.Admin.VideoVariantForm.bitrateGoodForMost)}`;
|
||||||
} else {
|
} else {
|
||||||
note = `${note} - Good for high bandwidth environments.`;
|
note = `${note} - ${t(Localization.Admin.VideoVariantForm.bitrateGoodForHigh)}`;
|
||||||
}
|
}
|
||||||
return note;
|
return note;
|
||||||
};
|
};
|
||||||
@@ -203,7 +228,7 @@ export const VideoVariantForm: FC<VideoVariantFormProps> = ({
|
|||||||
max={VIDEO_BITRATE_DEFAULTS.max}
|
max={VIDEO_BITRATE_DEFAULTS.max}
|
||||||
marks={VIDEO_BITRATE_SLIDER_MARKS}
|
marks={VIDEO_BITRATE_SLIDER_MARKS}
|
||||||
/>
|
/>
|
||||||
<p className="selected-value-note">{selectedVideoBRnote()}</p>
|
<p style={{ marginTop: '40px' }}>{selectedVideoBRnote()}</p>
|
||||||
</div>
|
</div>
|
||||||
<p className="read-more-subtext">
|
<p className="read-more-subtext">
|
||||||
<a
|
<a
|
||||||
|
|||||||
@@ -71,6 +71,13 @@
|
|||||||
"offlineMessageDescription": "The offline message is displayed to your page visitors when you're not streaming. Markdown is supported.",
|
"offlineMessageDescription": "The offline message is displayed to your page visitors when you're not streaming. Markdown is supported.",
|
||||||
"directoryDescription": "Increase your audience by appearing in the <a href=\"https://owncast.directory\" target=\"_blank\" rel=\"noreferrer\"><strong>Owncast Directory</strong></a>. This is an external service run by the Owncast project. <a href=\"https://owncast.online/docs/directory/?source=admin\" target=\"_blank\" rel=\"noopener noreferrer\">Learn more</a>.",
|
"directoryDescription": "Increase your audience by appearing in the <a href=\"https://owncast.directory\" target=\"_blank\" rel=\"noreferrer\"><strong>Owncast Directory</strong></a>. This is an external service run by the Owncast project. <a href=\"https://owncast.online/docs/directory/?source=admin\" target=\"_blank\" rel=\"noopener noreferrer\">Learn more</a>.",
|
||||||
"serverUrlRequiredForDirectory": "You must set your <strong>Server URL</strong> above to enable the directory."
|
"serverUrlRequiredForDirectory": "You must set your <strong>Server URL</strong> above to enable the directory."
|
||||||
|
},
|
||||||
|
"VideoVariantForm": {
|
||||||
|
"bitrateDisabledPassthrough": "Bitrate selection is disabled when Video Passthrough is enabled.",
|
||||||
|
"bitrateValueKbps": "{{bitrate}} kbps",
|
||||||
|
"bitrateGoodForSlow": "Good for slow, mobile and low bitrate viewers.",
|
||||||
|
"bitrateGoodForMost": "Good for most viewers, bandwidths and resolutions.",
|
||||||
|
"bitrateGoodForHigh": "Good for high speed & high bitrate viewers."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Common": {
|
"Common": {
|
||||||
|
|||||||
@@ -110,6 +110,15 @@ export const Localization = {
|
|||||||
serverUrlRequiredForDirectory: 'Admin.EditInstanceDetails.serverUrlRequiredForDirectory',
|
serverUrlRequiredForDirectory: 'Admin.EditInstanceDetails.serverUrlRequiredForDirectory',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// VideoVariantForm component specific keys
|
||||||
|
VideoVariantForm: {
|
||||||
|
bitrateDisabledPassthrough: 'Admin.VideoVariantForm.bitrateDisabledPassthrough',
|
||||||
|
bitrateValueKbps: 'Admin.VideoVariantForm.bitrateValueKbps',
|
||||||
|
bitrateGoodForSlow: 'Admin.VideoVariantForm.bitrateGoodForSlow',
|
||||||
|
bitrateGoodForMost: 'Admin.VideoVariantForm.bitrateGoodForMost',
|
||||||
|
bitrateGoodForHigh: 'Admin.VideoVariantForm.bitrateGoodForHigh',
|
||||||
|
},
|
||||||
|
|
||||||
// Logging and monitoring
|
// Logging and monitoring
|
||||||
info: 'Info',
|
info: 'Info',
|
||||||
warning: 'Warning',
|
warning: 'Warning',
|
||||||
|
|||||||
@@ -435,12 +435,12 @@ export const FRAMERATE_TOOLTIPS = {
|
|||||||
50: '50fps - Good for fast/action games, sports, HD video.',
|
50: '50fps - Good for fast/action games, sports, HD video.',
|
||||||
60: '60fps - Good for fast/action games, sports, HD video.',
|
60: '60fps - Good for fast/action games, sports, HD video.',
|
||||||
90: '90fps - Good for newer fast games and hardware.',
|
90: '90fps - Good for newer fast games and hardware.',
|
||||||
[FRAMERATE_DEFAULTS.max]: `${FRAMERATE_DEFAULTS.max}fps - Experimental, use at your own risk!`,
|
[FRAMERATE_DEFAULTS.max]: `${FRAMERATE_DEFAULTS.max}fps - Use at your own risk!`,
|
||||||
};
|
};
|
||||||
// VIDEO VARIANT FORM - bitrate
|
// VIDEO VARIANT FORM - bitrate
|
||||||
export const VIDEO_BITRATE_DEFAULTS = {
|
export const VIDEO_BITRATE_DEFAULTS = {
|
||||||
min: 400,
|
min: 400,
|
||||||
max: 6000,
|
max: 13000,
|
||||||
defaultValue: 1200,
|
defaultValue: 1200,
|
||||||
unit: 'kbps',
|
unit: 'kbps',
|
||||||
incrementBy: 100,
|
incrementBy: 100,
|
||||||
@@ -463,7 +463,8 @@ export const VIDEO_BITRATE_SLIDER_MARKS = {
|
|||||||
label: `${VIDEO_BITRATE_DEFAULTS.min} ${VIDEO_BITRATE_DEFAULTS.unit}`,
|
label: `${VIDEO_BITRATE_DEFAULTS.min} ${VIDEO_BITRATE_DEFAULTS.unit}`,
|
||||||
},
|
},
|
||||||
3000: 3000,
|
3000: 3000,
|
||||||
4500: 4500,
|
6000: 6000,
|
||||||
|
9000: 9000,
|
||||||
[VIDEO_BITRATE_DEFAULTS.max]: {
|
[VIDEO_BITRATE_DEFAULTS.max]: {
|
||||||
style: {
|
style: {
|
||||||
marginLeft: '-10px',
|
marginLeft: '-10px',
|
||||||
|
|||||||
Reference in New Issue
Block a user