Merge branch 'master' into patch-5

This commit is contained in:
controlol 2020-04-03 18:50:43 +02:00 committed by GitHub
commit cf6968aa26
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
55 changed files with 2631 additions and 78 deletions

View file

@ -11,7 +11,8 @@ function details() {
Operation:"Transcode",
Description: `[Contains built-in filter] This plugin transcodes non h265 files into h265 mkv using default settings. Audio/subtitles not affected. \n\n`,
Version: "1.00",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_075a_FFMPEG_HEVC_Generic.js"
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_075a_FFMPEG_HEVC_Generic.js",
Tags:'pre-processing,ffmpeg,h265,video only'
}
}

View file

@ -0,0 +1,208 @@
module.exports.details = function details() {
return {
id: "Tdarr_Plugin_075a_Transcode_Customisable",
Stage: "Pre-processing",
Name: "Video 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: "",
Tags:'pre-processing,handbrake,ffmpeg,configurable',
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
\\nCommon video codecs:
\\nmpeg4
\\nhevc
\\nh264
\\nmpeg2video
\\ntheora
\\nvp8
\\nvp9
\\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
}

View file

@ -11,7 +11,8 @@ function details() {
Operation:"Transcode",
Description: `[Contains built-in filter] This plugin transcodes non h265 files into h265 mkv using default settings. Only video and audio streams are kept. Useful for if you're getting errors because of certain containers not being able to handle certain subtitle/data streams. \n\n`,
Version: "1.00",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_075b_FFMPEG_HEVC_Generic_Video_Audio_Only.js"
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_075b_FFMPEG_HEVC_Generic_Video_Audio_Only.js",
Tags:'pre-processing,video only,ffmpeg,h265',
}
}

View file

@ -10,7 +10,8 @@ function details() {
Operation:"Transcode",
Description: `[Contains built-in filter] This plugin transcodes non h265 files into h265 mkv using default settings. Only video and audio streams are kept. Useful for if you're getting errors because of certain containers not being able to handle certain subtitle/data streams. A CRF value of 20 is used. \n\n`,
Version: "1.00",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_075c_FFMPEG_HEVC_Generic_Video_Audio_Only_CRF20.js"
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_075c_FFMPEG_HEVC_Generic_Video_Audio_Only_CRF20.js",
Tags:'pre-processing,video only,ffmpeg,h265',
}
}

View file

@ -10,7 +10,8 @@ function details() {
Operation:"Transcode",
Description: `[Contains built-in filter] This plugin transcodes non h265 files into h265 mkv using the graphics card and a CRF value of 20. Only video and audio streams are kept. Useful for if you're getting errors because of certain containers not being able to handle certain subtitle/data streams. A CRF value of 20 is used. The GPU (graphics card) is used. \n\n`,
Version: "1.00",
Link: "https://github.com/moodiest/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_075d_FFMPEG_HEVC_GPU_Generic_Video_Audio_Only_CRF20.js"
Link: "https://github.com/moodiest/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_075d_FFMPEG_HEVC_GPU_Generic_Video_Audio_Only_CRF20.js",
Tags:'pre-processing,video only,ffmpeg,h265',
}
}

View file

@ -0,0 +1,155 @@
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: "",
Tags:'pre-processing,audio only,ffmpeg,configurable',
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
}

View file

@ -0,0 +1,157 @@
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: "",
Tags:'pre-processing,subtitle only,ffmpeg,configurable',
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
}

View file

@ -0,0 +1,112 @@
module.exports.details = function details() {
return {
id: "Tdarr_Plugin_077b_HandBrake_NVENC_264_Configurable",
Stage: "Pre-processing",
Name: "HandBrake NVENC 264 Configurable",
Type: "Video",
Operation: "Transcode",
Description: `[Contains built-in filter] If files are not in H264, they will be transcoded into H264 using HandBrake NVENC H264. All audio and subtitles are kept. \n\n`,
Version: "1.00",
Link: "",
Tags: 'pre-processing,handbrake,nvenc h264,configurable',
Inputs: [
{
name: 'handbrake_preset',
tooltip: `\\nEnter the name of a HandBrake preset.
\\nYou can learn more about HandBrake presets here:
\\nhttps://handbrake.fr/docs/en/latest/technical/official-presets.html
\\nExample:\\n
Very Fast 1080p30
\\nExample:\\n
Fast 1080p30
`
},
{
name: 'output_container',
tooltip: `
\\nEnter the output container of the new file
\\nExample:\\n
.mp4
\\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.handbrake_preset === undefined
|| inputs.output_container === undefined) {
response.processFile = false
response.infoLog += "☒ Inputs not entered! \n"
return response
}
if (file.ffProbeData.streams[0].codec_name == 'h264') {
response.processFile = false
response.infoLog += "☑ File is already in h264, no need to transcode! \n"
return response
} else {
var container = inputs.output_container
if (container.charAt(0) != '.') {
container = '.' + container
}
var response = {
processFile: true,
preset: `-Z "${inputs.handbrake_preset}" -e nvenc_h264 --all-audio --all-subtitles`,
container: container,
handBrakeMode: true,
FFmpegMode: false,
reQueueAfter: true,
infoLog: '☒ File is not in h264, transcoding! \n'
}
return response
}
}

View file

@ -0,0 +1,114 @@
module.exports.details = function details() {
return {
id: "Tdarr_Plugin_43az_add_to_radarr",
Stage: "Post-processing",
Name: "Add movie to Radarr after processing",
Type: "Video",
Operation: "",
Description: `[TESTING]Add movie to Radarr after processing \n\n`,
Version: "1.00",
Link: "",
Tags:"3rd party,post-processing,configurable",
Inputs: [
{
name: 'server_ip',
tooltip: `
Enter the server IP address
\\nExample:\\n
192.168.0.10
`
},
{
name: 'port',
tooltip: `
Enter the port Radarr is using
\\nExample:\\n
7878
`
},
{
name: 'radarr_api_key',
tooltip: `
Enter the Radarr API key. You can find it on Radarr at /settings/general
\\nExample:\\n
3ff1ae1c39a2a2a397315e15266dea48
`
},
]
}
}
module.exports.plugin = function plugin(file, librarySettings, inputs) {
const request = require('request')
const IP = inputs.server_ip
const port = inputs.port
const APIKey = inputs.radarr_api_key
var term = file.file.split("/")
term = term[term.length - 1]
term = term.split(".")
term = term[term.length - 2]
term = encodeURI(term)
console.log(IP)
console.log(term)
request.get(`http://${IP}:${port}/api/movie/lookup?term=${term}&apikey=${APIKey}`, {
json: {
}
}, (error, res, body) => {
if (error) {
console.error(error)
}
// console.log(`statusCode: ${res.statusCode}`)
//console.log(body)
var response = body[0]
console.log(response.title) //Shrek
response.profileId = 6
response.path = file.file
response.qualityProfile = 6
request.post(`http://${IP}:${port}/api/movie?apikey=${APIKey}`, {
json: response
}, (error, res, body) => {
if (error) {
console.error(error)
}
console.log(`statusCode: ${res.statusCode}`)
// console.log(body)
})
})
//Optional response if you need to modify database
var response = {
file,
removeFromDB: false,
updateDB: false,
}
//return response
}

View file

@ -0,0 +1,162 @@
function details() {
return {
id: "Tdarr_Plugin_MC93_Migz1FFMPEG",
Stage: "Pre-processing",
Name: "Migz-Transcode Using Nvidia GPU & FFMPEG",
Type: "Video",
Operation:"Transcode",
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",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_Migz1FFMPEG.js",
Tags:'pre-processing,ffmpeg,video only,nvenc h265,configurable',
Inputs: [
{
name: 'container',
tooltip: `Specify output container of file, ensure that all stream types you may have are supported by your chosen container. mkv is recommended.
\\nExample:\\n
mkv
\\nExample:\\n
mp4`
},
{
name: 'bitrate_cutoff',
tooltip: `Specify bitrate cutoff, files with a current bitrate lower then this will not be transcoded. Rate is in kbps. Leave empty to disable.
\\nExample:\\n
6000
\\nExample:\\n
4000`
},
]
}
}
function plugin(file, librarySettings, inputs) {
var response = {
processFile: false,
preset: '',
handBrakeMode: false,
FFmpegMode: true,
reQueueAfter: true,
infoLog: ''
}
if (inputs.container == "") {
response.infoLog += "☒Container has not been configured within plugin settings, please configure required options. Skipping this plugin. \n"
response.processFile = false
return response
} else {
response.container = '.' + inputs.container
}
if (inputs.container == "mkv") {
extraArguments += "-map -0:d "
}
if (file.fileMedium !== "video") {
response.processFile = false
response.infoLog += "☒File is not a video. \n"
return response
}
if (typeof file.meta.Duration != 'undefined') {
var duration = (file.meta.Duration * 0.0166667)
} else {
var duration = (file.ffProbeData.streams[0].duration * 0.0166667)
}
var videoIdx = 0
var extraArguments = ""
var bitrateSettings = ""
var filesize = (file.file_size / 1000)
var currentBitrate = ~~(file.file_size / (duration * 0.0075))
var targetBitrate = ~~((file.file_size / (duration * 0.0075)) / 2)
var minimumBitrate = ~~(targetBitrate * 0.7)
var maximumBitrate = ~~(targetBitrate * 1.3)
if (targetBitrate == "0") {
response.processFile = false
response.infoLog += "☒Target bitrate could not be calculated. Skipping this plugin. \n"
return response
}
if (inputs.bitrate_cutoff != "") {
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`
return response
} 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`
return response
}
}
}
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "video") {
if (file.ffProbeData.streams[i].codec_name == 'mjpeg') {
extraArguments += `-map -v:${videoIdx} `
}
if (file.ffProbeData.streams[i].codec_name == 'hevc' && file.container == inputs.container) {
response.processFile = false
response.infoLog += `☑File is already in ${inputs.container} & hevc. \n`
return response
}
if (file.ffProbeData.streams[i].codec_name == 'hevc' && file.container != '${inputs.container}') {
response.infoLog += `☒File is hevc but is not in ${inputs.container} container. Remuxing. \n`
response.preset = `, -map 0 -c copy ${extraArguments}`
response.processFile = true;
return response
}
videoIdx++
}
}
bitrateSettings = `-b:v ${targetBitrate}k -minrate ${minimumBitrate}k -maxrate ${maximumBitrate}k`
response.infoLog += `Container for output selected as ${inputs.container}. \n Current bitrate = ${~~(file.file_size / (duration * 0.0075))} \n Bitrate settings: \nTarget = ${targetBitrate} \nMinimum = ${minimumBitrate} \nMaximum = ${maximumBitrate} \n`
//codec will be checked so it can be transcoded correctly
if (file.video_codec_name == 'h263') {
response.preset = `-c:v h263_cuvid`
}
else if (file.video_codec_name == 'h264') {
if (file.ffProbeData.streams[0].profile != 'High 10') { //if a h264 coded video is not HDR
response.preset = `-c:v h264_cuvid`
}
}
else if (file.video_codec_name == 'mjpeg') {
response.preset = `c:v mjpeg_cuvid`
}
else if (file.video_codec_name == 'mpeg1') {
response.preset = `-c:v mpeg1_cuvid`
}
else if (file.video_codec_name == 'mpeg2') {
response.preset = `-c:v mpeg2_cuvid`
}
else if (file.video_codec_name == 'vc1') {
response.preset = `-c:v vc1_cuvid`
}
else if (file.video_codec_name == 'vp8') {
response.preset = `-c:v vp8_cuvid`
}
else if (file.video_codec_name == 'vp9') {
response.preset = `-c:v vp9_cuvid`
}
response.preset += `,-map 0 -c:v hevc_nvenc -rc:v vbr_hq ${bitrateSettings} -bufsize 2M -spatial_aq:v 1 -c:a copy -c:s copy -max_muxing_queue_size 4096 ${extraArguments}`
response.processFile = true
response.infoLog += `☒File is not hevc. Transcoding. \n`
return response
}
module.exports.details = details;
module.exports.plugin = plugin;

View file

@ -0,0 +1,133 @@
function details() {
return {
id: "Tdarr_Plugin_MC93_Migz1FFMPEG_CPU",
Stage: "Pre-processing",
Name: "Migz-Transcode Using CPU & FFMPEG",
Type: "Video",
Operation:"Transcode",
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",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_Migz1FFMPEG_CPU.js",
Tags:'pre-processing,ffmpeg,video only,configurable,h265',
Inputs: [
{
name: 'container',
tooltip: `Specify output container of file, ensure that all stream types you may have are supported by your chosen container. mkv is recommended.
\\nExample:\\n
mkv
\\nExample:\\n
mp4`
},
{
name: 'bitrate_cutoff',
tooltip: `Specify bitrate cutoff, files with a current bitrate lower then this will not be transcoded. Rate is in kbps. Leave empty to disable.
\\nExample:\\n
6000
\\nExample:\\n
4000`
},
]
}
}
function plugin(file, librarySettings, inputs) {
var response = {
processFile: false,
preset: '',
handBrakeMode: false,
FFmpegMode: true,
reQueueAfter: true,
infoLog: ''
}
if (inputs.container == "") {
response.infoLog += "☒Container has not been configured within plugin settings, please configure required options. Skipping this plugin. \n"
response.processFile = false
return response
} else {
response.container = '.' + inputs.container
}
if (inputs.container == "mkv") {
extraArguments += "-map -0:d "
}
if (file.fileMedium !== "video") {
response.processFile = false
response.infoLog += "☒File is not a video. \n"
return response
}
if (typeof file.meta.Duration != 'undefined') {
var duration = (file.meta.Duration * 0.0166667)
} else {
var duration = (file.ffProbeData.streams[0].duration * 0.0166667)
}
var videoIdx = 0
var extraArguments = ""
var bitrateSettings = ""
var filesize = (file.file_size / 1000)
var currentBitrate = ~~(file.file_size / (duration * 0.0075))
var targetBitrate = ~~((file.file_size / (duration * 0.0075)) / 2)
var minimumBitrate = ~~(targetBitrate * 0.7)
var maximumBitrate = ~~(targetBitrate * 1.3)
if (targetBitrate == "0") {
response.processFile = false
response.infoLog += "☒Target bitrate could not be calculated. Skipping this plugin. \n"
return response
}
if (inputs.bitrate_cutoff != "") {
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`
return response
} 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`
return response
}
}
}
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "video") {
if (file.ffProbeData.streams[i].codec_name == 'mjpeg') {
extraArguments += `-map -v:${videoIdx} `
}
if (file.ffProbeData.streams[i].codec_name == 'hevc' && file.container == inputs.container) {
response.processFile = false
response.infoLog += `☑File is already in ${inputs.container} & hevc. \n`
return response
}
if (file.ffProbeData.streams[i].codec_name == 'hevc' && file.container != '${inputs.container}') {
response.infoLog += `☒File is hevc but is not in ${inputs.container} container. Remuxing. \n`
response.preset = `, -map 0 -c copy ${extraArguments}`
response.processFile = true;
return response
}
videoIdx++
}
}
bitrateSettings = `-b:v ${targetBitrate}k -minrate ${minimumBitrate}k -maxrate ${maximumBitrate}k`
response.infoLog += `Container for output selected as ${inputs.container}. \n Current bitrate = ${~~(file.file_size / (duration * 0.0075))} \n Bitrate settings: \nTarget = ${targetBitrate} \nMinimum = ${minimumBitrate} \nMaximum = ${maximumBitrate} \n`
response.preset += `,-map 0 -c:v libx265 ${bitrateSettings} -bufsize 2M -spatial_aq:v 1 -c:a copy -c:s copy -max_muxing_queue_size 4096 ${extraArguments}`
response.processFile = true
response.infoLog += `☒File is not hevc. Transcoding. \n`
return response
}
module.exports.details = details;
module.exports.plugin = plugin;

View file

@ -0,0 +1,106 @@
function details() {
return {
id: "Tdarr_Plugin_MC93_Migz2CleanTitle",
Stage: "Pre-processing",
Name: "Migz-Clean title metadata",
Type: "Video",
Operation: "Clean",
Description: `This plugin removes title metadata from video/audio/subtitles, if it exists. Video checking is mandatory, audio and subtitles are optional.\n\n`,
Version: "1.20",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_Migz2CleanTitle.js",
Tags:'pre-processing,ffmpeg,configurable',
Inputs: [
{
name: 'clean_audio',
tooltip: `Specify if audio titles should be checked & cleaned. Optional.
\\nExample:\\n
true
\\nExample:\\n
false`
},
{
name: 'clean_subtitles',
tooltip: `Specify if subtitle titles should be checked & cleaned. Optional.
\\nExample:\\n
true
\\nExample:\\n
false`
},
]
}
}
function plugin(file, librarySettings, inputs) {
var response = {
processFile : false,
preset : '',
container: '.' + file.container,
handBrakeMode : false,
FFmpegMode : true,
reQueueAfter : false,
infoLog : '',
}
var ffmpegCommandInsert = ''
var videoIdx = 0
var audioIdx = 0
var subtitleIdx = 0
var convert = false
if (file.fileMedium !== "video") {
console.log("File is not video")
response.infoLog += "☒File is not video \n"
response.processFile = false;
return response
}
if (typeof file.meta.Title != 'undefined') try {
ffmpegCommandInsert += ` -metadata title="" `
convert = true
} catch (err) { }
for (var i = 0; i < file.ffProbeData.streams.length; i++) try {
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "video") {
if (typeof file.ffProbeData.streams[i].tags.title != 'undefined') {
response.infoLog += `☒Video stream title is not empty, most likely junk metadata. Removing title from stream ${i} \n`
ffmpegCommandInsert += ` -metadata:s:v:${videoIdx} title="" `
convert = true
}
videoIdx++
}
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" && inputs.clean_audio.toLowerCase() == "true") {
if (file.ffProbeData.streams[i].tags.title.split('.').length-1 > 3) {
response.infoLog += `☒More then 3 full stops detected in subtitle title, likely to be junk metadata. Removing title from stream ${i} \n`
ffmpegCommandInsert += ` -metadata:s:a:${audioIdx} title="" `
convert = true
}
audioIdx++
}
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle" && inputs.clean_subtitles.toLowerCase() == "true") {
if (file.ffProbeData.streams[i].tags.title.split('.').length-1 > 3) {
response.infoLog += `☒More then 3 full stops detected in subtitle title, likely to be junk metadata. Removing title from stream ${i} \n`
ffmpegCommandInsert += ` -metadata:s:s:${subtitleIdx} title="" `
convert = true
}
subtitleIdx++
}
} catch (err) { }
if (convert == true) {
response.infoLog += "☒File has title metadata. Removing \n"
response.preset = `,${ffmpegCommandInsert} -c copy -max_muxing_queue_size 4096`
response.reQueueAfter = true;
response.processFile = true;
} else {
response.infoLog += "☑File has no title metadata \n"
}
return response
}
module.exports.details = details;
module.exports.plugin = plugin;

View file

@ -0,0 +1,172 @@
function details() {
return {
id: "Tdarr_Plugin_MC93_Migz3CleanAudio",
Stage: "Pre-processing",
Name: "Migz-Clean audio streams",
Type: "Audio",
Operation: "Clean",
Description: `This plugin keeps only specified language audio tracks & can tags those that have an unknown language. \n\n`,
Version: "2.00",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_Migz3CleanAudio.js",
Tags:'pre-processing,ffmpeg,audio only,configurable',
Inputs: [
{
name: 'language',
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
eng
\\nExample:\\n
eng,und
\\nExample:\\n
eng,und,jap`
},
{
name: 'commentary',
tooltip: `Specify if audio tracks that contain commentary/description should be removed.
\\nExample:\\n
true
\\nExample:\\n
false`
},
{
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
\\nExample:\\n
eng
\\nExample:\\n
por
`
},
{
name: 'tag_title',
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.
\\nExample:\\n
true
\\nExample:\\n
false`
},
]
}
}
function plugin(file, librarySettings, inputs) {
var response = {
processFile: false,
preset: '',
container: '.' + file.container,
handBrakeMode: false,
FFmpegMode: true,
reQueueAfter: false,
infoLog: '',
}
if (file.fileMedium !== "video") {
console.log("File is not video")
response.infoLog += "☒File is not video \n"
response.processFile = false;
return response
}
if (inputs.language == "") {
response.infoLog += "☒Language/s keep have not been configured within plugin settings, please configure required options. Skipping this plugin. \n"
response.processFile = false;
return response
}
var language = inputs.language.split(",")
var ffmpegCommandInsert = ''
var convert = false
var audioIdx = -1
var audioStreamsRemoved = 0
var audioStreamCount = file.ffProbeData.streams.filter(row => (row.codec_type.toLowerCase() == "audio")).length;
console.log("audioStreamCount:" + audioStreamCount)
response.infoLog += `Languages to keep are ${language} \n`
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
try {
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
audioIdx++
}
} catch (err) { }
try {
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" && language.indexOf(file.ffProbeData.streams[i].tags.language.toLowerCase()) === -1) {
audioStreamsRemoved++
ffmpegCommandInsert += `-map -0:a:${audioIdx} `
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) { }
try {
if (inputs.commentary.toLowerCase() == "true" && file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" && (file.ffProbeData.streams[i].tags.title.toLowerCase().includes('commentary') || file.ffProbeData.streams[i].tags.title.toLowerCase().includes('description') || file.ffProbeData.streams[i].tags.title.toLowerCase().includes('sdh'))) {
audioStreamsRemoved++
ffmpegCommandInsert += `-map -0:a:${audioIdx} `
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) { }
try {
if (inputs.tag_language != "") {
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" && file.ffProbeData.streams[i].tags.language.toLowerCase().includes('und') && language.indexOf('und') !== -1) {
ffmpegCommandInsert += `-metadata:s:a:${audioIdx} language=${inputs.tag_language} `
response.infoLog += `☒Audio stream detected as having unknown language tagged, tagging as ${inputs.tag_language}. \n`
convert = true
}
if (typeof file.ffProbeData.streams[i].tags.language === 'undefined' && file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
ffmpegCommandInsert += `-metadata:s:a:${audioIdx} language=${inputs.tag_language} `
response.infoLog += `☒Audio stream detected as having no language tagged, tagging as ${inputs.tag_language}. \n`
convert = true
}
}
} catch (err) { }
try {
if (typeof file.ffProbeData.streams[i].tags.title == 'undefined' && inputs.tag_title.toLowerCase() == "true" && file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
if (file.ffProbeData.streams[i].channels == "8") {
ffmpegCommandInsert += `-metadata:s:a:${audioIdx} title="7.1" `
response.infoLog += `☒Audio stream detected as 8 channel audio track with no title, tagging title. Audio stream 0:a:${audioIdx} tagged as "7.1" \n`
convert = true
}
if (file.ffProbeData.streams[i].channels == "6") {
ffmpegCommandInsert += `-metadata:s:a:${audioIdx} title="5.1" `
response.infoLog += `☒Audio stream detected as 6 channel audio track with no title, tagging title. Audio stream 0:a:${audioIdx} tagged as "5.1" \n`
convert = true
}
if (file.ffProbeData.streams[i].channels == "2") {
ffmpegCommandInsert += `-metadata:s:a:${audioIdx} title="2.0" `
response.infoLog += `☒Audio stream detected as 2 channel audio track with no title, tagging title. Audio stream 0:a:${audioIdx} tagged as "2.0" \n`
convert = true
}
}
} catch (err) { }
}
if (audioStreamsRemoved == audioStreamCount) {
response.infoLog += "☒Cancelling plugin otherwise all audio tracks would be removed. \n"
response.processFile = false
return response
}
if (convert === true && (audioStreamsRemoved != audioStreamCount)) {
response.processFile = true
response.preset = `, -map 0 ${ffmpegCommandInsert} -c copy -max_muxing_queue_size 4096`
response.container = '.' + file.container
response.reQueueAfter = true
} else {
response.processFile = false
response.infoLog += "☑File doesn't contain audio tracks which are unwanted or that require tagging.\n"
}
return response
}
module.exports.details = details;
module.exports.plugin = plugin;

View file

@ -0,0 +1,126 @@
function details() {
return {
id: "Tdarr_Plugin_MC93_Migz4CleanSubs",
Stage: "Pre-processing",
Name: "Migz-Clean subtitle streams",
Type: "subtitless",
Operation: "Clean",
Description: `This plugin keeps only specified language subtitle tracks & can tag those that have an unknown language. \n\n`,
Version: "2.00",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_Migz4CleanSubs.js",
Tags:'pre-processing,ffmpeg,subtitle only,configurable',
Inputs: [
{
name: 'language',
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
eng
\\nExample:\\n
eng,jap`
},
{
name: 'commentary',
tooltip: `Specify if subtitle tracks that contain commentary/description should be removed.
\\nExample:\\n
true
\\nExample:\\n
false`
},
{
name: 'tag_title',
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
\\nExample:\\n
por`
},
]
}
}
function plugin(file, librarySettings, inputs) {
var response = {
processFile: false,
preset: '',
container: '.' + file.container,
handBrakeMode: false,
FFmpegMode: true,
reQueueAfter: false,
infoLog: '',
}
if (file.fileMedium !== "video") {
console.log("File is not video")
response.infoLog += "☒File is not video \n"
response.processFile = false;
return response
}
if (inputs.language == "") {
response.infoLog += "☒Language/s keep have not been configured within plugin settings, please configure required options. Skipping this plugin. \n"
response.processFile = false;
return response
}
var language = inputs.language.split(",")
var ffmpegCommandInsert = ''
var subtitleIdx = -1
var convert = false
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
try {
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle") {
subtitleIdx++
}
} catch (err) { }
try {
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle" && language.indexOf(file.ffProbeData.streams[i].tags.language.toLowerCase()) === -1) {
ffmpegCommandInsert += `-map -0:s:${subtitleIdx} `
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) { }
try {
if (inputs.commentary.toLowerCase() == "true" && file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle" && (file.ffProbeData.streams[i].tags.title.toLowerCase().includes('commentary') || file.ffProbeData.streams[i].tags.title.toLowerCase().includes('description') || file.ffProbeData.streams[i].tags.title.toLowerCase().includes('sdh'))) {
ffmpegCommandInsert += `-map -0:s:${subtitleIdx} `
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) { }
try {
if (inputs.tag_title != "") {
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle" && file.ffProbeData.streams[i].tags.language.toLowerCase().includes('und')) {
ffmpegCommandInsert += `-metadata:s:s:${subtitleIdx} language=${inputs.tag_title} `
response.infoLog += `☒Subtitle stream detected as having unknown language tagged, tagging as ${inputs.tag_title}. \n`
convert = true
}
}
} catch (err) { }
try {
if (typeof file.ffProbeData.streams[i].tags.language == 'undefined' && file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle") {
ffmpegCommandInsert += `-metadata:s:s:${subtitleIdx} language=${inputs.tag_title} `
response.infoLog += `☒Subtitle stream detected as having no language tagged, tagging as ${inputs.tag_title}. \n`
convert = true
}
} catch (err) { }
}
if (convert === true ) {
response.processFile = true;
response.preset = `, -map 0 ${ffmpegCommandInsert} -c copy -max_muxing_queue_size 4096`
response.container = '.' + file.container
response.reQueueAfter = true;
} else {
response.processFile = false;
response.infoLog += "☑File doesn't contain subtitle tracks which are unwanted or that require tagging.\n"
}
return response
}
module.exports.details = details;
module.exports.plugin = plugin;

View file

@ -0,0 +1,120 @@
function details() {
return {
id: "Tdarr_Plugin_MC93_Migz5ConvertAudio",
Stage: "Pre-processing",
Name: "Migz-Convert audio streams",
Type: "Audio",
Operation: "Transcode",
Description: `This plugin can convert any 2.0 audio track/s to AAC and can create downmixed audio tracks. \n\n`,
Version: "2.00",
Link: "",
Tags:'pre-processing,ffmpeg,audio only,configurable',
Inputs: [
{
name: 'aac_stereo',
tooltip: `Specify if any 2.0 audio tracks should be converted to aac for maximum compatability with devices.
\\nExample:\\n
true
\\nExample:\\n
false`
},
{
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.
\\nExample:\\n
true
\\nExample:\\n
false`
},
]
}
}
function plugin(file, librarySettings, inputs) {
var response = {
processFile: false,
container: '.' + file.container,
handBrakeMode: false,
FFmpegMode: true,
reQueueAfter: true,
infoLog: '',
}
if (file.fileMedium !== "video") {
console.log("File is not video")
response.infoLog += "☒File is not video. \n"
response.processFile = false;
return response
}
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
return response
}
var ffmpegCommandInsert = ''
var audioIdx = 0
var has2Channel = false
var has6Channel = false
var has8Channel = false
var convert = false
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
try {
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
if (file.ffProbeData.streams[i].channels == "2") {
has2Channel = true
}
if (file.ffProbeData.streams[i].channels == "6") {
has6Channel = true
}
if (file.ffProbeData.streams[i].channels == "8") {
has8Channel = true
}
}
} catch (err) { }
}
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
if (inputs.downmix.toLowerCase() == "true") {
if (has8Channel == true && has6Channel == false && file.ffProbeData.streams[i].channels == "8") {
ffmpegCommandInsert += `-map 0:${i} -c:a:${audioIdx} ac3 -ac 6 -metadata:s:a:${audioIdx} title="5.1 " `
response.infoLog += "☒Audio track is 8 channel, no 6 channel exists. Creating 2 channel from 6 channel. \n"
convert = true
}
if (has6Channel == true && has2Channel == false && file.ffProbeData.streams[i].channels == "6") {
ffmpegCommandInsert += `-map 0:${i} -c:a:${audioIdx} aac -ac 2 -metadata:s:a:${audioIdx} title="2.0 " `
response.infoLog += "☒Audio track is 6 channel, no 2 channel exists. Creating 2 channel from 6 channel. \n"
convert = true
}
}
if (inputs.aac_stereo.toLowerCase() == "true") {
if (file.ffProbeData.streams[i].codec_name != "aac" && file.ffProbeData.streams[i].channels == "2" ) {
ffmpegCommandInsert += `-c:a:${audioIdx} aac `
response.infoLog += "☒Audio track is 2 channel but is not AAC. Converting. \n"
convert = true
}
}
audioIdx++
}
}
if (convert == true) {
response.processFile = true;
response.preset = `, -map 0 -c:v copy -c:a copy ${ffmpegCommandInsert} -strict -2 -c:s copy -max_muxing_queue_size 4096 `
} else {
response.infoLog += "☑File contains all required audio formats. \n"
response.processFile = false;
}
return response
}
module.exports.details = details;
module.exports.plugin = plugin;

View file

@ -0,0 +1,137 @@
function details() {
return {
id: "Tdarr_Plugin_MC93_Migz6OrderStreams",
Stage: "Pre-processing",
Name: "Migz-Organize Streams",
Type: "Streams",
Operation: "Organize",
Description: `Organizes streams into Video first, then Audio (2ch, 6ch, 8ch) and finally Subtitles. \n\n`,
Version: "1.00",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_Migz6OrderStreams.js",
Tags:'pre-processing,ffmpeg,'
}
}
function plugin(file) {
var response = {
processFile: false,
preset: '',
container: '.' + file.container,
handBrakeMode: false,
FFmpegMode: true,
infoLog: '',
}
var ffmpegCommandInsert = ''
var videoIdx = 0
var audioIdx = 0
var audio2Idx = 0
var audio6Idx = 0
var audio8Idx = 0
var subtitleIdx = 0
var convert = false
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
try {
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "video") {
if (audioIdx != "0" || subtitleIdx != "0") {
convert = true
response.infoLog += "☒ Video not first. \n"
}
videoIdx++
}
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
if (subtitleIdx != "0") {
convert = true
response.infoLog += "☒ Audio not second. \n"
}
audioIdx++
if (file.ffProbeData.streams[i].channels == "2") {
if (audio6Idx != "0" || audio8Idx != "0") {
convert = true
response.infoLog += "☒ Audio 2ch not first. \n"
}
audio2Idx++
}
if (file.ffProbeData.streams[i].channels == "6") {
if (audio8Idx != "0") {
convert = true
response.infoLog += "☒ Audio 6ch not second. \n"
}
audio6Idx++
}
if (file.ffProbeData.streams[i].channels == "8") {
audio8Idx++
response.infoLog += "☒ Audio 8ch not last. \n"
}
}
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle") {
subtitleIdx++
}
} catch (err) { }
}
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
try {
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "video" && file.ffProbeData.streams[i].codec_name.toLowerCase() != "mjpeg") {
ffmpegCommandInsert += `-map 0:${i} `
}
} catch (err) { }
}
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
try {
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" && file.ffProbeData.streams[i].channels == "2") {
ffmpegCommandInsert += `-map 0:${i} `
}
} catch (err) { }
}
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
try {
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" && file.ffProbeData.streams[i].channels == "6") {
ffmpegCommandInsert += `-map 0:${i} `
}
} catch (err) { }
}
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
try {
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" && file.ffProbeData.streams[i].channels == "8") {
ffmpegCommandInsert += `-map 0:${i} `
}
} catch (err) { }
}
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
try {
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" && file.ffProbeData.streams[i].channels != "2" && file.ffProbeData.streams[i].channels != "6" && file.ffProbeData.streams[i].channels != "8") {
ffmpegCommandInsert += `-map 0:${i} `
}
} catch (err) { }
}
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
try {
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle") {
ffmpegCommandInsert += `-map 0:${i} `
}
} catch (err) { }
}
if (convert == true) {
response.processFile = true;
response.preset = `,${ffmpegCommandInsert} -c copy -max_muxing_queue_size 4096`
response.reQueueAfter = true;
response.infoLog += "☒ Streams are out of order, reorganizing streams. Video, Audio, Subtitles. \n"
} else {
response.infoLog += "☑ Streams are in expected order. \n "
response.processFile = false;
}
return response
}
module.exports.details = details;
module.exports.plugin = plugin;

View file

@ -0,0 +1,60 @@
function details() {
return {
id: "Tdarr_Plugin_MC93_MigzImageRemoval",
Stage: "Pre-processing",
Name: "Migz-Remove image formats from file",
Type: "Video",
Operation:"Clean",
Description: `Identify any unwanted image formats in the file and remove those streams. MJPEG & PNG \n\n`,
Version: "1.0",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_MigzImageRemoval.js",
Tags:'pre-processing,ffmpeg,video only'
}
}
function plugin(file, librarySettings, inputs) {
var response = {
processFile: false,
preset: '',
handBrakeMode: false,
container: '.' + file.container,
FFmpegMode: true,
reQueueAfter: true,
infoLog: ''
}
if (file.fileMedium !== "video") {
response.processFile = false
response.infoLog += "☒File is not a video. \n"
return response
}
var videoIdx = 0
var extraArguments = ""
var convert = false
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "video") {
if (file.ffProbeData.streams[i].codec_name == 'mjpeg' || file.ffProbeData.streams[i].codec_name == 'png') {
convert = true
extraArguments += `-map -v:${videoIdx} `
}
videoIdx++
}
}
if (convert === true ) {
response.preset += `,-map 0 -c copy -max_muxing_queue_size 4096 ${extraArguments}`
response.infoLog += `☒File has image format stream, removing. \n`
response.processFile = true;
} else {
response.processFile = false;
response.infoLog += "☑File doesn't contain any unwanted image format streams.\n"
}
return response
}
module.exports.details = details;
module.exports.plugin = plugin;

View file

@ -0,0 +1,77 @@
module.exports.details = function details() {
return {
id: "Tdarr_Plugin_MC93_MigzPlex_Autoscan",
Stage: "Post-processing",
Name: "Send request for file to be scanned by plex_autoscan.",
Type: "Video",
Operation: "",
Description: `Send request for file to be scanned by plex_autoscan. https://github.com/l3uddz/plex_autoscan \n\n`,
Version: "1.00",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_MigzPlex_Autoscan.js",
Tags:"3rd party,post-processing,configurable",
Inputs: [
{
name: 'autoscan_address',
tooltip: `
Enter the IP address/URL for autoscan. Must include http(s)://
\\nExample:\\n
http://192.168.0.10
\\nExample:\\n
https://subdomain.domain.tld
`
},
{
name: 'autoscan_port',
tooltip: `
Enter the port Autoscan is using, default is 3468
\\nExample:\\n
3468
`
},
{
name: 'autoscan_passkey',
tooltip: `
Enter the autoscan passkey.
\\nExample:\\n
9c4b81fe234e4d6eb9011cefe514d915
`
},
]
}
}
module.exports.plugin = function plugin(file, librarySettings, inputs) {
const request = require('request')
const ADDRESS = inputs.autoscan_address
const PORT = inputs.autoscan_port
const PASSKEY = inputs.autoscan_passkey
var response = ""
filepath = `${file.file}`
request.post({
headers: {'content-type': 'application/json'},
url: `${ADDRESS}:${PORT}/${PASSKEY}`,
form: { "eventType" : "Manual", "filepath" : `${filepath}` }
}, (error, res, body) => {
if (error) {
console.error(error)
}
console.log(`statusCode: ${res.statusCode}`)
console.log(body)
})
console.log("request next")
console.log(request.post)
}

View file

@ -11,7 +11,8 @@ function details() {
Description: `[Contains built-in filter] This plugin removes metadata (if a title exists). The output container is mp4. \n\n
`,
Version: "1.00",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_a37x_Drawmonster_MP4_No_Title_Meta.js"
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_a37x_Drawmonster_MP4_No_Title_Meta.js",
Tags:'pre-processing,ffmpeg',
}
}

View file

@ -11,7 +11,8 @@ function details() {
Description: `[Contains built-in filter] This plugin transcodes into H264 using HandBrake's 'Very Fast 1080p30' preset if the file is not in H264 already. It removes subs, metadata (if a title exists) and adds a stereo 192kbit AAC track if an AAC track (any) doesn't exist. The output container is MP4. \n\n
`,
Version: "1.00",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_a8hc_HaveAGitGat_HandBrake_H264_VeryFast1080p30.js"
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_a8hc_HaveAGitGat_HandBrake_H264_VeryFast1080p30.js",
Tags:'pre-processing,handbrake,ffmpeg,h264',
}
}

View file

@ -11,7 +11,8 @@ function details() {
Description: `[Contains built-in filter] This plugin transcodes into H264 using HandBrake's 'Fast 1080p30' preset if the file is not in H264 already. It removes subs, metadata (if a title exists) and adds a stereo 192kbit AAC track if an AAC track (any) doesn't exist. The output container is MP4. \n\n
`,
Version: "1.00",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_a9hc_HaveAGitGat_HandBrake_H264_Fast1080p30.js"
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_a9hc_HaveAGitGat_HandBrake_H264_Fast1080p30.js",
Tags:'pre-processing,handbrake,ffmpeg,h264',
}
}

View file

@ -0,0 +1,149 @@
module.exports.details = function details() {
return {
id: "Tdarr_Plugin_a9hd_FFMPEG_Transcode_Specific_Audio_Stream_Codecs",
Stage: "Pre-processing",
Name: "Transcode Specific Audio Stream Codecs",
Type: "",
Operation: "Transcode",
Description: `[TESTING][Contains built-in filter] Transcode audio streams with specific codecs into another codec. \n\n`,
Version: "1.00",
Link: "",
Tags:'pre-processing,audio only,ffmpeg,configurable',
Inputs: [
{
name: 'codecs_to_transcode',
tooltip: `Specifiy the codecs which you'd like to transcode
\\nExample:\\n
ac3
\\nExample:\\n
eac3,ac3,aac
`
},
{
name: 'codec',
tooltip: `Specify the codec you'd like to transcode into:
\\n aac
\\n ac3
\\n eac3
\\n dts
\\n flac
\\n mp2
\\n mp3
\\n truehd
\\nExample:\\n
eac3
`
}
]
}
}
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_transcode === undefined
|| inputs.codec === undefined
) {
response.processFile = false
response.infoLog += "☒ Inputs not entered! \n"
return response
}
var encoder = inputs.codec
if (encoder == 'mp3') {
encoder = `libmp3lame`
} else if (encoder == 'dts') {
encoder = `dca`
}
var codecs_to_transcode = inputs.codecs_to_transcode.split(',')
var hasStreamsToTranscode = false
var ffmpegCommand = `, -c copy -map 0:v `
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" &&
file.ffProbeData.streams[i].codec_name &&
codecs_to_transcode.includes(file.ffProbeData.streams[i].codec_name.toLowerCase())
) {
ffmpegCommand += ` -map 0:${i} -c:${i} ${encoder} `
hasStreamsToTranscode = true
}
}
ffmpegCommand += ` -map 0:s? -map 0:d? `
console.log
if (hasStreamsToTranscode == false) {
response.processFile = false
response.infoLog += "☑ File does not have any streams that need to be transcoded! \n"
return response
} else {
response.processFile = true;
response.preset = ffmpegCommand
response.container = '.' + file.container
response.handBrakeMode = false
response.FFmpegMode = true
response.reQueueAfter = true;
response.infoLog += `☒ File has streams which aren't in desired codec! \n`
return response
}
}

View file

@ -11,7 +11,8 @@ function details() {
Description: `[Contains built-in filter] If the file is not in h265 it will be trancoded into h265 with FFmpeg using the following command '-e x265 -q 22 --encoder-preset slow --all-audio --all-subtitles copy:aac -E fdk_aac -Q 4 -x aq-mode=3'. If no aac, aac track will be added. Subtitles are kept. Metadata is removed.\n\n
`,
Version: "1.01",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_b38x_Nosirus_h265_aac_no_meta.js"
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_b38x_Nosirus_h265_aac_no_meta.js",
Tags:'pre-processing,ffmpeg,h265,',
}
}

View file

@ -11,7 +11,8 @@ function details() {
Description: `[Contains built-in filter] If the file has surround sound tracks not in ac3, they will be converted to ac3. \n\n
`,
Version: "1.00",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_b39x_the1poet_surround_sound_to_ac3.js"
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_b39x_the1poet_surround_sound_to_ac3.js",
Tags:'pre-processing,ffmpeg,audio only,',
}
}
@ -61,7 +62,7 @@ function plugin(file) {
try {
if ( file.ffProbeData.streams[1].channels >= 6 && file.ffProbeData.streams[i].codec_name !== 'ac3' && file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" ) {
if ( file.ffProbeData.streams[i].channels >= 6 && file.ffProbeData.streams[i].codec_name !== 'ac3' && file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" ) {
ffmpegCommandInsert += ` -c:a:${audioIdx} ac3 `
hasnonAC3SurroundTrack = true

View file

@ -6,8 +6,9 @@ function details() {
Type: "Video",
Operation:"Transcode",
Description: `[Contains built-in filter] This plugin uses different FFMPEG NVENC transcoding settings for 480p,576p,720p,1080p and 4KUHD. If files are not in hevc they will be transcoded. The output container is mkv. \n\n`,
Version: "1.08",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_d5d3_iiDrakeii_FFMPEG_NVENC_Tiered_MKV.js"
Version: "1.09",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_d5d3_iiDrakeii_FFMPEG_NVENC_Tiered_MKV.js",
Tags:'pre-processing,ffmpeg,video only,nvenc h265',
}
}
@ -17,7 +18,9 @@ function plugin(file) {
var bitratetarget = 0;
var bitratemax = 0;
var bitratecheck = 0;
var subcli = `-c:s copy`
var subcli = `-c:s copy`;
var maxmux = '';
var map = '-map 0'
//default values that will be returned
var response = {
processFile: false,
@ -26,7 +29,8 @@ function plugin(file) {
handBrakeMode: false,
FFmpegMode: false,
reQueueAfter: true,
infoLog: ''
infoLog: '',
maxmux: false,
}
//check if the file is a video, if not the function will be stopped immediately
@ -78,7 +82,30 @@ function plugin(file) {
else if (file.video_codec_name == 'vp9') {
response.preset = `-c:v vp9_cuvid`
}
//Set Subtitle Var before adding encode cli
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
try {
if (file.ffProbeData.streams[i].codec_name.toLowerCase() == "mov_text" && file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle" ) {
subcli = `-c:s srt`
}
}
catch (err) { }
//mitigate TrueHD audio causing Too many packets error
try {
if (file.ffProbeData.streams[i].codec_name.toLowerCase() == "truehd" || (file.ffProbeData.streams[i].codec_name.toLowerCase() == "dts" && file.ffProbeData.streams[i].profile.toLowerCase() == "dts-hd ma") || file.ffProbeData.streams[i].codec_name.toLowerCase() == "aac" && file.ffProbeData.streams[i].sample_rate.toLowerCase() == "44100" && file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" ) {
maxmux = ` -max_muxing_queue_size 9999`
}
}
catch (err) { }
//mitigate errors due to embeded pictures
try {
if ((file.ffProbeData.streams[i].codec_name.toLowerCase() == "png" || file.ffProbeData.streams[i].codec_name.toLowerCase() == "bmp" || file.ffProbeData.streams[i].codec_name.toLowerCase() == "mjpeg") && file.ffProbeData.streams[i].codec_type.toLowerCase() == "video" ) {
map = `-map 0:v:0 -map 0:a -map 0:s?`
}
}
catch (err) { }
}
//file will be encoded if the resolution is 480p or 576p
//codec will be checked so it can be transcoded correctly
if (file.video_resolution === "480p" || file.video_resolution === "576p" ) {
@ -91,18 +118,10 @@ function plugin(file) {
bitratetarget = 1000;
bitratemax = 1500;
}
response.preset += `,-map 0 -c:v hevc_nvenc -pix_fmt p010le -rc:v vbr_hq -qmin 0 -cq:v 29 -b:v ${bitratetarget}k -maxrate:v 1500k -preset slow -rc-lookahead 32 -spatial_aq:v 1 -aq-strength:v 8 -a53cc 0 -c:a copy ${subcli} -dn`;
response.preset += `,${map} -dn -c:v hevc_nvenc -pix_fmt p010le -rc:v vbr_hq -qmin 0 -cq:v 29 -b:v ${bitratetarget}k -maxrate:v 1500k -preset slow -rc-lookahead 32 -spatial_aq:v 1 -aq-strength:v 8 -a53cc 0 -c:a copy ${subcli}${maxmux}`;
transcode = 1;
}
//Set Subtitle Var before adding encode cli
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
try {
if (file.ffProbeData.streams[i].codec_name.toLowerCase() == "mov_text" && file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle" ) {
subcli = `-c:s srt`
}
}
catch (err) { }
}
//file will be encoded if the resolution is 720p
//codec will be checked so it can be transcoded correctly
if(file.video_resolution === "720p") {
@ -115,7 +134,7 @@ function plugin(file) {
bitratetarget = 2000;
bitratemax = 4000;
}
response.preset += `,-map 0 -c:v hevc_nvenc -pix_fmt p010le -rc:v vbr_hq -qmin 0 -cq:v 30 -b:v ${bitratetarget}k -maxrate:v ${bitratemax}k -preset slow -rc-lookahead 32 -spatial_aq:v 1 -aq-strength:v 8 -a53cc 0 -c:a copy ${subcli} -dn`;
response.preset += `,${map} -dn -c:v hevc_nvenc -pix_fmt p010le -rc:v vbr_hq -qmin 0 -cq:v 30 -b:v ${bitratetarget}k -maxrate:v ${bitratemax}k -preset slow -rc-lookahead 32 -spatial_aq:v 1 -aq-strength:v 8 -a53cc 0 -c:a copy ${subcli}${maxmux}`;
transcode = 1;
}
//file will be encoded if the resolution is 1080p
@ -130,7 +149,7 @@ function plugin(file) {
bitratetarget = 2500;
bitratemax = 5000;
}
response.preset += `,-map 0 -c:v hevc_nvenc -pix_fmt p010le -rc:v vbr_hq -qmin 0 -cq:v 31 -b:v ${bitratetarget}k -maxrate:v ${bitratemax}k -preset slow -rc-lookahead 32 -spatial_aq:v 1 -aq-strength:v 8 -a53cc 0 -c:a copy ${subcli} -dn`;
response.preset += `,${map} -dn -c:v hevc_nvenc -pix_fmt p010le -rc:v vbr_hq -qmin 0 -cq:V 31 -b:v ${bitratetarget}k -maxrate:v ${bitratemax}k -preset slow -rc-lookahead 32 -spatial_aq:v 1 -aq-strength:v 8 -a53cc 0 -c:a copy ${subcli}${maxmux}`;
transcode = 1;
}
//file will be encoded if the resolution is 4K
@ -145,25 +164,9 @@ function plugin(file) {
bitratetarget = 14000;
bitratemax = 20000;
}
response.preset += `,-map 0 -c:v hevc_nvenc -pix_fmt p010le -rc:v vbr_hq -qmin 0 -cq:v 31 -b:v ${bitratetarget}k -maxrate:v ${bitratemax}k -preset slow -rc-lookahead 32 -spatial_aq:v 1 -aq-strength:v 8 -a53cc 0 -c:a copy -c:s copy -dn`;
response.preset += `,${map} -dn -c:v hevc_nvenc -pix_fmt p010le -rc:v vbr_hq -qmin 0 -cq:v 31 -b:v ${bitratetarget}k -maxrate:v ${bitratemax}k -preset slow -rc-lookahead 32 -spatial_aq:v 1 -aq-strength:v 8 -a53cc 0 -c:a copy ${subcli}${maxmux}`;
transcode = 1;
}
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
try {
//mitigate TrueHD audio causing Too many packets error
if (file.ffProbeData.streams[i].codec_name.toLowerCase() == "truehd" && file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" ) {
response.preset += ` -max_muxing_queue_size 1024`
}
}
catch (err) { }
//mitigate errors due to embeded pictures
try {
if ((file.ffProbeData.streams[i].codec_name.toLowerCase() == "png" || file.ffProbeData.streams[i].codec_name.toLowerCase() == "bmp" || file.ffProbeData.streams[i].codec_name.toLowerCase() == "mjpeg") && file.ffProbeData.streams[i].codec_type.toLowerCase() == "video" ) {
response.preset += ` -map -0:v:1`
}
}
catch (err) { }
}
//check if the file is eligible for transcoding
//if true the neccessary response values will be changed
if (transcode == 1) {

View file

@ -7,6 +7,7 @@ function details() {
Operation:"",
Description: `Checks if file is not a video file due to Mjpeg stream. Removes Mjpeg Stream \n\n`,
Version: "1.00",
Tags:'pre-processing,ffmpeg,'
}
}

View file

@ -0,0 +1,194 @@
function details() {
return {
id: "Tdarr_Plugin_da11_Dallas_FFmpeg_Presets_H264_MP4",
Stage: "Pre-processing",
Name: "Dallas FFmpeg h264 mp4. Video: h264/mp4, Subs: Convert to mov_text or drop, Audio: aac",
Type: "Video",
Description: `This plugin transcodes into H264 with an MP4 container using the FFmpeg preset you select (slow,medium,fast,veryfast). It maintains all compatible subtitles and audio tracks. Drops picture tracks such as mjpeg\n\n`,
Version: "1.00",
Link: "https://github.com/JackDallas/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_da11_Dallas_FFmpeg_Presets_H264_MP4.js",
Tags:'pre-processing,ffmpeg,h264,video only,configurable',
Inputs: [
{
name: 'FFmpeg_preset',
tooltip: `Select the FFmpeg preset you wish to use,(slow,medium,fast,veryfast).
\\nExample:\\n
slow
\\nExample:\\n
medium
\\nExample:\\n
fast
\\nExample:\\n
veryfast`
}
]
};
}
const presets = [
"slow", "medium", "fast", "veryfast"
];
// Normalizes the preset or if invalid returns null
function getPreset(preset) {
if (!preset)
return null;
preset = preset.toLowerCase();
// Strip Spaces
preset = preset.replace(/\s+/g, '');
if (presets.includes(preset)) {
return preset;
}
return null;
}
const GOOD = true;
const BAD = false;
function plugin(file, librarySettings, inputs) {
var response = {
processFile: false,
preset: '',
container: '.mp4',
handBrakeMode: false,
FFmpegMode: false,
reQueueAfter: false,
infoLog: '',
addInfo(status, info) {
this.infoLog += (status ? "☑" : "☒") + " " + info + "\n";
}
}
// Check the file is a video
if (file.fileMedium !== "video") {
console.log("File is not video");
response.addInfo(BAD, `File is not video`);
response.processFile = false;
return response;
}
// Get and check the preset
let preset = getPreset(inputs.FFmpeg_preset);
if (preset === null) {
response.addInfo(BAD, `Invalid Preset, \"${inputs.FFmpeg_preset}\" please select from (slow,medium,fast,veryfast)`);
throw `Error: Invalid Preset, \"${inputs.FFmpeg_preset}\" please select from (slow,medium,fast,veryfast) \n`
}
var jsonString = JSON.stringify(file)
var hasSubs = false;
var hasBadSubs = false;
var subType = "-c:s mov_text";
var subMap = "";
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
try {
let streamData = file.ffProbeData.streams[i];
if (streamData.codec_type.toLowerCase() == "subtitle") {
if (streamData.codec_name === "hdmv_pgs_subtitle" || streamData.codec_name === "dvd_subtitle") {
hasBadSubs = true;
// Drop incompatible subs
subMap += " -map -0:" + streamData.index + " ";
} else if (streamData.codec_name != "mov_text") {
hasSubs = true
// Keep compatible subs
subMap += " -map 0:" + streamData.index + " ";
}
}
} catch (err) {
console.log("Error reading stream: " + JSON.stringify(err));
}
}
if (hasBadSubs)
response.addInfo(BAD, "File contains unsupported sub(s), dropping these!");
if (file.ffProbeData.streams[0].codec_name != 'h264') {
response.addInfo(BAD, "File is not in h264!");
response.preset = ', -map_metadata -1 -map 0:V ' + subMap + ' -map 0:a -c:v libx264 -preset medium -c:a aac -strict -2 ' + subType;
response.reQueueAfter = true;
response.processFile = true;
response.FFmpegMode = true;
return response;
} else {
response.addInfo(GOOD, "File is already in h264!");
}
if ((file.meta.Title != undefined) && !jsonString.includes("aac") && hasSubs) {
response.addInfo(BAD, "File has title metadata and no aac and subs");
response.preset = ', -map_metadata -1 -map 0:v ' + subMap + ' -map 0:a -c:v copy -c:a aac -strict -2 ' + subType;
response.reQueueAfter = true;
response.processFile = true;
response.FFmpegMode = true;
return response
}
if (!jsonString.includes("aac") && hasSubs) {
response.addInfo(BAD, "File has no aac track and has subs");
response.preset = ', -map 0:v ' + subMap + ' -map 0:a -c:v copy -c:a aac -strict -2 ' + subType;
response.reQueueAfter = true;
response.processFile = true;
response.FFmpegMode = true;
return response;
}
if (file.meta.Title != undefined && hasSubs) {
response.addInfo(BAD, "File has title and has subs");
response.preset = ', -map_metadata -1 -map 0:v ' + subMap + ' -map 0:a -c:v copy -c:a copy ' + subType;
response.reQueueAfter = true;
response.processFile = true;
response.FFmpegMode = true;
return response;
}
if (file.meta.Title != undefined) {
response.addInfo(BAD, "File has title metadata");
response.preset = ', -map_metadata -1 -map 0:v ' + subMap + ' -map 0:a -c:v copy -c:a copy ' + subType;
response.reQueueAfter = true;
response.processFile = true;
response.FFmpegMode = true;
return response;
} else {
response.addInfo(GOOD, "File has no title metadata");
}
if (!jsonString.includes("aac")) {
response.addInfo(BAD, "File has no aac track");
response.preset = ', -map 0:v ' + subMap + ' -map 0:a -c:v copy -c:a aac -strict -2 ' + subType;
response.reQueueAfter = true;
response.processFile = true;
response.FFmpegMode = true;
return response;
} else {
response.addInfo(GOOD, "File has aac track");
}
if (hasSubs) {
if (hasBadSubs) {
response.addInfo(BAD, "File has incompatible subs, dropping these...");
} else {
response.addInfo(BAD, "File has compatible subs, copying...");
}
response.preset = ', -map 0:v ' + subMap + ' -map 0:a -c:v copy -c:a copy ' + subType;
response.processFile = true;
response.FFmpegMode = true
return response
} else {
response.addInfo(GOOD, "File has no/compatible subs");
}
response.addInfo(GOOD, "File meets conditions!");
return response
}
module.exports.details = details;
module.exports.plugin = plugin;

View file

@ -11,7 +11,8 @@ function details() {
Description: `[Contains built-in filter] This plugin removes subs, metadata (if a title exists) and makes sure the video is h264 480p mkv. \n\n
`,
Version: "1.00",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_e3jc_Tharic_H.264_MKV_480p30_No_Subs_No_Title_Meta.js"
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_e3jc_Tharic_H.264_MKV_480p30_No_Subs_No_Title_Meta.js",
Tags:'pre-processing,handbrake,ffmpeg,h264'
}
}

View file

@ -11,7 +11,8 @@ function details() {
Description: `[Contains built-in filter] This plugin removes subs, metadata (if a title exists) and makes sure the video is h264 720p mkv. \n\n
`,
Version: "1.00",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_e3jd_Tharic_H.264_MKV_720p30_No_Subs_No_Title_Meta.js"
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_e3jd_Tharic_H.264_MKV_720p30_No_Subs_No_Title_Meta.js",
Tags:'pre-processing,handbrake,ffmpeg,h264'
}
}

View file

@ -11,7 +11,8 @@ function details() {
Description: `[Contains built-in filter] This plugin removes subs, metadata (if a title exists) and makes sure the video is h264 1080p mkv. \n\n
`,
Version: "1.00",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_e3je_Tharic_H.264_MKV_1080p30_No_Subs_No_Title_Meta.js"
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_e3je_Tharic_H.264_MKV_1080p30_No_Subs_No_Title_Meta.js",
Tags:'pre-processing,handbrake,ffmpeg,h264'
}
}

View file

@ -11,10 +11,11 @@ function details() {
Description: `This plugin will check for subtitles, they should be named according to the ISO 639-2 language code.\nA subtitle could look like this: eng.srt\n If there are subtitles found they will be added with FFMPEG, if there are no subs of that language found.\n On first run node module iso-639-2 will be installed in the documents folder.\n Created by @control#0405`,
Version: "1.3",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_e5c3_CnT_Add_Subtitles.js",
Tags:'pre-processing,ffmpeg,subtitle only,configurable',
Inputs: [
{
name: 'install_packages',
tooltip: `Please change this to "yes", it allows the plugin to install the required nodemodule. (iso-639-2)`
tooltip: `Please change this to "yes", it allows the plugin to install the required nodemodule. (iso-639-2) \\nExample:\\n yes`
},
{
name: 'container',

View file

@ -8,10 +8,10 @@ function details() {
Stage: "Pre-processing",
Name: "Sparticus 4K +AC3 No Subs Original container",
Type: "Video",
Description: `[Contains built-in filter] This plugin for 4K video removes subs. If no AC3 track exists, it adds one (max 5.1 channels). If only an AC3 commentary track exists, it adds a new AC3 main track (max 5.1 channels). The output container is the same as the original file. \n\n
`,
Description: `[Contains built-in filter] This plugin for 4K video removes subs. If no AC3 track exists, it adds one (max 5.1 channels). If only an AC3 commentary track exists, it adds a new AC3 main track (max 5.1 channels). The output container is the same as the original file. \n\n`,
Version: "1.04",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_fd5T_Sparticus_4K_AC3_No_Subs.js"
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_fd5T_Sparticus_4K_AC3_No_Subs.js",
Tags:'pre-processing,ffmpeg',
}
}

View file

@ -11,7 +11,8 @@ function details() {
Description: `[Contains built-in filter] This plugin removes subs, metadata (if a title exists) and adds a stereo 192kbit AAC track if an AAC track (English or any) doesn't exist. The output container is mp4. \n\n
`,
Version: "1.07",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_hk75_Drawmonster_MP4_AAC_No_Subs_No_metaTitle.js"
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_hk75_Drawmonster_MP4_AAC_No_Subs_No_metaTitle.js",
Tags:'pre-processing,ffmpeg',
}
}

View file

@ -11,7 +11,8 @@ function details() {
Description: `[Contains built-in filter] This plugin removes metadata (if a title exists) and adds a stereo 192kbit AAC track if an AAC track (any) doesn't exist. The output container is mp4. \n\n
`,
Version: "1.01",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_hk76_GilbN_MP4_AAC_No_metaTitle.js"
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_hk76_GilbN_MP4_AAC_No_metaTitle.js",
Tags:'pre-processing,ffmpeg',
}
}

View file

@ -7,7 +7,8 @@ function details() {
Type: "Video",
Description: `[Contains built-in filter] This plugin will move the video stream to the front so Tdarr will recognize the codec correctly.\n\n`,
Version: "1.00",
Link: "https://github.com/luigi311/Tdarr_Plugin_lmg1_Reorder_Streams"
Link: "https://github.com/luigi311/Tdarr_Plugin_lmg1_Reorder_Streams",
Tags:'pre-processing,ffmpeg',
}
}

View file

@ -11,7 +11,8 @@ function details() {
Description: `[Contains built-in filter] This plugin removes metadata (if a title exists). The output container is the same as the original. \n\n
`,
Version: "1.00",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_nc7x_Drawmonster_No_Title_Meta.js"
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_nc7x_Drawmonster_No_Title_Meta.js",
Tags:'pre-processing,ffmpeg',
}
}

View file

@ -0,0 +1,66 @@
function details() {
return {
id: "Tdarr_Plugin_r002_rootuser_FFMPEG_HQ_HEVC_MKV_Animation",
Stage: "Pre-processing",
Name: "FFMPEG HQ 10-bit HEVC MKV for Animation",
Type: "Video",
Operation:"Transcode",
Description: `[Contains built-in filter] High Quality FFMPEG transcoding settings for Animation. Converts all audio to AAC 512K. Preserves track names, metadata and attachments/fonts. Proper use of x265-params. CRF 18. Preset medium. 10-Bit Video encoding. Skips h.265 encoded videos. The output container is mkv. \n\n`,
Version: "1.1",
Link: "",
Tags:"pre-processing,ffmpeg,h265,aac,10bit,anime,"
}
}
function plugin(file) {
var transcode = 0; //if this var changes to 1 the file will be transcoded
//default values that will be returned
var response = {
processFile: false,
preset: '',
container: '.mkv',
handBrakeMode: false,
FFmpegMode: true,
reQueueAfter: true,
infoLog: ''
}
//check if the file is a video, if not the function will be stopped immediately
if (file.fileMedium !== "video") {
response.processFile = false
response.infoLog += "☒File is not a video! \n"
return response
} else {
response.infoLog += "☑File is a video! \n"
}
//check if the file is already hevc, it will not be transcoded if true and the function will be stopped immediately
if (file.ffProbeData.streams[0].codec_name == 'hevc') {
response.processFile = false
response.infoLog += "☑File is already in hevc! \n"
return response
}
//Transcoding options
{
response.preset = ',-map 0 -c:s copy -movflags use_metadata_tags -c:a aac -b:a 512k -c:v:0 libx265 -preset medium -x265-params crf=18:tune=animation:qcomp=0.7:aq-strength=1.1 -pix_fmt yuv420p10le -f matroska'
transcode = 1;
}
//check if the file is eligible for transcoding
//if true the neccessary response values will be changed
if (transcode == 1) {
response.processFile = true;
response.FFmpegMode = true
response.reQueueAfter = true;
response.infoLog += `☒File is ${file.video_resolution} but is not hevc!\n`
response.infoLog += `☒File will be transcoded!\n`
}
return response
}
module.exports.details = details;
module.exports.plugin = plugin;

View file

@ -0,0 +1,171 @@
function details() {
return {
id: "Tdarr_Plugin_raf4_Floorpie_FFmpeg_Tiered_HEVC_MKV",
Stage: "Pre-processing",
Name: "FFmpeg Tiered HEVC MKV",
Type: "Video",
Operation:"Transcode",
Description: `[Contains built-in filter] This plugin uses different FFmpeg transcoding settings for 480p,576p,720p and 1080p. If files are not in hevc they will be transcoded. The output container is mkv. \n\n`,
Version: "1.01",
Link: "",
Tags:"pre-processing,ffmpeg,h265,video only,"
}
}
function plugin(file) {
var transcode = 0; //if this var changes to 1 the file will be transcoded
//default values that will be returned
var response = {
processFile: false,
preset: '',
container: '.mkv',
handBrakeMode: false,
FFmpegMode: true,
reQueueAfter: true,
infoLog: ''
}
//check if the file is a video, if not the function will be stopped immediately
if (file.fileMedium !== "video") {
response.processFile = false
response.infoLog += "☒File is not a video! \n"
return response
} else {
response.infoLog += "☑File is a video! \n"
}
//check if the file is already hevc, it will not be transcoded if true and the function will be stopped immediately
if (file.ffProbeData.streams[0].codec_name == 'hevc') {
response.processFile = false
response.infoLog += "☑File is already in hevc! \n"
return response
}
//file will be encoded if the resolution is 480p or 576p
//codec will be checked so it can be transcoded correctly
if(file.video_resolution === "480p" || file.video_resolution === "576p" ) {
if (file.video_codec_name == 'h263') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 27'
}
else if (file.video_codec_name == 'h264') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 27'
}
else if (file.video_codec_name == 'mjpeg') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 27'
}
else if (file.video_codec_name == 'mpeg1') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 27'
}
else if (file.video_codec_name == 'mpeg2') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 27'
}
else if (file.video_codec_name == 'mpeg4') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 27'
}
else if (file.video_codec_name == 'vc1') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 27'
}
else if (file.video_codec_name == 'vp8') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 27'
}
else if (file.video_codec_name == 'vp9') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 27'
}
else {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 27'
}
transcode = 1;
}
//file will be encoded if the resolution is 720p
//codec will be checked so it can be transcoded correctly
if(file.video_resolution === "720p") {
if (file.video_codec_name == 'h263') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 25'
}
else if (file.video_codec_name == 'h264') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 25'
}
else if (file.video_codec_name == 'mjpeg') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 25'
}
else if (file.video_codec_name == 'mpeg1') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 25'
}
else if (file.video_codec_name == 'mpeg2') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 25'
}
else if (file.video_codec_name == 'mpeg4') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 25'
}
else if (file.video_codec_name == 'vc1') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 25'
}
else if (file.video_codec_name == 'vp8') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 25'
}
else if (file.video_codec_name == 'vp9') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 25'
}
else {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 25'
}
transcode = 1;
}
//file will be encoded if the resolution is 1080p
//codec will be checked so it can be transcoded correctly
if(file.video_resolution === "1080p") {
if (file.video_codec_name == 'h263') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 23'
}
else if (file.video_codec_name == 'h264') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 23'
}
else if (file.video_codec_name == 'mjpeg') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 23'
}
else if (file.video_codec_name == 'mpeg1') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 23'
}
else if (file.video_codec_name == 'mpeg2') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 23'
}
else if (file.video_codec_name == 'mpeg4') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 23'
}
else if (file.video_codec_name == 'vc1') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 23'
}
else if (file.video_codec_name == 'vp8') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 23'
}
else if (file.video_codec_name == 'vp9') {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 23'
}
else {
response.preset = ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 23'
}
transcode = 1;
}
//check if the file is eligible for transcoding
//if true the neccessary response values will be changed
if (transcode == 1) {
response.processFile = true;
response.FFmpegMode = true
response.reQueueAfter = true;
response.infoLog += `☒File is ${file.video_resolution} but is not hevc!\n`
response.infoLog += `☒File will be transcoded!\n`
}
return response
}
module.exports.details = details;
module.exports.plugin = plugin;

View file

@ -11,7 +11,8 @@ function details() {
Description: `[Contains built-in filter] This plugin transcodes all 4K videos to h265 using nvenc (if not in h265 already). For 4K and files in other resolutions: If not in mkv the file is remuxed into mkv. If the English language track is not in AC3,EAC3 or DTS then an AC3 track is added.\n\n
`,
Version: "1.00",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_s710_nick_h265_nvenc_4K.js"
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_s710_nick_h265_nvenc_4K.js",
Tags:'pre-processing,ffmpeg,nvenc h265',
}
}

View file

@ -11,7 +11,8 @@ function details() {
Description: `[Contains built-in filter] This plugin transcodes all videos to h265 (if not in h265 already) and remuxes if not in mkv. If the English language track is not in AC3,EAC3 or DTS then an AC3 track is added.\n\n
`,
Version: "1.00",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_s7x8_winsome_h265.js"
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_s7x8_winsome_h265.js",
Tags:'pre-processing,handbrake,ffmpeg,h265',
}
}

View file

@ -11,7 +11,8 @@ function details() {
Description: `[Contains built-in filter] This plugin transcodes all videos to h265 10 bit (if not in h265 already) and remuxes if not in mkv. If the English language track is not in AC3,EAC3 or DTS then an AC3 track is added.\n\n
`,
Version: "1.00",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_s7x9_winsome_h265_10bit.js"
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_s7x9_winsome_h265_10bit.js",
Tags:'pre-processing,handbrake,ffmpeg,h265',
}
}

View file

@ -11,7 +11,8 @@ function details() {
Description: `[Contains built-in filter] This plugin transcodes all videos to h265 using nvenc (if not in h265 already) and remuxes if not in mkv. If the English language track is not in AC3,EAC3 or DTS then an AC3 track is added.\n\n
`,
Version: "1.00",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_s7x9_winsome_h265_nvenc.js"
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_s7x9_winsome_h265_nvenc.js",
Tags:'pre-processing,handbrake,ffmpeg,nvenc h265',
}
}

View file

@ -11,7 +11,8 @@ function details() {
Operation: "Remux",
Description: `[Contains built-in filter] If commentary tracks are detected, they will be removed. \n\n`,
Version: "1.00",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_sdd3_Remove_Commentary_Tracks.js"
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_sdd3_Remove_Commentary_Tracks.js",
Tags:'pre-processing,ffmpeg,audio only',
}
}

View file

@ -11,7 +11,8 @@ function details() {
Description: `[Contains built-in filter] This plugin removes audio tracks which are not English or are not undefined. It ensures at least 1 audio track is left in any language. \n\n
`,
Version: "1.00",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_sdf5_Thierrrrry_Remove_Non_English_Audio.js"
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_sdf5_Thierrrrry_Remove_Non_English_Audio.js",
Tags:'pre-processing,ffmpeg,audio only',
}
}

View file

@ -10,7 +10,8 @@ function details() {
Type: "Video",
Description: `[Contains built-in filter] This plugin removes subtitles if detected. The output container is the same as the original. \n\n`,
Version: "1.00",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_x7ab_Remove_Subs.js"
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_x7ab_Remove_Subs.js",
Tags:'pre-processing,ffmpeg,subtitle only',
}
}

View file

@ -10,7 +10,8 @@ function details() {
Operation: "Remux",
Description: "[Contains built-in filter] If detected, closed captions (XDS,608,708) will be removed.",
Version: "1.00",
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_x7ac_Remove_Closed_Captions.js"
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_x7ac_Remove_Closed_Captions.js",
Tags:'pre-processing,ffmpeg,subtitle only',
}

View file

@ -8,10 +8,11 @@ function details() {
Stage: "Pre-processing",
Name: "TheRealShadoh FFmpeg Subs Medium, video MP4, audio AAC, keep subs. ",
Type: "Video",
Description: `[BUG][Contains built-in filter] This plugin transcodes into H264 using FFmpeg's 'Medium' preset if the file is not in H264 already. It maintains all subtitles. It removes metadata (if a title exists), and maintains all audio tracks. The output container is MP4. \n\n
Description: `[Contains built-in filter] This plugin transcodes into H264 using FFmpeg's 'Medium' preset if the file is not in H264 already. It maintains all subtitles. It removes metadata (if a title exists), and maintains all audio tracks. The output container is MP4. \n\n
`,
Version: "1.00",
Link: "https://github.com/TheRealShadoh/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_z0ab_TheRealShadoh_FFmpeg_Subs_H264_Medium.js"
Link: "https://github.com/TheRealShadoh/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_z0ab_TheRealShadoh_FFmpeg_Subs_H264_Medium.js",
Tags:'pre-processing,ffmpeg,h264',
}
}

View file

@ -0,0 +1,72 @@
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: "",
Tags:"post-processing",
}
}
module.exports.plugin = function plugin(file, librarySettings, inputs) {
try {
var fs = require('fs');
var path = require('path');
if (fs.existsSync(path.join(process.cwd() , '/npm'))) {
var rootModules = path.join(process.cwd() , '/npm/node_modules/')
} else{
var rootModules = ''
}
var fsextra = require(rootModules+'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) }
}

View file

@ -8,10 +8,11 @@ function details() {
Stage: "Pre-processing",
Name: "TheRealShadoh FFmpeg Subs Fast, video MP4, audio AAC, keep subs. ",
Type: "Video",
Description: `[BUG][Contains built-in filter] This plugin transcodes into H264 using FFmpeg's 'Fast' preset if the file is not in H264 already. It maintains all subtitles. It removes metadata (if a title exists), and maintains all audio tracks. The output container is MP4. \n\n
Description: `[Contains built-in filter] This plugin transcodes into H264 using FFmpeg's 'Fast' preset if the file is not in H264 already. It maintains all subtitles. It removes metadata (if a title exists), and maintains all audio tracks. The output container is MP4. \n\n
`,
Version: "1.00",
Link: "https://github.com/TheRealShadoh/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_z1ab_TheRealShadoh_FFmpeg_Subs_H264_Fast.js"
Link: "https://github.com/TheRealShadoh/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_z1ab_TheRealShadoh_FFmpeg_Subs_H264_Fast.js",
Tags:'pre-processing,ffmpeg,h264',
}
}

View file

@ -8,10 +8,11 @@ function details() {
Stage: "Pre-processing",
Name: "TheRealShadoh FFmpeg Subs Slow, video MP4, audio AAC, keep subs. ",
Type: "Video",
Description: `[BUG][Contains built-in filter] This plugin transcodes into H264 using FFmpeg's 'Slow' preset if the file is not in H264 already. It maintains all subtitles. It removes metadata (if a title exists), and maintains all audio tracks. The output container is MP4. \n\n
Description: `[Contains built-in filter] This plugin transcodes into H264 using FFmpeg's 'Slow' preset if the file is not in H264 already. It maintains all subtitles. It removes metadata (if a title exists), and maintains all audio tracks. The output container is MP4. \n\n
`,
Version: "1.00",
Link: "https://github.com/TheRealShadoh/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_z2ab_TheRealShadoh_FFmpeg_Subs_H264_Slow.js"
Link: "https://github.com/TheRealShadoh/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_z2ab_TheRealShadoh_FFmpeg_Subs_H264_Slow.js",
Tags:'pre-processing,ffmpeg,h264',
}
}

View file

@ -8,10 +8,11 @@ function details() {
Stage: "Pre-processing",
Name: "TheRealShadoh FFmpeg Subs VeryFast, video MP4, audio AAC, keep subs. ",
Type: "Video",
Description: `[BUG][Contains built-in filter] This plugin transcodes into H264 using FFmpeg's 'VeryFast' preset if the file is not in H264 already. It maintains all subtitles. It removes metadata (if a title exists), and maintains all audio tracks. The output container is MP4. \n\n
Description: `[Contains built-in filter] This plugin transcodes into H264 using FFmpeg's 'VeryFast' preset if the file is not in H264 already. It maintains all subtitles. It removes metadata (if a title exists), and maintains all audio tracks. The output container is MP4. \n\n
`,
Version: "1.00",
Link: "https://github.com/TheRealShadoh/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_z3ab_TheRealShadoh_FFmpeg_Subs_H264_Veryfast.js"
Link: "https://github.com/TheRealShadoh/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_z3ab_TheRealShadoh_FFmpeg_Subs_H264_Veryfast.js",
Tags:'pre-processing,ffmpeg,h264',
}
}