mirror of
https://github.com/gabehf/Tdarr_Plugins.git
synced 2026-03-15 18:25:54 -07:00
Fixed the NaN issue with BitRates. Some files had bitrate missing in the
MediaInfo data so pulling from the "extra" section for those. Also resolved an issue with the way the findMediaInfoItem function wasn't working with subtitle tracks (well it wasn't working for all files due to the general section because of a previous attempted subtitle fix but this should be much much much better and work in most all cases).
This commit is contained in:
parent
0fed4e0ddc
commit
886ce0b2ae
1 changed files with 138 additions and 72 deletions
208
Community/Tdarr_Plugin_JB69_JBHEVCQSV_MinimalFile.js
Executable file → Normal file
208
Community/Tdarr_Plugin_JB69_JBHEVCQSV_MinimalFile.js
Executable file → Normal file
|
|
@ -7,7 +7,7 @@
|
||||||
/*
|
/*
|
||||||
/// ///////////////////////////////////////////////////////////////////////////////////////////////////
|
/// ///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
Author: JarBinks, Zachg99, Jeff47
|
Author: JarBinks, Zachg99, Jeff47
|
||||||
Date: 01/13/2022
|
Date: 01/20/2022
|
||||||
This is my attempt to create an all in one routine that will maintain my library in optimal format
|
This is my attempt to create an all in one routine that will maintain my library in optimal format
|
||||||
!!!!FOR MY REQUIREMENTS!!!! Chances are very good you will need to make some changes to this routine
|
!!!!FOR MY REQUIREMENTS!!!! Chances are very good you will need to make some changes to this routine
|
||||||
and it's partner in order to make it work for you.
|
and it's partner in order to make it work for you.
|
||||||
|
|
@ -18,8 +18,8 @@ makes my library the best it could be. Thanks to everyone involved. Especially H
|
||||||
whos existing code and assistance were invaluable
|
whos existing code and assistance were invaluable
|
||||||
My belief is that given enough information about the video file an optimal configuration can be determined
|
My belief is that given enough information about the video file an optimal configuration can be determined
|
||||||
specific to that file
|
specific to that file
|
||||||
This is based on what my goals are and uses a mix of internal and external programs to gather as much
|
This is based on what my goals are and uses external programs to gather as much useful information as possible
|
||||||
useful information as possible to make decisions.
|
to make decisions.
|
||||||
There is a lot that goes into the gather and analysis part because:
|
There is a lot that goes into the gather and analysis part because:
|
||||||
It is the basis of the decisions and "garbage in, garbage out"
|
It is the basis of the decisions and "garbage in, garbage out"
|
||||||
The video files are far from perfect when we get them and we need to make sure we learn as much as possible
|
The video files are far from perfect when we get them and we need to make sure we learn as much as possible
|
||||||
|
|
@ -85,16 +85,10 @@ Subtitles:
|
||||||
The order I run them in:
|
The order I run them in:
|
||||||
Tdarr_Plugin_JB69_JBHEVCQSV_MinimalFile (JB - H265, AAC, MKV, bitrate optimized)
|
Tdarr_Plugin_JB69_JBHEVCQSV_MinimalFile (JB - H265, AAC, MKV, bitrate optimized)
|
||||||
Tdarr_Plugin_JB69_JBHEVCQSZ_PostFix (JB - MKV Stats, Chapters, Audio Language)
|
Tdarr_Plugin_JB69_JBHEVCQSZ_PostFix (JB - MKV Stats, Chapters, Audio Language)
|
||||||
I am running the docker image provided for Tdarr.
|
I am running the docker image provided for Tdarr
|
||||||
|
****To get the proper video bitrate you need to run this in the docker container:
|
||||||
This plugin needs (but doesn't require) the mkvtoolnix package. Install command within the container:
|
|
||||||
|
|
||||||
apt install mkvtoolnix
|
apt install mkvtoolnix
|
||||||
|
If those tools are added that no longer needs to be run.
|
||||||
That needs to be rerun with every rebuild of the container to get the proper mediainfo tags.
|
|
||||||
|
|
||||||
One outstanding issue is I'm getting errors from ffmpeg when I attempt to process .ts files.
|
|
||||||
|
|
||||||
Here is my docker config (I am running compose so yours might be a little different)
|
Here is my docker config (I am running compose so yours might be a little different)
|
||||||
tdarr_server:
|
tdarr_server:
|
||||||
container_name: tdarr_server
|
container_name: tdarr_server
|
||||||
|
|
@ -137,7 +131,7 @@ Subtitles:
|
||||||
- TZ=${TZ} # timezone, defined in .env
|
- TZ=${TZ} # timezone, defined in .env
|
||||||
- serverIP=192.168.x.x #container name of the server, should be modified if server is on another machine
|
- serverIP=192.168.x.x #container name of the server, should be modified if server is on another machine
|
||||||
- serverPort=8266
|
- serverPort=8266
|
||||||
- nodeID=TDARRNODE_2
|
- nodeID=TDARRNODE_1
|
||||||
- nodeIP=192.168.x.x #container name of the node
|
- nodeIP=192.168.x.x #container name of the node
|
||||||
- nodePort=9267 #not exposed via a "ports: " setting as the server/node communication is done on the internal
|
- nodePort=9267 #not exposed via a "ports: " setting as the server/node communication is done on the internal
|
||||||
#docker network and can communicate on all ports
|
#docker network and can communicate on all ports
|
||||||
|
|
@ -164,10 +158,122 @@ const details = () => ({
|
||||||
Type: 'Video',
|
Type: 'Video',
|
||||||
Operation: 'Transcode',
|
Operation: 'Transcode',
|
||||||
Description: `***You should not use this*** until you read the comments at the top of the code and understand
|
Description: `***You should not use this*** until you read the comments at the top of the code and understand
|
||||||
how it works **this does alot** and is 1 of 2 routines you should to run **Part 1** \n`,
|
how it works **this does a lot** and is 1 of 2 routines you should to run **Part 1** \n`,
|
||||||
Version: '2.2',
|
Version: '2.2',
|
||||||
Tags: 'pre-processing,ffmpeg,video,audio,qsv h265,aac',
|
Tags: 'pre-processing,ffmpeg,video,audio,qsv,h265,aac',
|
||||||
Inputs: [],
|
Inputs: [{
|
||||||
|
name: 'Stats_Days',
|
||||||
|
type: 'number',
|
||||||
|
defaultValue: 21,
|
||||||
|
inputUI: {
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
tooltip: `If the stats date on the file are older than this it will first update them,\\n
|
||||||
|
usually for mkv only.`,
|
||||||
|
}, {
|
||||||
|
name: 'Target_Video_Codec',
|
||||||
|
type: 'string',
|
||||||
|
defaultValue: 'hevc',
|
||||||
|
inputUI: {
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
tooltip: `This is the basis of the routine, if you want to change,\\n
|
||||||
|
it you probably want to use a different script`,
|
||||||
|
}, {
|
||||||
|
name: 'Use_10bit_Video',
|
||||||
|
type: 'boolean',
|
||||||
|
defaultValue: true,
|
||||||
|
inputUI: {
|
||||||
|
type: 'dropdown',
|
||||||
|
options: [
|
||||||
|
'true',
|
||||||
|
'false',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
tooltip: 'This will encode in 10 bit? Some processors can not.',
|
||||||
|
}, {
|
||||||
|
name: 'Target_Framerate',
|
||||||
|
type: 'number',
|
||||||
|
defaultValue: 25,
|
||||||
|
inputUI: {
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
tooltip: 'Any frame rate greater than this will be adjusted.',
|
||||||
|
}, {
|
||||||
|
name: 'Min_Size_Difference_to_Transcode',
|
||||||
|
type: 'number',
|
||||||
|
defaultValue: 1.2,
|
||||||
|
inputUI: {
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
tooltip: `If the existing bitrate is this much more than the target bitrate\\n
|
||||||
|
it is ok to transcode, otherwise there might not be enough extra\\n
|
||||||
|
to get decent quality.`,
|
||||||
|
}, {
|
||||||
|
name: 'Target_Reduction_for_Code_Switch',
|
||||||
|
type: 'number',
|
||||||
|
defaultValue: 0.8,
|
||||||
|
inputUI: {
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
tooltip: `When a video codec change happens and the source bitrate is lower\\n
|
||||||
|
than optimal, we still lower the bitrate by this since hevc is ok\\n
|
||||||
|
with a lower rate.`,
|
||||||
|
}, {
|
||||||
|
name: 'Max_Video_Height',
|
||||||
|
type: 'number',
|
||||||
|
defaultValue: 2160,
|
||||||
|
inputUI: {
|
||||||
|
type: 'dropdown',
|
||||||
|
options: [
|
||||||
|
720,
|
||||||
|
1080,
|
||||||
|
2160,
|
||||||
|
4320,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
tooltip: 'Any thing over this size, I.E. 8K, will be reduced to this.',
|
||||||
|
}, {
|
||||||
|
name: 'Target_Codec_Compression',
|
||||||
|
type: 'number',
|
||||||
|
defaultValue: 0.08,
|
||||||
|
inputUI: {
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
tooltip: 'This effects the target bitrate by assuming a compression ratio.',
|
||||||
|
}, {
|
||||||
|
name: 'Target_Audio_Codec',
|
||||||
|
type: 'string',
|
||||||
|
defaultValue: 'aac',
|
||||||
|
inputUI: {
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
tooltip: 'Desired Audio Codec, if you change this it might require code changes.',
|
||||||
|
}, {
|
||||||
|
name: 'Target_Audio_Language',
|
||||||
|
type: 'string',
|
||||||
|
defaultValue: 'eng',
|
||||||
|
inputUI: {
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
tooltip: 'Desired Audio Language.',
|
||||||
|
}, {
|
||||||
|
name: 'Target_Audio_Bitrate_Per_Channel',
|
||||||
|
type: 'number',
|
||||||
|
defaultValue: 64000,
|
||||||
|
inputUI: {
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
tooltip: '64K per channel gives you the good lossy quality out of AAC.',
|
||||||
|
}, {
|
||||||
|
name: 'Target_Audio_Channels',
|
||||||
|
type: 'number',
|
||||||
|
defaultValue: 6,
|
||||||
|
inputUI: {
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
tooltip: 'Any thing above this number of channels will be reduced to it.',
|
||||||
|
}],
|
||||||
});
|
});
|
||||||
|
|
||||||
function findMediaInfoItem(file, index) {
|
function findMediaInfoItem(file, index) {
|
||||||
|
|
@ -212,24 +318,16 @@ const plugin = (file, librarySettings, inputs, otherArguments) => {
|
||||||
// Settings
|
// Settings
|
||||||
/// ///////////////////////////////////////////////////////////////////////////////////////////////////
|
/// ///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Process Handling
|
// Process Handling
|
||||||
const intStatsDays = 21; // If the stats date on the file, usually for mkv only,
|
const intStatsDays = inputs.Stats_Days;
|
||||||
// are older than this it will first update them
|
|
||||||
|
|
||||||
// Video
|
// Video
|
||||||
const targetVideoCodec = 'hevc'; // This is the basis of the routine, if you want to change
|
const targetVideoCodec = inputs.Target_Video_Codec;
|
||||||
// it you probably want to use a different script
|
const bolUse10bit = inputs.Use_10bit_Video;
|
||||||
const bolUse10bit = true; // This will encode in 10 bit
|
const targetFrameRate = inputs.Target_Framerate;
|
||||||
const targetFrameRate = 25; // Any frame rate greater than this will be adjusted
|
const minSizeDiffForTranscode = inputs.Min_Size_Difference_to_Transcode;
|
||||||
|
const targetReductionForCodecSwitchOnly = inputs.Target_Reduction_for_Code_Switch;
|
||||||
const minSizeDiffForTranscode = 1.2; // If the existing bitrate is this much more than the target
|
const maxVideoHeight = inputs.Max_Video_Height;
|
||||||
// bitrate it is ok to transcode, otherwise there might not be enough extra
|
const targetCodecCompression = inputs.Target_Codec_Compression;
|
||||||
// to get decent quality
|
|
||||||
const targetReductionForCodecSwitchOnly = 0.8; // When a video codec change happens and the source bitrate is lower
|
|
||||||
// than optimal, we still lower the bitrate by this since hevc is ok
|
|
||||||
// with a lower rate
|
|
||||||
|
|
||||||
const maxVideoHeight = 2160; // Any thing over this size, I.E. 8K, will be reduced to this
|
|
||||||
const targetCodecCompression = 0.08; // This effects the target bitrate by assuming a compression ratio
|
|
||||||
|
|
||||||
// Since videos can have many widths and heights we need to convert to pixels (WxH) to understand what we
|
// Since videos can have many widths and heights we need to convert to pixels (WxH) to understand what we
|
||||||
// are dealing with and set a minimal optimal bitrate to not go below
|
// are dealing with and set a minimal optimal bitrate to not go below
|
||||||
|
|
@ -245,51 +343,18 @@ const plugin = (file, librarySettings, inputs, otherArguments) => {
|
||||||
const minVideoRateSD = 450000;
|
const minVideoRateSD = 450000;
|
||||||
|
|
||||||
// Audio
|
// Audio
|
||||||
const targetAudioCodec = 'aac'; // Desired Audio Coded, if you change this it will might require code changes
|
const targetAudioCodec = inputs.Target_Audio_Codec;
|
||||||
const targetAudioLanguage = 'eng'; // Desired Audio Language
|
const targetAudioLanguage = inputs.Target_Audio_Language;
|
||||||
const targetAudioBitratePerChannel = 64000; // 64K per channel gives you the good lossy quality out of AAC
|
const targetAudioBitratePerChannel = inputs.Target_Audio_Bitrate_Per_Channel;
|
||||||
const targetAudioChannels = 6; // Any thing above this number of channels will be
|
const targetAudioChannels = inputs.Target_Audio_Channels;
|
||||||
// reduced to it, because I cannot listen to it
|
|
||||||
|
|
||||||
// Subtitles
|
// Subtitles
|
||||||
// const bolIncludeSubs = true; //not used
|
// const bolIncludeSubs = true; //not currently used, it's possible to remove subs but not setup now
|
||||||
/// ///////////////////////////////////////////////////////////////////////////////////////////////////
|
/// ///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
const proc = require('child_process'); // Causes lint error, hopefully not needed
|
const proc = require('child_process');
|
||||||
let bolStatsAreCurrent = false;
|
let bolStatsAreCurrent = false;
|
||||||
|
|
||||||
// Run MediaInfo and load the results it into an object
|
|
||||||
/// ///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// response.infoLog += "Getting Media Info.\n";
|
|
||||||
// var objMedInfo = "";
|
|
||||||
// objMedInfo = JSON.parse(proc.execSync('mediainfo "' + currentFileName + '" --output=JSON').toString());
|
|
||||||
/// ///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// Run ffprobe with full info and load the results it into an object
|
|
||||||
/// ///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// response.infoLog += "Getting FFProbe Info.\n";
|
|
||||||
// var objFFProbeInfo = "";
|
|
||||||
// objFFProbeInfo = JSON.parse(proc.execSync('ffprobe -v error -print_format json
|
|
||||||
// -show_format -show_streams -show_chapters "' + currentFileName + '"').toString());
|
|
||||||
/// ///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// response.processFile = false;
|
|
||||||
// response.infoLog += objMedInfo + " \n";
|
|
||||||
// return response;
|
|
||||||
|
|
||||||
// response.infoLog += "HomePath:" + JSON.stringify(otherArguments, null, 4) + "\n";
|
|
||||||
// response.infoLog += "FIID:" + file._id + "\n";
|
|
||||||
// response.infoLog += "IPID:" + inputs._id + "\n";
|
|
||||||
// response.infoLog += "FIDB:" + JSON.stringify(file, null, 4) + "\n";
|
|
||||||
// response.infoLog += "CacheDir:" + librarySettings.cache + "\n";
|
|
||||||
// response.infoLog += "filename:" + require("crypto").createHash("md5").update(file._id).digest("hex") + "\n";
|
|
||||||
// response.infoLog += "MediaInfo:" + JSON.stringify(objMedInfo, null, 4) + "\n";
|
|
||||||
// response.infoLog += "FFProbeInfo:" + JSON.stringify(objFFProbeInfo, null, 4) + "\n";
|
|
||||||
// response.infoLog += "objFFProbeInfo:" + JSON.stringify(objFFProbeInfo, null, 4) + "\n";
|
|
||||||
|
|
||||||
// response.processFile = false;
|
|
||||||
// return response;
|
|
||||||
|
|
||||||
// Check if file is a video. If it isn't then exit plugin.
|
// Check if file is a video. If it isn't then exit plugin.
|
||||||
if (file.fileMedium !== 'video') {
|
if (file.fileMedium !== 'video') {
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
@ -340,6 +405,7 @@ const plugin = (file, librarySettings, inputs, otherArguments) => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
proc.execSync(`mkvpropedit --add-track-statistics-tags "${currentFileName}"`);
|
proc.execSync(`mkvpropedit --add-track-statistics-tags "${currentFileName}"`);
|
||||||
|
return response;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
response.infoLog += 'Error Updating Status Probably Bad file, A remux will probably fix, will continue\n';
|
response.infoLog += 'Error Updating Status Probably Bad file, A remux will probably fix, will continue\n';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue