1. Made changes to all plugins following lint testing. There are still various warnings/errors but my very limited knowledge of javascript means I just don't understand what the errors mean. Or in some cases I don't understand how to split the variable across several lines to confirm to the line limits.
I did manage to get it from
952 problems (943 errors, 9 warnings)
down to
37 problems (28 errors, 9 warnings)
2. Fix Flawed logic in FFMPEG plugins which would cause remux conditions to never trigger. Was checking if file was HEVC & VP9 which is impossible as they're both codecs.
3. Fixed a bug with CleanTitle where plugin would fail if a stream in the file didn't have a title.
4. Modify CleanSubtitle plugin to not remove sdh subtitles.
5. Include new plugin to just perform remuxes. Mainly aimed at remuxing to mkv or mp4.
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 This plugin will skip any files that are in the VP9 codec as these are already at a comparable compression level to H265. \n\n`,
Description:`Files not in H265 will be transcoded into H265 using Nvidia GPU with ffmpeg.
// Work out currentBitrate using "Bitrate = file size / (number of minutes * .0075)" - Used from here https://blog.frame.io/2017/03/06/calculate-video-bitrates/
// 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.
// Check if codec of stream is mjpeg/png, if so then remove this "video" stream. mjpeg/png are usually embedded pictures that can cause havoc with plugins.
// Check if codec of stream is mjpeg/png, if so then remove this "video" stream.
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 This plugin will skip any files that are in the VP9 codec as these are already at a comparable compression level to H265.\n\n`,
Description:`Files not in H265 will be transcoded into H265 using Nvidia GPU with ffmpeg.
// Work out currentBitrate using "Bitrate = file size / (number of minutes * .0075)" - Used from here https://blog.frame.io/2017/03/06/calculate-video-bitrates/
// 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.
// Check if codec of stream is mjpeg/png, if so then remove this "video" stream. mjpeg/png are usually embedded pictures that can cause havoc with plugins.
Description:`This plugin removes title metadata from video/audio/subtitles, if it exists. Video checking is mandatory, audio and subtitles are optional.\n\n`,
Description:'This plugin removes title metadata from video/audio/subtitles.\n\n',
tooltip:`Specify if audio titles should be checked & cleaned. Optional.
tooltip:`Specify if audio titles should be checked & cleaned. Optional.
\\nExample:\\n
\\nExample:\\n
true
true
@ -22,7 +20,7 @@ function details() {
false`,
false`,
},
},
{
{
name:"clean_subtitles",
name:'clean_subtitles',
tooltip:`Specify if subtitle titles should be checked & cleaned. Optional.
tooltip:`Specify if subtitle titles should be checked & cleaned. Optional.
\\nExample:\\n
\\nExample:\\n
true
true
@ -31,8 +29,11 @@ function details() {
false`,
false`,
},
},
{
{
name:"custom_title_matching",
name:'custom_title_matching',
tooltip:`By default if you enable audio or subtitle cleaning the plugin only looks for titles with more then 3 full stops, this is what i think is the safest way to identify junk metadata without removing real metadata that you might want to keep. Here you can specify your own text for it to also search for to match and remove. Comma separated. Optional.
tooltip:`If you enable audio or subtitle cleaning the plugin only looks for titles with more then 3 full stops.
//nThis is one way to identify junk metadata without removing real metadata that you might want.
//nHere you can specify your own text for it to also search for to match and remove.
//nComma separated. Optional.
\\nExample:\\n
\\nExample:\\n
MiNX-SmallHDepisodes
MiNX-SmallHDepisodes
@ -44,121 +45,149 @@ function details() {
}
}
functionplugin(file,librarySettings,inputs){
functionplugin(file,librarySettings,inputs){
varresponse={
constresponse={
processFile:false,
processFile:false,
preset:"",
preset:'',
container:"."+file.container,
container:`.${file.container}`,
handBrakeMode:false,
handBrakeMode:false,
FFmpegMode:true,
FFmpegMode:true,
reQueueAfter:false,
reQueueAfter:false,
infoLog:"",
infoLog:'',
};
};
// Set up required variables.
// Set up required variables.
varffmpegCommandInsert="";
letffmpegCommandInsert='';
varvideoIdx=0;
letvideoIdx=0;
varaudioIdx=0;
letaudioIdx=0;
varsubtitleIdx=0;
letsubtitleIdx=0;
varconvert=false;
letconvert=false;
letcustom_title_matching='';
// Check if inputs.custom_title_matching has been configured. If it has then set variable
// Check if inputs.custom_title_matching has been configured. If it has then set variable
// Check if title metadata of audio stream has more then 3 full stops. If so then it's likely to be junk metadata so remove. Then check if any audio streams match with user input custom_title_matching variable, if so then remove.
// Check if title metadata of audio stream has more then 3 full stops.
// If so then it's likely to be junk metadata so remove.
// Then check if any audio streams match with user input custom_title_matching variable, if so then remove.
// Check if title metadata of subtitle stream has more then 3 full stops. If so then it's likely to be junk metadata so remove. Then check if any audio streams match with user input custom_title_matching variable, if so then remove.
// Check if title metadata of subtitle stream has more then 3 full stops.
// If so then it's likely to be junk metadata so remove.
// Then check if any streams match with user input custom_title_matching variable, if so then remove.
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
tooltip:`Specify if audio tracks that contain commentary/description should be removed.
tooltip:`Specify if audio tracks that contain commentary/description should be removed.
\\nExample:\\n
\\nExample:\\n
true
true
@ -34,8 +35,11 @@ function details() {
false`,
false`,
},
},
{
{
name:"tag_language",
name:'tag_language',
tooltip:`Specify a single language for audio tracks with no language or unknown language to be tagged with, leave empty to disable, you must have "und" in your list of languages to keep for this to function. Must follow ISO-639-2 3 letter format. https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes
tooltip:`Specify a single language for audio tracks with no language or unknown language to be tagged with.
tooltip:`Specify audio tracks with no title to be tagged with the number of channels they contain. Do NOT use this with mp4, as mp4 does not support title tags.
tooltip:`Specify audio tracks with no title to be tagged with the number of channels they contain.
response.infoLog+=`☒Audio stream detected as being an unwanted language, removing. Audio stream 0:a:${audioIdx} - ${file.ffProbeData.streams[
response.infoLog+=`☒Audio stream detected as being unwanted, removing. Audio stream 0:a:${audioIdx}\n`;
i
].tags.language.toLowerCase()}\n`;
convert=true;
convert=true;
}
}
}catch(err){}
}catch(err){
// Error
}
// Catch error here incase the title metadata is completely missing.
// Catch error here incase the title metadata is completely missing.
try{
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.
// 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".
response.infoLog+=`☒Audio stream detected as being Commentary or Description, removing. Audio stream 0:a:${audioIdx} - ${file.ffProbeData.streams[i].tags.title}.\n`;
response.infoLog+=`☒Audio stream detected as being descriptive, removing. Stream 0:a:${audioIdx}\n`;
convert=true;
convert=true;
}
}
}catch(err){}
}catch(err){
// Error
}
// 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.
// Check if inputs.tag_language has something entered
// (Entered means user actually wants something to happen, empty would disable this)
response.infoLog+=`☒Audio stream detected as having unknown language tagged, tagging as ${inputs.tag_language}. \n`;
response.infoLog+=`☒Audio stream detected as having no language, tagging as ${inputs.tag_language}. \n`;
convert=true;
convert=true;
}
}
}catch(err){}
}catch(err){
// Error
}
// Checks if the tags 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.
// Checks if the tags metadata is completely missing.
// 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.
// Checks if the tags.language metadata is completely missing.
else{
// If so this would cause playback to show language as "undefined".
response.infoLog+=`☒Audio stream detected as having no language tagged, tagging as ${inputs.tag_language}. \n`;
response.infoLog+=`☒Audio stream detected as having no language, tagging as ${inputs.tag_language}. \n`;
convert=true;
convert=true;
}
}
}
}
}
try{
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.
// 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
\\nExample:\\n
eng
eng
@ -22,7 +21,7 @@ function details() {
eng,jap`,
eng,jap`,
},
},
{
{
name:"commentary",
name:'commentary',
tooltip:`Specify if subtitle tracks that contain commentary/description should be removed.
tooltip:`Specify if subtitle tracks that contain commentary/description should be removed.
\\nExample:\\n
\\nExample:\\n
true
true
@ -31,8 +30,10 @@ function details() {
false`,
false`,
},
},
{
{
name:"tag_language",
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
tooltip:`Specify a single language for subtitle tracks with no language or unknown language to be tagged with.
response.infoLog+=`☒Subtitle stream detected as being an unwanted language, removing. Subtitle stream 0:s:${subtitleIdx} - ${file.ffProbeData.streams[
response.infoLog+=`☒Subtitle stream detected as being unwanted, removing. Stream 0:s:${subtitleIdx}\n`;
i
].tags.language.toLowerCase()}\n`;
convert=true;
convert=true;
}
}
}catch(err){}
}catch(err){
// Error
}
// Catch error here incase the title metadata is completely missing.
// Catch error here incase the title metadata is completely missing.
try{
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.
// Check if inputs.commentary is set to true
// AND if stream is subtitle
// AND then checks for stream titles with the following "commentary or description".
response.infoLog+=`☒Subtitle stream detected as being Commentary or Description, removing. Subtitle stream 0:s:${subtitleIdx} - ${file.ffProbeData.streams[i].tags.title}.\n`;
response.infoLog+=`☒Subtitle stream detected as being descriptive, removing. Stream 0:s:${subtitleIdx}\n`;
convert=true;
convert=true;
}
}
}catch(err){}
}catch(err){
// Error
}
// 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 subtitle.
// Check if inputs.tag_language has something entered.
// (Entered means user actually wants something to happen, empty would disable this)
response.infoLog+=`☒Subtitle stream detected as having unknown language tagged, tagging as ${inputs.tag_language}. \n`;
response.infoLog+=`☒Subtitle stream detected as having no language, tagging as ${inputs.tag_language}. \n`;
convert=true;
convert=true;
}
}
}catch(err){}
}catch(err){
// Error
}
// Checks if the tags 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.
// Checks if the tags metadata is completely missing.
// 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.
// Checks if the tags.language metadata is completely missing.
else{
// If so this would cause playback to show language as "undefined".
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.
\\nOptional.
\\nExample:\\n
\\nExample:\\n
true
true
@ -21,8 +21,10 @@ function details() {
false`,
false`,
},
},
{
{
name:"downmix",
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. Optional.
tooltip:`Specify if downmixing should be used to create extra audio tracks.
// 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 audioIdx or subtitleIdx do NOT equal 0
if(audioIdx!="0"||subtitleIdx!="0"){
// If so then it means a audio or subtitle track has already appeared before the video track
// 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.
// Check if subtitleIdx does NOT equal 0.
if(subtitleIdx!="0"){
// If so then it means a subtitle track has already appeared before an audio track
// So file needs to be organized.
if(subtitleIdx!=='0'){
convert=true;
convert=true;
response.infoLog+="☒ Audio not second. \n";
response.infoLog+='☒ Audio not second. \n';
}
}
// Increment audioIdx.
// Increment audioIdx.
audioIdx++;
audioIdx+=1;
// Check if audio track is 2 channel.
// Check if audio track is 2 channel.
if(file.ffProbeData.streams[i].channels=="2"){
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.
// Check if audio6Idx or audio8Idx do NOT equal 0.
if(audio6Idx!="0"||audio8Idx!="0"){
// If so then it means a 6 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;
convert=true;
response.infoLog+="☒ Audio 2ch not first. \n";
response.infoLog+='☒ Audio 2ch not first. \n';
}
}
// Increment audio2Idx.
audio2Idx++;
}
}
// Check if audio track is 6 channel.
// Check if audio track is 6 channel.
if(file.ffProbeData.streams[i].channels=="6"){
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.
// Check if audio8Idx does NOT equal 0.
if(audio8Idx!="0"){
// If so then it means a 8 channel audio track has already appeared before the 6 channel audio track