Allows defining custom arguments
This commit is contained in:
+64
-1
@@ -52,9 +52,19 @@ function App() {
|
||||
RunningProcessInfo[]
|
||||
>([]);
|
||||
const [customFileExt, setCustomFileExt] = createSignal("");
|
||||
const [globalopts, setGlobalopts] = createSignal("");
|
||||
const [inputopts, setInputopts] = createSignal("");
|
||||
const [outputopts, setOutputopts] = createSignal("");
|
||||
const logs: { [id: number]: string[] } = {};
|
||||
let supportedCodecs: CodecInfo[] = [];
|
||||
let ffmpegParams: FFmpegParams = { vcodec: "" };
|
||||
let ffmpegParams: FFmpegParams = {
|
||||
vcodec: "",
|
||||
useropts: {
|
||||
global: "",
|
||||
input: "",
|
||||
output: "",
|
||||
},
|
||||
};
|
||||
let successfulCount = 0;
|
||||
let unsuccessfulCount = 0;
|
||||
let totalCount = 0;
|
||||
@@ -195,6 +205,11 @@ function App() {
|
||||
|
||||
ffmpegParams = {
|
||||
vcodec: codecObj?.shortName ?? "",
|
||||
useropts: {
|
||||
global: "",
|
||||
input: "",
|
||||
output: "",
|
||||
},
|
||||
};
|
||||
|
||||
let encoder = newValue;
|
||||
@@ -242,6 +257,11 @@ function App() {
|
||||
preset: ffmpegParams.preset,
|
||||
twopass: ffmpegParams.twopass,
|
||||
vbitrate: ffmpegParams.vbitrate,
|
||||
useropts: {
|
||||
global: globalopts(),
|
||||
input: inputopts(),
|
||||
output: outputopts(),
|
||||
},
|
||||
};
|
||||
|
||||
setOutputCommand(generateOutputCommand(ffmpegParams));
|
||||
@@ -570,6 +590,49 @@ function App() {
|
||||
/>
|
||||
</Match>
|
||||
</Switch>
|
||||
<div class="row flex-col align-items-center">
|
||||
<h3 class="k-form-section-title">
|
||||
Extra Arguments
|
||||
</h3>
|
||||
</div>
|
||||
<form class="k-form">
|
||||
<label>Global Options</label>
|
||||
<input
|
||||
type="text"
|
||||
name="globalopts"
|
||||
id="globalopts"
|
||||
value={globalopts()}
|
||||
oninput={(e) => {
|
||||
ffmpegParams.useropts.global =
|
||||
e.target.value;
|
||||
setGlobalopts(e.target.value);
|
||||
}}
|
||||
/>
|
||||
<label>Input Options</label>
|
||||
<input
|
||||
type="text"
|
||||
name="inputopts"
|
||||
id="inputopts"
|
||||
value={inputopts()}
|
||||
oninput={(e) => {
|
||||
ffmpegParams.useropts.input =
|
||||
e.target.value;
|
||||
setInputopts(e.target.value);
|
||||
}}
|
||||
/>
|
||||
<label>Output Options</label>
|
||||
<input
|
||||
type="text"
|
||||
name="outputopts"
|
||||
id="outputopts"
|
||||
value={outputopts()}
|
||||
oninput={(e) => {
|
||||
ffmpegParams.useropts.output =
|
||||
e.target.value;
|
||||
setOutputopts(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div class="row flex-col p-medium">
|
||||
<label for="outputCommand">Command</label>
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { type CodecInfo, type FFmpegParams } from "@/util/ffmpeg";
|
||||
import {
|
||||
DEFAULT_BITRATE,
|
||||
type CodecInfo,
|
||||
type FFmpegParams,
|
||||
} from "@/util/ffmpeg";
|
||||
import { os } from "@neutralinojs/lib";
|
||||
import BreezeIcon from "@/components/BreezeIcon";
|
||||
import { onMount } from "solid-js";
|
||||
@@ -10,7 +14,10 @@ function Librav1eOptions(props: {
|
||||
}) {
|
||||
onMount(() => {
|
||||
props.onParamChanged("crf", undefined);
|
||||
props.onParamChanged("vbitrate", undefined);
|
||||
props.onParamChanged(
|
||||
"vbitrate",
|
||||
props.params.vbitrate ?? DEFAULT_BITRATE,
|
||||
);
|
||||
props.onParamChanged("speed", 5);
|
||||
});
|
||||
|
||||
@@ -46,6 +53,19 @@ function Librav1eOptions(props: {
|
||||
props.onParamChanged("speed", e.target.value)
|
||||
}
|
||||
/>
|
||||
<label for="bitrate">Bitrate</label>
|
||||
<div class="row gap2 align-items-center">
|
||||
<input
|
||||
type="number"
|
||||
name="bitrate"
|
||||
id="bitrate"
|
||||
value={props.params.vbitrate ?? DEFAULT_BITRATE}
|
||||
oninput={(e) =>
|
||||
props.onParamChanged("vbitrate", e.target.value)
|
||||
}
|
||||
/>
|
||||
<span>Kbps</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
||||
@@ -72,6 +72,12 @@ export const videoFileExtensions: { [key: string]: string } = {
|
||||
vp9: "mkv",
|
||||
};
|
||||
|
||||
export interface ExtraFFmpegArguments {
|
||||
global: string;
|
||||
input: string;
|
||||
output: string;
|
||||
}
|
||||
|
||||
export interface FFmpegParams {
|
||||
inputFile?: string;
|
||||
outputFile?: string;
|
||||
@@ -93,6 +99,10 @@ export interface FFmpegParams {
|
||||
faststart?: boolean;
|
||||
doNotUseAn?: boolean;
|
||||
speed?: number;
|
||||
/**
|
||||
* Extra parameters defined by users
|
||||
*/
|
||||
useropts: ExtraFFmpegArguments;
|
||||
}
|
||||
|
||||
const NULL_LOCATION = window.NL_OS === "Windows" ? "NUL" : "/dev/null";
|
||||
@@ -109,24 +119,34 @@ export function generateOutputCommand(params: FFmpegParams) {
|
||||
? " -movflags +faststart"
|
||||
: "";
|
||||
|
||||
let globalopts = "-hwaccel auto -y";
|
||||
let inputopts =
|
||||
params.useropts.input !== "" ? " " + params.useropts.input : "";
|
||||
let outputopts =
|
||||
params.useropts.output !== "" ? " " + params.useropts.output : "";
|
||||
|
||||
if (params.useropts.global !== "") {
|
||||
globalopts += " " + params.useropts.global;
|
||||
}
|
||||
|
||||
if (params.twopass) {
|
||||
const commonOpts = `-i "${params.inputFile ?? "{fileName}"}" -c:v ${params.encoder ?? params.vcodec} -b:v ${
|
||||
const commonOpts = `${globalopts}${inputopts} -i "${params.inputFile ?? "{fileName}"}" -c:v ${params.encoder ?? params.vcodec} -b:v ${
|
||||
params.vbitrate ?? DEFAULT_BITRATE
|
||||
}k${faststart}${
|
||||
params.preset === undefined ? "" : ` -preset ${params.preset}`
|
||||
} -progress -`;
|
||||
} -progress -${outputopts}`;
|
||||
|
||||
return `ffmpeg -hwaccel auto -y ${commonOpts} ${params.vcodec === "hevc" ? "-x265-params pass=1" : "-pass 1"} ${
|
||||
return `ffmpeg ${commonOpts} ${params.vcodec === "hevc" ? "-x265-params pass=1" : "-pass 1"} ${
|
||||
params.doNotUseAn ? "-vsync cfr" : "-an"
|
||||
} -f null ${NULL_LOCATION} &&
|
||||
ffmpeg -y -hwaccel auto ${commonOpts} ${
|
||||
ffmpeg ${commonOpts} ${
|
||||
params.vcodec === "hevc" ? "-x265-params pass=2" : "-pass 2"
|
||||
} -c:a ${
|
||||
params.acodec ?? "copy"
|
||||
}${params.abitrate === undefined ? "" : ` -b:a ${params.abitrate}k`} "${params.outputFile ?? "{output}"}"`;
|
||||
}
|
||||
|
||||
return `ffmpeg -y -hwaccel auto -i "${params.inputFile ?? "{fileName}"}" -c:v ${params.encoder ?? params.vcodec}${
|
||||
return `ffmpeg ${globalopts}${inputopts} -i "${params.inputFile ?? "{fileName}"}" -c:v ${params.encoder ?? params.vcodec}${
|
||||
params.crf === undefined ? "" : ` -crf ${params.crf}`
|
||||
}${
|
||||
params.vbitrate === undefined ? "" : ` -b:v ${params.vbitrate}`
|
||||
@@ -136,7 +156,7 @@ ffmpeg -y -hwaccel auto ${commonOpts} ${
|
||||
params.abitrate === undefined ? "" : ` -b:a ${params.abitrate}k`
|
||||
}${
|
||||
params.speed === undefined ? "" : ` -speed ${params.speed}`
|
||||
} -progress - "${params.outputFile ?? "{output}"}"`;
|
||||
} -progress -${outputopts} "${params.outputFile ?? "{output}"}"`;
|
||||
}
|
||||
|
||||
export async function getLengthMicroseconds(target: string) {
|
||||
|
||||
Reference in New Issue
Block a user