diff --git a/Community/Tdarr_Plugin_075a_Transcode_Customisable.js b/Community/Tdarr_Plugin_075a_Transcode_Customisable.js new file mode 100644 index 0000000..581dc64 --- /dev/null +++ b/Community/Tdarr_Plugin_075a_Transcode_Customisable.js @@ -0,0 +1,195 @@ + + + +module.exports.details = function details() { + + return { + id: "Tdarr_Plugin_075a_Transcode_Customisable", + Stage: "Pre-processing", + Name: "Transcode Customisable", + Type: "", + Operation: "Transcode", + Description: `[TESTING][Contains built-in filter] Specify codec filter and transcode arguments for HandBrake or FFmpeg \n\n`, + Version: "1.00", + Link: "", + Inputs: [ + { + name: 'codecs_to_exclude', + tooltip: `Input codecs, separated by a comma, that should be excluded when processing. + + \\nFor example, if you're transcoding into hevc (h265), then add a filter to prevent hevc being transcoded so your newly transcoded files won't be infinitely looped/processed. \\n + + \\nExample:\\n + + hevc + + \\nYou can also enter multiple codecs: + + \\nExample:\\n + + mp3,aac,dts + + \\nExample:\\n + + h264,vp9 + + ` + }, + { + name: 'cli', + tooltip: `Enter the CLI to use. + + \\nExample:\\n + handbrake + + \\nExample:\\n + ffmpeg + + ` + }, + { + name: 'transcode_arguments', + tooltip: `\\nEnter HandBrake or FFmpeg transcode arguments. + + \\nHandBrake examples: + + \\nExample:\\n + -e x264 -q 20 -B + + \\nExample:\\n + -Z "Very Fast 1080p30" + + \\nExample:\\n + -Z "Fast 1080p30" -e nvenc_h265 + + \\nExample:\\n + -Z "Very Fast 1080p30" --all-subtitles --all-audio + + \\nExample:\\n + -Z "Very Fast 480p30" + + \\nExample:\\n + --preset-import-file "C:\Users\HaveAGitGat\Desktop\testpreset.json" -Z "My Preset" + + \\nYou can learn more about HandBrake presets here: + + \\nhttps://handbrake.fr/docs/en/latest/technical/official-presets.html + + + \\nWhen using FFmpeg, you need to separate the input and output parameters with a comma. FFmpeg Examples: + + \\nExample:\\n +-r 1,-r 24 + +\\nExample:\\n +,-sn -c:v copy -c:a copy + +\\nExample:\\n +,-c:v lib265 -crf 23 -ac 6 -c:a aac -preset veryfast + +\\nExample:\\n +,-map 0 -c copy -c:v libx265 -c:a aac + +\\nExample:\\n +-c:v h264_cuvid,-c:v hevc_nvenc -preset slow -c:a copy + +\\nPlease see the following for help with creating FFmpeg commands: + +\\nhttps://opensource.com/article/17/6/ffmpeg-convert-media-file-formats + + + + + ` + }, + { + name: 'output_container', + tooltip: ` + \\nEnter the output container of the new file + + \\nExample:\\n + .mp4 + + \\nExample:\\n + .mp3 + + \\nExample:\\n + .mkv + + ` + }, + ] + } + +} + +module.exports.plugin = function plugin(file, librarySettings, inputs) { + + + + //Must return this object + + var response = { + + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: '', + + } + + if (inputs.codecs_to_exclude === undefined + || inputs.cli === undefined + || inputs.transcode_arguments === undefined + || inputs.output_container === undefined) { + + response.processFile = false + response.infoLog += "☒ Inputs not entered! \n" + return response + + + } + + + if (inputs.codecs_to_exclude.includes(file.ffProbeData.streams[0].codec_name)) { + response.processFile = false + response.infoLog += `☑File is already in ${file.ffProbeData.streams[0].codec_name}! \n` + return response + } + + + + + //transcode settings + + if (inputs.cli == `handbrake`) { + response.handBrakeMode = true + response.FFmpegMode = false + } else if (inputs.cli == `ffmpeg`) { + response.handBrakeMode = false + response.FFmpegMode = true + + } else { + response.processFile = false + response.infoLog += "☒ CLI not input correctly! \n" + return response + + } + + + + response.processFile = true; + response.preset = inputs.transcode_arguments + response.container = inputs.output_container + + response.reQueueAfter = true; + response.infoLog += `☒File is not in desired codec! \n` + return response + + + +} + diff --git a/Community/Tdarr_Plugin_076a_re_order_audio_streams.js b/Community/Tdarr_Plugin_076a_re_order_audio_streams.js new file mode 100644 index 0000000..e1fdf39 --- /dev/null +++ b/Community/Tdarr_Plugin_076a_re_order_audio_streams.js @@ -0,0 +1,154 @@ + + + +module.exports.details = function details() { + + return { + id: "Tdarr_Plugin_076a_re_order_audio_streams", + Stage: "Pre-processing", + Name: "Re-order audio streams", + Type: "", + Operation: "Transcode", + Description: `[TESTING][Contains built-in filter] Specify a language tag for Tdarr to try and put as 1st audio track \n\n`, + Version: "1.00", + Link: "", + Inputs: [ + { + name: 'preferred_language', + tooltip: `Specify one language tag for Tdarr to try and put as 1st audio track + + \\nExample:\\n + + eng + + \\nExample:\\n + + en + + \\nExample:\\n + + fr + + \\nExample:\\n + + de + + ` + } + ] + } + +} + +module.exports.plugin = function plugin(file, librarySettings, inputs) { + + + + //Must return this object + + var response = { + + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: '', + + } + + + console.log(inputs.preferred_language) + + if (inputs.preferred_language === undefined) { + + response.processFile = false + response.infoLog += "☒ Inputs not entered! \n" + return response + + + } + + + var desiredTrackPosition = file.ffProbeData.streams.filter(stream => stream.codec_type.toLowerCase() == "video").length + + var audioInLang = file.ffProbeData.streams.filter(stream => { + + + if (stream.codec_type.toLowerCase() == "audio" + && stream.tags && stream.tags.language && inputs.preferred_language.includes(stream.tags.language.toLowerCase())) { + return true + } + + return false + + }) + + + if (audioInLang.length == 0) { + + response.processFile = false + response.infoLog += "☒ No audio tracks in desired language! \n" + return response + + } + + + var streamToMove = audioInLang[0] + + if (streamToMove.index == desiredTrackPosition) { + + response.processFile = false + response.infoLog += "☑ Preferred language is already first audio track! \n" + return response + + } + + + var ffmpegCommand = ', -c copy' + + if (file.ffProbeData.streams[0].codec_type.toLowerCase() == "video") { + ffmpegCommand += ` -map 0:v ` + } + + var allAudioTracks = file.ffProbeData.streams.filter(stream => stream.codec_type.toLowerCase() == "audio") + + + var streamIdx + + for (var i = 0; i < allAudioTracks.length; i++) { + + if (allAudioTracks[i].index == streamToMove.index) { + streamIdx = i + break + + } + } + + ffmpegCommand += ` -map 0:a:${streamIdx} -disposition:a:${streamIdx} default` + + for (var i = 0; i < allAudioTracks.length; i++) { + + if (i !== streamIdx) { + ffmpegCommand += ` -map 0:a:${i} -disposition:a:${i} none ` + } + } + + ffmpegCommand += ` -map 0:s? -map 0:d? ` + + + + response.processFile = true + response.preset = ffmpegCommand + response.container = `.` + file.container + response.handBrakeMode = false + response.FFmpegMode = true + response.reQueueAfter = true; + response.infoLog += `☒ Desired audio lang is not first audio stream, moving! \n` + return response + + + +} + diff --git a/Community/Tdarr_Plugin_076b_re_order_subtitle_streams.js b/Community/Tdarr_Plugin_076b_re_order_subtitle_streams.js new file mode 100644 index 0000000..91904e6 --- /dev/null +++ b/Community/Tdarr_Plugin_076b_re_order_subtitle_streams.js @@ -0,0 +1,156 @@ + + + +module.exports.details = function details() { + + return { + id: "Tdarr_Plugin_076b_re_order_subtitle_streams", + Stage: "Pre-processing", + Name: "Re-order subtitle streams", + Type: "", + Operation: "Transcode", + Description: `[TESTING][Contains built-in filter] Specify a language tag for Tdarr to try and put as 1st subtitle track \n\n`, + Version: "1.00", + Link: "", + Inputs: [ + { + name: 'preferred_language', + tooltip: `Specify one language tag for Tdarr to try and put as 1st subtitle track + + \\nExample:\\n + + eng + + \\nExample:\\n + + en + + \\nExample:\\n + + fr + + \\nExample:\\n + + de + + ` + } + ] + } + +} + +module.exports.plugin = function plugin(file, librarySettings, inputs) { + + + + //Must return this object + + var response = { + + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: '', + + } + + + console.log(inputs.preferred_language) + + if (inputs.preferred_language === undefined) { + + response.processFile = false + response.infoLog += "☒ Inputs not entered! \n" + return response + + + } + + + var desiredTrackPosition = file.ffProbeData.streams.filter(stream => stream.codec_type.toLowerCase() == "video" || stream.codec_type.toLowerCase() == "audio").length + + + + var subtitleInLang = file.ffProbeData.streams.filter(stream => { + + + if (stream.codec_type.toLowerCase() == "subtitle" + && stream.tags && stream.tags.language && inputs.preferred_language.includes(stream.tags.language.toLowerCase())) { + return true + } + + return false + + }) + + + if (subtitleInLang.length == 0) { + + response.processFile = false + response.infoLog += "☒ No subtitle tracks in desired language! \n" + return response + + } + + + var streamToMove = subtitleInLang[0] + + if (streamToMove.index == desiredTrackPosition) { + + response.processFile = false + response.infoLog += "☑ Preferred language is already first subtitle track! \n" + return response + + } + + + var ffmpegCommand = ', -c copy ' + + if (file.ffProbeData.streams[0].codec_type.toLowerCase() == "video") { + ffmpegCommand += ` -map 0:v -map 0:a ` + } + + var allSubtitleTracks = file.ffProbeData.streams.filter(stream => stream.codec_type.toLowerCase() == "subtitle") + + + var streamIdx + + for (var i = 0; i < allSubtitleTracks.length; i++) { + + if (allSubtitleTracks[i].index == streamToMove.index) { + streamIdx = i + break + + } + } + + ffmpegCommand += ` -map 0:s:${streamIdx} -disposition:s:${streamIdx} default` + + for (var i = 0; i < allSubtitleTracks.length; i++) { + + if (i !== streamIdx) { + ffmpegCommand += ` -map 0:s:${i} -disposition:a:${i} none ` + } + } + + ffmpegCommand += ` -map 0:d? ` + + + + response.processFile = true + response.preset = ffmpegCommand + response.container = `.` + file.container + response.handBrakeMode = false + response.FFmpegMode = true + response.reQueueAfter = true; + response.infoLog += `☒ Desired subtitle lang is not first subtitle stream, moving! \n` + return response + + + +} + diff --git a/Community/Tdarr_Plugin_z18s_rename_files_based_on_codec.js b/Community/Tdarr_Plugin_z18s_rename_files_based_on_codec.js new file mode 100644 index 0000000..43ad46d --- /dev/null +++ b/Community/Tdarr_Plugin_z18s_rename_files_based_on_codec.js @@ -0,0 +1,63 @@ + + + +module.exports.details = function details() { + + return { + id: "Tdarr_Plugin_z18s_rename_files_based_on_codec", + Stage: "Post-processing", + Name: "Rename based on codec", + Type: "Video", + Operation: "", + Description: `[TESTING][Contains built-in filter]This plugin renames 264 files to 265 or vice versa depending on codec. \n\n`, + Version: "1.00", + Link: "", + + } + +} + +module.exports.plugin = function plugin(file, librarySettings, inputs) { + + try { + + var fsextra = require('fs-extra') + + var fileNameOld = file._id + + if (file.ffProbeData.streams[0].codec_name == 'hevc' && file._id.includes('264')) { + file._id = file._id.replace("264", "265"); + file.file = file.file.replace("264", "265"); + } + + + + if (file.ffProbeData.streams[0].codec_name == 'h264' && file._id.includes('265')) { + file._id = file._id.replace("265", "264"); + file.file = file.file.replace("265", "264"); + } + + if (file.ffProbeData.streams[0].codec_name == 'h264' && file._id.includes('hevc')) { + file._id = file._id.replace("hevc", "264"); + file.file = file.file.replace("hevc", "264"); + } + + if (fileNameOld != file._id) { + + fsextra.moveSync(fileNameOld, file._id, { + overwrite: true + }) + + var response = { + file, + removeFromDB: false, + updateDB: true, + } + + return response + + + } + + } catch (err) { console.log(err) } +}