mirror of
https://github.com/gabehf/Tdarr_Plugins.git
synced 2026-03-14 17:55:55 -07:00
Update flows
This commit is contained in:
parent
658857fdf4
commit
25c4fab8d9
73 changed files with 4295 additions and 839 deletions
|
|
@ -225,20 +225,20 @@ var CLI = /** @class */ (function () {
|
|||
childProcess = require('child_process');
|
||||
errorLogFull = [];
|
||||
// eslint-disable-next-line no-console
|
||||
console.log("Running ".concat(this.config.cli, " ").concat(this.config.spawnArgs.join(' ')));
|
||||
this.config.jobLog("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());
|
||||
// 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());
|
||||
// console.log(data.toString());
|
||||
errorLogFull.push(data.toString());
|
||||
_this.parseOutput(data);
|
||||
});
|
||||
|
|
@ -253,7 +253,7 @@ var CLI = /** @class */ (function () {
|
|||
thread.on('close', function (code) {
|
||||
if (code !== 0) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(code, 'FFmpeg error');
|
||||
console.log(code, 'CLI error');
|
||||
}
|
||||
resolve(code);
|
||||
});
|
||||
|
|
@ -267,6 +267,9 @@ var CLI = /** @class */ (function () {
|
|||
})];
|
||||
case 1:
|
||||
cliExitCode = _a.sent();
|
||||
if (!this.config.logFullCliOutput) {
|
||||
this.config.jobLog(errorLogFull.slice(-1000).join(''));
|
||||
}
|
||||
return [2 /*return*/, {
|
||||
cliExitCode: cliExitCode,
|
||||
errorLogFull: errorLogFull,
|
||||
17
FlowPlugins/FlowHelpers/1.0.0/fileUtils.js
Normal file
17
FlowPlugins/FlowHelpers/1.0.0/fileUtils.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getFfType = exports.getFileName = exports.getContainer = void 0;
|
||||
var getContainer = function (filePath) {
|
||||
var parts = filePath.split('.');
|
||||
return parts[parts.length - 1];
|
||||
};
|
||||
exports.getContainer = getContainer;
|
||||
var getFileName = function (filePath) {
|
||||
var parts = filePath.split('/');
|
||||
var fileNameAndContainer = parts[parts.length - 1];
|
||||
var parts2 = fileNameAndContainer.split('.');
|
||||
return parts2[0];
|
||||
};
|
||||
exports.getFileName = getFileName;
|
||||
var getFfType = function (codecType) { return (codecType === 'video' ? 'v' : 'a'); };
|
||||
exports.getFfType = getFfType;
|
||||
325
FlowPlugins/FlowHelpers/1.0.0/hardwareUtils.js
Normal file
325
FlowPlugins/FlowHelpers/1.0.0/hardwareUtils.js
Normal file
|
|
@ -0,0 +1,325 @@
|
|||
"use strict";
|
||||
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);
|
||||
};
|
||||
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.getEncoder = exports.getBestNvencDevice = exports.hasEncoder = void 0;
|
||||
var hasEncoder = function (_a) {
|
||||
var ffmpegPath = _a.ffmpegPath, encoder = _a.encoder, inputArgs = _a.inputArgs, filter = _a.filter;
|
||||
return __awaiter(void 0, void 0, void 0, function () {
|
||||
var exec, isEnabled, err_1;
|
||||
return __generator(this, function (_b) {
|
||||
switch (_b.label) {
|
||||
case 0:
|
||||
exec = require('child_process').exec;
|
||||
isEnabled = false;
|
||||
_b.label = 1;
|
||||
case 1:
|
||||
_b.trys.push([1, 3, , 4]);
|
||||
return [4 /*yield*/, new Promise(function (resolve) {
|
||||
var command = "".concat(ffmpegPath, " ").concat(inputArgs.join(' ') || '', " -f lavfi -i color=c=black:s=256x256:d=1:r=30")
|
||||
+ " ".concat(filter || '')
|
||||
+ " -c:v ".concat(encoder, " -f null /dev/null");
|
||||
exec(command, function (
|
||||
// eslint-disable-next-line
|
||||
error) {
|
||||
if (error) {
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
resolve(true);
|
||||
});
|
||||
})];
|
||||
case 2:
|
||||
isEnabled = _b.sent();
|
||||
return [3 /*break*/, 4];
|
||||
case 3:
|
||||
err_1 = _b.sent();
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(err_1);
|
||||
return [3 /*break*/, 4];
|
||||
case 4: return [2 /*return*/, isEnabled];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
exports.hasEncoder = hasEncoder;
|
||||
// credit to UNCode101 for this
|
||||
var getBestNvencDevice = function (_a) {
|
||||
var args = _a.args, nvencDevice = _a.nvencDevice;
|
||||
var execSync = require('child_process').execSync;
|
||||
var gpu_num = -1;
|
||||
var lowest_gpu_util = 100000;
|
||||
var result_util = 0;
|
||||
var gpu_count = -1;
|
||||
var gpu_names = '';
|
||||
var gpus_to_exclude = [];
|
||||
// inputs.exclude_gpus === '' ? [] : inputs.exclude_gpus.split(',').map(Number);
|
||||
try {
|
||||
gpu_names = execSync('nvidia-smi --query-gpu=name --format=csv,noheader');
|
||||
gpu_names = gpu_names.toString().trim();
|
||||
var gpu_namesArr = gpu_names.split(/\r?\n/);
|
||||
/* When nvidia-smi returns an error it contains 'nvidia-smi' in the error
|
||||
Example: Linux: nvidia-smi: command not found
|
||||
Windows: 'nvidia-smi' is not recognized as an internal or external command,
|
||||
operable program or batch file. */
|
||||
if (!gpu_namesArr[0].includes('nvidia-smi')) {
|
||||
gpu_count = gpu_namesArr.length;
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
args.jobLog('Error in reading nvidia-smi output! \n');
|
||||
}
|
||||
if (gpu_count > 0) {
|
||||
for (var gpui = 0; gpui < gpu_count; gpui += 1) {
|
||||
// Check if GPU # is in GPUs to exclude
|
||||
if (gpus_to_exclude.includes(String(gpui))) {
|
||||
args.jobLog("GPU ".concat(gpui, ": ").concat(gpu_names[gpui], " is in exclusion list, will not be used!\n"));
|
||||
}
|
||||
else {
|
||||
try {
|
||||
var cmd_gpu = "nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader,nounits -i ".concat(gpui);
|
||||
result_util = parseInt(execSync(cmd_gpu), 10);
|
||||
if (!Number.isNaN(result_util)) { // != "No devices were found") {
|
||||
args.jobLog("GPU ".concat(gpui, " : Utilization ").concat(result_util, "%\n"));
|
||||
if (result_util < lowest_gpu_util) {
|
||||
gpu_num = gpui;
|
||||
lowest_gpu_util = result_util;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
args.jobLog("Error in reading GPU ".concat(gpui, " Utilization\nError: ").concat(error, "\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gpu_num >= 0) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
nvencDevice.inputArgs.push('-hwaccel_device', "".concat(gpu_num));
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
nvencDevice.outputArgs.push('-gpu', "".concat(gpu_num));
|
||||
}
|
||||
return nvencDevice;
|
||||
};
|
||||
exports.getBestNvencDevice = getBestNvencDevice;
|
||||
var encoderFilter = function (encoder, targetCodec) {
|
||||
if (targetCodec === 'hevc' && (encoder.includes('hevc') || encoder.includes('h265'))) {
|
||||
return true;
|
||||
}
|
||||
if (targetCodec === 'h264' && encoder.includes('h264')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
var getEncoder = function (_a) {
|
||||
var targetCodec = _a.targetCodec, hardwareEncoding = _a.hardwareEncoding, args = _a.args;
|
||||
return __awaiter(void 0, void 0, void 0, function () {
|
||||
var gpuEncoders, filteredGpuEncoders, _i, filteredGpuEncoders_1, gpuEncoder, _b, enabledDevices, res;
|
||||
return __generator(this, function (_c) {
|
||||
switch (_c.label) {
|
||||
case 0:
|
||||
if (!(args.workerType
|
||||
&& args.workerType.includes('gpu')
|
||||
&& hardwareEncoding && (targetCodec === 'hevc' || targetCodec === 'h264'))) return [3 /*break*/, 5];
|
||||
gpuEncoders = [
|
||||
{
|
||||
encoder: 'hevc_nvenc',
|
||||
enabled: false,
|
||||
inputArgs: [
|
||||
'-hwaccel',
|
||||
'cuda',
|
||||
],
|
||||
outputArgs: [],
|
||||
filter: '',
|
||||
},
|
||||
{
|
||||
encoder: 'hevc_amf',
|
||||
enabled: false,
|
||||
inputArgs: [],
|
||||
outputArgs: [],
|
||||
filter: '',
|
||||
},
|
||||
{
|
||||
encoder: 'hevc_vaapi',
|
||||
inputArgs: [
|
||||
'-hwaccel',
|
||||
'vaapi',
|
||||
'-hwaccel_device',
|
||||
'/dev/dri/renderD128',
|
||||
'-hwaccel_output_format',
|
||||
'vaapi',
|
||||
],
|
||||
outputArgs: [],
|
||||
enabled: false,
|
||||
filter: '-vf format=nv12,hwupload',
|
||||
},
|
||||
{
|
||||
encoder: 'hevc_qsv',
|
||||
enabled: false,
|
||||
inputArgs: [
|
||||
'-hwaccel',
|
||||
'qsv',
|
||||
],
|
||||
outputArgs: [],
|
||||
filter: '',
|
||||
},
|
||||
{
|
||||
encoder: 'hevc_videotoolbox',
|
||||
enabled: false,
|
||||
inputArgs: [
|
||||
'-hwaccel',
|
||||
'videotoolbox',
|
||||
],
|
||||
outputArgs: [],
|
||||
filter: '',
|
||||
},
|
||||
{
|
||||
encoder: 'h264_nvenc',
|
||||
enabled: false,
|
||||
inputArgs: [
|
||||
'-hwaccel',
|
||||
'cuda',
|
||||
],
|
||||
outputArgs: [],
|
||||
filter: '',
|
||||
},
|
||||
{
|
||||
encoder: 'h264_amf',
|
||||
enabled: false,
|
||||
inputArgs: [],
|
||||
outputArgs: [],
|
||||
filter: '',
|
||||
},
|
||||
{
|
||||
encoder: 'h264_qsv',
|
||||
enabled: false,
|
||||
inputArgs: [
|
||||
'-hwaccel',
|
||||
'qsv',
|
||||
],
|
||||
outputArgs: [],
|
||||
filter: '',
|
||||
},
|
||||
{
|
||||
encoder: 'h264_videotoolbox',
|
||||
enabled: false,
|
||||
inputArgs: [
|
||||
'-hwaccel',
|
||||
'videotoolbox',
|
||||
],
|
||||
outputArgs: [],
|
||||
filter: '',
|
||||
},
|
||||
];
|
||||
filteredGpuEncoders = gpuEncoders.filter(function (device) { return encoderFilter(device.encoder, targetCodec); });
|
||||
_i = 0, filteredGpuEncoders_1 = filteredGpuEncoders;
|
||||
_c.label = 1;
|
||||
case 1:
|
||||
if (!(_i < filteredGpuEncoders_1.length)) return [3 /*break*/, 4];
|
||||
gpuEncoder = filteredGpuEncoders_1[_i];
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
_b = gpuEncoder;
|
||||
return [4 /*yield*/, (0, exports.hasEncoder)({
|
||||
ffmpegPath: args.ffmpegPath,
|
||||
encoder: gpuEncoder.encoder,
|
||||
inputArgs: gpuEncoder.inputArgs,
|
||||
filter: gpuEncoder.filter,
|
||||
})];
|
||||
case 2:
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
_b.enabled = _c.sent();
|
||||
_c.label = 3;
|
||||
case 3:
|
||||
_i++;
|
||||
return [3 /*break*/, 1];
|
||||
case 4:
|
||||
enabledDevices = gpuEncoders.filter(function (device) { return device.enabled === true; });
|
||||
if (enabledDevices.length > 0) {
|
||||
if (enabledDevices[0].encoder.includes('nvenc')) {
|
||||
res = (0, exports.getBestNvencDevice)({
|
||||
args: args,
|
||||
nvencDevice: enabledDevices[0],
|
||||
});
|
||||
return [2 /*return*/, __assign(__assign({}, res), { isGpu: true })];
|
||||
}
|
||||
return [2 /*return*/, {
|
||||
encoder: enabledDevices[0].encoder,
|
||||
inputArgs: enabledDevices[0].inputArgs,
|
||||
outputArgs: enabledDevices[0].outputArgs,
|
||||
isGpu: true,
|
||||
}];
|
||||
}
|
||||
_c.label = 5;
|
||||
case 5:
|
||||
if (targetCodec === 'hevc') {
|
||||
return [2 /*return*/, {
|
||||
encoder: 'libx265',
|
||||
inputArgs: [],
|
||||
outputArgs: [],
|
||||
isGpu: false,
|
||||
}];
|
||||
}
|
||||
if (targetCodec === 'h264') {
|
||||
return [2 /*return*/, {
|
||||
encoder: 'libx264',
|
||||
inputArgs: [],
|
||||
outputArgs: [],
|
||||
isGpu: false,
|
||||
}];
|
||||
}
|
||||
return [2 /*return*/, {
|
||||
encoder: targetCodec,
|
||||
inputArgs: [],
|
||||
outputArgs: [],
|
||||
isGpu: false,
|
||||
}];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
exports.getEncoder = getEncoder;
|
||||
67
FlowPlugins/FlowHelpers/1.0.0/hardwareUtils.test.js
Normal file
67
FlowPlugins/FlowHelpers/1.0.0/hardwareUtils.test.js
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
"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 });
|
||||
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)({
|
||||
targetCodec: 'h264',
|
||||
hardwareEncoding: true,
|
||||
// @ts-expect-error type
|
||||
args: {
|
||||
workerType: 'transcodegpu',
|
||||
ffmpegPath: 'ffmpeg',
|
||||
jobLog: function (t) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(t);
|
||||
},
|
||||
},
|
||||
})];
|
||||
case 1:
|
||||
encoderProperties = _a.sent();
|
||||
// eslint-disable-next-line no-console
|
||||
console.log({
|
||||
encoderProperties: encoderProperties,
|
||||
});
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); };
|
||||
void run();
|
||||
Loading…
Add table
Add a link
Reference in a new issue