From 7521d7eef092bff84d95e631b67a2b91b422a643 Mon Sep 17 00:00:00 2001 From: HaveAGitGat <43864057+HaveAGitGat@users.noreply.github.com> Date: Sun, 20 Aug 2023 18:02:17 +0100 Subject: [PATCH] Init flow plugins --- .../ffmpegCommand10BitVideo/1.0.0/index.js | 36 +++ .../ffmpegCommandCropBlackBars/1.0.0/index.js | 36 +++ .../1.0.0/index.js | 36 +++ .../1.0.0/index.js | 36 +++ .../ffmpegCommandExecute/1.0.0/index.js | 153 +++++++++ .../ffmpegCommandHdrToSdr/1.0.0/index.js | 36 +++ .../1.0.0/index.js | 36 +++ .../1.0.0/index.js | 42 +++ .../1.0.0/index.js | 42 +++ .../ffmpegCommandRorderStreams/1.0.0/index.js | 36 +++ .../ffmpegCommandSetContainer/1.0.0/index.js | 52 +++ .../1.0.0/index.js | 36 +++ .../1.0.0/index.js | 73 +++++ .../ffmpegCommandSetVideoScale/1.0.0/index.js | 36 +++ .../ffmpegCommandStart/1.0.0/index.js | 55 ++++ .../ffmpegCommandVideoScale/1.0.0/index.js | 36 +++ .../file/checkFileMedium/1.0.0/index.js | 57 ++++ .../file/copyToDirectory/1.0.0/index.js | 52 +++ .../file/moveToDirectory/1.0.0/index.js | 35 +++ .../file/moveToDirectory/2.0.0/index.js | 36 +++ .../file/replaceOriginalFile/1.0.0/index.js | 122 ++++++++ .../input/inputFile/1.0.0/index.js | 35 +++ .../tools/unpack/1.0.0/index.js | 123 ++++++++ .../tools/webRequest/1.0.0/index.js | 123 ++++++++ .../video/checkVideoCodec/1.0.0/index.js | 62 ++++ .../video/checkVideoResolution/1.0.0/index.js | 67 ++++ .../video/transcodeVideo/1.0.0/index.js | 59 ++++ .../video/transcodeVideo/1.0.0/test.js | 1 + .../video/basicVideo.js | 199 ++++++++++++ FlowPlugins/FlowHelpers/1.0.0/cliParsers.js | 145 +++++++++ .../1.0.0/interfaces/interfaces.js | 2 + .../1.0.0/interfaces/synced/IFileObject.js | 2 + .../1.0.0/interfaces/synced/jobInterface.js | 2 + FlowPlugins/FlowHelpers/1.0.0/utils.js | 281 +++++++++++++++++ .../ffmpegCommand10BitVideo/1.0.0/index.ts | 43 +++ .../ffmpegCommandCropBlackBars/1.0.0/index.ts | 43 +++ .../1.0.0/index.ts | 43 +++ .../1.0.0/index.ts | 43 +++ .../ffmpegCommandExecute/1.0.0/index.ts | 132 ++++++++ .../ffmpegCommandHdrToSdr/1.0.0/index.ts | 43 +++ .../1.0.0/index.ts | 43 +++ .../1.0.0/index.ts | 52 +++ .../1.0.0/index.ts | 52 +++ .../ffmpegCommandRorderStreams/1.0.0/index.ts | 43 +++ .../ffmpegCommandSetContainer/1.0.0/index.ts | 61 ++++ .../1.0.0/index.ts | 43 +++ .../1.0.0/index.ts | 82 +++++ .../ffmpegCommandSetVideoScale/1.0.0/index.ts | 43 +++ .../ffmpegCommandStart/1.0.0/index.ts | 62 ++++ .../file/checkFileMedium/1.0.0/index.ts | 67 ++++ .../file/copyToDirectory/1.0.0/index.ts | 60 ++++ .../file/moveToDirectory/1.0.0/index.ts | 42 +++ .../file/moveToDirectory/2.0.0/index.ts | 44 +++ .../file/replaceOriginalFile/1.0.0/index.ts | 93 ++++++ .../input/inputFile/1.0.0/index.ts | 43 +++ .../tools/unpack/1.0.0/index.ts | 94 ++++++ .../tools/webRequest/1.0.0/index.ts | 94 ++++++ .../video/checkVideoCodec/1.0.0/index.ts | 71 +++++ .../video/checkVideoResolution/1.0.0/index.ts | 75 +++++ .../video/transcodeVideo/1.0.0/index.ts | 72 +++++ .../video/transcodeVideo/1.0.0/test.ts | 0 .../video/basicVideo.ts | 199 ++++++++++++ FlowPluginsTs/FlowHelpers/1.0.0/cliParsers.ts | 204 ++++++++++++ .../1.0.0/interfaces/interfaces.ts | 96 ++++++ .../1.0.0/interfaces/synced/IFileObject.ts | 197 ++++++++++++ .../1.0.0/interfaces/synced/jobInterface.ts | 10 + FlowPluginsTs/FlowHelpers/1.0.0/utils.ts | 296 ++++++++++++++++++ 67 files changed, 4765 insertions(+) create mode 100644 FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommand10BitVideo/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandCropBlackBars/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandCustomArguments/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandEnsureAudioStream/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandExecute/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandHdrToSdr/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandNormalizeAudio/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRemoveDataStreams/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRemoveSubtitles/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRorderStreams/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetContainer/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoBitrate/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoEncoder/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoScale/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandStart/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandVideoScale/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/file/checkFileMedium/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/file/copyToDirectory/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/file/moveToDirectory/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/file/moveToDirectory/2.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/file/replaceOriginalFile/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/input/inputFile/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/tools/unpack/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/tools/webRequest/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/video/checkVideoCodec/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/video/checkVideoResolution/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/video/transcodeVideo/1.0.0/index.js create mode 100644 FlowPlugins/CommunityFlowPlugins/video/transcodeVideo/1.0.0/test.js create mode 100644 FlowPlugins/CommunityFlowTemplates/video/basicVideo.js create mode 100644 FlowPlugins/FlowHelpers/1.0.0/cliParsers.js create mode 100644 FlowPlugins/FlowHelpers/1.0.0/interfaces/interfaces.js create mode 100644 FlowPlugins/FlowHelpers/1.0.0/interfaces/synced/IFileObject.js create mode 100644 FlowPlugins/FlowHelpers/1.0.0/interfaces/synced/jobInterface.js create mode 100644 FlowPlugins/FlowHelpers/1.0.0/utils.js create mode 100644 FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommand10BitVideo/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandCropBlackBars/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandCustomArguments/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandEnsureAudioStream/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandExecute/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandHdrToSdr/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandNormalizeAudio/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRemoveDataStreams/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRemoveSubtitles/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRorderStreams/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetContainer/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoBitrate/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoEncoder/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoScale/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandStart/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/file/checkFileMedium/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/file/copyToDirectory/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/file/moveToDirectory/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/file/moveToDirectory/2.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/file/replaceOriginalFile/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/input/inputFile/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/tools/unpack/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/tools/webRequest/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/video/checkVideoCodec/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/video/checkVideoResolution/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/video/transcodeVideo/1.0.0/index.ts create mode 100644 FlowPluginsTs/CommunityFlowPlugins/video/transcodeVideo/1.0.0/test.ts create mode 100644 FlowPluginsTs/CommunityFlowTemplates/video/basicVideo.ts create mode 100644 FlowPluginsTs/FlowHelpers/1.0.0/cliParsers.ts create mode 100644 FlowPluginsTs/FlowHelpers/1.0.0/interfaces/interfaces.ts create mode 100644 FlowPluginsTs/FlowHelpers/1.0.0/interfaces/synced/IFileObject.ts create mode 100644 FlowPluginsTs/FlowHelpers/1.0.0/interfaces/synced/jobInterface.ts create mode 100644 FlowPluginsTs/FlowHelpers/1.0.0/utils.ts diff --git a/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommand10BitVideo/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommand10BitVideo/1.0.0/index.js new file mode 100644 index 0000000..0990ba6 --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommand10BitVideo/1.0.0/index.js @@ -0,0 +1,36 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +var details = function () { return ({ + name: '10 Bit Video', + description: 'Set 10 Bit Video', + style: { + borderColor: '#6efefc', + opacity: 0.5, + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); }; +exports.details = details; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { + var lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandCropBlackBars/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandCropBlackBars/1.0.0/index.js new file mode 100644 index 0000000..af2727a --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandCropBlackBars/1.0.0/index.js @@ -0,0 +1,36 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +var details = function () { return ({ + name: 'Crop Black Bars', + description: 'Crop Black Bars', + style: { + borderColor: '#6efefc', + opacity: 0.5, + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); }; +exports.details = details; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { + var lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandCustomArguments/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandCustomArguments/1.0.0/index.js new file mode 100644 index 0000000..5f30691 --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandCustomArguments/1.0.0/index.js @@ -0,0 +1,36 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +var details = function () { return ({ + name: 'Custom Arguments', + description: 'Custom Arguments', + style: { + borderColor: '#6efefc', + opacity: 0.5, + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); }; +exports.details = details; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { + var lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandEnsureAudioStream/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandEnsureAudioStream/1.0.0/index.js new file mode 100644 index 0000000..0808373 --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandEnsureAudioStream/1.0.0/index.js @@ -0,0 +1,36 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +var details = function () { return ({ + name: 'Ensure Audio Stream', + description: 'Ensure that the file has an audio stream with set codec and channel count', + style: { + borderColor: '#6efefc', + opacity: 0.5, + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); }; +exports.details = details; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { + var lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandExecute/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandExecute/1.0.0/index.js new file mode 100644 index 0000000..70bf342 --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandExecute/1.0.0/index.js @@ -0,0 +1,153 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +var utils_1 = require("../../../../FlowHelpers/1.0.0/utils"); +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +var details = function () { return ({ + name: 'Execute', + description: 'Execute the created FFmpeg command', + style: { + borderColor: 'green', + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: 2, + icon: 'faPlay', + inputs: [], + outputs: [ + { + number: 1, + tooltip: 'File is 480p', + }, + { + number: 2, + tooltip: 'File is 576p', + }, + ], +}); }; +exports.details = details; +var getEncoder = function (codec) { + switch (codec) { + case 'h264': + return 'libx264'; + case 'hevc': + return 'libx265'; + default: + return codec; + } +}; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { return __awaiter(void 0, void 0, void 0, function () { + var lib, cliArgs, shouldProcess, outputFilePath, cli, res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + cliArgs = []; + cliArgs.push('-y'); + cliArgs.push('-i'); + cliArgs.push(args.inputFileObj._id); + shouldProcess = false; + // @ts-expect-error type + args.variables.ffmpegCommand.streams.forEach(function (stream) { + if (!stream.removed) { + cliArgs.push('-map'); + cliArgs.push("0:".concat(stream.index)); + cliArgs.push("-c:".concat(stream.index)); + args.jobLog(JSON.stringify({ stream: stream })); + if (args.inputs.forceProcess || stream.codec_name !== stream.targetCodec) { + shouldProcess = true; + cliArgs.push(getEncoder(stream.targetCodec)); + } + else { + cliArgs.push('copy'); + } + } + }); + if (!shouldProcess) { + args.jobLog('No need to process file, already as required'); + return [2 /*return*/, { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }]; + } + outputFilePath = "".concat(args.workDir, "/tempFile.").concat(args.variables.ffmpegCommand.container); + cliArgs.push(outputFilePath); + // @ts-expect-error type + args.deps.fsextra.ensureDirSync(args.workDir); + args.jobLog('Processing file'); + args.jobLog(JSON.stringify({ + cliArgs: cliArgs, + outputFilePath: outputFilePath, + })); + cli = new utils_1.CLI({ + cli: args.ffmpegPath, + spawnArgs: cliArgs, + spawnOpts: {}, + jobLog: args.jobLog, + outputFilePath: outputFilePath, + inputFileObj: args.inputFileObj, + logFullCliOutput: args.logFullCliOutput, + updateWorker: args.updateWorker, + }); + return [4 /*yield*/, cli.runCli()]; + case 1: + res = _a.sent(); + if (!args.logFullCliOutput) { + args.jobLog(res.errorLogFull.slice(-1000).join('')); + } + if (res.cliExitCode !== 0) { + args.jobLog('Running FFmpeg failed'); + throw new Error('FFmpeg failed'); + } + args.logOutcome('tSuc'); + return [2 /*return*/, { + outputFileObj: { + _id: outputFilePath, + }, + outputNumber: 1, + variables: args.variables, + }]; + } + }); +}); }; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandHdrToSdr/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandHdrToSdr/1.0.0/index.js new file mode 100644 index 0000000..0f5bd42 --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandHdrToSdr/1.0.0/index.js @@ -0,0 +1,36 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +var details = function () { return ({ + name: 'HDR to SDR', + description: 'Convert HDR to SDR', + style: { + borderColor: '#6efefc', + opacity: 0.5, + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); }; +exports.details = details; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { + var lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandNormalizeAudio/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandNormalizeAudio/1.0.0/index.js new file mode 100644 index 0000000..424b8fd --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandNormalizeAudio/1.0.0/index.js @@ -0,0 +1,36 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +var details = function () { return ({ + name: 'Normalize Audio', + description: 'Normalize Audio', + style: { + borderColor: '#6efefc', + opacity: 0.5, + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); }; +exports.details = details; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { + var lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRemoveDataStreams/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRemoveDataStreams/1.0.0/index.js new file mode 100644 index 0000000..85715e9 --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRemoveDataStreams/1.0.0/index.js @@ -0,0 +1,42 @@ +"use strict"; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint-disable no-param-reassign */ +var details = function () { return ({ + name: 'Remove Data Streams', + description: 'Remove Data Streams ', + style: { + borderColor: '#6efefc', + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); }; +exports.details = details; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { + var lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + // @ts-expect-error type + args.variables.ffmpegCommand.streams.forEach(function (stream) { + if (stream.codec_type === 'data') { + stream.removed = true; + } + }); + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRemoveSubtitles/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRemoveSubtitles/1.0.0/index.js new file mode 100644 index 0000000..2296e7a --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRemoveSubtitles/1.0.0/index.js @@ -0,0 +1,42 @@ +"use strict"; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint-disable no-param-reassign */ +var details = function () { return ({ + name: 'Remove Subtitles', + description: 'Remove subtitles from the file', + style: { + borderColor: '#6efefc', + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); }; +exports.details = details; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { + var lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + // @ts-expect-error type + args.variables.ffmpegCommand.streams.forEach(function (stream) { + if (stream.codec_type === 'subtitle') { + stream.removed = true; + } + }); + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRorderStreams/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRorderStreams/1.0.0/index.js new file mode 100644 index 0000000..1da68b5 --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRorderStreams/1.0.0/index.js @@ -0,0 +1,36 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +var details = function () { return ({ + name: 'Set Video Bitrate', + description: 'Set Video Bitrate', + style: { + borderColor: '#6efefc', + opacity: 0.5, + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); }; +exports.details = details; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { + var lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetContainer/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetContainer/1.0.0/index.js new file mode 100644 index 0000000..9c93015 --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetContainer/1.0.0/index.js @@ -0,0 +1,52 @@ +"use strict"; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint-disable no-param-reassign */ +var details = function () { return ({ + name: 'Set Container', + description: 'Set the container of the output file', + style: { + borderColor: '#6efefc', + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [ + { + name: 'container', + type: 'string', + defaultValue: 'mkv', + inputUI: { + type: 'dropdown', + options: [ + 'mkv', + 'mp4', + ], + }, + tooltip: 'Specify the container to use', + }, + ], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); }; +exports.details = details; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { + var lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + // @ts-expect-error type + args.variables.ffmpegCommand.container = args.inputs.container; + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoBitrate/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoBitrate/1.0.0/index.js new file mode 100644 index 0000000..1dc36c4 --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoBitrate/1.0.0/index.js @@ -0,0 +1,36 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +var details = function () { return ({ + name: 'Reorder Streams', + description: 'Reorder Streams', + style: { + borderColor: '#6efefc', + opacity: 0.5, + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); }; +exports.details = details; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { + var lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoEncoder/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoEncoder/1.0.0/index.js new file mode 100644 index 0000000..23ce59c --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoEncoder/1.0.0/index.js @@ -0,0 +1,73 @@ +"use strict"; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint-disable no-param-reassign */ +var details = function () { return ({ + name: 'Set Video Encoder', + description: 'Set the video encoder for all streams', + style: { + borderColor: '#6efefc', + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [ + { + name: 'targetCodec', + type: 'string', + defaultValue: 'hevc', + inputUI: { + type: 'dropdown', + options: [ + 'hevc', + // 'vp9', + 'h264', + // 'vp8', + ], + }, + tooltip: 'Specify the codec to use', + }, + { + name: 'forceEncoding', + type: 'boolean', + defaultValue: 'false', + inputUI: { + type: 'dropdown', + options: [ + 'false', + 'true', + ], + }, + tooltip: 'Specify whether to force encoding if stream already has the target codec', + }, + ], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); }; +exports.details = details; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { + var lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + // @ts-expect-error type + args.variables.ffmpegCommand.streams.forEach(function (stream) { + if (stream.codec_type === 'video') { + // @ts-expect-error type + stream.targetCodec = args.inputs.targetCodec; + stream.forceEncoding = args.inputs.forceEncoding; + } + }); + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoScale/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoScale/1.0.0/index.js new file mode 100644 index 0000000..4838ddf --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoScale/1.0.0/index.js @@ -0,0 +1,36 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +var details = function () { return ({ + name: 'Set Video Scale', + description: 'Change video scale', + style: { + borderColor: '#6efefc', + opacity: 0.5, + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); }; +exports.details = details; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { + var lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandStart/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandStart/1.0.0/index.js new file mode 100644 index 0000000..c677c4c --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandStart/1.0.0/index.js @@ -0,0 +1,55 @@ +"use strict"; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint-disable no-param-reassign */ +var details = function () { return ({ + name: 'Start', + description: 'Start FFmpeg Command', + style: { + borderColor: 'green', + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: 1, + icon: '', + inputs: [], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); }; +exports.details = details; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { + var lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + var containerParts = args.inputFileObj._id.split('.'); + var container = containerParts[containerParts.length - 1]; + var ffmpegCommand = { + inputFiles: [], + streams: JSON.parse(JSON.stringify(args.inputFileObj.ffProbeData.streams)).map(function (stream) { return (__assign(__assign({}, stream), { removed: false, targetCodec: stream.codec_name, args: [] })); }), + container: container, + }; + args.variables.ffmpegCommand = ffmpegCommand; + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandVideoScale/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandVideoScale/1.0.0/index.js new file mode 100644 index 0000000..3da2d18 --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandVideoScale/1.0.0/index.js @@ -0,0 +1,36 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +var details = function () { return ({ + name: 'Video Scale', + description: 'Change video scale', + style: { + borderColor: '#6efefc', + opacity: 0.5, + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); }; +exports.details = details; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { + var lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/file/checkFileMedium/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/file/checkFileMedium/1.0.0/index.js new file mode 100644 index 0000000..7f0c9ec --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/file/checkFileMedium/1.0.0/index.js @@ -0,0 +1,57 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +var details = function () { return ({ + name: 'Check File Medium', + description: 'Check if file is video, audio or other type of file', + style: { + borderColor: 'orange', + }, + tags: '', + isStartPlugin: false, + sidebarPosition: -1, + icon: 'faQuestion', + inputs: [], + outputs: [ + { + number: 1, + tooltip: 'File medium is a Video', + }, + { + number: 2, + tooltip: 'File medium is an Audio', + }, + { + number: 3, + tooltip: 'File medium is Other', + }, + ], +}); }; +exports.details = details; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { + var lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + var outputNumber = 1; + switch (args.inputFileObj.fileMedium) { + case 'video': + outputNumber = 1; + break; + case 'audio': + outputNumber = 2; + break; + case 'other': + outputNumber = 3; + break; + default: + throw new Error('File has no fileMedium!'); + } + return { + outputFileObj: args.inputFileObj, + outputNumber: outputNumber, + variables: args.variables, + }; +}; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/file/copyToDirectory/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/file/copyToDirectory/1.0.0/index.js new file mode 100644 index 0000000..3a5b507 --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/file/copyToDirectory/1.0.0/index.js @@ -0,0 +1,52 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +var details = function () { return ({ + name: 'Copy to Directory', + description: 'Copy the working file to a directory', + style: { + borderColor: 'green', + opacity: 0.5, + }, + tags: '', + isStartPlugin: false, + sidebarPosition: -1, + icon: 'faArrowRight', + inputs: [ + { + name: 'target_codec', + type: 'string', + defaultValue: 'hevc', + inputUI: { + type: 'dropdown', + options: [ + 'hevc', + // 'vp9', + 'h264', + // 'vp8', + ], + }, + tooltip: 'Specify the codec to use', + }, + ], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); }; +exports.details = details; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { + var lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/file/moveToDirectory/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/file/moveToDirectory/1.0.0/index.js new file mode 100644 index 0000000..0f6173d --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/file/moveToDirectory/1.0.0/index.js @@ -0,0 +1,35 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +var details = function () { return ({ + name: 'Move To Directory', + description: 'Move working file to directory.', + style: { + borderColor: 'green', + }, + tags: '', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); }; +exports.details = details; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { + var lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/file/moveToDirectory/2.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/file/moveToDirectory/2.0.0/index.js new file mode 100644 index 0000000..b92449a --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/file/moveToDirectory/2.0.0/index.js @@ -0,0 +1,36 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +var details = function () { return ({ + name: 'Move To Directory', + description: 'Move working file to directory.', + style: { + borderColor: 'green', + opacity: 0.5, + }, + tags: '', + isStartPlugin: false, + sidebarPosition: -1, + icon: 'faArrowRight', + inputs: [], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); }; +exports.details = details; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { + var lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/file/replaceOriginalFile/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/file/replaceOriginalFile/1.0.0/index.js new file mode 100644 index 0000000..5565bd6 --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/file/replaceOriginalFile/1.0.0/index.js @@ -0,0 +1,122 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +var details = function () { return ({ + name: 'Replace Original File', + description: 'Replace the origial file', + style: { + borderColor: 'green', + }, + tags: '', + isStartPlugin: false, + sidebarPosition: -1, + icon: 'faArrowRight', + inputs: [ + { + name: 'target_codec', + type: 'string', + defaultValue: 'hevc', + inputUI: { + type: 'dropdown', + options: [ + 'hevc', + // 'vp9', + 'h264', + // 'vp8', + ], + }, + tooltip: 'Specify the codec to use', + }, + ], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); }; +exports.details = details; +var getNewPath = function (originalPath, tempPath) { + var tempPathParts = tempPath.split('.'); + var container = tempPathParts[tempPathParts.length - 1]; + var originalPathParts = originalPath.split('.'); + originalPathParts[originalPathParts.length - 1] = container; + return originalPathParts.join('.'); +}; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { return __awaiter(void 0, void 0, void 0, function () { + var fs, lib, currentPath, newPath, newPathTmp; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + fs = require('fs'); + lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + currentPath = args.inputFileObj._id; + newPath = getNewPath(args.originalLibraryFile._id, currentPath); + newPathTmp = "".concat(newPath, ".tmp"); + args.jobLog(JSON.stringify({ + currentPath: currentPath, + newPath: newPath, + newPathTmp: newPathTmp, + })); + return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 2000); })]; + case 1: + _a.sent(); + fs.renameSync(currentPath, newPathTmp); + if (fs.existsSync(newPath)) { + fs.unlinkSync(newPath); + } + return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 2000); })]; + case 2: + _a.sent(); + fs.renameSync(newPathTmp, newPath); + return [2 /*return*/, { + outputFileObj: { + _id: newPath, + }, + outputNumber: 1, + variables: args.variables, + }]; + } + }); +}); }; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/input/inputFile/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/input/inputFile/1.0.0/index.js new file mode 100644 index 0000000..7c04a72 --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/input/inputFile/1.0.0/index.js @@ -0,0 +1,35 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +var details = function () { return ({ + name: 'Input File', + description: 'Transcode a video file using ffmpeg. GPU transcoding will be used if possible.', + style: { + borderColor: 'pink', + }, + tags: '', + isStartPlugin: true, + sidebarPosition: -1, + icon: '', + inputs: [], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); }; +exports.details = details; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { + var lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/tools/unpack/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/tools/unpack/1.0.0/index.js new file mode 100644 index 0000000..366c525 --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/tools/unpack/1.0.0/index.js @@ -0,0 +1,123 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +var details = function () { return ({ + name: 'Unpack File', + description: 'Unpack a file', + style: { + borderColor: 'green', + opacity: 0.5, + }, + tags: '', + isStartPlugin: false, + sidebarPosition: -1, + icon: 'faArrowRight', + inputs: [ + { + name: 'target_codec', + type: 'string', + defaultValue: 'hevc', + inputUI: { + type: 'dropdown', + options: [ + 'hevc', + // 'vp9', + 'h264', + // 'vp8', + ], + }, + tooltip: 'Specify the codec to use', + }, + ], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); }; +exports.details = details; +var getNewPath = function (originalPath, tempPath) { + var tempPathParts = tempPath.split('.'); + var container = tempPathParts[tempPathParts.length - 1]; + var originalPathParts = originalPath.split('.'); + originalPathParts[originalPathParts.length - 1] = container; + return originalPathParts.join('.'); +}; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { return __awaiter(void 0, void 0, void 0, function () { + var fs, lib, currentPath, newPath, newPathTmp; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + fs = require('fs'); + lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + currentPath = args.inputFileObj._id; + newPath = getNewPath(args.originalLibraryFile._id, currentPath); + newPathTmp = "".concat(newPath, ".tmp"); + args.jobLog(JSON.stringify({ + currentPath: currentPath, + newPath: newPath, + newPathTmp: newPathTmp, + })); + return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 2000); })]; + case 1: + _a.sent(); + fs.renameSync(currentPath, newPathTmp); + if (fs.existsSync(newPath)) { + fs.unlinkSync(newPath); + } + return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 2000); })]; + case 2: + _a.sent(); + fs.renameSync(newPathTmp, newPath); + return [2 /*return*/, { + outputFileObj: { + _id: newPath, + }, + outputNumber: 1, + variables: args.variables, + }]; + } + }); +}); }; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/tools/webRequest/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/tools/webRequest/1.0.0/index.js new file mode 100644 index 0000000..920a9b0 --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/tools/webRequest/1.0.0/index.js @@ -0,0 +1,123 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +var details = function () { return ({ + name: 'Send Web Request', + description: 'Send Web Request', + style: { + borderColor: 'green', + opacity: 0.5, + }, + tags: '', + isStartPlugin: false, + sidebarPosition: -1, + icon: 'faArrowRight', + inputs: [ + { + name: 'target_codec', + type: 'string', + defaultValue: 'hevc', + inputUI: { + type: 'dropdown', + options: [ + 'hevc', + // 'vp9', + 'h264', + // 'vp8', + ], + }, + tooltip: 'Specify the codec to use', + }, + ], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); }; +exports.details = details; +var getNewPath = function (originalPath, tempPath) { + var tempPathParts = tempPath.split('.'); + var container = tempPathParts[tempPathParts.length - 1]; + var originalPathParts = originalPath.split('.'); + originalPathParts[originalPathParts.length - 1] = container; + return originalPathParts.join('.'); +}; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { return __awaiter(void 0, void 0, void 0, function () { + var fs, lib, currentPath, newPath, newPathTmp; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + fs = require('fs'); + lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + currentPath = args.inputFileObj._id; + newPath = getNewPath(args.originalLibraryFile._id, currentPath); + newPathTmp = "".concat(newPath, ".tmp"); + args.jobLog(JSON.stringify({ + currentPath: currentPath, + newPath: newPath, + newPathTmp: newPathTmp, + })); + return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 2000); })]; + case 1: + _a.sent(); + fs.renameSync(currentPath, newPathTmp); + if (fs.existsSync(newPath)) { + fs.unlinkSync(newPath); + } + return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 2000); })]; + case 2: + _a.sent(); + fs.renameSync(newPathTmp, newPath); + return [2 /*return*/, { + outputFileObj: { + _id: newPath, + }, + outputNumber: 1, + variables: args.variables, + }]; + } + }); +}); }; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/video/checkVideoCodec/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/video/checkVideoCodec/1.0.0/index.js new file mode 100644 index 0000000..a53aa54 --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/video/checkVideoCodec/1.0.0/index.js @@ -0,0 +1,62 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +var details = function () { return ({ + name: 'Check Video Codec', + description: 'Check if a file has a specific video codec', + style: { + borderColor: 'orange', + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: 'faQuestion', + inputs: [ + { + name: 'codec', + type: 'string', + defaultValue: 'hevc', + inputUI: { + type: 'dropdown', + options: [ + 'hevc', + 'vp9', + 'h264', + 'vp8', + ], + }, + tooltip: 'Specify the codec check for', + }, + ], + outputs: [ + { + number: 1, + tooltip: 'File has codec', + }, + { + number: 2, + tooltip: 'File does not have codec', + }, + ], +}); }; +exports.details = details; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { + var lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + var hasCodec = false; + // @ts-expect-error type + args.inputFileObj.ffProbeData.streams.forEach(function (stream) { + if (stream.codec_type === 'video' && stream.codec_name === args.inputs.codec) { + hasCodec = true; + } + }); + return { + outputFileObj: args.inputFileObj, + outputNumber: hasCodec ? 1 : 2, + variables: args.variables, + }; +}; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/video/checkVideoResolution/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/video/checkVideoResolution/1.0.0/index.js new file mode 100644 index 0000000..bdbcfb2 --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/video/checkVideoResolution/1.0.0/index.js @@ -0,0 +1,67 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +var details = function () { return ({ + name: 'Check Video Resolution', + description: 'Check is video is 480p,576p,720p,1080p,1440p,4KUHD,DCI4K,8KUHD,Other', + style: { + borderColor: 'orange', + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: 'faQuestion', + inputs: [], + outputs: [ + { + number: 1, + tooltip: 'File is 480p', + }, + { + number: 2, + tooltip: 'File is 576p', + }, + { + number: 3, + tooltip: 'File is 720p', + }, + { + number: 4, + tooltip: 'File is 1080p', + }, + { + number: 5, + tooltip: 'File is 1440p', + }, + { + number: 6, + tooltip: 'File is 4KUHD', + }, + { + number: 7, + tooltip: 'File is DCI4K', + }, + { + number: 8, + tooltip: 'File is 8KUHD', + }, + { + number: 9, + tooltip: 'File is Other', + }, + ], +}); }; +exports.details = details; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { + var lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/video/transcodeVideo/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/video/transcodeVideo/1.0.0/index.js new file mode 100644 index 0000000..8a3a2cf --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/video/transcodeVideo/1.0.0/index.js @@ -0,0 +1,59 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.plugin = exports.details = void 0; +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +var details = function () { return ({ + name: 'Transcode Video File', + description: 'Transcode a video file using ffmpeg. GPU transcoding will be used if possible.', + style: { + borderColor: '#6efefc', + opacity: 0.5, + }, + tags: '', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [ + { + name: 'target_codec', + type: 'string', + defaultValue: 'hevc', + inputUI: { + type: 'dropdown', + options: [ + 'hevc', + // 'vp9', + 'h264', + // 'vp8', + ], + }, + tooltip: 'Specify the codec to use', + }, + ], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); }; +exports.details = details; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var plugin = function (args) { + var lib = require('../../../../../methods/lib')(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign + args.inputs = lib.loadDefaultValues(args.inputs, details); + var fs = require('fs'); + var oldFile = args.inputFileObj._id; + var newFile = "".concat(args.inputFileObj._id, ".tmp"); + if (fs.existsSync(newFile)) { + fs.unlinkSync(newFile); + } + fs.copyFileSync(oldFile, newFile); + return { + outputFileObj: { _id: newFile }, + outputNumber: 1, + variables: args.variables, + }; +}; +exports.plugin = plugin; diff --git a/FlowPlugins/CommunityFlowPlugins/video/transcodeVideo/1.0.0/test.js b/FlowPlugins/CommunityFlowPlugins/video/transcodeVideo/1.0.0/test.js new file mode 100644 index 0000000..3918c74 --- /dev/null +++ b/FlowPlugins/CommunityFlowPlugins/video/transcodeVideo/1.0.0/test.js @@ -0,0 +1 @@ +"use strict"; diff --git a/FlowPlugins/CommunityFlowTemplates/video/basicVideo.js b/FlowPlugins/CommunityFlowTemplates/video/basicVideo.js new file mode 100644 index 0000000..614ba97 --- /dev/null +++ b/FlowPlugins/CommunityFlowTemplates/video/basicVideo.js @@ -0,0 +1,199 @@ +"use strict"; +var details = function () { return ({ + name: 'Basic Video Template', + description: 'Basic Video Template', + tags: 'video', + flowPlugins: [ + { + id: 'nr55HwObs', + version: '1.0.0', + pluginName: 'inputFile', + inputsDB: {}, + position: { + x: 371.99540048613267, + y: -463.08388975391864, + }, + data: { + label: 'Input File', + }, + sourceRepo: 'Community', + }, + { + id: 'aDDcNO50Q', + version: '1.0.0', + pluginName: 'checkFileMedium', + inputsDB: {}, + position: { + x: 529.392455443893, + y: -349.448086326927, + }, + data: { + label: 'Check File Medium', + }, + sourceRepo: 'Community', + }, + { + id: 'dBwjiWjfA', + version: '1.0.0', + pluginName: 'replaceOriginalFile', + inputsDB: {}, + position: { + x: 517.8566785616271, + y: 145.89446592709146, + }, + data: { + label: 'Replace Original File', + }, + sourceRepo: 'Community', + }, + { + id: '1m231hS5K', + version: '1.0.0', + pluginName: 'ffmpegCommandSetVideoEncoder', + inputsDB: {}, + position: { + x: 104.71582826971436, + y: -44.833187887976514, + }, + data: { + label: 'Set Video Encoder', + }, + sourceRepo: 'Community', + }, + { + id: 'iYEwAG4rk', + version: '1.0.0', + pluginName: 'ffmpegCommandStart', + inputsDB: {}, + position: { + x: 138.43458422405857, + y: -149.36438875566702, + }, + data: { + label: 'Start', + }, + sourceRepo: 'Community', + }, + { + id: 'staFGJ7lQ', + version: '1.0.0', + pluginName: 'ffmpegCommandExecute', + inputsDB: {}, + position: { + x: 104.4813203353468, + y: 63.43024405079595, + }, + data: { + label: 'Execute', + }, + sourceRepo: 'Community', + }, + { + id: '3sQBco3U6', + version: '1.0.0', + pluginName: 'checkVideoCodec', + inputsDB: {}, + position: { + x: 252.92777615144564, + y: -274.3710285987198, + }, + data: { + label: 'Check if HEVC', + }, + sourceRepo: 'Community', + }, + ], + flowEdges: [ + { + source: 'nr55HwObs', + sourceHandle: '1', + target: 'aDDcNO50Q', + targetHandle: null, + animated: true, + type: 'smoothstep', + id: 'reactflow__edge-nr55HwObs1-aDDcNO50Q', + }, + { + source: 'aDDcNO50Q', + sourceHandle: '3', + target: 'dBwjiWjfA', + targetHandle: null, + animated: true, + type: 'smoothstep', + id: 'reactflow__edge-aDDcNO50Q3-dBwjiWjfA', + }, + { + source: 'aDDcNO50Q', + sourceHandle: '2', + target: 'dBwjiWjfA', + targetHandle: null, + animated: true, + type: 'smoothstep', + id: 'reactflow__edge-aDDcNO50Q2-dBwjiWjfA', + }, + { + source: 'iYEwAG4rk', + sourceHandle: '1', + target: '1m231hS5K', + targetHandle: null, + animated: true, + type: 'smoothstep', + id: 'reactflow__edge-iYEwAG4rk1-1m231hS5K', + }, + { + source: '1m231hS5K', + sourceHandle: '1', + target: 'staFGJ7lQ', + targetHandle: null, + animated: true, + type: 'smoothstep', + id: 'reactflow__edge-1m231hS5K1-staFGJ7lQ', + }, + { + source: 'staFGJ7lQ', + sourceHandle: '2', + target: 'dBwjiWjfA', + targetHandle: null, + animated: true, + type: 'smoothstep', + id: 'reactflow__edge-staFGJ7lQ2-dBwjiWjfA', + }, + { + source: 'staFGJ7lQ', + sourceHandle: '1', + target: 'dBwjiWjfA', + targetHandle: null, + animated: true, + type: 'smoothstep', + id: 'reactflow__edge-staFGJ7lQ1-dBwjiWjfA', + }, + { + source: 'aDDcNO50Q', + sourceHandle: '1', + target: '3sQBco3U6', + targetHandle: null, + animated: true, + type: 'smoothstep', + id: 'reactflow__edge-aDDcNO50Q1-3sQBco3U6', + }, + { + source: '3sQBco3U6', + sourceHandle: '1', + target: 'dBwjiWjfA', + targetHandle: null, + animated: true, + type: 'smoothstep', + id: 'reactflow__edge-3sQBco3U61-dBwjiWjfA', + }, + { + source: '3sQBco3U6', + sourceHandle: '2', + target: 'iYEwAG4rk', + targetHandle: null, + animated: true, + type: 'smoothstep', + id: 'reactflow__edge-3sQBco3U62-iYEwAG4rk', + }, + ], +}); }; +module.exports.details = details; diff --git a/FlowPlugins/FlowHelpers/1.0.0/cliParsers.js b/FlowPlugins/FlowHelpers/1.0.0/cliParsers.js new file mode 100644 index 0000000..ee72a82 --- /dev/null +++ b/FlowPlugins/FlowHelpers/1.0.0/cliParsers.js @@ -0,0 +1,145 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.editreadyParser = exports.getFFmpegVar = exports.getFFmpegPercentage = exports.ffmpegParser = exports.handbrakeParser = void 0; +var handbrakeParser = function (_a) { + var str = _a.str; + if (typeof str !== 'string') { + return 0; + } + var percentage = 0; + var numbers = '0123456789'; + var n = str.indexOf('%'); + if (str.length >= 6 + && str.indexOf('%') >= 6 + && numbers.includes(str.charAt(n - 5))) { + var output = str.substring(n - 6, n + 1); + var outputArr = output.split(''); + outputArr.splice(outputArr.length - 1, 1); + output = outputArr.join(''); + var outputNum = Number(output); + if (outputNum > 0) { + percentage = outputNum; + } + } + return percentage; +}; +exports.handbrakeParser = handbrakeParser; +// frame= 889 fps=106 q=26.0 Lsize= 25526kB time=00:00:35.69 bitrate=5858.3kbits/s speed=4.25x +var getFFmpegVar = function (_a) { + var str = _a.str, variable = _a.variable; + if (typeof str !== 'string') { + return ''; + } + var idx = str.indexOf(variable); + var out = ''; + var initSpacesEnded = false; + if (idx >= 0) { + var startIdx = idx + variable.length + 1; + for (var i = startIdx; i < str.length; i += 1) { + if (initSpacesEnded === true && str[i] === ' ') { + break; + } + else if (initSpacesEnded === false && str[i] !== ' ') { + initSpacesEnded = true; + } + if (initSpacesEnded === true && str[i] !== ' ') { + out += str[i]; + } + } + } + return out; +}; +exports.getFFmpegVar = getFFmpegVar; +var getFFmpegPercentage = function (_a) { + var f = _a.f, fc = _a.fc, vf = _a.vf, d = _a.d; + var frameCount01 = fc; + var VideoFrameRate = vf; + var Duration = d; + var perc = 0; + var frame = parseInt(f, 10); + frameCount01 = Math.ceil(frameCount01); + VideoFrameRate = Math.ceil(VideoFrameRate); + Duration = Math.ceil(Duration); + if (frameCount01 > 0) { + perc = ((frame / frameCount01) * 100); + } + else if (VideoFrameRate > 0 && Duration > 0) { + perc = ((frame / (VideoFrameRate * Duration)) * 100); + } + else { + perc = (frame); + } + var percString = perc.toFixed(2); + // eslint-disable-next-line no-restricted-globals + if (isNaN(perc)) { + return 0.00; + } + return parseFloat(percString); +}; +exports.getFFmpegPercentage = getFFmpegPercentage; +var ffmpegParser = function (_a) { + var str = _a.str, frameCount = _a.frameCount, videoFrameRate = _a.videoFrameRate, ffprobeDuration = _a.ffprobeDuration, metaDuration = _a.metaDuration; + if (typeof str !== 'string') { + return 0; + } + var percentage = 0; + if (str.length >= 6) { + var n = str.indexOf('fps'); + if (n >= 6) { + // get frame + var frame = getFFmpegVar({ + str: str, + variable: 'frame', + }); + var frameRate = videoFrameRate || 0; + var duration = 0; + if (ffprobeDuration + && parseFloat(ffprobeDuration) > 0) { + duration = parseFloat(ffprobeDuration); + } + else if (metaDuration) { + duration = metaDuration; + } + var per = getFFmpegPercentage({ + f: frame, + fc: frameCount, + vf: frameRate, + d: duration, + }); + var outputNum = Number(per); + if (outputNum > 0) { + percentage = outputNum; + } + } + } + return percentage; +}; +exports.ffmpegParser = ffmpegParser; +var editreadyParser = function (_a) { + var str = _a.str; + if (typeof str !== 'string') { + return 0; + } + var percentage = 0; + // const ex = 'STATUS: {"progress": "0.0000000"}'; + if (str.includes('STATUS:')) { + var parts = str.split('STATUS:'); + if (parts[1]) { + try { + var json = JSON.parse(parts[1]); + var progress = parseFloat(json.progress); + var percStr = (progress * 100).toFixed(2); + percentage = parseFloat(percStr); + } + catch (err) { + // err + } + } + } + // eslint-disable-next-line no-restricted-globals + if (isNaN(percentage)) { + return 0.00; + } + return percentage; +}; +exports.editreadyParser = editreadyParser; diff --git a/FlowPlugins/FlowHelpers/1.0.0/interfaces/interfaces.js b/FlowPlugins/FlowHelpers/1.0.0/interfaces/interfaces.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/FlowPlugins/FlowHelpers/1.0.0/interfaces/interfaces.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/FlowPlugins/FlowHelpers/1.0.0/interfaces/synced/IFileObject.js b/FlowPlugins/FlowHelpers/1.0.0/interfaces/synced/IFileObject.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/FlowPlugins/FlowHelpers/1.0.0/interfaces/synced/IFileObject.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/FlowPlugins/FlowHelpers/1.0.0/interfaces/synced/jobInterface.js b/FlowPlugins/FlowHelpers/1.0.0/interfaces/synced/jobInterface.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/FlowPlugins/FlowHelpers/1.0.0/interfaces/synced/jobInterface.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/FlowPlugins/FlowHelpers/1.0.0/utils.js b/FlowPlugins/FlowHelpers/1.0.0/utils.js new file mode 100644 index 0000000..84fdf96 --- /dev/null +++ b/FlowPlugins/FlowHelpers/1.0.0/utils.js @@ -0,0 +1,281 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.CLI = exports.getFFmpegVar = void 0; +var cliParsers_1 = require("./cliParsers"); +var fs = require('fs'); +var fancyTimeFormat = function (time) { + // Hours, minutes and seconds + // eslint-disable-next-line no-bitwise + var hrs = ~~(time / 3600); + // eslint-disable-next-line no-bitwise + var mins = ~~((time % 3600) / 60); + // eslint-disable-next-line no-bitwise + var secs = ~~time % 60; + // Output like "1:01" or "4:03:59" or "123:03:59" + var ret = ''; + // if (hrs > 0) { + ret += "".concat(hrs, ":").concat(mins < 10 ? '0' : ''); + // } + ret += "".concat(mins, ":").concat(secs < 10 ? '0' : ''); + ret += "".concat(secs); + return ret; +}; +// frame= 889 fps=106 q=26.0 Lsize= 25526kB time=00:00:35.69 bitrate=5858.3kbits/s speed=4.25x +var getFFmpegVar = function (_a) { + var str = _a.str, variable = _a.variable; + if (typeof str !== 'string') { + return ''; + } + var idx = str.indexOf(variable); + var out = ''; + var initSpacesEnded = false; + if (idx >= 0) { + var startIdx = idx + variable.length + 1; + for (var i = startIdx; i < str.length; i += 1) { + if (initSpacesEnded === true && str[i] === ' ') { + break; + } + else if (initSpacesEnded === false && str[i] !== ' ') { + initSpacesEnded = true; + } + if (initSpacesEnded === true && str[i] !== ' ') { + out += str[i]; + } + } + } + return out; +}; +exports.getFFmpegVar = getFFmpegVar; +var CLI = /** @class */ (function () { + function CLI(config) { + var _this = this; + // @ts-expect-error init + this.config = {}; + this.progAVG = []; + this.oldOutSize = 0; + this.oldEstSize = 0; + this.oldProgress = 0; + this.lastProgCheck = 0; + this.updateETA = function (perc) { + if (perc > 0) { + if (_this.lastProgCheck === 0) { + _this.lastProgCheck = new Date().getTime(); + _this.oldProgress = perc; + } + else if (perc !== _this.oldProgress) { + var n = new Date().getTime(); + var secsSinceLastCheck = (n - _this.lastProgCheck) / 1000; + if (secsSinceLastCheck > 1) { + // eta total + var eta = Math.round((100 / (perc - _this.oldProgress)) * secsSinceLastCheck); + // eta remaining + eta *= ((100 - perc) / 100); + _this.progAVG.push(eta); + // let values = [2, 56, 3, 41, 0, 4, 100, 23]; + var sum = _this.progAVG.reduce( + // eslint-disable-next-line + function (previous, current) { return (current += previous); }); + var avg = sum / _this.progAVG.length; + // est size + var estSize = 0; + var outputFileSizeInGbytes = void 0; + try { + if (fs.existsSync(_this.config.outputFilePath)) { + var singleFileSize = fs.statSync(_this.config.outputFilePath); + singleFileSize = singleFileSize.size; + outputFileSizeInGbytes = singleFileSize / (1024 * 1024 * 1024); + if (outputFileSizeInGbytes !== _this.oldOutSize) { + _this.oldOutSize = outputFileSizeInGbytes; + estSize = outputFileSizeInGbytes + + ((100 - perc) / perc) * outputFileSizeInGbytes; + _this.oldEstSize = estSize; + } + } + } + catch (err) { + // eslint-disable-next-line no-console + console.log(err); + } + _this.config.updateWorker({ + ETA: fancyTimeFormat(avg), + outputFileSizeInGbytes: outputFileSizeInGbytes === undefined ? 0 : outputFileSizeInGbytes, + estSize: _this.oldEstSize === undefined ? 0 : _this.oldEstSize, + }); + if (_this.progAVG.length > 30) { + _this.progAVG.splice(0, 1); + } + _this.lastProgCheck = n; + _this.oldProgress = perc; + } + } + } + }; + this.parseOutput = function (data) { + var _a, _b, _c, _d, _e, _f, _g; + var str = "".concat(data); + // + if (_this.config.logFullCliOutput === true) { + _this.config.jobLog(str); + } + if (_this.config.cli.toLowerCase().includes('handbrake')) { + var percentage = (0, cliParsers_1.handbrakeParser)({ + str: str, + }); + if (percentage > 0) { + _this.updateETA(percentage); + _this.config.updateWorker({ + percentage: percentage, + }); + } + } + else if (_this.config.cli.toLowerCase().includes('ffmpeg')) { + var n = str.indexOf('fps'); + var shouldUpdate = str.length >= 6 && n >= 6; + var fps = parseInt((0, exports.getFFmpegVar)({ + str: str, + variable: 'fps', + }), 10); + var frameCount = 0; + try { + // @ts-expect-error type + var frameCountTmp = (_a = _this.config.inputFileObj.ffProbeData) === null || _a === void 0 ? void 0 : _a.streams.filter(function (row) { return row.codec_type === 'video'; })[0].nb_frames; + if (frameCountTmp + // @ts-expect-error type + && !isNaN(frameCountTmp)) { // eslint-disable-line no-restricted-globals + // @ts-expect-error type + frameCount = frameCountTmp; + } + } + catch (err) { + // err + } + var percentage = (0, cliParsers_1.ffmpegParser)({ + str: str, + frameCount: frameCount, + videoFrameRate: (_c = (_b = _this.config.inputFileObj) === null || _b === void 0 ? void 0 : _b.meta) === null || _c === void 0 ? void 0 : _c.VideoFrameRate, + ffprobeDuration: (_e = (_d = _this.config.inputFileObj.ffProbeData) === null || _d === void 0 ? void 0 : _d.format) === null || _e === void 0 ? void 0 : _e.duration, + metaDuration: (_g = (_f = _this.config.inputFileObj) === null || _f === void 0 ? void 0 : _f.meta) === null || _g === void 0 ? void 0 : _g.Duration, + }); + if (shouldUpdate === true && fps > 0) { + _this.config.updateWorker({ + fps: fps, + }); + } + if (shouldUpdate === true && percentage > 0) { + _this.updateETA(percentage); + _this.config.updateWorker({ + percentage: percentage, + }); + } + } + else if (_this.config.cli.toLowerCase().includes('editready')) { + var percentage = (0, cliParsers_1.editreadyParser)({ + str: str, + }); + if (percentage > 0) { + _this.updateETA(percentage); + _this.config.updateWorker({ + percentage: percentage, + }); + } + } + }; + this.runCli = function () { return __awaiter(_this, void 0, void 0, function () { + var childProcess, errorLogFull, cliExitCode; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + childProcess = require('child_process'); + errorLogFull = []; + // eslint-disable-next-line no-console + console.log("Running ".concat(this.config.cli, " ").concat(this.config.spawnArgs.join(' '))); + return [4 /*yield*/, new Promise(function (resolve) { + try { + var opts = _this.config.spawnOpts || {}; + var thread = childProcess.spawn(_this.config.cli, _this.config.spawnArgs, opts); + thread.stdout.on('data', function (data) { + // eslint-disable-next-line no-console + console.log(data.toString()); + errorLogFull.push(data.toString()); + _this.parseOutput(data); + }); + thread.stderr.on('data', function (data) { + // eslint-disable-next-line no-console + console.log(data.toString()); + errorLogFull.push(data.toString()); + _this.parseOutput(data); + }); + thread.on('error', function () { + // catches execution error (bad file) + // eslint-disable-next-line no-console + console.log(1, "Error executing binary: ".concat(_this.config.cli)); + resolve(1); + }); + // thread.stdout.pipe(process.stdout); + // thread.stderr.pipe(process.stderr); + thread.on('close', function (code) { + if (code !== 0) { + // eslint-disable-next-line no-console + console.log(code, 'FFmpeg error'); + } + resolve(code); + }); + } + catch (err) { + // catches execution error (no file) + // eslint-disable-next-line no-console + console.log(1, "Error executing binary: ".concat(_this.config.cli)); + resolve(1); + } + })]; + case 1: + cliExitCode = _a.sent(); + return [2 /*return*/, { + cliExitCode: cliExitCode, + errorLogFull: errorLogFull, + }]; + } + }); + }); }; + this.config = config; + } + return CLI; +}()); +exports.CLI = CLI; diff --git a/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommand10BitVideo/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommand10BitVideo/1.0.0/index.ts new file mode 100644 index 0000000..0a8302b --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommand10BitVideo/1.0.0/index.ts @@ -0,0 +1,43 @@ +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +const details = () :IpluginDetails => ({ + name: '10 Bit Video', + description: 'Set 10 Bit Video', + style: { + borderColor: '#6efefc', + opacity: 0.5, + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + 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); + + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandCropBlackBars/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandCropBlackBars/1.0.0/index.ts new file mode 100644 index 0000000..c28801c --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandCropBlackBars/1.0.0/index.ts @@ -0,0 +1,43 @@ +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +const details = () :IpluginDetails => ({ + name: 'Crop Black Bars', + description: 'Crop Black Bars', + style: { + borderColor: '#6efefc', + opacity: 0.5, + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + 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); + + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandCustomArguments/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandCustomArguments/1.0.0/index.ts new file mode 100644 index 0000000..52392a0 --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandCustomArguments/1.0.0/index.ts @@ -0,0 +1,43 @@ +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +const details = () :IpluginDetails => ({ + name: 'Custom Arguments', + description: 'Custom Arguments', + style: { + borderColor: '#6efefc', + opacity: 0.5, + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + 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); + + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandEnsureAudioStream/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandEnsureAudioStream/1.0.0/index.ts new file mode 100644 index 0000000..d7d9365 --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandEnsureAudioStream/1.0.0/index.ts @@ -0,0 +1,43 @@ +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +const details = () :IpluginDetails => ({ + name: 'Ensure Audio Stream', + description: 'Ensure that the file has an audio stream with set codec and channel count', + style: { + borderColor: '#6efefc', + opacity: 0.5, + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + 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); + + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandExecute/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandExecute/1.0.0/index.ts new file mode 100644 index 0000000..a2f06f2 --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandExecute/1.0.0/index.ts @@ -0,0 +1,132 @@ +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; +import { CLI } from '../../../../FlowHelpers/1.0.0/utils'; + +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +const details = (): IpluginDetails => ({ + name: 'Execute', + description: 'Execute the created FFmpeg command', + style: { + borderColor: 'green', + }, + tags: 'video', + + isStartPlugin: false, + sidebarPosition: 2, + icon: 'faPlay', + inputs: [], + outputs: [ + { + number: 1, + tooltip: 'File is 480p', + }, + { + number: 2, + tooltip: 'File is 576p', + }, + ], +}); + +const getEncoder = (codec: string) => { + switch (codec) { + case 'h264': + return 'libx264'; + case 'hevc': + return 'libx265'; + default: + return codec; + } +}; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const plugin = async (args: IpluginInputArgs): Promise => { + 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 cliArgs: string[] = []; + + cliArgs.push('-y'); + cliArgs.push('-i'); + cliArgs.push(args.inputFileObj._id); + + let shouldProcess = false; + + // @ts-expect-error type + args.variables.ffmpegCommand.streams.forEach((stream) => { + if (!stream.removed) { + cliArgs.push('-map'); + cliArgs.push(`0:${stream.index}`); + cliArgs.push(`-c:${stream.index}`); + + args.jobLog(JSON.stringify({ stream })); + if (args.inputs.forceProcess || stream.codec_name !== stream.targetCodec) { + shouldProcess = true; + cliArgs.push(getEncoder(stream.targetCodec)); + } else { + cliArgs.push('copy'); + } + } + }); + + if (!shouldProcess) { + args.jobLog('No need to process file, already as required'); + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; + } + + // @ts-expect-error type + const outputFilePath = `${args.workDir}/tempFile.${args.variables.ffmpegCommand.container}`; + cliArgs.push(outputFilePath); + + // @ts-expect-error type + args.deps.fsextra.ensureDirSync(args.workDir); + + args.jobLog('Processing file'); + args.jobLog(JSON.stringify({ + cliArgs, + outputFilePath, + })); + + const cli = new CLI({ + cli: args.ffmpegPath, + spawnArgs: cliArgs, + spawnOpts: {}, + jobLog: args.jobLog, + outputFilePath, + inputFileObj: args.inputFileObj, + logFullCliOutput: args.logFullCliOutput, + updateWorker: args.updateWorker, + }); + + const res = await cli.runCli(); + + if (!args.logFullCliOutput) { + args.jobLog(res.errorLogFull.slice(-1000).join('')); + } + + if (res.cliExitCode !== 0) { + args.jobLog('Running FFmpeg failed'); + throw new Error('FFmpeg failed'); + } + + args.logOutcome('tSuc'); + + return { + outputFileObj: { + _id: outputFilePath, + }, + outputNumber: 1, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandHdrToSdr/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandHdrToSdr/1.0.0/index.ts new file mode 100644 index 0000000..4fa3be5 --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandHdrToSdr/1.0.0/index.ts @@ -0,0 +1,43 @@ +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +const details = () :IpluginDetails => ({ + name: 'HDR to SDR', + description: 'Convert HDR to SDR', + style: { + borderColor: '#6efefc', + opacity: 0.5, + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + 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); + + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandNormalizeAudio/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandNormalizeAudio/1.0.0/index.ts new file mode 100644 index 0000000..2b79ede --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandNormalizeAudio/1.0.0/index.ts @@ -0,0 +1,43 @@ +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +const details = () :IpluginDetails => ({ + name: 'Normalize Audio', + description: 'Normalize Audio', + style: { + borderColor: '#6efefc', + opacity: 0.5, + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + 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); + + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRemoveDataStreams/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRemoveDataStreams/1.0.0/index.ts new file mode 100644 index 0000000..7252de9 --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRemoveDataStreams/1.0.0/index.ts @@ -0,0 +1,52 @@ +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ + +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint-disable no-param-reassign */ +const details = ():IpluginDetails => ({ + name: 'Remove Data Streams', + description: 'Remove Data Streams ', + style: { + borderColor: '#6efefc', + }, + tags: 'video', + + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + 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); + + // @ts-expect-error type + args.variables.ffmpegCommand.streams.forEach((stream) => { + if (stream.codec_type === 'data') { + stream.removed = true; + } + }); + + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRemoveSubtitles/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRemoveSubtitles/1.0.0/index.ts new file mode 100644 index 0000000..4212b06 --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRemoveSubtitles/1.0.0/index.ts @@ -0,0 +1,52 @@ +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ + +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint-disable no-param-reassign */ +const details = ():IpluginDetails => ({ + name: 'Remove Subtitles', + description: 'Remove subtitles from the file', + style: { + borderColor: '#6efefc', + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + 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); + + // @ts-expect-error type + args.variables.ffmpegCommand.streams.forEach((stream) => { + if (stream.codec_type === 'subtitle') { + stream.removed = true; + } + }); + + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; + +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRorderStreams/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRorderStreams/1.0.0/index.ts new file mode 100644 index 0000000..6446a1d --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandRorderStreams/1.0.0/index.ts @@ -0,0 +1,43 @@ +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +const details = () :IpluginDetails => ({ + name: 'Set Video Bitrate', + description: 'Set Video Bitrate', + style: { + borderColor: '#6efefc', + opacity: 0.5, + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + 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); + + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetContainer/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetContainer/1.0.0/index.ts new file mode 100644 index 0000000..3815891 --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetContainer/1.0.0/index.ts @@ -0,0 +1,61 @@ +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ + +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint-disable no-param-reassign */ +const details = ():IpluginDetails => ({ + name: 'Set Container', + description: 'Set the container of the output file', + style: { + borderColor: '#6efefc', + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [ + { + name: 'container', + type: 'string', + defaultValue: 'mkv', + inputUI: { + type: 'dropdown', + options: [ + 'mkv', + 'mp4', + ], + }, + tooltip: 'Specify the container to use', + }, + ], + 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); + + // @ts-expect-error type + args.variables.ffmpegCommand.container = args.inputs.container; + + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoBitrate/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoBitrate/1.0.0/index.ts new file mode 100644 index 0000000..dca3703 --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoBitrate/1.0.0/index.ts @@ -0,0 +1,43 @@ +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +const details = () :IpluginDetails => ({ + name: 'Reorder Streams', + description: 'Reorder Streams', + style: { + borderColor: '#6efefc', + opacity: 0.5, + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + 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); + + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoEncoder/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoEncoder/1.0.0/index.ts new file mode 100644 index 0000000..b2f8d09 --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoEncoder/1.0.0/index.ts @@ -0,0 +1,82 @@ +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ + +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint-disable no-param-reassign */ +const details = () :IpluginDetails => ({ + name: 'Set Video Encoder', + description: 'Set the video encoder for all streams', + style: { + borderColor: '#6efefc', + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [ + { + name: 'targetCodec', + type: 'string', + defaultValue: 'hevc', + inputUI: { + type: 'dropdown', + options: [ + 'hevc', + // 'vp9', + 'h264', + // 'vp8', + ], + }, + tooltip: 'Specify the codec to use', + }, + { + name: 'forceEncoding', + type: 'boolean', + defaultValue: 'false', + inputUI: { + type: 'dropdown', + options: [ + 'false', + 'true', + ], + }, + tooltip: 'Specify whether to force encoding if stream already has the target codec', + }, + ], + 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); + + // @ts-expect-error type + args.variables.ffmpegCommand.streams.forEach((stream) => { + if (stream.codec_type === 'video') { + // @ts-expect-error type + stream.targetCodec = args.inputs.targetCodec; + stream.forceEncoding = args.inputs.forceEncoding; + } + }); + + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoScale/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoScale/1.0.0/index.ts new file mode 100644 index 0000000..620a636 --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoScale/1.0.0/index.ts @@ -0,0 +1,43 @@ +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +const details = () :IpluginDetails => ({ + name: 'Set Video Scale', + description: 'Change video scale', + style: { + borderColor: '#6efefc', + opacity: 0.5, + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + 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); + + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandStart/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandStart/1.0.0/index.ts new file mode 100644 index 0000000..1196c4e --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandStart/1.0.0/index.ts @@ -0,0 +1,62 @@ +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ + +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; +import { Istreams } from '../../../../FlowHelpers/1.0.0/interfaces/synced/IFileObject'; + +/* eslint-disable no-param-reassign */ +const details = () :IpluginDetails => ({ + name: 'Start', + description: 'Start FFmpeg Command', + style: { + borderColor: 'green', + }, + tags: 'video', + + isStartPlugin: false, + sidebarPosition: 1, + icon: '', + inputs: [], + 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 containerParts = args.inputFileObj._id.split('.'); + const container = containerParts[containerParts.length - 1]; + + const ffmpegCommand = { + inputFiles: [], + streams: JSON.parse(JSON.stringify(args.inputFileObj.ffProbeData.streams)).map((stream:Istreams) => ({ + ...stream, + removed: false, + targetCodec: stream.codec_name, + args: [], + })), + container, + }; + + args.variables.ffmpegCommand = ffmpegCommand; + + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/file/checkFileMedium/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/file/checkFileMedium/1.0.0/index.ts new file mode 100644 index 0000000..c3ac47e --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/file/checkFileMedium/1.0.0/index.ts @@ -0,0 +1,67 @@ +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +const details = (): IpluginDetails => ({ + name: 'Check File Medium', + description: 'Check if file is video, audio or other type of file', + style: { + borderColor: 'orange', + }, + tags: '', + + isStartPlugin: false, + sidebarPosition: -1, + icon: 'faQuestion', + inputs: [], + outputs: [ + { + number: 1, + tooltip: 'File medium is a Video', + + }, + { + number: 2, + tooltip: 'File medium is an Audio', + }, + { + number: 3, + tooltip: 'File medium is Other', + }, + ], +}); + +// 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); + + let outputNumber = 1; + switch (args.inputFileObj.fileMedium) { + case 'video': + outputNumber = 1; + break; + case 'audio': + outputNumber = 2; + break; + case 'other': + outputNumber = 3; + break; + default: + throw new Error('File has no fileMedium!'); + } + + return { + outputFileObj: args.inputFileObj, + outputNumber, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/file/copyToDirectory/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/file/copyToDirectory/1.0.0/index.ts new file mode 100644 index 0000000..000b7d8 --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/file/copyToDirectory/1.0.0/index.ts @@ -0,0 +1,60 @@ +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +const details = ():IpluginDetails => ({ + name: 'Copy to Directory', + description: 'Copy the working file to a directory', + style: { + borderColor: 'green', + opacity: 0.5, + }, + tags: '', + + isStartPlugin: false, + sidebarPosition: -1, + icon: 'faArrowRight', + inputs: [ + { + name: 'target_codec', + type: 'string', + defaultValue: 'hevc', + inputUI: { + type: 'dropdown', + options: [ + 'hevc', + // 'vp9', + 'h264', + // 'vp8', + ], + }, + tooltip: 'Specify the codec to use', + }, + ], + 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); + + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/file/moveToDirectory/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/file/moveToDirectory/1.0.0/index.ts new file mode 100644 index 0000000..8fbcbcd --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/file/moveToDirectory/1.0.0/index.ts @@ -0,0 +1,42 @@ +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +const details = ():IpluginDetails => ({ + name: 'Move To Directory', + description: 'Move working file to directory.', + style: { + borderColor: 'green', + }, + tags: '', + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [], + 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); + + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/file/moveToDirectory/2.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/file/moveToDirectory/2.0.0/index.ts new file mode 100644 index 0000000..631230a --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/file/moveToDirectory/2.0.0/index.ts @@ -0,0 +1,44 @@ +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +const details = ():IpluginDetails => ({ + name: 'Move To Directory', + description: 'Move working file to directory.', + style: { + borderColor: 'green', + opacity: 0.5, + }, + tags: '', + + isStartPlugin: false, + sidebarPosition: -1, + icon: 'faArrowRight', + inputs: [], + 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); + + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/file/replaceOriginalFile/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/file/replaceOriginalFile/1.0.0/index.ts new file mode 100644 index 0000000..0d9cc1c --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/file/replaceOriginalFile/1.0.0/index.ts @@ -0,0 +1,93 @@ +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +const details = ():IpluginDetails => ({ + name: 'Replace Original File', + description: 'Replace the origial file', + style: { + borderColor: 'green', + }, + tags: '', + isStartPlugin: false, + sidebarPosition: -1, + icon: 'faArrowRight', + inputs: [ + { + name: 'target_codec', + type: 'string', + defaultValue: 'hevc', + inputUI: { + type: 'dropdown', + options: [ + 'hevc', + // 'vp9', + 'h264', + // 'vp8', + ], + }, + tooltip: 'Specify the codec to use', + }, + ], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); + +const getNewPath = (originalPath:string, tempPath:string) => { + const tempPathParts = tempPath.split('.'); + const container = tempPathParts[tempPathParts.length - 1]; + + const originalPathParts = originalPath.split('.'); + + originalPathParts[originalPathParts.length - 1] = container; + + return originalPathParts.join('.'); +}; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const plugin = async (args:IpluginInputArgs):Promise => { + const fs = require('fs'); + 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 currentPath = args.inputFileObj._id; + const newPath = getNewPath(args.originalLibraryFile._id, currentPath); + const newPathTmp = `${newPath}.tmp`; + + args.jobLog(JSON.stringify({ + currentPath, + newPath, + newPathTmp, + })); + + await new Promise((resolve) => setTimeout(resolve, 2000)); + + fs.renameSync(currentPath, newPathTmp); + + if (fs.existsSync(newPath)) { + fs.unlinkSync(newPath); + } + + await new Promise((resolve) => setTimeout(resolve, 2000)); + fs.renameSync(newPathTmp, newPath); + + return { + outputFileObj: { + _id: newPath, + }, + outputNumber: 1, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/input/inputFile/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/input/inputFile/1.0.0/index.ts new file mode 100644 index 0000000..18f4368 --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/input/inputFile/1.0.0/index.ts @@ -0,0 +1,43 @@ +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +const details = ():IpluginDetails => ({ + name: 'Input File', + description: 'Transcode a video file using ffmpeg. GPU transcoding will be used if possible.', + style: { + borderColor: 'pink', + }, + tags: '', + + isStartPlugin: true, + sidebarPosition: -1, + icon: '', + inputs: [], + 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); + + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/tools/unpack/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/tools/unpack/1.0.0/index.ts new file mode 100644 index 0000000..64ff22f --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/tools/unpack/1.0.0/index.ts @@ -0,0 +1,94 @@ +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +const details = ():IpluginDetails => ({ + name: 'Unpack File', + description: 'Unpack a file', + style: { + borderColor: 'green', + opacity: 0.5, + }, + tags: '', + isStartPlugin: false, + sidebarPosition: -1, + icon: 'faArrowRight', + inputs: [ + { + name: 'target_codec', + type: 'string', + defaultValue: 'hevc', + inputUI: { + type: 'dropdown', + options: [ + 'hevc', + // 'vp9', + 'h264', + // 'vp8', + ], + }, + tooltip: 'Specify the codec to use', + }, + ], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); + +const getNewPath = (originalPath:string, tempPath:string) => { + const tempPathParts = tempPath.split('.'); + const container = tempPathParts[tempPathParts.length - 1]; + + const originalPathParts = originalPath.split('.'); + + originalPathParts[originalPathParts.length - 1] = container; + + return originalPathParts.join('.'); +}; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const plugin = async (args:IpluginInputArgs):Promise => { + const fs = require('fs'); + 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 currentPath = args.inputFileObj._id; + const newPath = getNewPath(args.originalLibraryFile._id, currentPath); + const newPathTmp = `${newPath}.tmp`; + + args.jobLog(JSON.stringify({ + currentPath, + newPath, + newPathTmp, + })); + + await new Promise((resolve) => setTimeout(resolve, 2000)); + + fs.renameSync(currentPath, newPathTmp); + + if (fs.existsSync(newPath)) { + fs.unlinkSync(newPath); + } + + await new Promise((resolve) => setTimeout(resolve, 2000)); + fs.renameSync(newPathTmp, newPath); + + return { + outputFileObj: { + _id: newPath, + }, + outputNumber: 1, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/tools/webRequest/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/tools/webRequest/1.0.0/index.ts new file mode 100644 index 0000000..8b90ce6 --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/tools/webRequest/1.0.0/index.ts @@ -0,0 +1,94 @@ +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +const details = ():IpluginDetails => ({ + name: 'Send Web Request', + description: 'Send Web Request', + style: { + borderColor: 'green', + opacity: 0.5, + }, + tags: '', + isStartPlugin: false, + sidebarPosition: -1, + icon: 'faArrowRight', + inputs: [ + { + name: 'target_codec', + type: 'string', + defaultValue: 'hevc', + inputUI: { + type: 'dropdown', + options: [ + 'hevc', + // 'vp9', + 'h264', + // 'vp8', + ], + }, + tooltip: 'Specify the codec to use', + }, + ], + outputs: [ + { + number: 1, + tooltip: 'Continue to next plugin', + }, + ], +}); + +const getNewPath = (originalPath:string, tempPath:string) => { + const tempPathParts = tempPath.split('.'); + const container = tempPathParts[tempPathParts.length - 1]; + + const originalPathParts = originalPath.split('.'); + + originalPathParts[originalPathParts.length - 1] = container; + + return originalPathParts.join('.'); +}; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const plugin = async (args:IpluginInputArgs):Promise => { + const fs = require('fs'); + 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 currentPath = args.inputFileObj._id; + const newPath = getNewPath(args.originalLibraryFile._id, currentPath); + const newPathTmp = `${newPath}.tmp`; + + args.jobLog(JSON.stringify({ + currentPath, + newPath, + newPathTmp, + })); + + await new Promise((resolve) => setTimeout(resolve, 2000)); + + fs.renameSync(currentPath, newPathTmp); + + if (fs.existsSync(newPath)) { + fs.unlinkSync(newPath); + } + + await new Promise((resolve) => setTimeout(resolve, 2000)); + fs.renameSync(newPathTmp, newPath); + + return { + outputFileObj: { + _id: newPath, + }, + outputNumber: 1, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/video/checkVideoCodec/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/video/checkVideoCodec/1.0.0/index.ts new file mode 100644 index 0000000..d9c8bac --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/video/checkVideoCodec/1.0.0/index.ts @@ -0,0 +1,71 @@ +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +const details = ():IpluginDetails => ({ + name: 'Check Video Codec', + description: 'Check if a file has a specific video codec', + style: { + borderColor: 'orange', + }, + tags: 'video', + isStartPlugin: false, + sidebarPosition: -1, + icon: 'faQuestion', + inputs: [ + { + name: 'codec', + type: 'string', + defaultValue: 'hevc', + inputUI: { + type: 'dropdown', + options: [ + 'hevc', + 'vp9', + 'h264', + 'vp8', + ], + }, + tooltip: 'Specify the codec check for', + }, + ], + outputs: [ + { + number: 1, + tooltip: 'File has codec', + }, + { + number: 2, + tooltip: 'File does not have codec', + }, + ], +}); + +// 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); + + let hasCodec = false; + + // @ts-expect-error type + args.inputFileObj.ffProbeData.streams.forEach((stream) => { + if (stream.codec_type === 'video' && stream.codec_name === args.inputs.codec) { + hasCodec = true; + } + }); + + return { + outputFileObj: args.inputFileObj, + outputNumber: hasCodec ? 1 : 2, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/video/checkVideoResolution/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/video/checkVideoResolution/1.0.0/index.ts new file mode 100644 index 0000000..cc38a4e --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/video/checkVideoResolution/1.0.0/index.ts @@ -0,0 +1,75 @@ +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +const details = ():IpluginDetails => ({ + name: 'Check Video Resolution', + description: 'Check is video is 480p,576p,720p,1080p,1440p,4KUHD,DCI4K,8KUHD,Other', + style: { + borderColor: 'orange', + }, + tags: 'video', + + isStartPlugin: false, + sidebarPosition: -1, + icon: 'faQuestion', + inputs: [], + outputs: [ + { + number: 1, + tooltip: 'File is 480p', + }, + { + number: 2, + tooltip: 'File is 576p', + }, + { + number: 3, + tooltip: 'File is 720p', + }, + { + number: 4, + tooltip: 'File is 1080p', + }, + { + number: 5, + tooltip: 'File is 1440p', + }, + { + number: 6, + tooltip: 'File is 4KUHD', + }, + { + number: 7, + tooltip: 'File is DCI4K', + }, + { + number: 8, + tooltip: 'File is 8KUHD', + }, + { + number: 9, + tooltip: 'File is Other', + }, + ], +}); + +// 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); + + return { + outputFileObj: args.inputFileObj, + outputNumber: 1, + variables: args.variables, + }; +}; +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/video/transcodeVideo/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/video/transcodeVideo/1.0.0/index.ts new file mode 100644 index 0000000..4fbfd44 --- /dev/null +++ b/FlowPluginsTs/CommunityFlowPlugins/video/transcodeVideo/1.0.0/index.ts @@ -0,0 +1,72 @@ +import { + IpluginDetails, + IpluginInputArgs, + IpluginOutputArgs, +} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces'; + +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +const details = ():IpluginDetails => ({ + name: 'Transcode Video File', + description: 'Transcode a video file using ffmpeg. GPU transcoding will be used if possible.', + style: { + borderColor: '#6efefc', + opacity: 0.5, + }, + tags: '', + + isStartPlugin: false, + sidebarPosition: -1, + icon: '', + inputs: [ + { + name: 'target_codec', + type: 'string', + defaultValue: 'hevc', + inputUI: { + type: 'dropdown', + options: [ + 'hevc', + // 'vp9', + 'h264', + // 'vp8', + ], + }, + tooltip: 'Specify the codec to use', + }, + ], + 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 fs = require('fs'); + + const oldFile = args.inputFileObj._id; + const newFile = `${args.inputFileObj._id}.tmp`; + + if (fs.existsSync(newFile)) { + fs.unlinkSync(newFile); + } + + fs.copyFileSync(oldFile, newFile); + + return { + outputFileObj: { _id: newFile }, + outputNumber: 1, + variables: args.variables, + }; +}; + +export { + details, + plugin, +}; diff --git a/FlowPluginsTs/CommunityFlowPlugins/video/transcodeVideo/1.0.0/test.ts b/FlowPluginsTs/CommunityFlowPlugins/video/transcodeVideo/1.0.0/test.ts new file mode 100644 index 0000000..e69de29 diff --git a/FlowPluginsTs/CommunityFlowTemplates/video/basicVideo.ts b/FlowPluginsTs/CommunityFlowTemplates/video/basicVideo.ts new file mode 100644 index 0000000..10650dd --- /dev/null +++ b/FlowPluginsTs/CommunityFlowTemplates/video/basicVideo.ts @@ -0,0 +1,199 @@ +const details = () => ({ + name: 'Basic Video Template', + description: 'Basic Video Template', + tags: 'video', + flowPlugins: [ + { + id: 'nr55HwObs', + version: '1.0.0', + pluginName: 'inputFile', + inputsDB: {}, + position: { + x: 371.99540048613267, + y: -463.08388975391864, + }, + data: { + label: 'Input File', + }, + sourceRepo: 'Community', + }, + { + id: 'aDDcNO50Q', + version: '1.0.0', + pluginName: 'checkFileMedium', + inputsDB: {}, + position: { + x: 529.392455443893, + y: -349.448086326927, + }, + data: { + label: 'Check File Medium', + }, + sourceRepo: 'Community', + }, + { + id: 'dBwjiWjfA', + version: '1.0.0', + pluginName: 'replaceOriginalFile', + inputsDB: {}, + position: { + x: 517.8566785616271, + y: 145.89446592709146, + }, + data: { + label: 'Replace Original File', + }, + sourceRepo: 'Community', + }, + { + id: '1m231hS5K', + version: '1.0.0', + pluginName: 'ffmpegCommandSetVideoEncoder', + inputsDB: {}, + position: { + x: 104.71582826971436, + y: -44.833187887976514, + }, + data: { + label: 'Set Video Encoder', + }, + sourceRepo: 'Community', + }, + { + id: 'iYEwAG4rk', + version: '1.0.0', + pluginName: 'ffmpegCommandStart', + inputsDB: {}, + position: { + x: 138.43458422405857, + y: -149.36438875566702, + }, + data: { + label: 'Start', + }, + sourceRepo: 'Community', + }, + { + id: 'staFGJ7lQ', + version: '1.0.0', + pluginName: 'ffmpegCommandExecute', + inputsDB: {}, + position: { + x: 104.4813203353468, + y: 63.43024405079595, + }, + data: { + label: 'Execute', + }, + sourceRepo: 'Community', + }, + { + id: '3sQBco3U6', + version: '1.0.0', + pluginName: 'checkVideoCodec', + inputsDB: {}, + position: { + x: 252.92777615144564, + y: -274.3710285987198, + }, + data: { + label: 'Check if HEVC', + }, + sourceRepo: 'Community', + }, + ], + flowEdges: [ + { + source: 'nr55HwObs', + sourceHandle: '1', + target: 'aDDcNO50Q', + targetHandle: null, + animated: true, + type: 'smoothstep', + id: 'reactflow__edge-nr55HwObs1-aDDcNO50Q', + }, + { + source: 'aDDcNO50Q', + sourceHandle: '3', + target: 'dBwjiWjfA', + targetHandle: null, + animated: true, + type: 'smoothstep', + id: 'reactflow__edge-aDDcNO50Q3-dBwjiWjfA', + }, + { + source: 'aDDcNO50Q', + sourceHandle: '2', + target: 'dBwjiWjfA', + targetHandle: null, + animated: true, + type: 'smoothstep', + id: 'reactflow__edge-aDDcNO50Q2-dBwjiWjfA', + }, + { + source: 'iYEwAG4rk', + sourceHandle: '1', + target: '1m231hS5K', + targetHandle: null, + animated: true, + type: 'smoothstep', + id: 'reactflow__edge-iYEwAG4rk1-1m231hS5K', + }, + { + source: '1m231hS5K', + sourceHandle: '1', + target: 'staFGJ7lQ', + targetHandle: null, + animated: true, + type: 'smoothstep', + id: 'reactflow__edge-1m231hS5K1-staFGJ7lQ', + }, + { + source: 'staFGJ7lQ', + sourceHandle: '2', + target: 'dBwjiWjfA', + targetHandle: null, + animated: true, + type: 'smoothstep', + id: 'reactflow__edge-staFGJ7lQ2-dBwjiWjfA', + }, + { + source: 'staFGJ7lQ', + sourceHandle: '1', + target: 'dBwjiWjfA', + targetHandle: null, + animated: true, + type: 'smoothstep', + id: 'reactflow__edge-staFGJ7lQ1-dBwjiWjfA', + }, + { + source: 'aDDcNO50Q', + sourceHandle: '1', + target: '3sQBco3U6', + targetHandle: null, + animated: true, + type: 'smoothstep', + id: 'reactflow__edge-aDDcNO50Q1-3sQBco3U6', + }, + { + source: '3sQBco3U6', + sourceHandle: '1', + target: 'dBwjiWjfA', + targetHandle: null, + animated: true, + type: 'smoothstep', + id: 'reactflow__edge-3sQBco3U61-dBwjiWjfA', + }, + { + source: '3sQBco3U6', + sourceHandle: '2', + target: 'iYEwAG4rk', + targetHandle: null, + animated: true, + type: 'smoothstep', + id: 'reactflow__edge-3sQBco3U62-iYEwAG4rk', + }, + ], +}); + +module.exports.details = details; diff --git a/FlowPluginsTs/FlowHelpers/1.0.0/cliParsers.ts b/FlowPluginsTs/FlowHelpers/1.0.0/cliParsers.ts new file mode 100644 index 0000000..a9604d9 --- /dev/null +++ b/FlowPluginsTs/FlowHelpers/1.0.0/cliParsers.ts @@ -0,0 +1,204 @@ +const handbrakeParser = ({ + str, +}: + { + str: string + }): number => { + if (typeof str !== 'string') { + return 0; + } + + let percentage = 0; + const numbers = '0123456789'; + const n = str.indexOf('%'); + + if ( + str.length >= 6 + && str.indexOf('%') >= 6 + && numbers.includes(str.charAt(n - 5)) + ) { + let output: string = str.substring(n - 6, n + 1); + const outputArr: string[] = output.split(''); + outputArr.splice(outputArr.length - 1, 1); + output = outputArr.join(''); + + const outputNum = Number(output); + if (outputNum > 0) { + percentage = outputNum; + } + } + + return percentage; +}; + +// frame= 889 fps=106 q=26.0 Lsize= 25526kB time=00:00:35.69 bitrate=5858.3kbits/s speed=4.25x +const getFFmpegVar = ({ + str, + variable, +}: { + str: string, variable: string +}): string => { + if (typeof str !== 'string') { + return ''; + } + + const idx = str.indexOf(variable); + + let out = ''; + let initSpacesEnded = false; + + if (idx >= 0) { + const startIdx = idx + variable.length + 1; + for (let i = startIdx; i < str.length; i += 1) { + if (initSpacesEnded === true && str[i] === ' ') { + break; + } else if (initSpacesEnded === false && str[i] !== ' ') { + initSpacesEnded = true; + } + + if (initSpacesEnded === true && str[i] !== ' ') { + out += str[i]; + } + } + } + + return out; +}; + +const getFFmpegPercentage = ({ + f, + fc, + vf, + d, +}: { + + f: string, fc: number, vf: number, d: number +}): number => { + let frameCount01: number = fc; + let VideoFrameRate: number = vf; + let Duration: number = d; + + let perc = 0; + + const frame: number = parseInt(f, 10); + frameCount01 = Math.ceil(frameCount01); + VideoFrameRate = Math.ceil(VideoFrameRate); + Duration = Math.ceil(Duration); + + if (frameCount01 > 0) { + perc = ((frame / frameCount01) * 100); + } else if (VideoFrameRate > 0 && Duration > 0) { + perc = ((frame / (VideoFrameRate * Duration)) * 100); + } else { + perc = (frame); + } + + const percString = perc.toFixed(2); + + // eslint-disable-next-line no-restricted-globals + if (isNaN(perc)) { + return 0.00; + } + + return parseFloat(percString); +}; + +const ffmpegParser = ({ + str, + frameCount, + + videoFrameRate, + ffprobeDuration, + metaDuration, +}: { + str: string, + frameCount: number, + + videoFrameRate: number | undefined, + ffprobeDuration: string | undefined, + metaDuration: number | undefined, +}): number => { + if (typeof str !== 'string') { + return 0; + } + + let percentage = 0; + if (str.length >= 6) { + const n = str.indexOf('fps'); + + if (n >= 6) { + // get frame + const frame = getFFmpegVar({ + str, + variable: 'frame', + }); + + const frameRate = videoFrameRate || 0; + let duration = 0; + + if ( + ffprobeDuration + && parseFloat(ffprobeDuration) > 0 + ) { + duration = parseFloat(ffprobeDuration); + } else if (metaDuration) { + duration = metaDuration; + } + + const per = getFFmpegPercentage( + { + f: frame, + fc: frameCount, + vf: frameRate, + d: duration, + }, + ); + + const outputNum = Number(per); + if (outputNum > 0) { + percentage = outputNum; + } + } + } + + return percentage; +}; + +const editreadyParser = ({ str }:{str: string}): number => { + if (typeof str !== 'string') { + return 0; + } + let percentage = 0; + + // const ex = 'STATUS: {"progress": "0.0000000"}'; + + if (str.includes('STATUS:')) { + const parts = str.split('STATUS:'); + + if (parts[1]) { + try { + const json = JSON.parse(parts[1]); + const progress = parseFloat(json.progress); + const percStr = (progress * 100).toFixed(2); + percentage = parseFloat(percStr); + } catch (err) { + // err + } + } + } + + // eslint-disable-next-line no-restricted-globals + if (isNaN(percentage)) { + return 0.00; + } + + return percentage; +}; + +export { + handbrakeParser, + ffmpegParser, + getFFmpegPercentage, + getFFmpegVar, + editreadyParser, +}; diff --git a/FlowPluginsTs/FlowHelpers/1.0.0/interfaces/interfaces.ts b/FlowPluginsTs/FlowHelpers/1.0.0/interfaces/interfaces.ts new file mode 100644 index 0000000..71d6233 --- /dev/null +++ b/FlowPluginsTs/FlowHelpers/1.0.0/interfaces/interfaces.ts @@ -0,0 +1,96 @@ +import { IFileObject, Istreams } from './synced/IFileObject'; +import Ijob from './synced/jobInterface'; + +export interface IpluginInputUi { + type: 'dropdown' | 'text', + options: string[], +} + +export interface IpluginInputs { + name: string, + type: 'string' | 'boolean' | 'number', + defaultValue: string, + inputUI: IpluginInputUi, + tooltip: string, +} + +export interface IpluginDetails { + name: string, + description: string, + style: { + borderColor: string, + opacity?: number, + }, + tags: string, + isStartPlugin: boolean, + sidebarPosition: number, + icon: string, + inputs: IpluginInputs[], + + outputs: { + number: number, + tooltip: string, + }[], +} + +export interface Ilog { + (text: string): void +} + +export interface IupdateWorker { + (obj: Record): void, +} + +export interface IffmpegCommandStream extends Istreams { + removed: boolean, + targetCodec: string, + args: string[], +} + +export interface IffmpegCommand { + inputFiles: string[], + streams: IffmpegCommandStream[] + container: string, +} + +export interface Ivariables { + ffmpegCommand?: IffmpegCommand +} + +export interface IpluginOutputArgs { + outputNumber: number, + outputFileObj: { + _id: string, + }, + variables: Ivariables + +} + +export interface IpluginInputArgs { + inputFileObj: IFileObject, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + librarySettings: any, + inputs: Record, + jobLog: Ilog, + workDir: string, + platform: string, + arch: string, + handbrakePath: string, + ffmpegPath: string, + mkvpropeditPath: string, + originalLibraryFile: IFileObject, + nodeHardwareType: string, + workerType: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + config: any, + job: Ijob, + platform_arch_isdocker: string, + variables: Ivariables, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + lastSuccesfulPlugin: any, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + lastSuccessfulRun: any, + updateWorker: IupdateWorker, + logFullCliOutput: boolean, + logOutcome:(outcome:string) => void, +} diff --git a/FlowPluginsTs/FlowHelpers/1.0.0/interfaces/synced/IFileObject.ts b/FlowPluginsTs/FlowHelpers/1.0.0/interfaces/synced/IFileObject.ts new file mode 100644 index 0000000..45ea961 --- /dev/null +++ b/FlowPluginsTs/FlowHelpers/1.0.0/interfaces/synced/IFileObject.ts @@ -0,0 +1,197 @@ +export interface IstatSync { // tlint-disable-line statSync + mtimeMs: number, + ctimeMs: number, + + ctime?: '', + mtime?: '', + atime?: '', +} + +export interface Itags { + language?: string, + title?: string, + [key:string]: string | undefined, +} +export interface Istreams { + codec_name: string; + codec_type?: string, + bit_rate?: number, + channels?: number, + tags?: Itags, + avg_frame_rate?: string, + nb_frames?: string, + + duration?: number; + width?: number, + height?: number, + // eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/explicit-module-boundary-types + [index: string]: any +} + +export interface Iformat { + 'filename'?: string, + 'nb_streams'?: number, + 'nb_programs'?: number, + 'format_name'?: string, + 'format_long_name'?: string, + 'start_time'?: string, + 'duration'?: string, + 'size'?: string, + 'bit_rate'?: string, + 'probe_score'?: number, + [key:string]: string | number | undefined + } + +export interface IffProbeData { + streams?: Istreams[] + format?: Iformat +} + +export interface Imeta { + TrackDuration?: number, + MediaDuration?: number, + 'SourceFile'?: string, + 'errors'?: [], + 'Duration'?: number, + 'ExifToolVersion'?: number, + 'FileName'?: string, + 'Directory'?: string, + 'FileSize'?: string, + 'FileModifyDate'?: { + 'year'?: number, + 'month'?: number, + 'day'?: number, + 'hour'?: number, + 'minute'?: number, + 'second'?: number, + 'millisecond'?: number, + 'tzoffsetMinutes'?: number, + 'rawValue'?: string, + }, + 'FileAccessDate'?: { + 'year'?: number, + 'month'?: number, + 'day'?: number, + 'hour'?: number, + 'minute'?: number, + 'second'?: number, + 'millisecond'?: number, + 'tzoffsetMinutes'?: number, + 'rawValue'?: string, + }, + 'FileCreateDate'?: { + 'year'?: number, + 'month'?: number, + 'day'?: number, + 'hour'?: number, + 'minute'?: number, + 'second'?: number, + 'millisecond'?: number, + 'tzoffsetMinutes'?: number, + 'rawValue'?: string, + }, + 'FilePermissions'?: string, + 'FileType'?: string, + 'FileTypeExtension'?: string, + 'MIMEType'?: string, + 'EBMLVersion'?: 1, + 'EBMLReadVersion'?: 1, + 'DocType'?: string, + 'DocTypeVersion'?: 4, + 'DocTypeReadVersion'?: 2, + 'TimecodeScale'?: string, + 'MuxingApp'?: string, + 'WritingApp'?: string, + 'VideoFrameRate'?: number, + 'ImageWidth'?: number, + 'ImageHeight'?: number, + 'TrackNumber'?: number, + 'TrackLanguage'?: string, + 'CodecID'?: string, + 'TrackType'?: string, + 'AudioChannels'?: number, + 'AudioSampleRate'?: number, + 'AudioBitsPerSample'?: number, + 'TagName'?: 'DURATION', + 'TagString'?: string, + 'ImageSize'?: string, + 'Megapixels'?: number, +} + +export interface ImediaInfo { + track?: [{ + '@type': string, + 'UniqueID': string, + 'VideoCount': string, + 'AudioCount': string, + 'Format': string, + 'Format_Version': string, + 'FileSize': string, + 'Duration': string, + 'OverallBitRate': string, + 'FrameRate': string, + 'FrameCount': string, + 'IsStreamable': string, + 'Encoded_Application': string, + 'Encoded_Library': string, + 'extra': { + 'ErrorDetectionType': string, + } + }], +} + +export interface IFileObjectMin { + _id: string, + file: string, + DB: string, + footprintId: string, +} + +type IbaseStatus = '' | 'Hold' | 'Queued' +export type IHealthCheck = IbaseStatus | 'Success' | 'Error' | 'Cancelled' +export type ITranscodeDecisionMaker = IbaseStatus | 'Transcode success' + | 'Transcode error' | 'Transcode cancelled' | 'Not required' + +export interface IFileObjectStripped extends IFileObjectMin { + container: string, + scannerReads: { + ffProbeRead: string, + } + createdAt: number, + lastPluginDetails: string, + bit_rate: number, + statSync: IstatSync, // tlint-disable-line statSync + file_size: number, + ffProbeData: IffProbeData, + hasClosedCaptions: boolean, + bumped: boolean, + HealthCheck: IHealthCheck, + TranscodeDecisionMaker: ITranscodeDecisionMaker, + holdUntil: number, + fileMedium: string, + video_codec_name: string, + audio_codec_name: string, + video_resolution: string, + + lastHealthCheckDate: number, + lastTranscodeDate: number, + history: string, + oldSize: number, + newSize: number, + videoStreamIndex: number; + // eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/explicit-module-boundary-types + [index: string]: any, +} + +export interface IFileObject extends IFileObjectStripped { + scannerReads: { + ffProbeRead: string, + exiftoolRead: string, + mediaInfoRead: string, + closedCaptionRead: string, + } + meta?: Imeta, + mediaInfo?: ImediaInfo, + // eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/explicit-module-boundary-types + [index: string]: any, +} diff --git a/FlowPluginsTs/FlowHelpers/1.0.0/interfaces/synced/jobInterface.ts b/FlowPluginsTs/FlowHelpers/1.0.0/interfaces/synced/jobInterface.ts new file mode 100644 index 0000000..c3e10fa --- /dev/null +++ b/FlowPluginsTs/FlowHelpers/1.0.0/interfaces/synced/jobInterface.ts @@ -0,0 +1,10 @@ +interface Ijob { + version: string, + footprintId: string, + jobId: string, + start: number, + type: string, + fileId: string +} + +export default Ijob; diff --git a/FlowPluginsTs/FlowHelpers/1.0.0/utils.ts b/FlowPluginsTs/FlowHelpers/1.0.0/utils.ts new file mode 100644 index 0000000..63dab96 --- /dev/null +++ b/FlowPluginsTs/FlowHelpers/1.0.0/utils.ts @@ -0,0 +1,296 @@ +import { editreadyParser, ffmpegParser, handbrakeParser } from './cliParsers'; +import { Ilog, IupdateWorker } from './interfaces/interfaces'; +import { IFileObject, Istreams } from './interfaces/synced/IFileObject'; + +const fs = require('fs'); + +const fancyTimeFormat = (time: number) => { + // Hours, minutes and seconds + + // eslint-disable-next-line no-bitwise + const hrs = ~~(time / 3600); + // eslint-disable-next-line no-bitwise + const mins = ~~((time % 3600) / 60); + // eslint-disable-next-line no-bitwise + const secs = ~~time % 60; + + // Output like "1:01" or "4:03:59" or "123:03:59" + let ret = ''; + + // if (hrs > 0) { + ret += `${hrs}:${mins < 10 ? '0' : ''}`; + // } + + ret += `${mins}:${secs < 10 ? '0' : ''}`; + ret += `${secs}`; + return ret; +}; + +// frame= 889 fps=106 q=26.0 Lsize= 25526kB time=00:00:35.69 bitrate=5858.3kbits/s speed=4.25x +export const getFFmpegVar = ({ + str, + variable, +}: { + str: string, variable: string +}): string => { + if (typeof str !== 'string') { + return ''; + } + + const idx = str.indexOf(variable); + + let out = ''; + let initSpacesEnded = false; + + if (idx >= 0) { + const startIdx = idx + variable.length + 1; + for (let i = startIdx; i < str.length; i += 1) { + if (initSpacesEnded === true && str[i] === ' ') { + break; + } else if (initSpacesEnded === false && str[i] !== ' ') { + initSpacesEnded = true; + } + + if (initSpacesEnded === true && str[i] !== ' ') { + out += str[i]; + } + } + } + + return out; +}; + +interface Iconfig { + cli: string, + spawnArgs: string[], + spawnOpts: Record, + jobLog: Ilog, + outputFilePath: string, + updateWorker: IupdateWorker, + logFullCliOutput: boolean, + inputFileObj: IFileObject, +} + +class CLI { + // @ts-expect-error init + config: Iconfig = {}; + + progAVG: number[] = []; + + oldOutSize = 0; + + oldEstSize = 0; + + oldProgress = 0; + + lastProgCheck = 0; + + constructor(config: Iconfig) { + this.config = config; + } + + updateETA = (perc: number): void => { + if (perc > 0) { + if (this.lastProgCheck === 0) { + this.lastProgCheck = new Date().getTime(); + this.oldProgress = perc; + } else if (perc !== this.oldProgress) { + const n = new Date().getTime(); + const secsSinceLastCheck = (n - this.lastProgCheck) / 1000; + + if (secsSinceLastCheck > 1) { + // eta total + let eta = Math.round( + (100 / (perc - this.oldProgress)) * secsSinceLastCheck, + ); + + // eta remaining + eta *= ((100 - perc) / 100); + this.progAVG.push(eta); + + // let values = [2, 56, 3, 41, 0, 4, 100, 23]; + const sum = this.progAVG.reduce( + // eslint-disable-next-line + (previous, current) => (current += previous), + ); + const avg = sum / this.progAVG.length; + + // est size + let estSize = 0; + + let outputFileSizeInGbytes; + + try { + if (fs.existsSync(this.config.outputFilePath)) { + let singleFileSize = fs.statSync(this.config.outputFilePath); + singleFileSize = singleFileSize.size; + outputFileSizeInGbytes = singleFileSize / (1024 * 1024 * 1024); + + if (outputFileSizeInGbytes !== this.oldOutSize) { + this.oldOutSize = outputFileSizeInGbytes; + estSize = outputFileSizeInGbytes + + ((100 - perc) / perc) * outputFileSizeInGbytes; + this.oldEstSize = estSize; + } + } + } catch (err) { + // eslint-disable-next-line no-console + console.log(err); + } + + this.config.updateWorker({ + ETA: fancyTimeFormat(avg), + outputFileSizeInGbytes: outputFileSizeInGbytes === undefined ? 0 : outputFileSizeInGbytes, + estSize: this.oldEstSize === undefined ? 0 : this.oldEstSize, + }); + + if (this.progAVG.length > 30) { + this.progAVG.splice(0, 1); + } + + this.lastProgCheck = n; + this.oldProgress = perc; + } + } + } + }; + + parseOutput = (data: string): void => { + const str = `${data}`; + // + if (this.config.logFullCliOutput === true) { + this.config.jobLog(str); + } + + if (this.config.cli.toLowerCase().includes('handbrake')) { + const percentage = handbrakeParser({ + str, + }); + if (percentage > 0) { + this.updateETA(percentage); + this.config.updateWorker({ + percentage, + }); + } + } else if (this.config.cli.toLowerCase().includes('ffmpeg')) { + const n = str.indexOf('fps'); + const shouldUpdate = str.length >= 6 && n >= 6; + + const fps = parseInt(getFFmpegVar({ + str, + variable: 'fps', + }), 10); + + let frameCount = 0; + + try { + // @ts-expect-error type + const frameCountTmp = this.config.inputFileObj.ffProbeData?.streams + .filter((row: Istreams) => row.codec_type === 'video')[0].nb_frames; + + if (frameCountTmp + // @ts-expect-error type + && !isNaN(frameCountTmp)) { // eslint-disable-line no-restricted-globals + // @ts-expect-error type + frameCount = frameCountTmp; + } + } catch (err) { + // err + } + + const percentage = ffmpegParser({ + str, + frameCount, + videoFrameRate: this.config.inputFileObj?.meta?.VideoFrameRate, + ffprobeDuration: this.config.inputFileObj.ffProbeData?.format?.duration, + metaDuration: this.config.inputFileObj?.meta?.Duration, + }); + + if (shouldUpdate === true && fps > 0) { + this.config.updateWorker({ + fps, + }); + } + + if (shouldUpdate === true && percentage > 0) { + this.updateETA(percentage); + this.config.updateWorker({ + percentage, + }); + } + } else if (this.config.cli.toLowerCase().includes('editready')) { + const percentage = editreadyParser({ + str, + }); + if (percentage > 0) { + this.updateETA(percentage); + this.config.updateWorker({ + percentage, + }); + } + } + }; + + runCli = async (): Promise<{ + cliExitCode: number, + errorLogFull: string[], + }> => { + const childProcess = require('child_process'); + + const errorLogFull: string[] = []; + + // eslint-disable-next-line no-console + console.log(`Running ${this.config.cli} ${this.config.spawnArgs.join(' ')}`); + const cliExitCode: number = await new Promise((resolve) => { + try { + const opts = this.config.spawnOpts || {}; + const thread = childProcess.spawn(this.config.cli, this.config.spawnArgs, opts); + + thread.stdout.on('data', (data: string) => { + // eslint-disable-next-line no-console + console.log(data.toString()); + errorLogFull.push(data.toString()); + this.parseOutput(data); + }); + + thread.stderr.on('data', (data: string) => { + // eslint-disable-next-line no-console + console.log(data.toString()); + errorLogFull.push(data.toString()); + this.parseOutput(data); + }); + + thread.on('error', () => { + // catches execution error (bad file) + // eslint-disable-next-line no-console + console.log(1, `Error executing binary: ${this.config.cli}`); + resolve(1); + }); + + // thread.stdout.pipe(process.stdout); + // thread.stderr.pipe(process.stderr); + thread.on('close', (code: number) => { + if (code !== 0) { + // eslint-disable-next-line no-console + console.log(code, 'FFmpeg error'); + } + resolve(code); + }); + } catch (err) { + // catches execution error (no file) + // eslint-disable-next-line no-console + console.log(1, `Error executing binary: ${this.config.cli}`); + resolve(1); + } + }); + + return { + cliExitCode, + errorLogFull, + }; + }; +} + +export { + CLI, +};