diff --git a/CHANGELOG.md b/CHANGELOG.md
index 296d86a..81a52dd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,7 @@
### v1.4.0 > v1.5.0
+- Add scale filter to non-hwaccel encoders
- Add PeerTube and Media Network to publication services (plattforms, software)
- Add reset button to hide a player logo (datarhei/restreamer#431)
- Mod adds Istafeed.me as StreamKey service to Instagram's publishing service
diff --git a/src/misc/coders/settings/Video.js b/src/misc/coders/settings/Video.js
index 2c038cf..5aacc1c 100644
--- a/src/misc/coders/settings/Video.js
+++ b/src/misc/coders/settings/Video.js
@@ -203,6 +203,53 @@ Size.defaultProps = {
onChange: function (event) {},
};
+function Height(props) {
+ const { i18n } = useLingui();
+ const height = [
+ { value: '4320', label: '4320' },
+ { value: '2880', label: '2880' },
+ { value: '2160', label: '2160' },
+ { value: '1800', label: '1800' },
+ { value: '1600', label: '1600' },
+ { value: '1440', label: '1440' },
+ { value: '1080', label: '1080' },
+ { value: '900', label: '900' },
+ { value: '720', label: '720' },
+ { value: '540', label: '540' },
+ { value: '360', label: '360' },
+ ];
+
+ if (props.allowNone === true) {
+ height.unshift({ value: 'none', label: 'none' });
+ }
+
+ if (props.allowCustom === true) {
+ height.push({ value: 'custom', label: i18n._(t`Custom ...`) });
+ }
+
+ return (
+
+ );
+}
+
+Height.defaultProps = {
+ allowNone: false,
+ allowCustom: false,
+ variant: 'outlined',
+ label: Height,
+ customLabel: Custom size,
+ onChange: function (event) {},
+};
+
function Format(props) {
const { i18n } = useLingui();
const sizes = [
@@ -248,5 +295,6 @@ export default {
Framerate,
Profile,
Size,
+ Height,
Format,
};
diff --git a/src/misc/filters/index.js b/src/misc/filters/index.js
index 8ace2f7..382f0d0 100644
--- a/src/misc/filters/index.js
+++ b/src/misc/filters/index.js
@@ -5,6 +5,7 @@ import * as Volume from './audio/Volume';
import * as Loudnorm from './audio/Loudnorm';
// Video Filter
+import * as Scale from './video/Scale';
import * as Transpose from './video/Transpose';
import * as HFlip from './video/HFlip';
import * as VFlip from './video/VFlip';
@@ -51,6 +52,7 @@ audioRegistry.Register(Loudnorm);
// Video Filters
const videoRegistry = new Registry('video');
+videoRegistry.Register(Scale);
videoRegistry.Register(Transpose);
videoRegistry.Register(HFlip);
videoRegistry.Register(VFlip);
diff --git a/src/misc/filters/video/Scale.js b/src/misc/filters/video/Scale.js
new file mode 100644
index 0000000..49f7859
--- /dev/null
+++ b/src/misc/filters/video/Scale.js
@@ -0,0 +1,91 @@
+import React from 'react';
+
+import { Trans } from '@lingui/macro';
+import Grid from '@mui/material/Grid';
+
+import Video from '../../coders/settings/Video';
+
+// Scale Filter
+// https://ffmpeg.org/ffmpeg-all.html#scale-1
+
+function init(initialState) {
+ const state = {
+ value: 'none',
+ ...initialState,
+ };
+
+ return state;
+}
+
+function createGraph(settings) {
+ settings = init(settings);
+
+ const mapping = [];
+
+ if (settings.value !== 'none') {
+ mapping.push(`scale=-1:${settings.value}`);
+ }
+
+ return mapping.join(',');
+}
+
+function Filter(props) {
+ const settings = init(props.settings);
+
+ const handleChange = (newSettings) => {
+ let automatic = false;
+ if (!newSettings) {
+ newSettings = settings;
+ automatic = true;
+ }
+
+ props.onChange(newSettings, createGraph(newSettings), automatic);
+ };
+
+ const update = (what) => (event) => {
+ const newSettings = {
+ ...settings,
+ [what]: event.target.value,
+ };
+
+ handleChange(newSettings);
+ };
+
+ React.useEffect(() => {
+ handleChange(null);
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
+
+ return (
+
+
+ Scale by height} value={settings.value} onChange={update('value')}>
+
+
+ );
+}
+
+Filter.defaultProps = {
+ settings: {},
+ onChange: function (settings, mapping) {},
+};
+
+const filter = 'scale';
+const name = 'Scale';
+const type = 'video';
+const hwaccel = false;
+
+function summarize(settings) {
+ return `${name} (-1:${settings.value})`;
+}
+
+function defaults() {
+ const settings = init({});
+
+ return {
+ settings: settings,
+ graph: createGraph(settings),
+ };
+}
+
+export { name, filter, type, hwaccel, summarize, defaults, createGraph, Filter as component };