mirror of
https://github.com/gabehf/Tdarr_Plugins.git
synced 2026-03-18 11:46:25 -07:00
Plugin update
This commit is contained in:
parent
5f68989571
commit
90e2b3923a
85 changed files with 2093 additions and 1007 deletions
|
|
@ -1,7 +1,9 @@
|
|||
/* eslint-disable */
|
||||
function details() {
|
||||
const loadDefaultValues = require('../methods/loadDefaultValues');
|
||||
const details = () => {
|
||||
return {
|
||||
id: "Tdarr_Plugin_DOOM_NVENC_Tiered_MKV_CleanAll",
|
||||
Stage: 'Pre-processing',
|
||||
Name: "DOOM Tiered H265 MKV, remove audio & subtitles [NVENC]",
|
||||
Stage: "Pre-processing",
|
||||
Type: "Video",
|
||||
|
|
@ -9,40 +11,70 @@ function details() {
|
|||
Description:
|
||||
"In a single pass ensures all files are in MKV containers and where possible encoded in h265 (Tiered bitrate based on resolution), removes audio and subtitles that are not in the configured language or marked as commentary.",
|
||||
Version: "2.0",
|
||||
Tags: "pre-processing,ffmpeg,nvenc h265",
|
||||
Tags: "pre-processing,ffmpeg,nvenc h265",
|
||||
Inputs: [
|
||||
{
|
||||
name: "target_bitrate_480p576p",
|
||||
type: 'string',
|
||||
defaultValue: '1000000',
|
||||
inputUI: {
|
||||
type: 'text',
|
||||
},
|
||||
tooltip: `Specify the target bitrate for 480p and 576p files, if current bitrate exceeds the target. Otherwise target_pct_reduction will be used.
|
||||
\\nExample 1 Mbps:\\n
|
||||
1000000`,
|
||||
},
|
||||
{
|
||||
name: "target_bitrate_720p",
|
||||
type: 'string',
|
||||
defaultValue: '2000000',
|
||||
inputUI: {
|
||||
type: 'text',
|
||||
},
|
||||
tooltip: `Specify the target bitrate for 720p files, if current bitrate exceeds the target. Otherwise target_pct_reduction will be used.
|
||||
\\nExample 2 Mbps:\\n
|
||||
2000000`,
|
||||
},
|
||||
{
|
||||
name: "target_bitrate_1080p",
|
||||
type: 'string',
|
||||
defaultValue: '2500000',
|
||||
inputUI: {
|
||||
type: 'text',
|
||||
},
|
||||
tooltip: `Specify the target bitrate for 1080p files, if current bitrate exceeds the target. Otherwise target_pct_reduction will be used.
|
||||
\\nExample 2.5 Mbps:\\n
|
||||
2500000`,
|
||||
},
|
||||
{
|
||||
name: "target_bitrate_4KUHD",
|
||||
type: 'string',
|
||||
defaultValue: '14000000',
|
||||
inputUI: {
|
||||
type: 'text',
|
||||
},
|
||||
tooltip: `Specify the target bitrate for 4KUHD files, if current bitrate exceeds the target. Otherwise target_pct_reduction will be used.
|
||||
\\nExample 14 Mbps:\\n
|
||||
14000000`,
|
||||
},
|
||||
{
|
||||
{
|
||||
name: "target_pct_reduction",
|
||||
type: 'string',
|
||||
defaultValue: '.50',
|
||||
inputUI: {
|
||||
type: 'text',
|
||||
},
|
||||
tooltip: `Specify the target reduction of bitrate, if current bitrate is less than resolution targets.
|
||||
\\nExample 50%:\\n
|
||||
.50`,
|
||||
},
|
||||
{
|
||||
name: "audio_language",
|
||||
type: 'string',
|
||||
defaultValue: 'eng',
|
||||
inputUI: {
|
||||
type: 'text',
|
||||
},
|
||||
tooltip: `Specify language tag/s here for the audio tracks you'd like to keep, recommended to keep "und" as this stands for undertermined, some files may not have the language specified. Must follow ISO-639-2 3 letter format. https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes
|
||||
\\nExample:\\n
|
||||
eng
|
||||
|
|
@ -55,6 +87,11 @@ function details() {
|
|||
},
|
||||
{
|
||||
name: "audio_commentary",
|
||||
type: 'string',
|
||||
defaultValue: 'false',
|
||||
inputUI: {
|
||||
type: 'text',
|
||||
},
|
||||
tooltip: `Specify if audio tracks that contain commentary/description should be removed.
|
||||
\\nExample:\\n
|
||||
true
|
||||
|
|
@ -64,6 +101,11 @@ function details() {
|
|||
},
|
||||
{
|
||||
name: "subtitle_language",
|
||||
type: 'string',
|
||||
defaultValue: '',
|
||||
inputUI: {
|
||||
type: 'text',
|
||||
},
|
||||
tooltip: `Specify language tag/s here for the subtitle tracks you'd like to keep. Must follow ISO-639-2 3 letter format. https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes
|
||||
\\nExample:\\n
|
||||
eng
|
||||
|
|
@ -73,6 +115,11 @@ function details() {
|
|||
},
|
||||
{
|
||||
name: "subtitle_commentary",
|
||||
type: 'string',
|
||||
defaultValue: 'false',
|
||||
inputUI: {
|
||||
type: 'text',
|
||||
},
|
||||
tooltip: `Specify if subtitle tracks that contain commentary/description should be removed.
|
||||
\\nExample:\\n
|
||||
true
|
||||
|
|
@ -173,7 +220,7 @@ class Configurator {
|
|||
function calculateBitrate(file) {
|
||||
var bitrateprobe = file.ffProbeData.streams[0].bit_rate;
|
||||
if (isNaN(bitrateprobe)) {
|
||||
bitrateprobe = file.bit_rate;
|
||||
bitrateprobe = file.bit_rate;
|
||||
}
|
||||
return bitrateprobe;
|
||||
}
|
||||
|
|
@ -204,9 +251,9 @@ function buildAudioConfiguration(inputs, file, logger) {
|
|||
var stream_count = 0;
|
||||
var streams_removing = 0;
|
||||
var languages = inputs.audio_language.split(",");
|
||||
|
||||
|
||||
function audioProcess(stream, id) {
|
||||
stream_count++;
|
||||
stream_count++;
|
||||
if ("tags" in stream && "title" in stream.tags && inputs.audio_commentary.toLowerCase() == "true") {
|
||||
if (
|
||||
stream.tags.title.toLowerCase().includes("commentary") ||
|
||||
|
|
@ -231,16 +278,16 @@ function buildAudioConfiguration(inputs, file, logger) {
|
|||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loopOverStreamsOfType(file, "audio", audioProcess);
|
||||
|
||||
loopOverStreamsOfType(file, "audio", audioProcess);
|
||||
|
||||
if (stream_count == streams_removing) {
|
||||
logger.AddError(
|
||||
`*** All audio tracks would have been removed. Defaulting to keeping all tracks for this file.`
|
||||
);
|
||||
configuration.ResetOutputSetting(["-c:a copy"]);
|
||||
configuration.ResetOutputSetting(["-c:a copy"]);
|
||||
}
|
||||
|
||||
return configuration;
|
||||
|
|
@ -258,24 +305,24 @@ function buildSubtitleConfiguration(inputs, file, logger) {
|
|||
|
||||
loopOverStreamsOfType(file, "subtitle", function (stream, id) {
|
||||
if ((stream.codec_name === "eia_608") ||
|
||||
(stream.codec_tag_string === "mp4s")) {
|
||||
(stream.codec_tag_string === "mp4s")) {
|
||||
// unsupported subtitle codec?
|
||||
configuration.AddOutputSetting(`-map -0:s:${id}`);
|
||||
logger.AddError(
|
||||
`Removing unsupported subtitle`
|
||||
);
|
||||
return;
|
||||
logger.AddError(
|
||||
`Removing unsupported subtitle`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove unknown sub streams
|
||||
if (!("codec_name" in stream)) {
|
||||
configuration.AddOutputSetting(`-map -0:s:${id}`);
|
||||
logger.AddError(
|
||||
`Removing unknown subtitle`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Remove unknown sub streams
|
||||
if (!("codec_name" in stream)) {
|
||||
configuration.AddOutputSetting(`-map -0:s:${id}`);
|
||||
logger.AddError(
|
||||
`Removing unknown subtitle`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if ("tags" in stream) {
|
||||
// Remove unwanted languages
|
||||
if ("language" in stream.tags) {
|
||||
|
|
@ -284,12 +331,12 @@ function buildSubtitleConfiguration(inputs, file, logger) {
|
|||
logger.AddError(
|
||||
`Removing subtitle in language ${stream.tags.language}`
|
||||
);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove commentary subtitles
|
||||
if ("title" in stream.tags && (inputs.subtitle_commentary.toLowerCase() == "true")) {
|
||||
if ("title" in stream.tags && (inputs.subtitle_commentary.toLowerCase() == "true")) {
|
||||
if (
|
||||
stream.tags.title.toLowerCase().includes("commentary") ||
|
||||
stream.tags.title.toLowerCase().includes("description") ||
|
||||
|
|
@ -299,7 +346,7 @@ function buildSubtitleConfiguration(inputs, file, logger) {
|
|||
logger.AddError(
|
||||
`Removing Commentary or Description subtitle: ${stream.tags.title}`
|
||||
);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -317,101 +364,107 @@ function buildSubtitleConfiguration(inputs, file, logger) {
|
|||
* MKV container.
|
||||
*/
|
||||
function buildVideoConfiguration(inputs, file, logger) {
|
||||
var configuration = new Configurator(["-map 0", "-map -0:d", "-c:v copy"]);
|
||||
|
||||
var tiered = {
|
||||
"480p" : {"bitrate" : inputs.target_bitrate_480p576p,
|
||||
"max_increase" : 500,
|
||||
"cq" : 29
|
||||
},
|
||||
"576p" : {"bitrate" : inputs.target_bitrate_480p576p,
|
||||
"max_increase" : 500,
|
||||
"cq" : 29
|
||||
},
|
||||
"720p" : {"bitrate" : inputs.target_bitrate_720p,
|
||||
"max_increase" : 2000,
|
||||
"cq" : 30
|
||||
},
|
||||
"1080p" : {"bitrate" : inputs.target_bitrate_1080p,
|
||||
"max_increase" : 2500,
|
||||
"cq" : 31
|
||||
},
|
||||
"4KUHD" : {"bitrate" : inputs.target_bitrate_4KUHD,
|
||||
"max_increase" : 6000,
|
||||
"cq" : 31
|
||||
},
|
||||
"Other" : {"bitrate" : inputs.target_bitrate_1080p,
|
||||
"max_increase" : 2500,
|
||||
"cq" : 31
|
||||
}
|
||||
};
|
||||
|
||||
var inputSettings = {
|
||||
"h263" : "-c:v h263_cuvid",
|
||||
"h264" : "",
|
||||
"mjpeg" : "c:v mjpeg_cuvid",
|
||||
"mpeg1" : "-c:v mpeg1_cuvid",
|
||||
"mpeg2" : "-c:v mpeg2_cuvid",
|
||||
"vc1" : "-c:v vc1_cuvid",
|
||||
"vp8" : "-c:v vp8_cuvid",
|
||||
"vp9" : "-c:v vp9_cuvid"
|
||||
}
|
||||
|
||||
function videoProcess(stream, id) {
|
||||
if (stream.codec_name === "mjpeg") {
|
||||
configuration.AddOutputSetting(`-map -v:${id}`);
|
||||
return;
|
||||
}
|
||||
var configuration = new Configurator(["-map 0", "-map -0:d", "-c:v copy"]);
|
||||
|
||||
if ((stream.codec_name === "hevc" || stream.codec_name === "vp9") && file.container === "mkv") {
|
||||
logger.AddSuccess("File is in HEVC codec and in MKV");
|
||||
return;
|
||||
}
|
||||
var tiered = {
|
||||
"480p": {
|
||||
"bitrate": inputs.target_bitrate_480p576p,
|
||||
"max_increase": 500,
|
||||
"cq": 29
|
||||
},
|
||||
"576p": {
|
||||
"bitrate": inputs.target_bitrate_480p576p,
|
||||
"max_increase": 500,
|
||||
"cq": 29
|
||||
},
|
||||
"720p": {
|
||||
"bitrate": inputs.target_bitrate_720p,
|
||||
"max_increase": 2000,
|
||||
"cq": 30
|
||||
},
|
||||
"1080p": {
|
||||
"bitrate": inputs.target_bitrate_1080p,
|
||||
"max_increase": 2500,
|
||||
"cq": 31
|
||||
},
|
||||
"4KUHD": {
|
||||
"bitrate": inputs.target_bitrate_4KUHD,
|
||||
"max_increase": 6000,
|
||||
"cq": 31
|
||||
},
|
||||
"Other": {
|
||||
"bitrate": inputs.target_bitrate_1080p,
|
||||
"max_increase": 2500,
|
||||
"cq": 31
|
||||
}
|
||||
};
|
||||
|
||||
// Check if should Remux.
|
||||
if ((stream.codec_name === "hevc" || stream.codec_name === "vp9") && file.container !== "mkv") {
|
||||
configuration.AddOutputSetting("-c:v copy");
|
||||
logger.AddError("File is in HEVC codec but not MKV. Will remux");
|
||||
}
|
||||
|
||||
// remove png streams.
|
||||
if (stream.codec_name === "png") {
|
||||
configuration.AddOutputSetting(`-map -0:v:${id}`);
|
||||
} else if (stream.codec_name !== "hevc" && stream.codec_name !== "vp9") { // Check if should Transcode.
|
||||
var bitrateprobe = calculateBitrate(file);
|
||||
var bitratetarget = 0;
|
||||
var bitratemax = 0;
|
||||
var cq = 0;
|
||||
var bitratecheck = 0;
|
||||
var inputSettings = {
|
||||
"h263": "-c:v h263_cuvid",
|
||||
"h264": "",
|
||||
"mjpeg": "c:v mjpeg_cuvid",
|
||||
"mpeg1": "-c:v mpeg1_cuvid",
|
||||
"mpeg2": "-c:v mpeg2_cuvid",
|
||||
"vc1": "-c:v vc1_cuvid",
|
||||
"vp8": "-c:v vp8_cuvid",
|
||||
"vp9": "-c:v vp9_cuvid"
|
||||
}
|
||||
|
||||
/* Determine tiered bitrate variables */
|
||||
var tier = tiered[file.video_resolution];
|
||||
function videoProcess(stream, id) {
|
||||
if (stream.codec_name === "mjpeg") {
|
||||
configuration.AddOutputSetting(`-map -v:${id}`);
|
||||
return;
|
||||
}
|
||||
|
||||
bitratecheck = parseInt(tier["bitrate"]);
|
||||
if (bitrateprobe !== null && bitrateprobe < bitratecheck) {
|
||||
bitratetarget = parseInt((bitrateprobe * inputs.target_pct_reduction) / 1000);
|
||||
} else {
|
||||
bitratetarget = parseInt(tier["bitrate"] / 1000);
|
||||
}
|
||||
bitratemax = bitratetarget + tier["max_increase"];
|
||||
cq = tier["cq"];
|
||||
|
||||
configuration.RemoveOutputSetting("-c:v copy");
|
||||
configuration.AddOutputSetting(
|
||||
`-c:v hevc_nvenc -rc:v vbr_hq -qmin 0 -cq:v ${cq} -b:v ${bitratetarget}k -maxrate:v ${bitratemax}k -preset medium -rc-lookahead 32 -spatial_aq:v 1 -aq-strength:v 8`
|
||||
);
|
||||
|
||||
configuration.AddInputSetting(inputSettings[file.video_codec_name]);
|
||||
|
||||
if (file.video_codec_name === "h264" && file.ffProbeData.streams[0].profile !== "High 10") {
|
||||
configuration.AddInputSetting("-c:v h264_cuvid");
|
||||
}
|
||||
if ((stream.codec_name === "hevc" || stream.codec_name === "vp9") && file.container === "mkv") {
|
||||
logger.AddSuccess("File is in HEVC codec and in MKV");
|
||||
return;
|
||||
}
|
||||
|
||||
logger.AddError("Transcoding to HEVC using NVidia NVENC");
|
||||
}
|
||||
}
|
||||
|
||||
loopOverStreamsOfType(file, "video", videoProcess);
|
||||
// Check if should Remux.
|
||||
if ((stream.codec_name === "hevc" || stream.codec_name === "vp9") && file.container !== "mkv") {
|
||||
configuration.AddOutputSetting("-c:v copy");
|
||||
logger.AddError("File is in HEVC codec but not MKV. Will remux");
|
||||
}
|
||||
|
||||
// remove png streams.
|
||||
if (stream.codec_name === "png") {
|
||||
configuration.AddOutputSetting(`-map -0:v:${id}`);
|
||||
} else if (stream.codec_name !== "hevc" && stream.codec_name !== "vp9") { // Check if should Transcode.
|
||||
var bitrateprobe = calculateBitrate(file);
|
||||
var bitratetarget = 0;
|
||||
var bitratemax = 0;
|
||||
var cq = 0;
|
||||
var bitratecheck = 0;
|
||||
|
||||
/* Determine tiered bitrate variables */
|
||||
var tier = tiered[file.video_resolution];
|
||||
|
||||
bitratecheck = parseInt(tier["bitrate"]);
|
||||
if (bitrateprobe !== null && bitrateprobe < bitratecheck) {
|
||||
bitratetarget = parseInt((bitrateprobe * inputs.target_pct_reduction) / 1000);
|
||||
} else {
|
||||
bitratetarget = parseInt(tier["bitrate"] / 1000);
|
||||
}
|
||||
bitratemax = bitratetarget + tier["max_increase"];
|
||||
cq = tier["cq"];
|
||||
|
||||
configuration.RemoveOutputSetting("-c:v copy");
|
||||
configuration.AddOutputSetting(
|
||||
`-c:v hevc_nvenc -rc:v vbr_hq -qmin 0 -cq:v ${cq} -b:v ${bitratetarget}k -maxrate:v ${bitratemax}k -preset medium -rc-lookahead 32 -spatial_aq:v 1 -aq-strength:v 8`
|
||||
);
|
||||
|
||||
configuration.AddInputSetting(inputSettings[file.video_codec_name]);
|
||||
|
||||
if (file.video_codec_name === "h264" && file.ffProbeData.streams[0].profile !== "High 10") {
|
||||
configuration.AddInputSetting("-c:v h264_cuvid");
|
||||
}
|
||||
|
||||
logger.AddError("Transcoding to HEVC using NVidia NVENC");
|
||||
}
|
||||
}
|
||||
|
||||
loopOverStreamsOfType(file, "video", videoProcess);
|
||||
|
||||
if (!configuration.shouldProcess) {
|
||||
logger.AddSuccess("No video processing necessary");
|
||||
|
|
@ -421,8 +474,10 @@ function buildVideoConfiguration(inputs, file, logger) {
|
|||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
function plugin(file, _librarySettings, inputs) {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const plugin = (file, librarySettings, inputs, otherArguments) => {
|
||||
// eslint-disable-next-line no-unused-vars,no-param-reassign
|
||||
inputs = loadDefaultValues(inputs, details);
|
||||
var response = {
|
||||
container: ".mkv",
|
||||
FFmpegMode: true,
|
||||
|
|
@ -438,26 +493,26 @@ function plugin(file, _librarySettings, inputs) {
|
|||
var videoSettings = buildVideoConfiguration(inputs, file, logger);
|
||||
var subtitleSettings = buildSubtitleConfiguration(inputs, file, logger);
|
||||
|
||||
response.preset = `${videoSettings.GetInputSettings()},${videoSettings.GetOutputSettings()}`
|
||||
response.preset = `${videoSettings.GetInputSettings()},${videoSettings.GetOutputSettings()}`
|
||||
response.preset += ` ${audioSettings.GetOutputSettings()}`
|
||||
response.preset += ` ${subtitleSettings.GetOutputSettings()}`
|
||||
response.preset += ` -max_muxing_queue_size 9999`;
|
||||
|
||||
|
||||
// Extra parameters
|
||||
var id = 0;
|
||||
var badTypes = ['mov_text', 'eia_608', 'timed_id3', 'mp4s'];
|
||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||
if (badTypes.includes(file.ffProbeData.streams[i].codec_name)) {
|
||||
response.preset += ` -map -0:${i}`;
|
||||
};
|
||||
id++;
|
||||
if (badTypes.includes(file.ffProbeData.streams[i].codec_name)) {
|
||||
response.preset += ` -map -0:${i}`;
|
||||
};
|
||||
id++;
|
||||
}
|
||||
// b frames argument
|
||||
response.preset += ` -bf 5`;
|
||||
|
||||
|
||||
// fix probe size errors
|
||||
response.preset += ` -analyzeduration 2147483647 -probesize 2147483647`;
|
||||
|
||||
|
||||
response.processFile =
|
||||
audioSettings.shouldProcess ||
|
||||
videoSettings.shouldProcess ||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue