Compare File Size Ratio Live

make-only-subtitle-default
HaveAGitGat 2 years ago
parent 6d6ff0bb88
commit 9ac675d401

@ -99,6 +99,7 @@ const plugin = async (args: IpluginInputArgs): Promise<IpluginOutputArgs> => {
inputFileObj: args.inputFileObj, inputFileObj: args.inputFileObj,
logFullCliOutput: args.logFullCliOutput, logFullCliOutput: args.logFullCliOutput,
updateWorker: args.updateWorker, updateWorker: args.updateWorker,
args,
}); });
const res = await cli.runCli(); const res = await cli.runCli();
@ -160,6 +161,7 @@ const plugin = async (args: IpluginInputArgs): Promise<IpluginOutputArgs> => {
inputFileObj: args.inputFileObj, inputFileObj: args.inputFileObj,
logFullCliOutput: args.logFullCliOutput, logFullCliOutput: args.logFullCliOutput,
updateWorker: args.updateWorker, updateWorker: args.updateWorker,
args,
}); });
const res2 = await cli2.runCli(); const res2 = await cli2.runCli();

@ -356,6 +356,7 @@ const plugin = async (args: IpluginInputArgs): Promise<IpluginOutputArgs> => {
inputFileObj: args.inputFileObj, inputFileObj: args.inputFileObj,
logFullCliOutput: args.logFullCliOutput, logFullCliOutput: args.logFullCliOutput,
updateWorker: args.updateWorker, updateWorker: args.updateWorker,
args,
}); });
const res = await cli.runCli(); const res = await cli.runCli();

@ -182,6 +182,7 @@ const plugin = async (args: IpluginInputArgs): Promise<IpluginOutputArgs> => {
inputFileObj: args.inputFileObj, inputFileObj: args.inputFileObj,
logFullCliOutput: args.logFullCliOutput, logFullCliOutput: args.logFullCliOutput,
updateWorker: args.updateWorker, updateWorker: args.updateWorker,
args,
}); });
const res = await cli.runCli(); const res = await cli.runCli();

@ -187,6 +187,7 @@ const plugin = async (args: IpluginInputArgs): Promise<IpluginOutputArgs> => {
inputFileObj: args.inputFileObj, inputFileObj: args.inputFileObj,
logFullCliOutput: args.logFullCliOutput, logFullCliOutput: args.logFullCliOutput,
updateWorker: args.updateWorker, updateWorker: args.updateWorker,
args,
}); });
const res = await cli.runCli(); const res = await cli.runCli();

@ -168,6 +168,7 @@ const plugin = async (args: IpluginInputArgs): Promise<IpluginOutputArgs> => {
inputFileObj: args.inputFileObj, inputFileObj: args.inputFileObj,
logFullCliOutput: args.logFullCliOutput, logFullCliOutput: args.logFullCliOutput,
updateWorker: args.updateWorker, updateWorker: args.updateWorker,
args,
}); });
const res = await cli.runCli(); const res = await cli.runCli();

@ -0,0 +1,167 @@
import {
IpluginDetails,
IpluginInputArgs,
IpluginOutputArgs,
} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces';
/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */
const details = (): IpluginDetails => ({
name: 'Compare File Size Ratio Live',
description: `
Compare either the estimated final size or current output size to the input size and
give an error if estimated final size or current size surpasses the threshold %.
Works with 'FfmpegCommand', 'HandBrake Custom Arguments', 'Run Classic Transcode' and other flow plugins
that output a file.
Can be placed anywhere before a plugin which outputs a new file.
',
`,
style: {
borderColor: 'orange',
},
tags: '',
isStartPlugin: false,
pType: '',
requiresVersion: '2.11.01',
sidebarPosition: -1,
icon: 'faQuestion',
inputs: [
{
label: 'Enabled',
name: 'enabled',
type: 'boolean',
defaultValue: 'true',
inputUI: {
type: 'switch',
},
tooltip: 'Enable or disable this plugin. For example you may want to enable it for one set of transcoding tests.',
},
{
label: 'Compare Method',
name: 'compareMethod',
type: 'string',
defaultValue: 'estimatedFinalSize',
inputUI: {
type: 'dropdown',
options: [
'estimatedFinalSize',
'currentSize',
],
displayConditions: {
logic: 'AND',
sets: [
{
logic: 'AND',
inputs: [
{
name: 'enabled',
value: 'true',
condition: '===',
},
],
},
],
},
},
tooltip: `Specify the method to compare.
Estimated Final Size: Compare the estimated final output size to the input size.
Current Size: Compare the current output size to the input size.
`,
},
{
label: 'Threshold Size %',
name: 'thresholdPerc',
type: 'number',
defaultValue: '60',
inputUI: {
type: 'text',
displayConditions: {
logic: 'AND',
sets: [
{
logic: 'AND',
inputs: [
{
name: 'enabled',
value: 'true',
condition: '===',
},
],
},
],
},
},
tooltip: `Enter the threshold size percentage relative to the input size.
An error will be triggered if the estimated or current size exceeds this percentage.
For example, if the input size is 100MB and the threshold is 60%, the estimated final size or current size
must not surpass 60MB else an error will be given and processing will stop.
`,
},
{
label: 'Check Delay (seconds)',
name: 'checkDelaySeconds',
type: 'number',
defaultValue: '20',
inputUI: {
type: 'text',
displayConditions: {
logic: 'AND',
sets: [
{
logic: 'AND',
inputs: [
{
name: 'enabled',
value: 'true',
condition: '===',
},
],
},
],
},
},
tooltip: `
Specify the delay in seconds before beginning the comparison.
A larger delay gives more time for the estimated final size to stabilize.
`,
},
],
outputs: [
{
number: 1,
tooltip: 'Continue to next plugin',
},
],
});
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const plugin = (args: IpluginInputArgs):IpluginOutputArgs => {
const lib = require('../../../../../methods/lib')();
// eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign
args.inputs = lib.loadDefaultValues(args.inputs, details);
const enabled = Boolean(args.inputs.enabled);
const compareMethod = String(args.inputs.compareMethod);
const thresholdPerc = Number(args.inputs.thresholdPerc);
const checkDelaySeconds = Number(args.inputs.checkDelaySeconds);
// eslint-disable-next-line no-param-reassign
args.variables.liveSizeCompare = {
enabled,
compareMethod,
thresholdPerc,
checkDelaySeconds,
};
return {
outputFileObj: args.inputFileObj,
outputNumber: 1,
variables: args.variables,
};
};
export {
details,
plugin,
};

@ -122,6 +122,7 @@ const plugin = async (args:IpluginInputArgs):Promise<IpluginOutputArgs> => {
inputFileObj: args.inputFileObj, inputFileObj: args.inputFileObj,
logFullCliOutput: args.logFullCliOutput, logFullCliOutput: args.logFullCliOutput,
updateWorker: args.updateWorker, updateWorker: args.updateWorker,
args,
}); });
const res = await cli.runCli(); const res = await cli.runCli();

@ -165,6 +165,7 @@ const plugin = async (args: IpluginInputArgs): Promise<IpluginOutputArgs> => {
inputFileObj: args.inputFileObj, inputFileObj: args.inputFileObj,
logFullCliOutput: args.logFullCliOutput, logFullCliOutput: args.logFullCliOutput,
updateWorker: args.updateWorker, updateWorker: args.updateWorker,
args,
}); });
const res = await cli.runCli(); const res = await cli.runCli();

@ -15,7 +15,7 @@ const details = ():IpluginDetails => ({
tags: '', tags: '',
isStartPlugin: false, isStartPlugin: false,
pType: '', pType: '',
requiresVersion: '2.11.01', requiresVersion: '2.18.01',
sidebarPosition: -1, sidebarPosition: -1,
icon: 'faBell', icon: 'faBell',
inputs: [ inputs: [
@ -71,6 +71,7 @@ const plugin = async (args:IpluginInputArgs):Promise<IpluginOutputArgs> => {
inputFileObj: args.inputFileObj, inputFileObj: args.inputFileObj,
logFullCliOutput: args.logFullCliOutput, logFullCliOutput: args.logFullCliOutput,
updateWorker: args.updateWorker, updateWorker: args.updateWorker,
args,
}); });
const res = await cli.runCli(); const res = await cli.runCli();

@ -251,6 +251,7 @@ const plugin = async (args: IpluginInputArgs): Promise<IpluginOutputArgs> => {
inputFileObj: args.inputFileObj, inputFileObj: args.inputFileObj,
logFullCliOutput: args.logFullCliOutput, logFullCliOutput: args.logFullCliOutput,
updateWorker: args.updateWorker, updateWorker: args.updateWorker,
args,
}); });
const res = await cli.runCli(); const res = await cli.runCli();

@ -48,6 +48,7 @@ const plugin = async (args:IpluginInputArgs):Promise<IpluginOutputArgs> => {
inputFileObj: args.inputFileObj, inputFileObj: args.inputFileObj,
logFullCliOutput: args.logFullCliOutput, logFullCliOutput: args.logFullCliOutput,
updateWorker: args.updateWorker, updateWorker: args.updateWorker,
args,
}); });
const res = await cli.runCli(); const res = await cli.runCli();

@ -93,6 +93,7 @@ const plugin = async (args:IpluginInputArgs):Promise<IpluginOutputArgs> => {
inputFileObj: args.inputFileObj, inputFileObj: args.inputFileObj,
logFullCliOutput: args.logFullCliOutput, logFullCliOutput: args.logFullCliOutput,
updateWorker: args.updateWorker, updateWorker: args.updateWorker,
args,
}); });
const res = await cli.runCli(); const res = await cli.runCli();

@ -2,7 +2,7 @@ import fs from 'fs';
import { import {
editreadyParser, ffmpegParser, getHandBrakeFps, handbrakeParser, editreadyParser, ffmpegParser, getHandBrakeFps, handbrakeParser,
} from './cliParsers'; } from './cliParsers';
import { Ilog, IupdateWorker } from './interfaces/interfaces'; import { Ilog, IpluginInputArgs, IupdateWorker } from './interfaces/interfaces';
import { IFileObject, Istreams } from './interfaces/synced/IFileObject'; import { IFileObject, Istreams } from './interfaces/synced/IFileObject';
import { fileExists } from './fileUtils'; import { fileExists } from './fileUtils';
@ -71,6 +71,7 @@ interface Iconfig {
updateWorker: IupdateWorker, updateWorker: IupdateWorker,
logFullCliOutput: boolean, logFullCliOutput: boolean,
inputFileObj: IFileObject, inputFileObj: IFileObject,
args: IpluginInputArgs,
} }
class CLI { class CLI {
@ -89,6 +90,13 @@ class CLI {
hbPass = 0; hbPass = 0;
// eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/explicit-module-boundary-types
thread: any;
cancelled = false;
startTime = new Date().getTime();
constructor(config: Iconfig) { constructor(config: Iconfig) {
this.config = config; this.config = config;
} }
@ -156,6 +164,58 @@ class CLI {
this.lastProgCheck = n; this.lastProgCheck = n;
this.oldProgress = perc; this.oldProgress = perc;
const secondsSinceStart = (new Date().getTime() - this.startTime) / 1000;
// live size compare
if (
this.config.args.variables.liveSizeCompare?.enabled
) {
const {
compareMethod,
thresholdPerc,
checkDelaySeconds,
} = this.config.args.variables.liveSizeCompare;
if (secondsSinceStart > checkDelaySeconds) {
// MB
const inputFileSize = this.config.inputFileObj.file_size;
const inputFileSizeInGbytes = inputFileSize / 1024;
const cancel = (ratio:number) => {
this.config.jobLog(`Input file size: ${inputFileSizeInGbytes}GB`);
this.config.jobLog(`Ratio: ${ratio}%`);
this.config.jobLog(`Ratio is greater than threshold: ${thresholdPerc}%, cancelling job`);
this.cancelled = true;
this.killThread();
};
if (
compareMethod === 'estimatedFinalSize'
&& estSize !== undefined
&& estSize > 0
) {
const ratio = (estSize / inputFileSizeInGbytes) * 100;
if (ratio > thresholdPerc) {
this.config.jobLog(`Estimated final size: ${estSize}GB`);
cancel(ratio);
}
} else if (
compareMethod === 'currentSize'
&& outputFileSizeInGbytes !== undefined
&& outputFileSizeInGbytes > 0
) {
const ratio = (outputFileSizeInGbytes / inputFileSizeInGbytes) * 100;
if (ratio > thresholdPerc) {
this.config.jobLog(`Current output size: ${outputFileSizeInGbytes}GB`);
cancel(ratio);
}
}
}
}
} }
} }
} }
@ -255,8 +315,7 @@ class CLI {
} }
}; };
// eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/explicit-module-boundary-types killThread = (): void => {
killThread = (thread:any): void => {
const killArray = [ const killArray = [
'SIGKILL', 'SIGKILL',
'SIGHUP', 'SIGHUP',
@ -265,14 +324,14 @@ class CLI {
]; ];
try { try {
thread.kill(); this.thread.kill();
} catch (err) { } catch (err) {
// err // err
} }
killArray.forEach((com: string) => { killArray.forEach((com: string) => {
try { try {
thread.kill(com); this.thread.kill(com);
} catch (err) { } catch (err) {
// err // err
} }
@ -289,15 +348,12 @@ class CLI {
this.config.jobLog(`Running ${this.config.cli} ${this.config.spawnArgs.join(' ')}`); this.config.jobLog(`Running ${this.config.cli} ${this.config.spawnArgs.join(' ')}`);
// eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/explicit-module-boundary-types
let thread: any;
const exitHandler = () => { const exitHandler = () => {
if (thread) { if (this.thread) {
try { try {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log('Main thread exiting, cleaning up running CLI'); console.log('Main thread exiting, cleaning up running CLI');
this.killThread(thread); this.killThread();
} catch (err) { } catch (err) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log('Error running cliUtils on Exit function'); console.log('Error running cliUtils on Exit function');
@ -309,24 +365,24 @@ class CLI {
process.on('exit', exitHandler); process.on('exit', exitHandler);
const cliExitCode: number = await new Promise((resolve) => { let cliExitCode: number = await new Promise((resolve) => {
try { try {
const opts = this.config.spawnOpts || {}; const opts = this.config.spawnOpts || {};
const spawnArgs = this.config.spawnArgs.map((row) => row.trim()).filter((row) => row !== ''); const spawnArgs = this.config.spawnArgs.map((row) => row.trim()).filter((row) => row !== '');
thread = childProcess.spawn(this.config.cli, spawnArgs, opts); this.thread = childProcess.spawn(this.config.cli, spawnArgs, opts);
thread.stdout.on('data', (data: string) => { this.thread.stdout.on('data', (data: string) => {
errorLogFull.push(data.toString()); errorLogFull.push(data.toString());
this.parseOutput(data); this.parseOutput(data);
}); });
thread.stderr.on('data', (data: string) => { this.thread.stderr.on('data', (data: string) => {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
errorLogFull.push(data.toString()); errorLogFull.push(data.toString());
this.parseOutput(data); this.parseOutput(data);
}); });
thread.on('error', () => { this.thread.on('error', () => {
// catches execution error (bad file) // catches execution error (bad file)
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log(`Error executing binary: ${this.config.cli}`); console.log(`Error executing binary: ${this.config.cli}`);
@ -336,7 +392,7 @@ class CLI {
// thread.stdout.pipe(process.stdout); // thread.stdout.pipe(process.stdout);
// thread.stderr.pipe(process.stderr); // thread.stderr.pipe(process.stderr);
thread.on('close', (code: number) => { this.thread.on('close', (code: number) => {
if (code !== 0) { if (code !== 0) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log(`CLI error code: ${code}`); console.log(`CLI error code: ${code}`);
@ -355,12 +411,16 @@ class CLI {
process.removeListener('exit', exitHandler); process.removeListener('exit', exitHandler);
thread = undefined; this.thread = undefined;
if (!this.config.logFullCliOutput) { if (!this.config.logFullCliOutput) {
this.config.jobLog(errorLogFull.slice(-1000).join('')); this.config.jobLog(errorLogFull.slice(-1000).join(''));
} }
if (this.cancelled) {
cliExitCode = 1;
}
return { return {
cliExitCode, cliExitCode,
errorLogFull, errorLogFull,

@ -96,12 +96,20 @@ export interface IffmpegCommand {
overallOuputArguments: string[], overallOuputArguments: string[],
} }
export interface IliveSizeCompare {
enabled: boolean,
compareMethod: string,
thresholdPerc: number,
checkDelaySeconds: number,
}
export interface Ivariables { export interface Ivariables {
ffmpegCommand: IffmpegCommand, ffmpegCommand: IffmpegCommand,
flowFailed: boolean, flowFailed: boolean,
user: Record<string, string>, user: Record<string, string>,
healthCheck?: 'Success', healthCheck?: 'Success',
queueTags?: string, queueTags?: string,
liveSizeCompare?: IliveSizeCompare
} }
export interface IpluginOutputArgs { export interface IpluginOutputArgs {

Loading…
Cancel
Save