From 9cc06d6ce662e3163d6102da3d2c02f6067d10d3 Mon Sep 17 00:00:00 2001 From: Orry Verducci Date: Mon, 31 Jul 2023 13:47:30 +0100 Subject: [PATCH 1/2] Add framerate filter --- CHANGELOG.md | 1 + src/misc/filters/index.js | 2 + src/misc/filters/video/Framerate.js | 143 ++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 src/misc/filters/video/Framerate.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 97cdb5e..6746981 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## v1.8.0 > vx.x.x - Mod uses placeholders for ingress setups ([#560](https://github.com/datarhei/restreamer-ui/issues/560)) +- Add frame interpolation (framerate) filter ## v1.7.0 > v1.8.0 diff --git a/src/misc/filters/index.js b/src/misc/filters/index.js index 728982d..fe4b284 100644 --- a/src/misc/filters/index.js +++ b/src/misc/filters/index.js @@ -6,6 +6,7 @@ import * as Loudnorm from './audio/Loudnorm'; // Video Filter import * as Bwdif from './video/Bwdif'; +import * as Framerate from './video/Framerate'; import * as Scale from './video/Scale'; import * as Transpose from './video/Transpose'; import * as HFlip from './video/HFlip'; @@ -54,6 +55,7 @@ audioRegistry.Register(Loudnorm); // Video Filters const videoRegistry = new Registry('video'); videoRegistry.Register(Bwdif); +videoRegistry.Register(Framerate); videoRegistry.Register(Scale); videoRegistry.Register(Transpose); videoRegistry.Register(HFlip); diff --git a/src/misc/filters/video/Framerate.js b/src/misc/filters/video/Framerate.js new file mode 100644 index 0000000..0243e19 --- /dev/null +++ b/src/misc/filters/video/Framerate.js @@ -0,0 +1,143 @@ +import React from 'react'; + +import { useLingui } from '@lingui/react'; +import { Trans, t } from '@lingui/macro'; +import Grid from '@mui/material/Grid'; + +import Checkbox from '../../Checkbox'; +import SelectCustom from '../../../misc/SelectCustom'; + +// Framerate Filter +// http://ffmpeg.org/ffmpeg-all.html#framerate + +function init(initialState) { + const state = { + enabled: false, + fps: '30', + ...initialState, + }; + + return state; +} + +function createGraph(settings) { + settings = init(settings); + + const mapping = []; + + if (settings.enabled) { + mapping.push(`framerate=fps=${settings.fps}`); + } + + return mapping.join(','); +} + +function Framerate(props) { + const { i18n } = useLingui(); + const sizes = [ + { value: '60', label: '60' }, + { value: '59.94', label: '59.94' }, + { value: '50', label: '50' }, + { value: '30', label: '30' }, + { value: '29.97', label: '29.97 (NTSC)' }, + { value: '25', label: '25 (PAL)' }, + { value: '24', label: '24 (Film)' }, + { value: '23.97', label: '23.97 (NTSC Film)' }, + { value: '15', label: '15' }, + { value: '10', label: '10' }, + { value: 'custom', label: i18n._(t`Custom ...`) }, + ]; + + return ( + + ); +} + +Framerate.defaultProps = { + label: Framerate, + customLabel: Custom framerate, + value: '', + variant: 'outlined', + allowCustom: true, + onChange: function (event) {}, +}; + +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, + }; + if (['enabled'].includes(what)) { + newSettings[what] = !settings.enabled; + } else { + newSettings[what] = event.target.value; + } + + handleChange(newSettings); + }; + + React.useEffect(() => { + handleChange(null); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return ( + + + Framerate conversion (frame interpolation)} checked={settings.enabled} onChange={update('enabled')} /> + + {settings.enabled && ( + + + + + + )} + + ); +} + +Filter.defaultProps = { + settings: {}, + onChange: function (settings, mapping) {}, +}; + +const filter = 'fps'; +const name = 'Frame Interpolation'; +const type = 'video'; +const hwaccel = false; + +function summarize(settings) { + return `${name} (${settings.fps}fps)`; +} + +function defaults() { + const settings = init({}); + + return { + settings: settings, + graph: createGraph(settings), + }; +} + +export { name, filter, type, hwaccel, summarize, defaults, createGraph, Filter as component }; From 8de6830f3f6a6ec5d6d73ad424df769a11f10e8d Mon Sep 17 00:00:00 2001 From: Orry Verducci Date: Thu, 3 Aug 2023 14:10:06 +0100 Subject: [PATCH 2/2] Correct changelog order --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6746981..6c75c1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,8 @@ ## v1.8.0 > vx.x.x -- Mod uses placeholders for ingress setups ([#560](https://github.com/datarhei/restreamer-ui/issues/560)) - Add frame interpolation (framerate) filter +- Mod uses placeholders for ingress setups ([#560](https://github.com/datarhei/restreamer-ui/issues/560)) ## v1.7.0 > v1.8.0