Description:`Files will be transcoded using Nvidia GPU with ffmpeg, settings are dependant on file bitrate, working by the logic that H265 can support the same ammount of data at half the bitrate of H264. NVDEC & NVENC compatable GPU required. \n\n`,
Version:"2.20",
Operation:"Transcode",
Description:`Files not in H265 will be transcoded into H265 using Nvidia GPU with ffmpeg, settings are dependant on file bitrate, working by the logic that H265 can support the same ammount of data at half the bitrate of H264. NVDEC & NVENC compatable GPU required. \n\n`,
// Work out currentBitrate using "Bitrate = file size / (number of minutes * .0075)" - Used from here https://blog.frame.io/2017/03/06/calculate-video-bitrates/
// Use the same calculation used for currentBitrate but divide it in half to get targetBitrate. Logic of h265 can be half the bitrate as h264 without losing quality.
// Allow some leeway under and over the targetBitrate.
varminimumBitrate=~~(targetBitrate*0.7)
varmaximumBitrate=~~(targetBitrate*1.3)
// If targetBitrate comes out as 0 then something has gone wrong and bitrates could not be calculcated. Cancel plugin completely.
if(targetBitrate=="0"){
response.processFile=false
response.infoLog+="☒Target bitrate could not be calculated. Skipping this plugin. \n"
returnresponse
}
// Check if inputs.bitrate cutoff has something entered (Entered means user actually wants something to happen, empty would disable this).
if(inputs.bitrate_cutoff!=""){
// Checks if currentBitrate is below inputs.bitrate_cutoff, if so then cancel plugin without touching original files.
if(currentBitrate<=inputs.bitrate_cutoff){
if(file.container==inputs.container){
response.processFile=false
response.infoLog+=`☑Current bitrate is below configured bitrate cutoff of ${inputs.bitrate_cutoff} & file container is already ${inputs.container}. Nothing to do, skipping. \n`
returnresponse
}else{
response.processFile=true
response.preset+=`, -c copy ${extraArguments}`
response.infoLog+=`☒Current bitrate is below configured bitrate cutoff of ${inputs.bitrate_cutoff} but is not in correct container. Remuxing to ${inputs.container} but not transcoding. \n`
response.infoLog+=`☑Current bitrate is below configured bitrate cutoff of ${inputs.bitrate_cutoff}. Nothing to do, cancelling plugin. \n`
Description:`Files will be transcoded using CPU with ffmpeg, settings are dependant on file bitrate, working by the logic that H265 can support the same ammount of data at half the bitrate of H264. \n\n`,
Version:"1.1",
Operation:"Transcode",
Description:`Files not in H265 will be transcoded into H265 using CPU with ffmpeg, settings are dependant on file bitrate, working by the logic that H265 can support the same ammount of data at half the bitrate of H264. \n\n`,
// Work out currentBitrate using "Bitrate = file size / (number of minutes * .0075)" - Used from here https://blog.frame.io/2017/03/06/calculate-video-bitrates/
// Use the same calculation used for currentBitrate but divide it in half to get targetBitrate. Logic of h265 can be half the bitrate as h264 without losing quality.
// Allow some leeway under and over the targetBitrate.
varminimumBitrate=~~(targetBitrate*0.7)
varmaximumBitrate=~~(targetBitrate*1.3)
// If targetBitrate comes out as 0 then something has gone wrong and bitrates could not be calculcated. Cancel plugin completely.
if(targetBitrate=="0"){
response.processFile=false
response.infoLog+="☒Target bitrate could not be calculated. Skipping this plugin. \n"
returnresponse
}
// Check if inputs.bitrate cutoff has something entered (Entered means user actually wants something to happen, empty would disable this).
if(inputs.bitrate_cutoff!=""){
// Checks if currentBitrate is below inputs.bitrate_cutoff, if so then cancel plugin without touching original files.
if(currentBitrate<=inputs.bitrate_cutoff){
if(file.container==inputs.container){
response.processFile=false
response.infoLog+=`☑Current bitrate is below configured bitrate cutoff of ${inputs.bitrate_cutoff} & file container is already ${inputs.container}. Nothing to do, skipping. \n`
returnresponse
}else{
response.processFile=true
response.preset+=`, -c copy ${extraArguments}`
response.infoLog+=`☒Current bitrate is below configured bitrate cutoff of ${inputs.bitrate_cutoff} but is not in correct container. Remuxing to ${inputs.container} but not transcoding. \n`
response.infoLog+=`☑Current bitrate is below configured bitrate cutoff of ${inputs.bitrate_cutoff}. Nothing to do, cancelling plugin. \n`
Description:`This plugin removes title metadata from video/audio/subtitles, if it exists. Video checking is mandatory, audio and subtitles are optional.\n\n`,
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
@ -38,8 +37,7 @@ function details() {
eng
\\nExample:\\n
por
`
por`
},
{
name:'tag_title',
@ -65,6 +63,7 @@ function plugin(file, librarySettings, inputs) {
infoLog:'',
}
// Check if file is a video. If it isn't then exit plugin.
if(file.fileMedium!=="video"){
console.log("File is not video")
response.infoLog+="☒File is not video \n"
@ -72,64 +71,68 @@ function plugin(file, librarySettings, inputs) {
returnresponse
}
// Check if inputs.language has been configured. If it hasn't then exit plugin.
if(inputs.language==""){
response.infoLog+="☒Language/s keep have not been configured within plugin settings, please configure required options. Skipping this plugin. \n"
response.infoLog+=`☒Audio stream detected as being an unwanted language, removing. Audio stream 0:a:${audioIdx} - ${file.ffProbeData.streams[i].tags.language.toLowerCase()}\n`
convert=true
}
}catch(err){}
}catch(err){}
// Catch error here incase the title metadata is completely missing.
try{
// Check if inputs.commentary is set to true AND if stream is audio AND then checks for stream titles with the following "commentary, description, sdh". Removing any streams that are applicable.
response.infoLog+=`☒Audio stream detected as being Commentary or Description, removing. Audio stream 0:a:${audioIdx} - ${file.ffProbeData.streams[i].tags.title}. \n`
convert=true
}
}catch(err){}
}catch(err){}
// Check if inputs.tag_language has something entered (Entered means user actually wants something to happen, empty would disable this) AND checks that stream is audio.
// Checks if the tags.language metadata is completely missing, if so this would cause playback to show language as "undefined". No catch error here otherwise it would never detect the metadata as missing.
response.infoLog+=`☒Audio stream detected as having no language tagged, tagging as ${inputs.tag_language}. \n`
convert=true
}
}
}catch(err){}
try{
// Check if title metadata is missing from any streams AND inputs.tag_title set to true AND if stream type is audio. Add title to any applicable streams.
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
@ -29,7 +28,7 @@ function details() {
false`
},
{
name:'tag_title',
name:'tag_language',
tooltip:`Specify a single language for subtitle tracks with no language or unknown language to be tagged with, leave empty to disable. Must follow ISO-639-2 3 letter format. https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes
\\nExample:\\n
eng
@ -52,6 +51,7 @@ function plugin(file, librarySettings, inputs) {
infoLog:'',
}
// Check if file is a video. If it isn't then exit plugin.
if(file.fileMedium!=="video"){
console.log("File is not video")
response.infoLog+="☒File is not video \n"
@ -59,59 +59,70 @@ function plugin(file, librarySettings, inputs) {
returnresponse
}
// Check if inputs.language has been configured. If it hasn't then exit plugin.
if(inputs.language==""){
response.infoLog+="☒Language/s keep have not been configured within plugin settings, please configure required options. Skipping this plugin. \n"
response.infoLog+=`☒Subtitle stream detected as being an unwanted language, removing. Subtitle stream 0:s:${subtitleIdx} - ${file.ffProbeData.streams[i].tags.language.toLowerCase()}\n`
convert=true
}
}catch(err){}
}catch(err){}
// Catch error here incase the title metadata is completely missing.
try{
// Check if inputs.commentary is set to true AND if stream is subtitle AND then checks for stream titles with the following "commentary, description, sdh". Removing any streams that are applicable.
response.infoLog+=`☒Subtitle stream detected as being Commentary or Description, removing. Subtitle stream 0:s:${SubtitleIdx} - ${file.ffProbeData.streams[i].tags.title}. \n`
convert=true
}
}catch(err){}
}catch(err){}
// Check if inputs.tag_language has something entered (Entered means user actually wants something to happen, empty would disable this) AND checks that stream is audio.
response.infoLog+=`☒Subtitle stream detected as having unknown language tagged, tagging as ${inputs.tag_language}. \n`
convert=true
}
}
}catch(err){}
}catch(err){}
try{
// Checks if the tags.language metadata is completely missing, if so this would cause playback to show language as "undefined". No catch error here otherwise it would never detect the metadata as missing.
tooltip:`Specify if any 2.0 audio tracks should be converted to aac for maximum compatability with devices.
tooltip:`Specify if any 2.0 audio tracks should be converted to aac for maximum compatability with devices. Optional.
\\nExample:\\n
true
@ -21,7 +20,7 @@ function details() {
},
{
name:'downmix',
tooltip:`Specify if downmixing should be used to create extra audio tracks. I.e if you have an 8ch but no 2ch or 6ch, create the missing audio tracks from the 8 ch. Likewise if you only have 6ch, create the missing 2ch from it.
tooltip:`Specify if downmixing should be used to create extra audio tracks. I.e if you have an 8ch but no 2ch or 6ch, create the missing audio tracks from the 8 ch. Likewise if you only have 6ch, create the missing 2ch from it. Optional.
\\nExample:\\n
true
@ -42,7 +41,14 @@ function plugin(file, librarySettings, inputs) {
infoLog:'',
}
// Check if both inputs.aac_stereo AND inputs.downmix have been left empty. If they have then exit plugin.
response.infoLog+="☒Neither aac_stereo or downmix options have been configured within plugin settings, please configure required options. Skipping this plugin. \n"
response.processFile=false
returnresponse
}
// Check if file is a video. If it isn't then exit plugin.
if(file.fileMedium!=="video"){
console.log("File is not video")
response.infoLog+="☒File is not video. \n"
@ -50,12 +56,7 @@ function plugin(file, librarySettings, inputs) {
returnresponse
}
if(inputs.aac_stereo==""&&inputs.downmix==""){
response.infoLog+="☒Neither aac_stereo or downmix options have been configured within plugin settings, please configure required options. Skipping this plugin. \n"
response.processFile=false
returnresponse
}
// Set up required variables.
varffmpegCommandInsert=''
varaudioIdx=0
varhas2Channel=false
@ -63,8 +64,10 @@ function plugin(file, librarySettings, inputs) {
// Check if audioIdx or subtitleIdx do NOT equal 0, if they do then it means a audio or subtitle track has already appeared before the video track so file needs to be organized.
// Check if subtitleIdx does NOT equal 0, if it does then it means a subtitle track has already appeared before an audio track so file needs to be organized.
if(subtitleIdx!="0"){
convert=true
response.infoLog+="☒ Audio not second. \n"
}
// Increment audioIdx.
audioIdx++
// Check if audio track is 2 channel.
if(file.ffProbeData.streams[i].channels=="2"){
// Check if audio6Idx or audio8Idx do NOT equal 0, if they do then it means a 6 channel or 8 channel audio track has already appeared before the 2 channel audio track so file needs to be organized.
if(audio6Idx!="0"||audio8Idx!="0"){
convert=true
response.infoLog+="☒ Audio 2ch not first. \n"
}
// Increment audio2Idx.
audio2Idx++
}
// Check if audio track is 6 channel.
if(file.ffProbeData.streams[i].channels=="6"){
// Check if audio8Idx does NOT equal 0, if it does then it means a 8 channel audio track has already appeared before the 6 channel audio track so file needs to be organized.