Plugin update

This commit is contained in:
HaveAGitGat 2021-12-11 19:48:53 +00:00
parent 5f68989571
commit 90e2b3923a
85 changed files with 2093 additions and 1007 deletions

View file

@ -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 ||