Add scale filter to non-hwaccel encoders
This commit is contained in:
parent
c367261053
commit
c008fb1eef
@ -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
|
||||
|
||||
@ -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 (
|
||||
<SelectCustom
|
||||
options={height}
|
||||
label={props.label}
|
||||
customLabel={props.customLabel}
|
||||
value={props.value}
|
||||
onChange={props.onChange}
|
||||
variant={props.variant}
|
||||
allowNone={props.allowNone}
|
||||
allowCustom={props.allowCustom}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Height.defaultProps = {
|
||||
allowNone: false,
|
||||
allowCustom: false,
|
||||
variant: 'outlined',
|
||||
label: <Trans>Height</Trans>,
|
||||
customLabel: <Trans>Custom size</Trans>,
|
||||
onChange: function (event) {},
|
||||
};
|
||||
|
||||
function Format(props) {
|
||||
const { i18n } = useLingui();
|
||||
const sizes = [
|
||||
@ -248,5 +295,6 @@ export default {
|
||||
Framerate,
|
||||
Profile,
|
||||
Size,
|
||||
Height,
|
||||
Format,
|
||||
};
|
||||
|
||||
@ -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);
|
||||
|
||||
91
src/misc/filters/video/Scale.js
Normal file
91
src/misc/filters/video/Scale.js
Normal file
@ -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 (
|
||||
<React.Fragment>
|
||||
<Grid item xs={12}>
|
||||
<Video.Height allowNone allowCustom label={<Trans>Scale by height</Trans>} value={settings.value} onChange={update('value')}></Video.Height>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
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 };
|
||||
Loading…
x
Reference in New Issue
Block a user