mirror of
https://github.com/gabehf/Tdarr_Plugins.git
synced 2026-03-16 10:45:53 -07:00
New
This commit is contained in:
parent
270f35004b
commit
1620b32fc2
4 changed files with 568 additions and 0 deletions
195
Community/Tdarr_Plugin_075a_Transcode_Customisable.js
Normal file
195
Community/Tdarr_Plugin_075a_Transcode_Customisable.js
Normal file
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
154
Community/Tdarr_Plugin_076a_re_order_audio_streams.js
Normal file
154
Community/Tdarr_Plugin_076a_re_order_audio_streams.js
Normal file
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
156
Community/Tdarr_Plugin_076b_re_order_subtitle_streams.js
Normal file
156
Community/Tdarr_Plugin_076b_re_order_subtitle_streams.js
Normal file
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
63
Community/Tdarr_Plugin_z18s_rename_files_based_on_codec.js
Normal file
63
Community/Tdarr_Plugin_z18s_rename_files_based_on_codec.js
Normal file
|
|
@ -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) }
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue