Merge branch 'master' into pr/694

master
HaveAGitGat 10 months ago
commit 7321a63b4a

@ -297,6 +297,10 @@ const getEncoder = async ({
enabled: false,
filter: '-vf format=nv12,hwupload',
},
{
encoder: 'hevc_rkmpp',
enabled: false,
},
{
encoder: 'hevc_qsv',
enabled: false,
@ -310,6 +314,10 @@ const getEncoder = async ({
encoder: 'h264_nvenc',
enabled: false,
},
{
encoder: 'h264_rkmpp',
enabled: false,
},
{
encoder: 'h264_amf',
enabled: false,

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -105,7 +105,7 @@ var plugin = function (args) {
'mpg',
'mpeg',
].includes(container)) {
args.variables.ffmpegCommand.overallOuputArguments.push('-fflags', '+genpts');
args.variables.ffmpegCommand.overallInputArguments.push('-fflags', '+genpts');
}
}
return {

@ -172,6 +172,7 @@ var details = function () { return ({
options: [
'auto',
'nvenc',
'rkmpp',
'qsv',
'vaapi',
'videotoolbox',

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");
@ -42,7 +42,7 @@ var fileUtils_1 = require("../../../../FlowHelpers/1.0.0/fileUtils");
/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */
var details = function () { return ({
name: 'Delete File',
description: 'Delete the working file or original file.',
description: "\n Delete the working file or original file.\n You don't need to use this plugin to clean up files in the cache, Tdarr will do this automatically after the flow.\n To manually clear the cache, use the 'Clear Cache' flow plugin.\n If the working file is deleted, the plugin after this one should load a valid working file,\n such as 'Set Original File' to load the original file, else subsequent plugins will error.\n ",
style: {
borderColor: 'red',
},
@ -67,6 +67,32 @@ var details = function () { return ({
},
tooltip: 'Specify the file to delete',
},
{
label: 'Delete Working File If It\'s The Original File',
name: 'deleteWorkingFileIfOriginal',
type: 'boolean',
defaultValue: 'true',
inputUI: {
type: 'switch',
displayConditions: {
logic: 'AND',
sets: [
{
logic: 'AND',
inputs: [
{
name: 'fileToDelete',
value: 'workingFile',
condition: '===',
},
],
},
],
},
},
tooltip: 'If the option above is set to delete the working file,'
+ ' and the working file is the original file, delete the file.',
},
{
label: 'Delete Parent Folder If Empty',
name: 'deleteParentFolderIfEmpty',
@ -88,49 +114,62 @@ var details = function () { return ({
exports.details = details;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
var plugin = function (args) { return __awaiter(void 0, void 0, void 0, function () {
var lib, fileToDelete, deleteParentFolderIfEmpty, fileDir, files;
return __generator(this, function (_a) {
switch (_a.label) {
var lib, fileToDelete, _a, deleteParentFolderIfEmpty, deleteWorkingFileIfOriginal, workingFileIsOriginal, fileDir, files;
return __generator(this, function (_b) {
switch (_b.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);
fileToDelete = String(args.inputs.fileToDelete);
deleteParentFolderIfEmpty = args.inputs.deleteParentFolderIfEmpty;
if (!(fileToDelete === 'workingFile')) return [3 /*break*/, 2];
_a = args.inputs, deleteParentFolderIfEmpty = _a.deleteParentFolderIfEmpty, deleteWorkingFileIfOriginal = _a.deleteWorkingFileIfOriginal;
if (!(fileToDelete === 'workingFile')) return [3 /*break*/, 4];
workingFileIsOriginal = args.originalLibraryFile._id === args.inputFileObj._id;
if (workingFileIsOriginal) {
args.jobLog('Working file is the original file!');
}
else {
args.jobLog('Working file is not the original file!');
}
if (!((workingFileIsOriginal && deleteWorkingFileIfOriginal)
|| !workingFileIsOriginal)) return [3 /*break*/, 2];
args.jobLog("Deleting working file ".concat(args.inputFileObj._id));
return [4 /*yield*/, fs_1.promises.unlink(args.inputFileObj._id)];
case 1:
_a.sent();
return [3 /*break*/, 4];
_b.sent();
return [3 /*break*/, 3];
case 2:
if (!(fileToDelete === 'originalFile')) return [3 /*break*/, 4];
args.jobLog('Skipping delete of working file because it is the original file');
_b.label = 3;
case 3: return [3 /*break*/, 6];
case 4:
if (!(fileToDelete === 'originalFile')) return [3 /*break*/, 6];
args.jobLog("Deleting original file ".concat(args.originalLibraryFile._id));
return [4 /*yield*/, fs_1.promises.unlink(args.originalLibraryFile._id)];
case 3:
_a.sent();
_a.label = 4;
case 4:
case 5:
_b.sent();
_b.label = 6;
case 6:
fileDir = (0, fileUtils_1.getFileAbosluteDir)(args.originalLibraryFile._id);
if (!deleteParentFolderIfEmpty) return [3 /*break*/, 9];
if (!deleteParentFolderIfEmpty) return [3 /*break*/, 11];
args.jobLog("Checking if folder ".concat(fileDir, " is empty"));
return [4 /*yield*/, fs_1.promises.readdir(fileDir)];
case 5:
files = _a.sent();
if (!(files.length === 0)) return [3 /*break*/, 7];
case 7:
files = _b.sent();
if (!(files.length === 0)) return [3 /*break*/, 9];
args.jobLog("Deleting empty folder ".concat(fileDir));
return [4 /*yield*/, fs_1.promises.rmdir(fileDir)];
case 6:
_a.sent();
return [3 /*break*/, 8];
case 7:
args.jobLog("Folder ".concat(fileDir, " is not empty, skipping delete"));
_a.label = 8;
case 8: return [3 /*break*/, 10];
case 8:
_b.sent();
return [3 /*break*/, 10];
case 9:
args.jobLog("Folder ".concat(fileDir, " is not empty, skipping delete"));
_b.label = 10;
case 10: return [3 /*break*/, 12];
case 11:
args.jobLog("Skipping delete of parent folder ".concat(fileDir));
_a.label = 10;
case 10: return [2 /*return*/, {
_b.label = 12;
case 12: return [2 /*return*/, {
outputFileObj: args.inputFileObj,
outputNumber: 1,
variables: args.variables,

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");
@ -46,7 +46,7 @@ var fileUtils_1 = require("../../../../FlowHelpers/1.0.0/fileUtils");
/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */
var details = function () { return ({
name: 'Replace Original File',
description: 'Replace the original file. If the file hasn\'t changed then no action is taken.',
description: "\n Replace the original file with the 'working' file passed into this plugin. \n If the file hasn't changed then no action is taken.\n Note: The 'working' filename and container will replace the original filename and container.\n ",
style: {
borderColor: 'green',
},
@ -67,7 +67,7 @@ var details = function () { return ({
exports.details = details;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
var plugin = function (args) { return __awaiter(void 0, void 0, void 0, function () {
var lib, currentPath, orignalFolder, fileName, container, newPath, newPathTmp;
var lib, currentPath, orignalFolder, fileName, container, newPath, newPathTmp, originalFileExists, currentFileIsNotOriginal;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
@ -108,8 +108,14 @@ var plugin = function (args) { return __awaiter(void 0, void 0, void 0, function
_a.sent();
return [4 /*yield*/, (0, fileUtils_1.fileExists)(args.originalLibraryFile._id)];
case 3:
if (!((_a.sent())
&& args.originalLibraryFile._id !== currentPath)) return [3 /*break*/, 5];
originalFileExists = _a.sent();
currentFileIsNotOriginal = args.originalLibraryFile._id !== currentPath;
args.jobLog(JSON.stringify({
originalFileExists: originalFileExists,
currentFileIsNotOriginal: currentFileIsNotOriginal,
}));
if (!(originalFileExists
&& currentFileIsNotOriginal)) return [3 /*break*/, 5];
args.jobLog("Deleting original file:".concat(args.originalLibraryFile._id));
return [4 /*yield*/, fs_1.promises.unlink(args.originalLibraryFile._id)];
case 4:

@ -4,8 +4,7 @@ exports.plugin = exports.details = void 0;
/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */
var details = function () { return ({
name: 'Set Original File',
description: 'Set the working file to the original file path at the very start of the flow. '
+ 'The original file won\'t be affected by subsequent plugins (E.g. Replace Original File).',
description: 'Set the working file to the original file path at the very start of the flow.',
style: {
borderColor: 'green',
},

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -20,8 +20,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");
@ -62,6 +62,7 @@ var details = function () { return ({
options: [
'hevc_nvenc',
'hevc_amf',
'hevc_rkmpp',
'hevc_vaapi',
'hevc_qsv',
'hevc_videotoolbox',

@ -0,0 +1,169 @@
"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 = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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 };
}
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.plugin = exports.details = void 0;
var fs_1 = require("fs");
var normJoinPath_1 = __importDefault(require("../../../../FlowHelpers/1.0.0/normJoinPath"));
var helperText = "\n jobCache: Clears all other files in this job's cache folder (which is a subfolder of the library cache).\n libraryCache: Clears all other files in the library cache.\n ";
/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */
var details = function () { return ({
name: 'Clear Cache',
description: "\n This plugin allows you to clear various cache folders, keeping only the current 'working' file.\n ".concat(helperText, "\n\n "),
style: {
borderColor: 'red',
},
tags: '',
isStartPlugin: false,
pType: '',
requiresVersion: '2.11.01',
sidebarPosition: -1,
icon: 'faTrash',
inputs: [
{
label: 'Cache To Clear',
name: 'cacheToClear',
type: 'string',
defaultValue: 'jobCache',
inputUI: {
type: 'dropdown',
options: [
'jobCache',
'libraryCache',
],
},
tooltip: "Specify which cache to clear \n ".concat(helperText, "\n "),
},
],
outputs: [
{
number: 1,
tooltip: 'Continue to next plugin',
},
],
}); };
exports.details = details;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
var plugin = function (args) { return __awaiter(void 0, void 0, void 0, function () {
var lib, cacheToClear, currentFile, jobCacheDir, libraryCacheDir, folderToClear, traverseFolder;
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);
cacheToClear = args.inputs.cacheToClear;
currentFile = args.inputFileObj._id;
jobCacheDir = args.workDir;
libraryCacheDir = args.librarySettings.cache;
folderToClear = '';
if (cacheToClear === 'jobCache') {
folderToClear = jobCacheDir;
}
else if (cacheToClear === 'libraryCache') {
folderToClear = libraryCacheDir;
}
args.jobLog("Clearing ".concat(cacheToClear, " folder: \"").concat(folderToClear, "\""));
args.jobLog("Keeping current file: \"".concat(currentFile, "\""));
traverseFolder = function (dir) { return __awaiter(void 0, void 0, void 0, function () {
var filesInDir, i, file, stat, err_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, fs_1.promises.readdir(dir)];
case 1:
filesInDir = (_a.sent()).map(function (file) { return (0, normJoinPath_1.default)({
upath: args.deps.upath,
paths: [
dir,
file,
],
}); });
i = 0;
_a.label = 2;
case 2:
if (!(i < filesInDir.length)) return [3 /*break*/, 10];
file = filesInDir[i];
return [4 /*yield*/, fs_1.promises.stat(file)];
case 3:
stat = _a.sent();
if (!stat.isDirectory()) return [3 /*break*/, 5];
// eslint-disable-next-line no-await-in-loop
return [4 /*yield*/, traverseFolder(file)];
case 4:
// eslint-disable-next-line no-await-in-loop
_a.sent();
return [3 /*break*/, 9];
case 5:
if (!(file !== currentFile
// prevent deleting non Tdarr cache files
&& file.includes('tdarr-workDir2'))) return [3 /*break*/, 9];
args.jobLog("Deleting \"".concat(file, "\""));
_a.label = 6;
case 6:
_a.trys.push([6, 8, , 9]);
// eslint-disable-next-line no-await-in-loop
return [4 /*yield*/, fs_1.promises.unlink(file)];
case 7:
// eslint-disable-next-line no-await-in-loop
_a.sent();
return [3 /*break*/, 9];
case 8:
err_1 = _a.sent();
args.jobLog("File delete error: ".concat(JSON.stringify(err_1)));
return [3 /*break*/, 9];
case 9:
i += 1;
return [3 /*break*/, 2];
case 10: return [2 /*return*/];
}
});
}); };
return [4 /*yield*/, traverseFolder(folderToClear)];
case 1:
_a.sent();
return [2 /*return*/, {
outputFileObj: args.inputFileObj,
outputNumber: 1,
variables: args.variables,
}];
}
});
}); };
exports.plugin = plugin;

@ -0,0 +1,113 @@
"use strict";
/* eslint-disable max-len */
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 = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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 fs_1 = require("fs");
var fileUtils_1 = require("../../../../FlowHelpers/1.0.0/fileUtils");
/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */
var details = function () { return ({
name: 'Custom JS Function',
description: 'Write a custom function in JS to run with up to 4 outputs',
style: {
borderColor: 'green',
},
tags: '',
isStartPlugin: false,
pType: '',
requiresVersion: '2.11.01',
sidebarPosition: -1,
icon: 'faArrowRight',
inputs: [
{
label: 'JS Code',
name: 'code',
type: 'string',
defaultValue: "\nmodule.exports = async (args) => {\n\n// see args object data here https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/FlowPluginsTs/FlowHelpers/1.0.0/interfaces/interfaces.ts\n// example setting flow variable: https://github.com/HaveAGitGat/Tdarr/issues/1147#issuecomment-2593348443\n// example reading ffmpeg metadata: https://github.com/HaveAGitGat/Tdarr_Plugins/issues/737#issuecomment-2581536112\n// example setting working file as previous working file: https://github.com/HaveAGitGat/Tdarr/issues/1106#issuecomment-2622177459\n\n// some example file data:\nconsole.log(args.inputFileObj._id)\nconsole.log(args.inputFileObj.file_size)\nconsole.log(args.inputFileObj.ffProbeData.streams[0].codec_name)\nconsole.log(args.inputFileObj.mediaInfo.track[0].BitRate)\n\n// access global variable:\nconsole.log(args.userVariables.global.test)\n// access library variable:\nconsole.log(args.userVariables.library.test)\n\n\n\n// do something here\n\n return {\n outputFileObj: args.inputFileObj,\n outputNumber: 1,\n variables: args.variables,\n };\n}\n ",
inputUI: {
type: 'textarea',
style: {
height: '200px',
},
},
tooltip: 'Write your custom function here',
},
],
outputs: [
{
number: 1,
tooltip: 'Continue to output 1',
},
{
number: 2,
tooltip: 'Continue to output 2',
},
{
number: 3,
tooltip: 'Continue to output 3',
},
{
number: 4,
tooltip: 'Continue to output 4',
},
],
}); };
exports.details = details;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
var plugin = function (args) { return __awaiter(void 0, void 0, void 0, function () {
var lib, code, outputFilePath, func, response;
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);
code = String(args.inputs.code);
outputFilePath = "".concat((0, fileUtils_1.getPluginWorkDir)(args), "/script.js");
return [4 /*yield*/, fs_1.promises.writeFile(outputFilePath, code)];
case 1:
_a.sent();
func = require(outputFilePath);
return [4 /*yield*/, func(args)];
case 2:
response = _a.sent();
return [2 /*return*/, response];
}
});
}); };
exports.plugin = plugin;

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -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: 'Remove From Tdarr',
description: "\n If this plugin is executed, then when the flow ends, the item will be \n removed from the Tdarr database and won't appear in Transcode Success or Error tables on the 'Tdarr' tab.\n Use the 'Delete File' plugin if you would like to delete the file from disk.\n ",
style: {
borderColor: 'red',
},
tags: '',
isStartPlugin: false,
pType: '',
requiresVersion: '2.31.01',
sidebarPosition: -1,
icon: 'faTrash',
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) {
// eslint-disable-next-line no-param-reassign
args.variables.removeFromTdarr = true;
return {
outputFileObj: args.inputFileObj,
outputNumber: 1,
variables: args.variables,
};
};
exports.plugin = plugin;

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -103,6 +103,16 @@ var details = function () { return ({
},
tooltip: 'Specify request body',
},
{
label: 'Log Response Body',
name: 'logResponseBody',
type: 'boolean',
defaultValue: 'false',
inputUI: {
type: 'switch',
},
tooltip: 'Specify whether to log response body in the job report',
},
],
outputs: [
{
@ -114,7 +124,7 @@ var details = function () { return ({
exports.details = details;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
var plugin = function (args) { return __awaiter(void 0, void 0, void 0, function () {
var lib, method, requestUrl, requestHeaders, requestBody, requestConfig, res, err_1;
var lib, method, requestUrl, requestHeaders, requestBody, logResponseBody, requestConfig, res, err_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
@ -125,6 +135,7 @@ var plugin = function (args) { return __awaiter(void 0, void 0, void 0, function
requestUrl = String(args.inputs.requestUrl);
requestHeaders = JSON.parse(String(args.inputs.requestHeaders));
requestBody = JSON.parse(String(args.inputs.requestBody));
logResponseBody = args.inputs.logResponseBody;
requestConfig = {
method: method,
url: requestUrl,
@ -138,6 +149,9 @@ var plugin = function (args) { return __awaiter(void 0, void 0, void 0, function
case 2:
res = _a.sent();
args.jobLog("Web request succeeded: Status Code: ".concat(res.status));
if (logResponseBody) {
args.jobLog("Response Body: ".concat(JSON.stringify(res.data)));
}
return [3 /*break*/, 4];
case 3:
err_1 = _a.sent();

@ -0,0 +1,281 @@
"use strict";
/* eslint-disable no-template-curly-in-string */
/* eslint-disable import/prefer-default-export */
Object.defineProperty(exports, "__esModule", { value: true });
exports.details = void 0;
var details = function () { return ({
"name": "Chapter 8: Unmapped Nodes",
"description": "Chapter 8: Unmapped Nodes",
"tags": "",
"flowPlugins": [
{
"name": "Tags: Worker Type - Mapped Node",
"sourceRepo": "Community",
"pluginName": "tagsWorkerType",
"version": "1.0.0",
"id": "XDkUDTqXV",
"position": {
"x": 618.728206498488,
"y": 797.6991616678526
},
"fpEnabled": true,
"inputsDB": {
"requiredNodeTags": "mapped"
}
},
{
"name": "Tags: Worker Type - Unmapped Node",
"sourceRepo": "Community",
"pluginName": "tagsWorkerType",
"version": "1.0.0",
"id": "Gm1kh8K5w",
"position": {
"x": 487.23666063579026,
"y": 281.79774016757386
},
"fpEnabled": true,
"inputsDB": {
"requiredNodeTags": "unmapped"
}
},
{
"name": "Input File",
"sourceRepo": "Community",
"pluginName": "inputFile",
"version": "1.0.0",
"id": "pE6rU7gkW",
"position": {
"x": 788.5712895368422,
"y": 45.83576905176477
},
"fpEnabled": true
},
{
"name": "Check if hevc",
"sourceRepo": "Community",
"pluginName": "checkVideoCodec",
"version": "1.0.0",
"id": "91b7IrsEc",
"position": {
"x": 788.2207108267078,
"y": 203.7781028159269
},
"fpEnabled": true
},
{
"name": "Start",
"sourceRepo": "Community",
"pluginName": "ffmpegCommandStart",
"version": "1.0.0",
"id": "4Swd6qzvc",
"position": {
"x": 489.25252076795084,
"y": 370.51229288382495
},
"fpEnabled": true
},
{
"name": "Execute",
"sourceRepo": "Community",
"pluginName": "ffmpegCommandExecute",
"version": "1.0.0",
"id": "450g167D8",
"position": {
"x": 488.72295602997406,
"y": 699.5034828311435
},
"fpEnabled": true
},
{
"name": "Set Video Encoder",
"sourceRepo": "Community",
"pluginName": "ffmpegCommandSetVideoEncoder",
"version": "1.0.0",
"id": "8B_6pRd_U",
"position": {
"x": 488.5270135748424,
"y": 477.83202026423606
},
"fpEnabled": true
},
{
"name": "Replace Original File",
"sourceRepo": "Community",
"pluginName": "replaceOriginalFile",
"version": "1.0.0",
"id": "4fkfOyR3l",
"position": {
"x": 797.2573001129032,
"y": 882.7619863463507
},
"fpEnabled": true
},
{
"name": "Set Container",
"sourceRepo": "Community",
"pluginName": "ffmpegCommandSetContainer",
"version": "1.0.0",
"id": "TtKXi3Q7h",
"position": {
"x": 488.21110165973323,
"y": 570.3064821931456
},
"fpEnabled": true
},
{
"name": "Tags: Worker Type - Mapped Node",
"sourceRepo": "Community",
"pluginName": "tagsWorkerType",
"version": "1.0.0",
"id": "7Y_fzVfGm",
"position": {
"x": 788.7823658666633,
"y": 127.15363454994434
},
"fpEnabled": true,
"inputsDB": {
"requiredNodeTags": "mapped"
}
},
{
"name": "We will check the file codec on a mapped node. This way bandwidth and time is saved as we don't need to unnecessarily send the whole file to the unmapped node.",
"sourceRepo": "Community",
"pluginName": "comment",
"version": "1.0.0",
"id": "6oOV2PLSr",
"position": {
"x": 958.0256289687773,
"y": 129.22000506355067
},
"fpEnabled": true
},
{
"name": "If the codec is not what we want, we'll require the next transcoding steps to run on an unmapped node. The unmapped node will automatically download the file from the server.",
"sourceRepo": "Community",
"pluginName": "comment",
"version": "1.0.0",
"id": "j343VFewY",
"position": {
"x": 316.4293037925603,
"y": 290.6548883625747
},
"fpEnabled": true
},
{
"name": "After the transcode, we'll run the original file replacement on a mapped node which has access to the server file system. The mapped node will automatically download the working file from the unmapped node.",
"sourceRepo": "Community",
"pluginName": "comment",
"version": "1.0.0",
"id": "hVhthld87",
"position": {
"x": 364.852600714643,
"y": 769.3367928955186
},
"fpEnabled": true
},
{
"name": "Before starting, ensure that in the Node options panel on the Tdarr tab, the mapped node has node tag 'mapped' and the umapped node has node tag 'umapped'.",
"sourceRepo": "Community",
"pluginName": "comment",
"version": "1.0.0",
"id": "9sd__MisF",
"position": {
"x": 791.5682800167409,
"y": -93.09360376469954
},
"fpEnabled": true
},
{
"name": "Unmapped nodes are a new node type for Tdarr Pro members on 2.27.01 and above. More info: https://docs.tdarr.io/docs/nodes/nodes#unmapped",
"sourceRepo": "Community",
"pluginName": "comment",
"version": "1.0.0",
"id": "EILF-RWh2",
"position": {
"x": 791.4236829857584,
"y": -209.23734619332546
},
"fpEnabled": true
}
],
"flowEdges": [
{
"source": "4Swd6qzvc",
"sourceHandle": "1",
"target": "8B_6pRd_U",
"targetHandle": null,
"id": "3Df7Xoy93"
},
{
"source": "8B_6pRd_U",
"sourceHandle": "1",
"target": "TtKXi3Q7h",
"targetHandle": null,
"id": "epqtLsPuG"
},
{
"source": "TtKXi3Q7h",
"sourceHandle": "1",
"target": "450g167D8",
"targetHandle": null,
"id": "ljOeP0cAZ"
},
{
"source": "450g167D8",
"sourceHandle": "1",
"target": "XDkUDTqXV",
"targetHandle": null,
"id": "3412q1wK2"
},
{
"source": "XDkUDTqXV",
"sourceHandle": "1",
"target": "4fkfOyR3l",
"targetHandle": null,
"id": "3jQP_egvG"
},
{
"source": "pE6rU7gkW",
"sourceHandle": "1",
"target": "7Y_fzVfGm",
"targetHandle": null,
"id": "XHRuig1Dp"
},
{
"source": "7Y_fzVfGm",
"sourceHandle": "1",
"target": "91b7IrsEc",
"targetHandle": null,
"id": "_CJ9H5I_X"
},
{
"source": "91b7IrsEc",
"sourceHandle": "1",
"target": "4fkfOyR3l",
"targetHandle": null,
"id": "2x5mRYwOU"
},
{
"source": "91b7IrsEc",
"sourceHandle": "2",
"target": "Gm1kh8K5w",
"targetHandle": null,
"id": "8eBsa60Xp"
},
{
"source": "Gm1kh8K5w",
"sourceHandle": "1",
"target": "4Swd6qzvc",
"targetHandle": null,
"id": "IryDiBCVX"
},
{
"source": "EILF-RWh2",
"sourceHandle": "1",
"target": "9sd__MisF",
"targetHandle": null,
"id": "IPiPj8zhv"
}
]
}); };
exports.details = details;

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");

@ -20,8 +20,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
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;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["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.");
@ -226,6 +226,16 @@ var getEncoder = function (_a) { return __awaiter(void 0, [_a], void 0, function
outputArgs: [],
filter: '',
},
{
encoder: 'hevc_rkmpp',
enabled: false,
inputArgs: [
'-hwaccel',
'rkmpp',
],
outputArgs: [],
filter: '',
},
{
encoder: 'hevc_amf',
enabled: false,
@ -295,6 +305,16 @@ var getEncoder = function (_a) { return __awaiter(void 0, [_a], void 0, function
outputArgs: [],
filter: '',
},
{
encoder: 'h264_rkmpp',
enabled: false,
inputArgs: [
'-hwaccel',
'rkmpp',
],
outputArgs: [],
filter: '',
},
{
encoder: 'h264_videotoolbox',
enabled: false,

@ -37,32 +37,45 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
};
Object.defineProperty(exports, "__esModule", { value: true });
var hardwareUtils_1 = require("./hardwareUtils");
var run = function () { return __awaiter(void 0, void 0, void 0, function () {
var encoderProperties;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, (0, hardwareUtils_1.getEncoder)({
var baseInput = {
targetCodec: 'h264',
hardwareEncoding: true,
hardwareType: 'auto',
// @ts-expect-error type
args: {
workerType: 'transcodegpu',
ffmpegPath: 'ffmpeg',
jobLog: function (t) {
// eslint-disable-next-line no-console
console.log(t);
jobLog: function () {
//
},
},
})];
};
var checkHardware = function (settings) { return __awaiter(void 0, void 0, void 0, function () {
var input, encoderProperties;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
input = JSON.parse(JSON.stringify(baseInput));
input.args.jobLog = function () {
// eslint-disable-next-line no-console
// console.log(t);
};
if (settings.targetCodec) {
input.targetCodec = settings.targetCodec;
}
if (settings.hardwareEncoding) {
input.hardwareEncoding = settings.hardwareEncoding;
}
if (settings.hardwareType) {
input.hardwareType = settings.hardwareType;
}
if (settings.ffmpegPath) {
input.args.ffmpegPath = settings.ffmpegPath;
}
return [4 /*yield*/, (0, hardwareUtils_1.getEncoder)(input)];
case 1:
encoderProperties = _a.sent();
// eslint-disable-next-line no-console
console.log({
encoderProperties: encoderProperties,
});
return [2 /*return*/];
return [2 /*return*/, encoderProperties];
}
});
}); };
void run();
exports.default = checkHardware;

@ -124,7 +124,7 @@ const plugin = (args: IpluginInputArgs): IpluginOutputArgs => {
'mpeg',
].includes(container)
) {
args.variables.ffmpegCommand.overallOuputArguments.push('-fflags', '+genpts');
args.variables.ffmpegCommand.overallInputArguments.push('-fflags', '+genpts');
}
}

@ -140,6 +140,7 @@ const details = (): IpluginDetails => ({
options: [
'auto',
'nvenc',
'rkmpp',
'qsv',
'vaapi',
'videotoolbox',

@ -10,7 +10,13 @@ import { getFileAbosluteDir } from '../../../../FlowHelpers/1.0.0/fileUtils';
/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */
const details = (): IpluginDetails => ({
name: 'Delete File',
description: 'Delete the working file or original file.',
description: `
Delete the working file or original file.
You don't need to use this plugin to clean up files in the cache, Tdarr will do this automatically after the flow.
To manually clear the cache, use the 'Clear Cache' flow plugin.
If the working file is deleted, the plugin after this one should load a valid working file,
such as 'Set Original File' to load the original file, else subsequent plugins will error.
`,
style: {
borderColor: 'red',
},
@ -35,6 +41,32 @@ const details = (): IpluginDetails => ({
},
tooltip: 'Specify the file to delete',
},
{
label: 'Delete Working File If It\'s The Original File',
name: 'deleteWorkingFileIfOriginal',
type: 'boolean',
defaultValue: 'true',
inputUI: {
type: 'switch',
displayConditions: {
logic: 'AND',
sets: [
{
logic: 'AND',
inputs: [
{
name: 'fileToDelete',
value: 'workingFile',
condition: '===',
},
],
},
],
},
},
tooltip: 'If the option above is set to delete the working file,'
+ ' and the working file is the original file, delete the file.',
},
{
label: 'Delete Parent Folder If Empty',
name: 'deleteParentFolderIfEmpty',
@ -61,11 +93,29 @@ const plugin = async (args: IpluginInputArgs): Promise<IpluginOutputArgs> => {
args.inputs = lib.loadDefaultValues(args.inputs, details);
const fileToDelete = String(args.inputs.fileToDelete);
const { deleteParentFolderIfEmpty } = args.inputs;
const {
deleteParentFolderIfEmpty,
deleteWorkingFileIfOriginal,
} = args.inputs;
if (fileToDelete === 'workingFile') {
const workingFileIsOriginal = args.originalLibraryFile._id === args.inputFileObj._id;
if (workingFileIsOriginal) {
args.jobLog('Working file is the original file!');
} else {
args.jobLog('Working file is not the original file!');
}
if (
(workingFileIsOriginal && deleteWorkingFileIfOriginal)
|| !workingFileIsOriginal
) {
args.jobLog(`Deleting working file ${args.inputFileObj._id}`);
await fsp.unlink(args.inputFileObj._id);
} else {
args.jobLog('Skipping delete of working file because it is the original file');
}
} else if (fileToDelete === 'originalFile') {
args.jobLog(`Deleting original file ${args.originalLibraryFile._id}`);
await fsp.unlink(args.originalLibraryFile._id);

@ -13,7 +13,11 @@ import {
/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */
const details = (): IpluginDetails => ({
name: 'Replace Original File',
description: 'Replace the original file. If the file hasn\'t changed then no action is taken.',
description: `
Replace the original file with the 'working' file passed into this plugin.
If the file hasn't changed then no action is taken.
Note: The 'working' filename and container will replace the original filename and container.
`,
style: {
borderColor: 'green',
},
@ -75,10 +79,18 @@ const plugin = async (args: IpluginInputArgs): Promise<IpluginOutputArgs> => {
args,
});
const originalFileExists = await fileExists(args.originalLibraryFile._id);
const currentFileIsNotOriginal = args.originalLibraryFile._id !== currentPath;
args.jobLog(JSON.stringify({
originalFileExists,
currentFileIsNotOriginal,
}));
// delete original file
if (
await fileExists(args.originalLibraryFile._id)
&& args.originalLibraryFile._id !== currentPath
originalFileExists
&& currentFileIsNotOriginal
) {
args.jobLog(`Deleting original file:${args.originalLibraryFile._id}`);
await fsp.unlink(args.originalLibraryFile._id);

@ -7,8 +7,7 @@ import {
/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */
const details = ():IpluginDetails => ({
name: 'Set Original File',
description: 'Set the working file to the original file path at the very start of the flow. '
+ 'The original file won\'t be affected by subsequent plugins (E.g. Replace Original File).',
description: 'Set the working file to the original file path at the very start of the flow.',
style: {
borderColor: 'green',
},

@ -38,6 +38,7 @@ const details = (): IpluginDetails => ({
options: [
'hevc_nvenc',
'hevc_amf',
'hevc_rkmpp',
'hevc_vaapi',
'hevc_qsv',
'hevc_videotoolbox',

@ -0,0 +1,125 @@
import { promises as fsp } from 'fs';
import {
IpluginDetails,
IpluginInputArgs,
IpluginOutputArgs,
} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces';
import normJoinPath from '../../../../FlowHelpers/1.0.0/normJoinPath';
const helperText = `
jobCache: Clears all other files in this job's cache folder (which is a subfolder of the library cache).
libraryCache: Clears all other files in the library cache.
`;
/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */
const details = (): IpluginDetails => ({
name: 'Clear Cache',
description: `
This plugin allows you to clear various cache folders, keeping only the current 'working' file.
${helperText}
`,
style: {
borderColor: 'red',
},
tags: '',
isStartPlugin: false,
pType: '',
requiresVersion: '2.11.01',
sidebarPosition: -1,
icon: 'faTrash',
inputs: [
{
label: 'Cache To Clear',
name: 'cacheToClear',
type: 'string',
defaultValue: 'jobCache',
inputUI: {
type: 'dropdown',
options: [
'jobCache',
'libraryCache',
],
},
tooltip: `Specify which cache to clear
${helperText}
`,
},
],
outputs: [
{
number: 1,
tooltip: 'Continue to next plugin',
},
],
});
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const plugin = async (args: IpluginInputArgs): Promise<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 { cacheToClear } = args.inputs;
const currentFile = args.inputFileObj._id;
const jobCacheDir = args.workDir;
const libraryCacheDir = args.librarySettings.cache;
let folderToClear = '';
if (cacheToClear === 'jobCache') {
folderToClear = jobCacheDir;
} else if (cacheToClear === 'libraryCache') {
folderToClear = libraryCacheDir;
}
args.jobLog(`Clearing ${cacheToClear} folder: "${folderToClear}"`);
args.jobLog(`Keeping current file: "${currentFile}"`);
const traverseFolder = async (dir:string) => {
const filesInDir = (await fsp.readdir(dir)).map((file) => normJoinPath({
upath: args.deps.upath,
paths: [
dir,
file,
],
}));
for (let i = 0; i < filesInDir.length; i += 1) {
const file = filesInDir[i];
// eslint-disable-next-line no-await-in-loop
const stat = await fsp.stat(file);
if (stat.isDirectory()) {
// eslint-disable-next-line no-await-in-loop
await traverseFolder(file);
} else if (
file !== currentFile
// prevent deleting non Tdarr cache files
&& file.includes('tdarr-workDir2')
) {
args.jobLog(`Deleting "${file}"`);
try {
// eslint-disable-next-line no-await-in-loop
await fsp.unlink(file);
} catch (err) {
args.jobLog(`File delete error: ${JSON.stringify(err)}`);
}
}
}
};
await traverseFolder(folderToClear);
return {
outputFileObj: args.inputFileObj,
outputNumber: 1,
variables: args.variables,
};
};
export {
details,
plugin,
};

@ -0,0 +1,105 @@
/* eslint-disable max-len */
import { promises as fsp } from 'fs';
import { getPluginWorkDir } from '../../../../FlowHelpers/1.0.0/fileUtils';
import {
IpluginDetails,
IpluginInputArgs,
IpluginOutputArgs,
} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces';
/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */
const details = (): IpluginDetails => ({
name: 'Custom JS Function',
description: 'Write a custom function in JS to run with up to 4 outputs',
style: {
borderColor: 'green',
},
tags: '',
isStartPlugin: false,
pType: '',
requiresVersion: '2.11.01',
sidebarPosition: -1,
icon: 'faArrowRight',
inputs: [
{
label: 'JS Code',
name: 'code',
type: 'string',
defaultValue: `
module.exports = async (args) => {
// see args object data here https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/FlowPluginsTs/FlowHelpers/1.0.0/interfaces/interfaces.ts
// example setting flow variable: https://github.com/HaveAGitGat/Tdarr/issues/1147#issuecomment-2593348443
// example reading ffmpeg metadata: https://github.com/HaveAGitGat/Tdarr_Plugins/issues/737#issuecomment-2581536112
// example setting working file as previous working file: https://github.com/HaveAGitGat/Tdarr/issues/1106#issuecomment-2622177459
// some example file data:
console.log(args.inputFileObj._id)
console.log(args.inputFileObj.file_size)
console.log(args.inputFileObj.ffProbeData.streams[0].codec_name)
console.log(args.inputFileObj.mediaInfo.track[0].BitRate)
// access global variable:
console.log(args.userVariables.global.test)
// access library variable:
console.log(args.userVariables.library.test)
// do something here
return {
outputFileObj: args.inputFileObj,
outputNumber: 1,
variables: args.variables,
};
}
`,
inputUI: {
type: 'textarea',
style: {
height: '200px',
},
},
tooltip: 'Write your custom function here',
},
],
outputs: [
{
number: 1,
tooltip: 'Continue to output 1',
},
{
number: 2,
tooltip: 'Continue to output 2',
},
{
number: 3,
tooltip: 'Continue to output 3',
},
{
number: 4,
tooltip: 'Continue to output 4',
},
],
});
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const plugin = async (args: IpluginInputArgs): Promise<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 code = String(args.inputs.code);
const outputFilePath = `${getPluginWorkDir(args)}/script.js`;
await fsp.writeFile(outputFilePath, code);
// eslint-disable-next-line import/no-dynamic-require
const func = require(outputFilePath);
const response = await func(args);
return response;
};
export {
details,
plugin,
};

@ -0,0 +1,47 @@
import {
IpluginDetails,
IpluginInputArgs,
IpluginOutputArgs,
} from '../../../../FlowHelpers/1.0.0/interfaces/interfaces';
/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */
const details = (): IpluginDetails => ({
name: 'Remove From Tdarr',
description: `
If this plugin is executed, then when the flow ends, the item will be
removed from the Tdarr database and won't appear in Transcode Success or Error tables on the 'Tdarr' tab.
Use the 'Delete File' plugin if you would like to delete the file from disk.
`,
style: {
borderColor: 'red',
},
tags: '',
isStartPlugin: false,
pType: '',
requiresVersion: '2.31.01',
sidebarPosition: -1,
icon: 'faTrash',
inputs: [],
outputs: [
{
number: 1,
tooltip: 'Continue to next plugin',
},
],
});
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const plugin = (args: IpluginInputArgs): IpluginOutputArgs => {
// eslint-disable-next-line no-param-reassign
args.variables.removeFromTdarr = true;
return {
outputFileObj: args.inputFileObj,
outputNumber: 1,
variables: args.variables,
};
};
export {
details,
plugin,
};

@ -74,6 +74,16 @@ const details = (): IpluginDetails => ({
},
tooltip: 'Specify request body',
},
{
label: 'Log Response Body',
name: 'logResponseBody',
type: 'boolean',
defaultValue: 'false',
inputUI: {
type: 'switch',
},
tooltip: 'Specify whether to log response body in the job report',
},
],
outputs: [
{
@ -93,6 +103,7 @@ const plugin = async (args: IpluginInputArgs): Promise<IpluginOutputArgs> => {
const requestUrl = String(args.inputs.requestUrl);
const requestHeaders = JSON.parse(String(args.inputs.requestHeaders));
const requestBody = JSON.parse(String(args.inputs.requestBody));
const { logResponseBody } = args.inputs;
const requestConfig = {
method,
@ -104,6 +115,10 @@ const plugin = async (args: IpluginInputArgs): Promise<IpluginOutputArgs> => {
try {
const res = await args.deps.axios(requestConfig);
args.jobLog(`Web request succeeded: Status Code: ${res.status}`);
if (logResponseBody) {
args.jobLog(`Response Body: ${JSON.stringify(res.data)}`);
}
} catch (err) {
args.jobLog('Web Request Failed');
args.jobLog(JSON.stringify(err));

@ -0,0 +1,284 @@
/* eslint-disable no-template-curly-in-string */
/* eslint-disable import/prefer-default-export */
import { IflowTemplate } from '../../FlowHelpers/1.0.0/interfaces/interfaces';
const details = () :IflowTemplate => ({
"name": "Chapter 8: Unmapped Nodes",
"description": "Chapter 8: Unmapped Nodes",
"tags": "",
"flowPlugins": [
{
"name": "Tags: Worker Type - Mapped Node",
"sourceRepo": "Community",
"pluginName": "tagsWorkerType",
"version": "1.0.0",
"id": "XDkUDTqXV",
"position": {
"x": 618.728206498488,
"y": 797.6991616678526
},
"fpEnabled": true,
"inputsDB": {
"requiredNodeTags": "mapped"
}
},
{
"name": "Tags: Worker Type - Unmapped Node",
"sourceRepo": "Community",
"pluginName": "tagsWorkerType",
"version": "1.0.0",
"id": "Gm1kh8K5w",
"position": {
"x": 487.23666063579026,
"y": 281.79774016757386
},
"fpEnabled": true,
"inputsDB": {
"requiredNodeTags": "unmapped"
}
},
{
"name": "Input File",
"sourceRepo": "Community",
"pluginName": "inputFile",
"version": "1.0.0",
"id": "pE6rU7gkW",
"position": {
"x": 788.5712895368422,
"y": 45.83576905176477
},
"fpEnabled": true
},
{
"name": "Check if hevc",
"sourceRepo": "Community",
"pluginName": "checkVideoCodec",
"version": "1.0.0",
"id": "91b7IrsEc",
"position": {
"x": 788.2207108267078,
"y": 203.7781028159269
},
"fpEnabled": true
},
{
"name": "Start",
"sourceRepo": "Community",
"pluginName": "ffmpegCommandStart",
"version": "1.0.0",
"id": "4Swd6qzvc",
"position": {
"x": 489.25252076795084,
"y": 370.51229288382495
},
"fpEnabled": true
},
{
"name": "Execute",
"sourceRepo": "Community",
"pluginName": "ffmpegCommandExecute",
"version": "1.0.0",
"id": "450g167D8",
"position": {
"x": 488.72295602997406,
"y": 699.5034828311435
},
"fpEnabled": true
},
{
"name": "Set Video Encoder",
"sourceRepo": "Community",
"pluginName": "ffmpegCommandSetVideoEncoder",
"version": "1.0.0",
"id": "8B_6pRd_U",
"position": {
"x": 488.5270135748424,
"y": 477.83202026423606
},
"fpEnabled": true
},
{
"name": "Replace Original File",
"sourceRepo": "Community",
"pluginName": "replaceOriginalFile",
"version": "1.0.0",
"id": "4fkfOyR3l",
"position": {
"x": 797.2573001129032,
"y": 882.7619863463507
},
"fpEnabled": true
},
{
"name": "Set Container",
"sourceRepo": "Community",
"pluginName": "ffmpegCommandSetContainer",
"version": "1.0.0",
"id": "TtKXi3Q7h",
"position": {
"x": 488.21110165973323,
"y": 570.3064821931456
},
"fpEnabled": true
},
{
"name": "Tags: Worker Type - Mapped Node",
"sourceRepo": "Community",
"pluginName": "tagsWorkerType",
"version": "1.0.0",
"id": "7Y_fzVfGm",
"position": {
"x": 788.7823658666633,
"y": 127.15363454994434
},
"fpEnabled": true,
"inputsDB": {
"requiredNodeTags": "mapped"
}
},
{
"name": "We will check the file codec on a mapped node. This way bandwidth and time is saved as we don't need to unnecessarily send the whole file to the unmapped node.",
"sourceRepo": "Community",
"pluginName": "comment",
"version": "1.0.0",
"id": "6oOV2PLSr",
"position": {
"x": 958.0256289687773,
"y": 129.22000506355067
},
"fpEnabled": true
},
{
"name": "If the codec is not what we want, we'll require the next transcoding steps to run on an unmapped node. The unmapped node will automatically download the file from the server.",
"sourceRepo": "Community",
"pluginName": "comment",
"version": "1.0.0",
"id": "j343VFewY",
"position": {
"x": 316.4293037925603,
"y": 290.6548883625747
},
"fpEnabled": true
},
{
"name": "After the transcode, we'll run the original file replacement on a mapped node which has access to the server file system. The mapped node will automatically download the working file from the unmapped node.",
"sourceRepo": "Community",
"pluginName": "comment",
"version": "1.0.0",
"id": "hVhthld87",
"position": {
"x": 364.852600714643,
"y": 769.3367928955186
},
"fpEnabled": true
},
{
"name": "Before starting, ensure that in the Node options panel on the Tdarr tab, the mapped node has node tag 'mapped' and the umapped node has node tag 'umapped'.",
"sourceRepo": "Community",
"pluginName": "comment",
"version": "1.0.0",
"id": "9sd__MisF",
"position": {
"x": 791.5682800167409,
"y": -93.09360376469954
},
"fpEnabled": true
},
{
"name": "Unmapped nodes are a new node type for Tdarr Pro members on 2.27.01 and above. More info: https://docs.tdarr.io/docs/nodes/nodes#unmapped",
"sourceRepo": "Community",
"pluginName": "comment",
"version": "1.0.0",
"id": "EILF-RWh2",
"position": {
"x": 791.4236829857584,
"y": -209.23734619332546
},
"fpEnabled": true
}
],
"flowEdges": [
{
"source": "4Swd6qzvc",
"sourceHandle": "1",
"target": "8B_6pRd_U",
"targetHandle": null,
"id": "3Df7Xoy93"
},
{
"source": "8B_6pRd_U",
"sourceHandle": "1",
"target": "TtKXi3Q7h",
"targetHandle": null,
"id": "epqtLsPuG"
},
{
"source": "TtKXi3Q7h",
"sourceHandle": "1",
"target": "450g167D8",
"targetHandle": null,
"id": "ljOeP0cAZ"
},
{
"source": "450g167D8",
"sourceHandle": "1",
"target": "XDkUDTqXV",
"targetHandle": null,
"id": "3412q1wK2"
},
{
"source": "XDkUDTqXV",
"sourceHandle": "1",
"target": "4fkfOyR3l",
"targetHandle": null,
"id": "3jQP_egvG"
},
{
"source": "pE6rU7gkW",
"sourceHandle": "1",
"target": "7Y_fzVfGm",
"targetHandle": null,
"id": "XHRuig1Dp"
},
{
"source": "7Y_fzVfGm",
"sourceHandle": "1",
"target": "91b7IrsEc",
"targetHandle": null,
"id": "_CJ9H5I_X"
},
{
"source": "91b7IrsEc",
"sourceHandle": "1",
"target": "4fkfOyR3l",
"targetHandle": null,
"id": "2x5mRYwOU"
},
{
"source": "91b7IrsEc",
"sourceHandle": "2",
"target": "Gm1kh8K5w",
"targetHandle": null,
"id": "8eBsa60Xp"
},
{
"source": "Gm1kh8K5w",
"sourceHandle": "1",
"target": "4Swd6qzvc",
"targetHandle": null,
"id": "IryDiBCVX"
},
{
"source": "EILF-RWh2",
"sourceHandle": "1",
"target": "9sd__MisF",
"targetHandle": null,
"id": "IPiPj8zhv"
}
]
});
export {
details,
};

@ -1,25 +1,52 @@
import { getEncoder } from './hardwareUtils';
import { getEncoder, IgetEncoder } from './hardwareUtils';
const run = async () => {
const encoderProperties = await getEncoder({
const baseInput = {
targetCodec: 'h264',
hardwareEncoding: true,
hardwareType: 'auto',
// @ts-expect-error type
args: {
workerType: 'transcodegpu',
ffmpegPath: 'ffmpeg',
jobLog: (t:string) => {
// eslint-disable-next-line no-console
console.log(t);
jobLog: () => {
//
},
},
});
};
interface IcheckHardware {
targetCodec:string | undefined,
hardwareEncoding:boolean | undefined,
hardwareType:string | undefined,
ffmpegPath:string | undefined,
}
const checkHardware = async (settings:IcheckHardware):Promise<IgetEncoder> => {
const input = JSON.parse(JSON.stringify(baseInput));
input.args.jobLog = () => {
// eslint-disable-next-line no-console
console.log({
encoderProperties,
});
// console.log(t);
};
if (settings.targetCodec) {
input.targetCodec = settings.targetCodec;
}
if (settings.hardwareEncoding) {
input.hardwareEncoding = settings.hardwareEncoding;
}
if (settings.hardwareType) {
input.hardwareType = settings.hardwareType;
}
if (settings.ffmpegPath) {
input.args.ffmpegPath = settings.ffmpegPath;
}
const encoderProperties = await getEncoder(input);
return encoderProperties;
};
void run();
export default checkHardware;

@ -203,6 +203,16 @@ export const getEncoder = async ({
outputArgs: [],
filter: '',
},
{
encoder: 'hevc_rkmpp',
enabled: false,
inputArgs: [
'-hwaccel',
'rkmpp',
],
outputArgs: [],
filter: '',
},
{
encoder: 'hevc_amf',
enabled: false,
@ -275,6 +285,16 @@ export const getEncoder = async ({
outputArgs: [],
filter: '',
},
{
encoder: 'h264_rkmpp',
enabled: false,
inputArgs: [
'-hwaccel',
'rkmpp',
],
outputArgs: [],
filter: '',
},
{
encoder: 'h264_videotoolbox',
enabled: false,

@ -111,7 +111,8 @@ export interface Ivariables {
user: Record<string, string>,
healthCheck?: 'Success',
queueTags?: string,
liveSizeCompare?: IliveSizeCompare
liveSizeCompare?: IliveSizeCompare,
removeFromTdarr?: boolean,
}
export interface IpluginOutputArgs {
@ -127,6 +128,10 @@ export interface IpluginInputArgs {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
librarySettings: any,
inputs: Record<string, unknown>,
userVariables: {
global: Record<string, string>,
library: Record<string, string>,
},
jobLog: Ilog,
workDir: string,
platform: string,

Loading…
Cancel
Save