@ -9,19 +9,22 @@ function details() {
Type : "Video" ,
Operation : "Transcode" ,
Description : ` Uses iiDrakeii's filter, and crops video files when letterboxing is detected. \n This uses the FFMPEG NVENC transcoding(hw). \n If a file is 4K it will be scaled down to 1080p. \n Now with user definable bitrates!(since 1.104 beta) \n Created by @control#0405 ` ,
Version : "1. 2 ",
Version : "1. 3 ",
Link : "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_e5c3_CnT_Remove_Letterbox.js" ,
Inputs : [
{
name : 'bitrate' ,
tooltip : ` Desired bitrate for a 1080p video, minimum transcode size is based of this too! \n 720p will be half of 1080p, 480p will be half of 720p. \n The default is '3000', this value is based of movies. \n I would suggest 1500-2000 for series. `
tooltip : ` Desired bitrate for a 1080p video, minimum transcode size is based of this too! \\ n 720p will be half of 1080p, 480p will be half of 720p. \\ nThe default is '3000', this value is based of movies. \\ nI would suggest 1500-2000 for series. \\ nExample: \\ n3000 `
} ,
{
name : 'container' ,
tooltip : ` Enter the output container of the new file. \\ n Default: .mkv \\ nExample: \\ n.mkv `
} ,
]
}
}
function plugin ( file , librarySettings , inputs ) {
console . log ( inputs . bitrate ) ;
function plugin ( file , librarySettings , inputs , otherArguments ) {
if ( inputs . bitrate == "" ) {
var min _bitrate = 6600 ;
var avg _rate = 3000 ;
@ -31,14 +34,10 @@ function plugin(file, librarySettings, inputs) {
var avg _rate = inputs . bitrate ;
var max _rate = inputs . bitrate * 2 ;
}
var source = file . meta . SourceFile ; //source file
var dir = file . meta . Directory ; //source directory
var sourcename = file . meta . FileName . substring ( 0 , file . meta . FileName . lastIndexOf ( "." ) ) ; //filename without extension
var cropfile = ` ${ dir } / ${ sourcename } .txt ` ; //location and name of the crop file
var min _crop = parseInt ( file . meta . ImageHeight * . 98 ) ; //if the crop value is larger than this the file won't be cropped
var duration = file . meta . Duration ; //duration of video in seconds
var stats = fs . statSync ( source ) ;
var size = stats [ "size" ] / 1000000000 ;
size = size . toFixed ( 2 ) ;
@ -52,10 +51,15 @@ function plugin(file, librarySettings, inputs) {
preset : '' ,
container : '.mkv' ,
handBrakeMode : false ,
FFmpegMode : fals e,
FFmpegMode : tru e,
reQueueAfter : true ,
infoLog : ''
}
if ( inputs . container !== undefined ) {
response . container = inputs . container ;
console . log ( ` Changed container to: ` + inputs . container ) ;
}
var returns = {
create _crop : create _crop _values ( file ) ,
@ -63,11 +67,6 @@ function plugin(file, librarySettings, inputs) {
size : size _check ( file , min _bitrate )
}
var transcode = {
hevc : hevc ( file ) , //if it's not hevc it will be processed, unless file size is too small
highres : highres ( file ) //changes to '1' if it's 4k, it should be transcoded to 1080p
}
var log = {
size : returns . size . log ,
hevc : ` ` ,
@ -75,22 +74,14 @@ function plugin(file, librarySettings, inputs) {
crop : returns . crop . log ,
createcrop : returns . create _crop . log
}
//check if the file is a video
//if (file.fileMedium !== "video") {
// response.infoLog += `☒ - File is not a video \n`
// return response;
//} else {
// response.infoLog += `☑ - File is a video \n`
//}
//filters
if ( size _check ( file , min _bitrate ) . size == 1 ) {
if ( hevc ( file ) == 1 ) {
process = 1 ;
log . hevc = ` ☑ - Video is not HEVC \n ` ;
} else {
log . hevc += "☒ - File is already in HEVC \n"
process = 1 ;
}
if ( highres ( file ) == 1 ) {
@ -110,14 +101,19 @@ function plugin(file, librarySettings, inputs) {
log . resolution +
log . size +
log . hevc ;
response . preset = ` ${ decoder } , -map 0:v:0 -map 0:a -map 0:s? ${ encoder } `
//change response
if ( process == 1 ) {
response . processFile = true ;
response . FFmpegMode = true ;
response . infoLog += ` File will be processed \n ` ;
response . preset = ` ${ decoder } , -map 0:v:0 -map 0:a -map 0:s? ${ encoder } `
response . reQueueAfter = true ;
} else if ( file . forceProcessing === true ) {
response . processFile = true ;
response . infoLog += ` Force processing! \n ` ;
} else if ( response . container !== ` . ` + file . container ) {
response . infoLog += ` Container is not correct \n Muxing to ${ response . container } ! \n ` ;
response . preset = ` ${ decoder } , -c copy ` ;
response . processFile = true ;
} else {
response . infoLog += ` Processing not necessary \n ` ;
}
@ -227,17 +223,25 @@ function decoder_string(file) {
}
function crop _decider ( file , crop _height ) {
var min _crop = parseInt ( file . meta . ImageHeight * . 98 ) ; //if the crop value is larger than this the file won't be cropped
var returns = {
crop : ` 0 ` , //sets the crop filter
log : ` ` ,
}
for ( var i = 0 ; i < file . ffProbeData . streams . length ; i ++ ) {
if ( file . ffProbeData . streams [ i ] . width !== undefined ) {
var imageWidth = file . ffProbeData . streams [ i ] . width ;
var imageHeight = file . ffProbeData . streams [ i ] . height ;
break ;
}
}
var min _crop = parseInt ( imageHeight * . 98 ) ; //if the crop value is larger than this the file won't be cropped
//tree for resolution : quality
if ( file . meta . ImageWidth >= 1300 ) { //file will be encoded if the resolution is 1080p, or greater (it will be downscaled)
if ( imageWidth >= 1300 ) { //file will be encoded if the resolution is 1080p, or greater (it will be downscaled)
//crop only if it is a larger crop than 1%;
if ( crop _height < min _crop ) {
var crop _hdis = parseInt ( ( file . meta . ImageHeight - crop _height ) / 2 ) ;
var crop _hdis = parseInt ( ( imageHeight- crop _height ) / 2 ) ;
if ( crop _height >= 790 ) {
returns . crop = ` -filter:0 crop=1920: ${ crop _height } :0: ${ crop _hdis } ` ;
returns . log += ` ☑ - crop is larger than 1% \n ` ;
@ -245,10 +249,10 @@ function crop_decider(file, crop_height) {
} else {
returns . log += ` ☒ - Crop is not necessary \n ` ;
}
} else if ( f ile. meta . I mageWidth < 1300 && file . meta . ImageWidth >= 770 ) {
} else if ( imageWidth < 1300 && file . meta . ImageWidth >= 770 ) {
//crop only if it is a larger crop than 1%;
if ( crop _height < min _crop ) {
var crop _hdis = parseInt ( ( f ile. meta . I mageHeight- crop _height ) / 2 ) ;
var crop _hdis = parseInt ( ( imageHeight- crop _height ) / 2 ) ;
if ( crop _height >= 530 ) {
returns . crop = ` -filter:0 crop=1280: ${ crop _height } :0: ${ crop _hdis } ` ;
returns . log += ` ☑ - crop is larger than 1% \n ` ;
@ -256,7 +260,7 @@ function crop_decider(file, crop_height) {
} else {
returns . log += ` ☒ - Crop is not necessary \n ` ;
}
} else if ( f ile. meta . I mageWidth < 770 ) { //file won't be cropped at this resolution
} else if ( imageWidth < 770 ) { //file won't be cropped at this resolution
returns . log += ` No crop: Resolution < 720p \n ` ;
}
@ -275,12 +279,10 @@ function size_check(file, min_bitrate) {
}
//tree for resolution : quality
if ( file . meta. ImageWidth >= 1300 ) { //file will be encoded if the resolution is 1080p, or greater (it will be downscaled)
if ( file . video_resolution === "1080p" || file . video _resolution === "4KUHD" ) { //file will be encoded if the resolution is 1080p, or greater (it will be downscaled)
var min _transcode _size = ( min _bitrate * duration * 0.125 ) / 1000000 ; //minimum size in GB for transcode
min _transcode _size = min _transcode _size . toFixed ( 2 ) ;
console . log ( min _bitrate )
//check if file is large enough for transcode
if ( size >= ( min _bitrate * duration * 0.125 ) / 1000000 ) {
returns . log += ` ☑ - ${ size } GB > ${ min _transcode _size } GB \n ` ;
@ -288,7 +290,7 @@ function size_check(file, min_bitrate) {
} else {
returns . log += ` ☒ - ${ size } GB < ${ min _transcode _size } GB \n ` ;
}
} else if ( file . meta. ImageWidth < 1300 && file . meta . ImageWidth >= 770 ) { //file will be encoded if the resolution is 720p
} else if ( file . video_resolution === "720p" ) { //file will be encoded if the resolution is 720p
var min _transcode _size = ( ( min _bitrate / 2 ) * duration * 0.125 ) / 1000000 ; //minimum size in GB for transcode
min _transcode _size = min _transcode _size . toFixed ( 2 ) ;
@ -299,7 +301,7 @@ function size_check(file, min_bitrate) {
} else {
returns . log += ` ☒ - ${ size } GB < ${ min _transcode _size } GB \n ` ;
}
} else if ( file . meta. ImageWidth < 770 ) { //file will be encoded if the resolution is 480p or 576p
} else if ( file . video_resolution === "480p" || file . video _resolution === "576p" ) { //file will be encoded if the resolution is 480p or 576p
var min _transcode _size = ( ( min _bitrate / 4 ) * duration * 0.125 ) / 1000000 ; //minimum size in GB for transcode
min _transcode _size = min _transcode _size . toFixed ( 2 ) ;
@ -324,7 +326,7 @@ function error_fix(file) {
for ( var i = 0 ; i < file . ffProbeData . streams . length ; i ++ ) {
//these subtitle codecs don't fit in a mkv container
if ( file . ffProbeData . streams [ i ] . codec _name . toLowerCase ( ) == "eia_608" || file . ffProbeData . streams [ i ] . codec _name . toLowerCase ( ) == "mov_text" && file . ffProbeData . streams [ i ] . codec _type . toLowerCase . includes ( "sub" ) ) {
if ( file . ffProbeData . streams [ i ] . codec _name . toLowerCase ( ) == "eia_608" || file . ffProbeData . streams [ i ] . codec _name . toLowerCase ( ) == "mov_text" && file . ffProbeData . streams [ i ] . codec _type . toLowerCase . includes ( "sub" ) && response . container == '.mkv' ) {
fix . sub _codec = 1 ;
}
@ -343,14 +345,12 @@ function encoder_string(file, avg_rate, max_rate) {
var fix = error _fix ( file ) ;
var sub = ` ` ;
console . log ( avg _rate ) ;
//tree for resolution : quality
if ( file . meta. ImageWidth >= 1300 ) { //file will be encoded if the resolution is 1080p, or greater (it will be downscaled)
if ( file . video _resolution === "1080p" || file . video _resolution === "4KUHD" ) { //file will be encoded if the resolution is 1080p, or greater (it will be downscaled)
encoder += ` -pix_fmt p010le -rc:v vbr_hq -qmin 0 -cq:v 26 -b:v ${ avg _rate } k -maxrate:v ${ max _rate } k ` ; //-qp 26
} else if ( file . meta. ImageWidth < 1300 && file . meta . ImageWidth >= 770 ) { //file will be encoded if the resolution is 720p
} else if ( file . video_resolution === "720p" ) { //file will be encoded if the resolution is 720p
encoder += ` -pix_fmt p010le -rc:v vbr_hq -qmin 0 -cq:v 26 -b:v ${ avg _rate / 2 } k -maxrate:v ${ max _rate / 2 } k ` ; //-qp 28
} else if ( file . meta. ImageWidth < 770 ) { //file will be encoded if the resolution is 480p or 576p
} else if ( file . video_resolution === "480p" || file . video _resolution === "576p" ) { //file will be encoded if the resolution is 480p or 576p
encoder += ` -pix_fmt p010le -rc:v vbr_hq -qmin 0 -cq:v 26 -b:v ${ avg _rate / 4 } k -maxrate:v ${ max _rate / 4 } k ` ; //-qp 30
}
encoder += ` -c:v hevc_nvenc -preset slow -rc-lookahead 32 -spatial_aq:v 1 -aq-strength:v 8 -a53cc 0 -dn ` ;
@ -379,6 +379,8 @@ function encoder_string(file, avg_rate, max_rate) {
function encoder _string _full ( file , highres , crop , avg _rate , max _rate ) {
var encoder = encoder _string ( file , avg _rate , max _rate ) ;
console . log ( ` crop filter: ` + crop )
if ( highres == 1 && crop != "0" ) {
return crop + ` ,scale=-1:1920 ` + encoder ;
} else if ( highres == 1 ) {