mirror of
https://github.com/gabehf/Tdarr_Plugins.git
synced 2026-03-17 03:06:27 -07:00
tidy
This commit is contained in:
parent
d28272f6d4
commit
9c8ac98728
60 changed files with 5481 additions and 5980 deletions
4
.prettierignore
Normal file
4
.prettierignore
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
node_modules/
|
||||||
|
.github/
|
||||||
|
|
||||||
|
# npx prettier@2.0.5 . --write
|
||||||
|
|
@ -1,178 +1,190 @@
|
||||||
function details() {
|
function details() {
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_MC93_Migz1FFMPEG",
|
id: "Tdarr_Plugin_MC93_Migz1FFMPEG",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
Name: "Migz-Transcode Using Nvidia GPU & FFMPEG",
|
Name: "Migz-Transcode Using Nvidia GPU & FFMPEG",
|
||||||
Type: "Video",
|
Type: "Video",
|
||||||
Operation: "Transcode",
|
Operation: "Transcode",
|
||||||
Description: `Files not in H265 will be transcoded into H265 using Nvidia GPU with ffmpeg, settings are dependant on file bitrate, working by the logic that H265 can support the same ammount of data at half the bitrate of H264. NVDEC & NVENC compatable GPU required. \n\n`,
|
Description: `Files not in H265 will be transcoded into H265 using Nvidia GPU with ffmpeg, settings are dependant on file bitrate, working by the logic that H265 can support the same ammount of data at half the bitrate of H264. NVDEC & NVENC compatable GPU required. \n\n`,
|
||||||
Version: "2.4",
|
Version: "2.4",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_Migz1FFMPEG.js",
|
Link:
|
||||||
Tags: 'pre-processing,ffmpeg,video only,nvenc h265,configurable',
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_Migz1FFMPEG.js",
|
||||||
Inputs: [{
|
Tags: "pre-processing,ffmpeg,video only,nvenc h265,configurable",
|
||||||
name: 'container',
|
Inputs: [
|
||||||
tooltip: `Specify output container of file, ensure that all stream types you may have are supported by your chosen container. mkv is recommended.
|
{
|
||||||
|
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
|
\\nExample:\\n
|
||||||
mkv
|
mkv
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
mp4`
|
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.
|
||||||
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
|
\\nExample:\\n
|
||||||
6000
|
6000
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
4000`
|
4000`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'enable_10bit',
|
name: "enable_10bit",
|
||||||
tooltip: `Specify if output file should be 10bit. Default is false.
|
tooltip: `Specify if output file should be 10bit. Default is false.
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
true
|
true
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
false`
|
false`,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file, librarySettings, inputs) {
|
function plugin(file, librarySettings, inputs) {
|
||||||
var response = {
|
var response = {
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: true,
|
FFmpegMode: true,
|
||||||
reQueueAfter: true,
|
reQueueAfter: true,
|
||||||
infoLog: ''
|
infoLog: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check if inputs.container has been configured. If it hasn't then exit plugin.
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if file is MKV, if so then add extra argument to drop data. MKV does not support data streams.
|
||||||
|
if (inputs.container == "mkv") {
|
||||||
|
extraArguments += "-map -0:d ";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if file is a video. If it isn't then exit plugin.
|
||||||
|
if (file.fileMedium !== "video") {
|
||||||
|
response.processFile = false;
|
||||||
|
response.infoLog += "☒File is not a video. \n";
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if duration info is filled, if so times it by 0.0166667 to get time in minutes. If not filled then get duration of stream 0 and do the same.
|
||||||
|
if (typeof file.meta.Duration != "undefined") {
|
||||||
|
var duration = file.meta.Duration * 0.0166667;
|
||||||
|
} else {
|
||||||
|
var duration = file.ffProbeData.streams[0].duration * 0.0166667;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up required variables.
|
||||||
|
var videoIdx = 0;
|
||||||
|
var extraArguments = "";
|
||||||
|
var bitrateSettings = "";
|
||||||
|
// Work out currentBitrate using "Bitrate = file size / (number of minutes * .0075)" - Used from here https://blog.frame.io/2017/03/06/calculate-video-bitrates/
|
||||||
|
var currentBitrate = ~~(file.file_size / (duration * 0.0075));
|
||||||
|
// Use the same calculation used for currentBitrate but divide it in half to get targetBitrate. Logic of h265 can be half the bitrate as h264 without losing quality.
|
||||||
|
var targetBitrate = ~~(file.file_size / (duration * 0.0075) / 2);
|
||||||
|
// Allow some leeway under and over the targetBitrate.
|
||||||
|
var minimumBitrate = ~~(targetBitrate * 0.7);
|
||||||
|
var maximumBitrate = ~~(targetBitrate * 1.3);
|
||||||
|
|
||||||
|
// If targetBitrate comes out as 0 then something has gone wrong and bitrates could not be calculcated. Cancel plugin completely.
|
||||||
|
if (targetBitrate == "0") {
|
||||||
|
response.processFile = false;
|
||||||
|
response.infoLog +=
|
||||||
|
"☒Target bitrate could not be calculated. Skipping this plugin. \n";
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if inputs.bitrate cutoff has something entered (Entered means user actually wants something to happen, empty would disable this).
|
||||||
|
if (inputs.bitrate_cutoff != "") {
|
||||||
|
// Checks if currentBitrate is below inputs.bitrate_cutoff, if so then cancel plugin without touching original files.
|
||||||
|
if (currentBitrate <= inputs.bitrate_cutoff) {
|
||||||
|
response.processFile = false;
|
||||||
|
response.infoLog += `☑Current bitrate is below configured bitrate cutoff of ${inputs.bitrate_cutoff}. Nothing to do, cancelling plugin. \n`;
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check if inputs.container has been configured. If it hasn't then exit plugin.
|
// Check if 10bit variable is true.
|
||||||
if (inputs.container == "") {
|
if (inputs.enable_10bit == "true") {
|
||||||
response.infoLog += "☒Container has not been configured within plugin settings, please configure required options. Skipping this plugin. \n"
|
// If set to true then add 10bit argument
|
||||||
response.processFile = false
|
extraArguments += `-pix_fmt p010le `;
|
||||||
return response
|
}
|
||||||
} else {
|
|
||||||
response.container = '.' + inputs.container
|
// Go through each stream in the file.
|
||||||
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
// Check if stream is a video.
|
||||||
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "video") {
|
||||||
|
// Check if codec of stream is mjpeg, if so then remove this "video" stream. mjpeg are usually imbedded pictures that can cause havoc with plugins.
|
||||||
|
if (file.ffProbeData.streams[i].codec_name == "mjpeg") {
|
||||||
|
extraArguments += `-map -v:${videoIdx} `;
|
||||||
|
}
|
||||||
|
// Check if codec of stream is hevc AND check if file.container matches inputs.container. If so nothing for plugin to do.
|
||||||
|
if (
|
||||||
|
file.ffProbeData.streams[i].codec_name == "hevc" &&
|
||||||
|
file.container == inputs.container
|
||||||
|
) {
|
||||||
|
response.processFile = false;
|
||||||
|
response.infoLog += `☑File is already hevc & in ${inputs.container}. \n`;
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
// Check if codec of stream is hevc AND check if file.container does NOT match inputs.container. If so remux file.
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
// Increment videoIdx.
|
||||||
|
videoIdx++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check if file is MKV, if so then add extra argument to drop data. MKV does not support data streams.
|
// Set bitrateSettings variable using bitrate information calulcated earlier.
|
||||||
if (inputs.container == "mkv") {
|
bitrateSettings = `-b:v ${targetBitrate}k -minrate ${minimumBitrate}k -maxrate ${maximumBitrate}k -bufsize ${currentBitrate}k`;
|
||||||
extraArguments += "-map -0:d "
|
// Print to infoLog information around file & bitrate settings.
|
||||||
|
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`;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if file is a video. If it isn't then exit plugin.
|
response.preset += `,-map 0 -c:v hevc_nvenc -rc:v vbr_hq -cq:v 19 ${bitrateSettings} -spatial_aq:v 1 -rc-lookahead:v 32 -c:a copy -c:s copy -max_muxing_queue_size 4096 ${extraArguments}`;
|
||||||
if (file.fileMedium !== "video") {
|
response.processFile = true;
|
||||||
response.processFile = false
|
response.infoLog += `☒File is not hevc. Transcoding. \n`;
|
||||||
response.infoLog += "☒File is not a video. \n"
|
return response;
|
||||||
return response
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if duration info is filled, if so times it by 0.0166667 to get time in minutes. If not filled then get duration of stream 0 and do the same.
|
|
||||||
if (typeof file.meta.Duration != 'undefined') {
|
|
||||||
var duration = (file.meta.Duration * 0.0166667)
|
|
||||||
} else {
|
|
||||||
var duration = (file.ffProbeData.streams[0].duration * 0.0166667)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up required variables.
|
|
||||||
var videoIdx = 0
|
|
||||||
var extraArguments = ""
|
|
||||||
var bitrateSettings = ""
|
|
||||||
// Work out currentBitrate using "Bitrate = file size / (number of minutes * .0075)" - Used from here https://blog.frame.io/2017/03/06/calculate-video-bitrates/
|
|
||||||
var currentBitrate = ~~(file.file_size / (duration * 0.0075))
|
|
||||||
// Use the same calculation used for currentBitrate but divide it in half to get targetBitrate. Logic of h265 can be half the bitrate as h264 without losing quality.
|
|
||||||
var targetBitrate = ~~((file.file_size / (duration * 0.0075)) / 2)
|
|
||||||
// Allow some leeway under and over the targetBitrate.
|
|
||||||
var minimumBitrate = ~~(targetBitrate * 0.7)
|
|
||||||
var maximumBitrate = ~~(targetBitrate * 1.3)
|
|
||||||
|
|
||||||
// If targetBitrate comes out as 0 then something has gone wrong and bitrates could not be calculcated. Cancel plugin completely.
|
|
||||||
if (targetBitrate == "0") {
|
|
||||||
response.processFile = false
|
|
||||||
response.infoLog += "☒Target bitrate could not be calculated. Skipping this plugin. \n"
|
|
||||||
return response
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if inputs.bitrate cutoff has something entered (Entered means user actually wants something to happen, empty would disable this).
|
|
||||||
if (inputs.bitrate_cutoff != "") {
|
|
||||||
// Checks if currentBitrate is below inputs.bitrate_cutoff, if so then cancel plugin without touching original files.
|
|
||||||
if (currentBitrate <= inputs.bitrate_cutoff) {
|
|
||||||
response.processFile = false
|
|
||||||
response.infoLog += `☑Current bitrate is below configured bitrate cutoff of ${inputs.bitrate_cutoff}. Nothing to do, cancelling plugin. \n`
|
|
||||||
return response
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if 10bit variable is true.
|
|
||||||
if (inputs.enable_10bit == "true") {
|
|
||||||
// If set to true then add 10bit argument
|
|
||||||
extraArguments += `-pix_fmt p010le `
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go through each stream in the file.
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
|
||||||
// Check if stream is a video.
|
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "video") {
|
|
||||||
|
|
||||||
// Check if codec of stream is mjpeg, if so then remove this "video" stream. mjpeg are usually imbedded pictures that can cause havoc with plugins.
|
|
||||||
if (file.ffProbeData.streams[i].codec_name == 'mjpeg') {
|
|
||||||
extraArguments += `-map -v:${videoIdx} `
|
|
||||||
}
|
|
||||||
// Check if codec of stream is hevc AND check if file.container matches inputs.container. If so nothing for plugin to do.
|
|
||||||
if (file.ffProbeData.streams[i].codec_name == 'hevc' && file.container == inputs.container) {
|
|
||||||
response.processFile = false
|
|
||||||
response.infoLog += `☑File is already hevc & in ${inputs.container}. \n`
|
|
||||||
return response
|
|
||||||
}
|
|
||||||
// Check if codec of stream is hevc AND check if file.container does NOT match inputs.container. If so remux file.
|
|
||||||
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
|
|
||||||
}
|
|
||||||
// Increment videoIdx.
|
|
||||||
videoIdx++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set bitrateSettings variable using bitrate information calulcated earlier.
|
|
||||||
bitrateSettings = `-b:v ${targetBitrate}k -minrate ${minimumBitrate}k -maxrate ${maximumBitrate}k -bufsize ${currentBitrate}k`
|
|
||||||
// Print to infoLog information around file & bitrate settings.
|
|
||||||
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 -cq:v 19 ${bitrateSettings} -spatial_aq:v 1 -rc-lookahead:v 32 -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.details = details;
|
||||||
module.exports.plugin = plugin;
|
module.exports.plugin = plugin;
|
||||||
|
|
@ -1,157 +1,168 @@
|
||||||
function details() {
|
function details() {
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_MC93_Migz1FFMPEG_CPU",
|
id: "Tdarr_Plugin_MC93_Migz1FFMPEG_CPU",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
Name: "Migz-Transcode Using CPU & FFMPEG",
|
Name: "Migz-Transcode Using CPU & FFMPEG",
|
||||||
Type: "Video",
|
Type: "Video",
|
||||||
Operation: "Transcode",
|
Operation: "Transcode",
|
||||||
Description: `Files not in H265 will be transcoded into H265 using CPU with ffmpeg, settings are dependant on file bitrate, working by the logic that H265 can support the same ammount of data at half the bitrate of H264. \n\n`,
|
Description: `Files not in H265 will be transcoded into H265 using CPU with ffmpeg, settings are dependant on file bitrate, working by the logic that H265 can support the same ammount of data at half the bitrate of H264. \n\n`,
|
||||||
Version: "1.3",
|
Version: "1.3",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_Migz1FFMPEG_CPU.js",
|
Link:
|
||||||
Tags: 'pre-processing,ffmpeg,video only,configurable,h265',
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_Migz1FFMPEG_CPU.js",
|
||||||
Inputs: [{
|
Tags: "pre-processing,ffmpeg,video only,configurable,h265",
|
||||||
name: 'container',
|
Inputs: [
|
||||||
tooltip: `Specify output container of file, ensure that all stream types you may have are supported by your chosen container. mkv is recommended.
|
{
|
||||||
|
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
|
\\nExample:\\n
|
||||||
mkv
|
mkv
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
mp4`
|
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.
|
||||||
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
|
\\nExample:\\n
|
||||||
6000
|
6000
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
4000`
|
4000`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'enable_10bit',
|
name: "enable_10bit",
|
||||||
tooltip: `Specify if output file should be 10bit. Default is false.
|
tooltip: `Specify if output file should be 10bit. Default is false.
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
true
|
true
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
false`
|
false`,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file, librarySettings, inputs) {
|
function plugin(file, librarySettings, inputs) {
|
||||||
var response = {
|
var response = {
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: true,
|
FFmpegMode: true,
|
||||||
reQueueAfter: true,
|
reQueueAfter: true,
|
||||||
infoLog: ''
|
infoLog: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check if inputs.container has been configured. If it hasn't then exit plugin.
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if file is MKV, if so then add extra argument to drop data. MKV does not support data streams.
|
||||||
|
if (inputs.container == "mkv") {
|
||||||
|
extraArguments += "-map -0:d ";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if file is a video. If it isn't then exit plugin.
|
||||||
|
if (file.fileMedium !== "video") {
|
||||||
|
response.processFile = false;
|
||||||
|
response.infoLog += "☒File is not a video. \n";
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if duration info is filled, if so times it by 0.0166667 to get time in minutes. If not filled then get duration of stream 0 and do the same.
|
||||||
|
if (typeof file.meta.Duration != "undefined") {
|
||||||
|
var duration = file.meta.Duration * 0.0166667;
|
||||||
|
} else {
|
||||||
|
var duration = file.ffProbeData.streams[0].duration * 0.0166667;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up required variables.
|
||||||
|
var videoIdx = -1;
|
||||||
|
var extraArguments = "";
|
||||||
|
var bitrateSettings = "";
|
||||||
|
// Work out currentBitrate using "Bitrate = file size / (number of minutes * .0075)" - Used from here https://blog.frame.io/2017/03/06/calculate-video-bitrates/
|
||||||
|
var currentBitrate = ~~(file.file_size / (duration * 0.0075));
|
||||||
|
// Use the same calculation used for currentBitrate but divide it in half to get targetBitrate. Logic of h265 can be half the bitrate as h264 without losing quality.
|
||||||
|
var targetBitrate = ~~(file.file_size / (duration * 0.0075) / 2);
|
||||||
|
// Allow some leeway under and over the targetBitrate.
|
||||||
|
var minimumBitrate = ~~(targetBitrate * 0.7);
|
||||||
|
var maximumBitrate = ~~(targetBitrate * 1.3);
|
||||||
|
|
||||||
|
// If targetBitrate comes out as 0 then something has gone wrong and bitrates could not be calculcated. Cancel plugin completely.
|
||||||
|
if (targetBitrate == "0") {
|
||||||
|
response.processFile = false;
|
||||||
|
response.infoLog +=
|
||||||
|
"☒Target bitrate could not be calculated. Skipping this plugin. \n";
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if inputs.bitrate cutoff has something entered (Entered means user actually wants something to happen, empty would disable this).
|
||||||
|
if (inputs.bitrate_cutoff != "") {
|
||||||
|
// Checks if currentBitrate is below inputs.bitrate_cutoff, if so then cancel plugin without touching original files.
|
||||||
|
if (currentBitrate <= inputs.bitrate_cutoff) {
|
||||||
|
response.processFile = false;
|
||||||
|
response.infoLog += `☑Current bitrate is below configured bitrate cutoff of ${inputs.bitrate_cutoff}. Nothing to do, cancelling plugin. \n`;
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check if inputs.container has been configured. If it hasn't then exit plugin.
|
// Check if 10bit variable is true.
|
||||||
if (inputs.container == "") {
|
if (inputs.enable_10bit == "true") {
|
||||||
response.infoLog += "☒Container has not been configured within plugin settings, please configure required options. Skipping this plugin. \n"
|
// If set to true then add 10bit argument
|
||||||
response.processFile = false
|
extraArguments += `-pix_fmt p010le `;
|
||||||
return response
|
}
|
||||||
} else {
|
|
||||||
response.container = '.' + inputs.container
|
// Go through each stream in the file.
|
||||||
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
// Check if stream is a video.
|
||||||
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "video") {
|
||||||
|
// Check if codec of stream is mjpeg, if so then remove this "video" stream. mjpeg are usually imbedded pictures that can cause havoc with plugins.
|
||||||
|
if (file.ffProbeData.streams[i].codec_name == "mjpeg") {
|
||||||
|
extraArguments += `-map -v:${videoIdx} `;
|
||||||
|
}
|
||||||
|
// Check if codec of stream is hevc AND check if file.container matches inputs.container. If so nothing for plugin to do.
|
||||||
|
if (
|
||||||
|
file.ffProbeData.streams[i].codec_name == "hevc" &&
|
||||||
|
file.container == inputs.container
|
||||||
|
) {
|
||||||
|
response.processFile = false;
|
||||||
|
response.infoLog += `☑File is already hevc & in ${inputs.container}. \n`;
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
// Check if codec of stream is hevc AND check if file.container does NOT match inputs.container. If so remux file.
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
// Increment videoIdx.
|
||||||
|
videoIdx++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check if file is MKV, if so then add extra argument to drop data. MKV does not support data streams.
|
// Set bitrateSettings variable using bitrate information calulcated earlier.
|
||||||
if (inputs.container == "mkv") {
|
bitrateSettings = `-b:v ${targetBitrate}k -minrate ${minimumBitrate}k -maxrate ${maximumBitrate}k -bufsize ${currentBitrate}k`;
|
||||||
extraArguments += "-map -0:d "
|
// Print to infoLog information around file & bitrate settings.
|
||||||
}
|
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`;
|
||||||
|
|
||||||
// Check if file is a video. If it isn't then exit plugin.
|
response.preset += `,-map 0 -c:v libx265 ${bitrateSettings} -c:a copy -c:s copy -max_muxing_queue_size 4096 ${extraArguments}`;
|
||||||
if (file.fileMedium !== "video") {
|
response.processFile = true;
|
||||||
response.processFile = false
|
response.infoLog += `☒File is not hevc. Transcoding. \n`;
|
||||||
response.infoLog += "☒File is not a video. \n"
|
return response;
|
||||||
return response
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if duration info is filled, if so times it by 0.0166667 to get time in minutes. If not filled then get duration of stream 0 and do the same.
|
|
||||||
if (typeof file.meta.Duration != 'undefined') {
|
|
||||||
var duration = (file.meta.Duration * 0.0166667)
|
|
||||||
} else {
|
|
||||||
var duration = (file.ffProbeData.streams[0].duration * 0.0166667)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up required variables.
|
|
||||||
var videoIdx = -1
|
|
||||||
var extraArguments = ""
|
|
||||||
var bitrateSettings = ""
|
|
||||||
// Work out currentBitrate using "Bitrate = file size / (number of minutes * .0075)" - Used from here https://blog.frame.io/2017/03/06/calculate-video-bitrates/
|
|
||||||
var currentBitrate = ~~(file.file_size / (duration * 0.0075))
|
|
||||||
// Use the same calculation used for currentBitrate but divide it in half to get targetBitrate. Logic of h265 can be half the bitrate as h264 without losing quality.
|
|
||||||
var targetBitrate = ~~((file.file_size / (duration * 0.0075)) / 2)
|
|
||||||
// Allow some leeway under and over the targetBitrate.
|
|
||||||
var minimumBitrate = ~~(targetBitrate * 0.7)
|
|
||||||
var maximumBitrate = ~~(targetBitrate * 1.3)
|
|
||||||
|
|
||||||
// If targetBitrate comes out as 0 then something has gone wrong and bitrates could not be calculcated. Cancel plugin completely.
|
|
||||||
if (targetBitrate == "0") {
|
|
||||||
response.processFile = false
|
|
||||||
response.infoLog += "☒Target bitrate could not be calculated. Skipping this plugin. \n"
|
|
||||||
return response
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if inputs.bitrate cutoff has something entered (Entered means user actually wants something to happen, empty would disable this).
|
|
||||||
if (inputs.bitrate_cutoff != "") {
|
|
||||||
// Checks if currentBitrate is below inputs.bitrate_cutoff, if so then cancel plugin without touching original files.
|
|
||||||
if (currentBitrate <= inputs.bitrate_cutoff) {
|
|
||||||
response.processFile = false
|
|
||||||
response.infoLog += `☑Current bitrate is below configured bitrate cutoff of ${inputs.bitrate_cutoff}. Nothing to do, cancelling plugin. \n`
|
|
||||||
return response
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if 10bit variable is true.
|
|
||||||
if (inputs.enable_10bit == "true") {
|
|
||||||
// If set to true then add 10bit argument
|
|
||||||
extraArguments += `-pix_fmt p010le `
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go through each stream in the file.
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
|
||||||
// Check if stream is a video.
|
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "video") {
|
|
||||||
|
|
||||||
// Check if codec of stream is mjpeg, if so then remove this "video" stream. mjpeg are usually imbedded pictures that can cause havoc with plugins.
|
|
||||||
if (file.ffProbeData.streams[i].codec_name == 'mjpeg') {
|
|
||||||
extraArguments += `-map -v:${videoIdx} `
|
|
||||||
}
|
|
||||||
// Check if codec of stream is hevc AND check if file.container matches inputs.container. If so nothing for plugin to do.
|
|
||||||
if (file.ffProbeData.streams[i].codec_name == 'hevc' && file.container == inputs.container) {
|
|
||||||
response.processFile = false
|
|
||||||
response.infoLog += `☑File is already hevc & in ${inputs.container}. \n`
|
|
||||||
return response
|
|
||||||
}
|
|
||||||
// Check if codec of stream is hevc AND check if file.container does NOT match inputs.container. If so remux file.
|
|
||||||
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
|
|
||||||
}
|
|
||||||
// Increment videoIdx.
|
|
||||||
videoIdx++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set bitrateSettings variable using bitrate information calulcated earlier.
|
|
||||||
bitrateSettings = `-b:v ${targetBitrate}k -minrate ${minimumBitrate}k -maxrate ${maximumBitrate}k -bufsize ${currentBitrate}k`
|
|
||||||
// Print to infoLog information around file & bitrate settings.
|
|
||||||
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} -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.details = details;
|
||||||
module.exports.plugin = plugin;
|
module.exports.plugin = plugin;
|
||||||
|
|
@ -1,116 +1,125 @@
|
||||||
function details() {
|
function details() {
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_MC93_Migz2CleanTitle",
|
id: "Tdarr_Plugin_MC93_Migz2CleanTitle",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
Name: "Migz-Clean title metadata",
|
Name: "Migz-Clean title metadata",
|
||||||
Type: "Video",
|
Type: "Video",
|
||||||
Operation: "Clean",
|
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`,
|
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.2",
|
Version: "1.2",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_Migz2CleanTitle.js",
|
Link:
|
||||||
Tags: 'pre-processing,ffmpeg,configurable',
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_Migz2CleanTitle.js",
|
||||||
Inputs: [{
|
Tags: "pre-processing,ffmpeg,configurable",
|
||||||
name: 'clean_audio',
|
Inputs: [
|
||||||
tooltip: `Specify if audio titles should be checked & cleaned. Optional.
|
{
|
||||||
|
name: "clean_audio",
|
||||||
|
tooltip: `Specify if audio titles should be checked & cleaned. Optional.
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
true
|
true
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
false`
|
false`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'clean_subtitles',
|
name: "clean_subtitles",
|
||||||
tooltip: `Specify if subtitle titles should be checked & cleaned. Optional.
|
tooltip: `Specify if subtitle titles should be checked & cleaned. Optional.
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
true
|
true
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
false`
|
false`,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file, librarySettings, inputs) {
|
function plugin(file, librarySettings, inputs) {
|
||||||
var response = {
|
var response = {
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
container: '.' + file.container,
|
container: "." + file.container,
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: true,
|
FFmpegMode: true,
|
||||||
reQueueAfter: false,
|
reQueueAfter: false,
|
||||||
infoLog: '',
|
infoLog: "",
|
||||||
|
};
|
||||||
|
|
||||||
}
|
// Set up required variables.
|
||||||
|
var ffmpegCommandInsert = "";
|
||||||
|
var videoIdx = 0;
|
||||||
|
var audioIdx = 0;
|
||||||
|
var subtitleIdx = 0;
|
||||||
|
var convert = false;
|
||||||
|
|
||||||
// Set up required variables.
|
// Check if file is a video. If it isn't then exit plugin.
|
||||||
var ffmpegCommandInsert = ''
|
if (file.fileMedium !== "video") {
|
||||||
var videoIdx = 0
|
console.log("File is not video");
|
||||||
var audioIdx = 0
|
response.infoLog += "☒File is not video \n";
|
||||||
var subtitleIdx = 0
|
response.processFile = false;
|
||||||
var convert = false
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if file is a video. If it isn't then exit plugin.
|
// Check if overall file metadata title is not empty, if it's not empty set to "".
|
||||||
if (file.fileMedium !== "video") {
|
if (typeof file.meta.Title != "undefined")
|
||||||
console.log("File is not video")
|
try {
|
||||||
response.infoLog += "☒File is not video \n"
|
ffmpegCommandInsert += ` -metadata title="" `;
|
||||||
response.processFile = false;
|
convert = true;
|
||||||
return response
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if overall file metadata title is not empty, if it's not empty set to "".
|
|
||||||
if (typeof file.meta.Title != 'undefined') try {
|
|
||||||
ffmpegCommandInsert += ` -metadata title="" `
|
|
||||||
convert = true
|
|
||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
|
|
||||||
// Go through each stream in the file.
|
// Go through each stream in the file.
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) try {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++)
|
||||||
// Check if stream is a video.
|
try {
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "video") {
|
// Check if stream is a video.
|
||||||
// Check if stream title is not empty, if it's nto empty set to "".
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "video") {
|
||||||
if (typeof file.ffProbeData.streams[i].tags.title != 'undefined') {
|
// Check if stream title is not empty, if it's nto empty set to "".
|
||||||
response.infoLog += `☒Video stream title is not empty, most likely junk metadata. Removing title from stream ${i} \n`
|
if (typeof file.ffProbeData.streams[i].tags.title != "undefined") {
|
||||||
ffmpegCommandInsert += ` -metadata:s:v:${videoIdx} title="" `
|
response.infoLog += `☒Video stream title is not empty, most likely junk metadata. Removing title from stream ${i} \n`;
|
||||||
convert = true
|
ffmpegCommandInsert += ` -metadata:s:v:${videoIdx} title="" `;
|
||||||
}
|
convert = true;
|
||||||
// Increment videoIdx.
|
|
||||||
videoIdx++
|
|
||||||
}
|
}
|
||||||
|
// Increment videoIdx.
|
||||||
|
videoIdx++;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if title metadata of audio stream has more then 3 full stops. If so then it's likely to be junk metadata so remove.
|
// Check if title metadata of audio stream has more then 3 full stops. If so then it's likely to be junk metadata so remove.
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" && inputs.clean_audio.toLowerCase() == "true") {
|
if (
|
||||||
if (file.ffProbeData.streams[i].tags.title.split('.').length - 1 > 3) {
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" &&
|
||||||
response.infoLog += `☒More then 3 full stops detected in audio title, likely to be junk metadata. Removing title from stream ${i} \n`
|
inputs.clean_audio.toLowerCase() == "true"
|
||||||
ffmpegCommandInsert += ` -metadata:s:a:${audioIdx} title="" `
|
) {
|
||||||
convert = true
|
if (file.ffProbeData.streams[i].tags.title.split(".").length - 1 > 3) {
|
||||||
}
|
response.infoLog += `☒More then 3 full stops detected in audio title, likely to be junk metadata. Removing title from stream ${i} \n`;
|
||||||
// Increment audioIdx.
|
ffmpegCommandInsert += ` -metadata:s:a:${audioIdx} title="" `;
|
||||||
audioIdx++
|
convert = true;
|
||||||
}
|
}
|
||||||
|
// Increment audioIdx.
|
||||||
|
audioIdx++;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if title metadata of subtitle stream has more then 3 full stops. If so then it's likely to be junk metadata so remove.
|
// Check if title metadata of subtitle stream has more then 3 full stops. If so then it's likely to be junk metadata so remove.
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle" && inputs.clean_subtitles.toLowerCase() == "true") {
|
if (
|
||||||
if (file.ffProbeData.streams[i].tags.title.split('.').length - 1 > 3) {
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle" &&
|
||||||
response.infoLog += `☒More then 3 full stops detected in subtitle title, likely to be junk metadata. Removing title from stream ${i} \n`
|
inputs.clean_subtitles.toLowerCase() == "true"
|
||||||
ffmpegCommandInsert += ` -metadata:s:s:${subtitleIdx} title="" `
|
) {
|
||||||
convert = 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`;
|
||||||
// Increment subtitleIdx.
|
ffmpegCommandInsert += ` -metadata:s:s:${subtitleIdx} title="" `;
|
||||||
subtitleIdx++
|
convert = true;
|
||||||
}
|
}
|
||||||
|
// Increment subtitleIdx.
|
||||||
|
subtitleIdx++;
|
||||||
|
}
|
||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
|
|
||||||
// Convert file if convert variable is set to true.
|
// Convert file if convert variable is set to true.
|
||||||
if (convert == true) {
|
if (convert == true) {
|
||||||
response.infoLog += "☒File has title metadata. Removing \n"
|
response.infoLog += "☒File has title metadata. Removing \n";
|
||||||
response.preset = `,${ffmpegCommandInsert} -c copy -map 0 -max_muxing_queue_size 4096`
|
response.preset = `,${ffmpegCommandInsert} -c copy -map 0 -max_muxing_queue_size 4096`;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
} else {
|
} else {
|
||||||
response.infoLog += "☑File has no title metadata \n"
|
response.infoLog += "☑File has no title metadata \n";
|
||||||
}
|
}
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
module.exports.details = details;
|
module.exports.details = details;
|
||||||
module.exports.plugin = plugin;
|
module.exports.plugin = plugin;
|
||||||
|
|
@ -1,17 +1,19 @@
|
||||||
function details() {
|
function details() {
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_MC93_Migz3CleanAudio",
|
id: "Tdarr_Plugin_MC93_Migz3CleanAudio",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
Name: "Migz-Clean audio streams",
|
Name: "Migz-Clean audio streams",
|
||||||
Type: "Audio",
|
Type: "Audio",
|
||||||
Operation: "Clean",
|
Operation: "Clean",
|
||||||
Description: `This plugin keeps only specified language audio tracks & can tags those that have an unknown language. \n\n`,
|
Description: `This plugin keeps only specified language audio tracks & can tags those that have an unknown language. \n\n`,
|
||||||
Version: "2.2",
|
Version: "2.2",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_Migz3CleanAudio.js",
|
Link:
|
||||||
Tags: 'pre-processing,ffmpeg,audio only,configurable',
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_Migz3CleanAudio.js",
|
||||||
Inputs: [{
|
Tags: "pre-processing,ffmpeg,audio only,configurable",
|
||||||
name: 'language',
|
Inputs: [
|
||||||
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
|
{
|
||||||
|
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
|
\\nExample:\\n
|
||||||
eng
|
eng
|
||||||
|
|
||||||
|
|
@ -19,169 +21,201 @@ function details() {
|
||||||
eng,und
|
eng,und
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
eng,und,jap`
|
eng,und,jap`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'commentary',
|
name: "commentary",
|
||||||
tooltip: `Specify if audio tracks that contain commentary/description should be removed.
|
tooltip: `Specify if audio tracks that contain commentary/description should be removed.
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
true
|
true
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
false`
|
false`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'tag_language',
|
name: "tag_language",
|
||||||
tooltip: `Specify a single language for audio tracks with no language or unknown language to be tagged with, leave empty to disable, you must have "und" in your list of languages to keep for this to function. Must follow ISO-639-2 3 letter format. https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes
|
tooltip: `Specify a single language for audio tracks with no language or unknown language to be tagged with, 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
|
\\nExample:\\n
|
||||||
eng
|
eng
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
por`
|
por`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'tag_title',
|
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.
|
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
|
\\nExample:\\n
|
||||||
true
|
true
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
false`
|
false`,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file, librarySettings, inputs) {
|
function plugin(file, librarySettings, inputs) {
|
||||||
var response = {
|
var response = {
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
container: '.' + file.container,
|
container: "." + file.container,
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: true,
|
FFmpegMode: true,
|
||||||
reQueueAfter: false,
|
reQueueAfter: false,
|
||||||
infoLog: '',
|
infoLog: "",
|
||||||
}
|
};
|
||||||
|
|
||||||
// Check if file is a video. If it isn't then exit plugin.
|
// Check if file is a video. If it isn't then exit plugin.
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
console.log("File is not video")
|
console.log("File is not video");
|
||||||
response.infoLog += "☒File is not video \n"
|
response.infoLog += "☒File is not video \n";
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if inputs.language has been configured. If it hasn't then exit plugin.
|
// Check if inputs.language has been configured. If it hasn't then exit plugin.
|
||||||
if (inputs.language == "") {
|
if (inputs.language == "") {
|
||||||
response.infoLog += "☒Language/s keep have not been configured within plugin settings, please configure required options. Skipping this plugin. \n"
|
response.infoLog +=
|
||||||
response.processFile = false;
|
"☒Language/s keep have not been configured within plugin settings, please configure required options. Skipping this plugin. \n";
|
||||||
return response
|
response.processFile = false;
|
||||||
}
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
// Set up required variables.
|
// Set up required variables.
|
||||||
var language = inputs.language.split(",")
|
var language = inputs.language.split(",");
|
||||||
var ffmpegCommandInsert = ''
|
var ffmpegCommandInsert = "";
|
||||||
var convert = false
|
var convert = false;
|
||||||
var audioIdx = 0
|
var audioIdx = 0;
|
||||||
var audioStreamsRemoved = 0
|
var audioStreamsRemoved = 0;
|
||||||
var audioStreamCount = file.ffProbeData.streams.filter(row => (row.codec_type.toLowerCase() == "audio")).length;
|
var audioStreamCount = file.ffProbeData.streams.filter(
|
||||||
|
(row) => row.codec_type.toLowerCase() == "audio"
|
||||||
|
).length;
|
||||||
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
// Catch error here incase the language metadata is completely missing.
|
||||||
|
try {
|
||||||
|
// Check if stream is audio AND checks if the tracks language code does not match any of the languages entered in inputs.language.
|
||||||
|
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) {}
|
||||||
|
|
||||||
// Catch error here incase the language metadata is completely missing.
|
// Catch error here incase the title metadata is completely missing.
|
||||||
try {
|
try {
|
||||||
// Check if stream is audio AND checks if the tracks language code does not match any of the languages entered in inputs.language.
|
// Check if inputs.commentary is set to true AND if stream is audio AND then checks for stream titles with the following "commentary, description, sdh". Removing any streams that are applicable.
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" && language.indexOf(file.ffProbeData.streams[i].tags.language.toLowerCase()) === -1) {
|
if (
|
||||||
audioStreamsRemoved++
|
inputs.commentary.toLowerCase() == "true" &&
|
||||||
ffmpegCommandInsert += `-map -0:a:${audioIdx} `
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" &&
|
||||||
response.infoLog += `☒Audio stream detected as being an unwanted language, removing. Audio stream 0:a:${audioIdx} - ${file.ffProbeData.streams[i].tags.language.toLowerCase()} \n`
|
(file.ffProbeData.streams[i].tags.title
|
||||||
convert = true
|
.toLowerCase()
|
||||||
}
|
.includes("commentary") ||
|
||||||
} catch (err) {}
|
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) {}
|
||||||
|
|
||||||
// Catch error here incase the title metadata is completely missing.
|
// Check if inputs.tag_language has something entered (Entered means user actually wants something to happen, empty would disable this) AND checks that stream is audio.
|
||||||
try {
|
if (
|
||||||
// Check if inputs.commentary is set to true AND if stream is audio AND then checks for stream titles with the following "commentary, description, sdh". Removing any streams that are applicable.
|
inputs.tag_language != "" &&
|
||||||
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'))) {
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio"
|
||||||
audioStreamsRemoved++
|
) {
|
||||||
ffmpegCommandInsert += `-map -0:a:${audioIdx} `
|
// Catch error here incase the metadata is completely missing.
|
||||||
response.infoLog += `☒Audio stream detected as being Commentary or Description, removing. Audio stream 0:a:${audioIdx} - ${file.ffProbeData.streams[i].tags.title}. \n`
|
try {
|
||||||
convert = true
|
// Look for audio with "und" as metadata language.
|
||||||
}
|
if (
|
||||||
} catch (err) {}
|
file.ffProbeData.streams[i].tags.language
|
||||||
|
.toLowerCase()
|
||||||
// Check if inputs.tag_language has something entered (Entered means user actually wants something to happen, empty would disable this) AND checks that stream is audio.
|
.includes("und")
|
||||||
if (inputs.tag_language != "" && file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
) {
|
||||||
// Catch error here incase the metadata is completely missing.
|
ffmpegCommandInsert += `-metadata:s:a:${audioIdx} language=${inputs.tag_language} `;
|
||||||
try {
|
response.infoLog += `☒Audio stream detected as having unknown language tagged, tagging as ${inputs.tag_language}. \n`;
|
||||||
// Look for audio with "und" as metadata language.
|
convert = true;
|
||||||
if (file.ffProbeData.streams[i].tags.language.toLowerCase().includes('und')) {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
} catch (err) {}
|
|
||||||
|
|
||||||
// Checks if the tags metadata is completely missing, if so this would cause playback to show language as "undefined". No catch error here otherwise it would never detect the metadata as missing.
|
|
||||||
if (typeof file.ffProbeData.streams[i].tags == 'undefined') {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
// Checks if the tags.language metadata is completely missing, if so this would cause playback to show language as "undefined". No catch error here otherwise it would never detect the metadata as missing.
|
|
||||||
else {
|
|
||||||
if (typeof file.ffProbeData.streams[i].tags.language == 'undefined') {
|
|
||||||
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 {
|
// Checks if the tags metadata is completely missing, if so this would cause playback to show language as "undefined". No catch error here otherwise it would never detect the metadata as missing.
|
||||||
// Check if title metadata is missing from any streams AND inputs.tag_title set to true AND if stream type is audio. Add title to any applicable streams.
|
if (typeof file.ffProbeData.streams[i].tags == "undefined") {
|
||||||
if (typeof file.ffProbeData.streams[i].tags.title == 'undefined' && inputs.tag_title.toLowerCase() == "true" && file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
ffmpegCommandInsert += `-metadata:s:a:${audioIdx} language=${inputs.tag_language} `;
|
||||||
if (file.ffProbeData.streams[i].channels == "8") {
|
response.infoLog += `☒Audio stream detected as having no language tagged, tagging as ${inputs.tag_language}. \n`;
|
||||||
ffmpegCommandInsert += `-metadata:s:a:${audioIdx} title="7.1" `
|
convert = true;
|
||||||
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
|
// Checks if the tags.language metadata is completely missing, if so this would cause playback to show language as "undefined". No catch error here otherwise it would never detect the metadata as missing.
|
||||||
}
|
else {
|
||||||
if (file.ffProbeData.streams[i].channels == "6") {
|
if (typeof file.ffProbeData.streams[i].tags.language == "undefined") {
|
||||||
ffmpegCommandInsert += `-metadata:s:a:${audioIdx} title="5.1" `
|
ffmpegCommandInsert += `-metadata:s:a:${audioIdx} language=${inputs.tag_language} `;
|
||||||
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`
|
response.infoLog += `☒Audio stream detected as having no language tagged, tagging as ${inputs.tag_language}. \n`;
|
||||||
convert = true
|
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) {}
|
|
||||||
|
|
||||||
// Check if stream type is audio and increment audioIdx if true.
|
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
|
||||||
audioIdx++
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Failsafe to cancel processing if all streams would be removed following this plugin. We don't want no audio.
|
|
||||||
if (audioStreamsRemoved == audioStreamCount) {
|
|
||||||
response.infoLog += "☒Cancelling plugin otherwise all audio tracks would be removed. \n"
|
|
||||||
response.processFile = false
|
|
||||||
return response
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert file if convert variable is set to true.
|
try {
|
||||||
if (convert === true) {
|
// Check if title metadata is missing from any streams AND inputs.tag_title set to true AND if stream type is audio. Add title to any applicable streams.
|
||||||
response.processFile = true
|
if (
|
||||||
response.preset = `, -map 0 ${ffmpegCommandInsert} -c copy -max_muxing_queue_size 4096`
|
typeof file.ffProbeData.streams[i].tags.title == "undefined" &&
|
||||||
response.container = '.' + file.container
|
inputs.tag_title.toLowerCase() == "true" &&
|
||||||
response.reQueueAfter = true
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio"
|
||||||
} else {
|
) {
|
||||||
response.processFile = false
|
if (file.ffProbeData.streams[i].channels == "8") {
|
||||||
response.infoLog += "☑File doesn't contain audio tracks which are unwanted or that require tagging.\n"
|
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) {}
|
||||||
|
|
||||||
|
// Check if stream type is audio and increment audioIdx if true.
|
||||||
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
||||||
|
audioIdx++;
|
||||||
}
|
}
|
||||||
return response
|
}
|
||||||
|
// Failsafe to cancel processing if all streams would be removed following this plugin. We don't want no audio.
|
||||||
|
if (audioStreamsRemoved == audioStreamCount) {
|
||||||
|
response.infoLog +=
|
||||||
|
"☒Cancelling plugin otherwise all audio tracks would be removed. \n";
|
||||||
|
response.processFile = false;
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert file if convert variable is set to true.
|
||||||
|
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 audio tracks which are unwanted or that require tagging.\n";
|
||||||
|
}
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
module.exports.details = details;
|
module.exports.details = details;
|
||||||
module.exports.plugin = plugin;
|
module.exports.plugin = plugin;
|
||||||
|
|
@ -1,145 +1,172 @@
|
||||||
function details() {
|
function details() {
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_MC93_Migz4CleanSubs",
|
id: "Tdarr_Plugin_MC93_Migz4CleanSubs",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
Name: "Migz-Clean subtitle streams",
|
Name: "Migz-Clean subtitle streams",
|
||||||
Type: "subtitles",
|
Type: "subtitles",
|
||||||
Operation: "Clean",
|
Operation: "Clean",
|
||||||
Description: `This plugin keeps only specified language subtitle tracks & can tag those that have an unknown language. \n\n`,
|
Description: `This plugin keeps only specified language subtitle tracks & can tag those that have an unknown language. \n\n`,
|
||||||
Version: "2.2",
|
Version: "2.2",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_Migz4CleanSubs.js",
|
Link:
|
||||||
Tags: 'pre-processing,ffmpeg,subtitle only,configurable',
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_Migz4CleanSubs.js",
|
||||||
Inputs: [{
|
Tags: "pre-processing,ffmpeg,subtitle only,configurable",
|
||||||
name: 'language',
|
Inputs: [
|
||||||
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
|
{
|
||||||
|
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
|
\\nExample:\\n
|
||||||
eng
|
eng
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
eng,jap`
|
eng,jap`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'commentary',
|
name: "commentary",
|
||||||
tooltip: `Specify if subtitle tracks that contain commentary/description should be removed.
|
tooltip: `Specify if subtitle tracks that contain commentary/description should be removed.
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
true
|
true
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
false`
|
false`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'tag_language',
|
name: "tag_language",
|
||||||
tooltip: `Specify a single language for subtitle tracks with no language or unknown language to be tagged with, leave empty to disable. Must follow ISO-639-2 3 letter format. https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes
|
tooltip: `Specify a single language for subtitle tracks with no language or unknown language to be tagged with, 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
|
\\nExample:\\n
|
||||||
eng
|
eng
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
por`
|
por`,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file, librarySettings, inputs) {
|
function plugin(file, librarySettings, inputs) {
|
||||||
var response = {
|
var response = {
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
container: '.' + file.container,
|
container: "." + file.container,
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: true,
|
FFmpegMode: true,
|
||||||
reQueueAfter: false,
|
reQueueAfter: false,
|
||||||
infoLog: '',
|
infoLog: "",
|
||||||
}
|
};
|
||||||
|
|
||||||
// Check if file is a video. If it isn't then exit plugin.
|
// Check if file is a video. If it isn't then exit plugin.
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
console.log("File is not video")
|
console.log("File is not video");
|
||||||
response.infoLog += "☒File is not video \n"
|
response.infoLog += "☒File is not video \n";
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if inputs.language has been configured. If it hasn't then exit plugin.
|
// Check if inputs.language has been configured. If it hasn't then exit plugin.
|
||||||
if (inputs.language == "") {
|
if (inputs.language == "") {
|
||||||
response.infoLog += "☒Language/s keep have not been configured within plugin settings, please configure required options. Skipping this plugin. \n"
|
response.infoLog +=
|
||||||
response.processFile = false;
|
"☒Language/s keep have not been configured within plugin settings, please configure required options. Skipping this plugin. \n";
|
||||||
return response
|
response.processFile = false;
|
||||||
}
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
// Set up required variables.
|
// Set up required variables.
|
||||||
var language = inputs.language.split(",")
|
var language = inputs.language.split(",");
|
||||||
var ffmpegCommandInsert = ''
|
var ffmpegCommandInsert = "";
|
||||||
var subtitleIdx = 0
|
var subtitleIdx = 0;
|
||||||
var convert = false
|
var convert = false;
|
||||||
|
|
||||||
// Go through each stream in the file.
|
// Go through each stream in the file.
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
// Catch error here incase the language metadata is completely missing.
|
||||||
|
try {
|
||||||
|
// Check if stream is subtitle AND checks if the tracks language code does not match any of the languages entered in inputs.language.
|
||||||
|
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) {}
|
||||||
|
|
||||||
// Catch error here incase the language metadata is completely missing.
|
// Catch error here incase the title metadata is completely missing.
|
||||||
try {
|
try {
|
||||||
// Check if stream is subtitle AND checks if the tracks language code does not match any of the languages entered in inputs.language.
|
// Check if inputs.commentary is set to true AND if stream is subtitle AND then checks for stream titles with the following "commentary, description, sdh". Removing any streams that are applicable.
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle" && language.indexOf(file.ffProbeData.streams[i].tags.language.toLowerCase()) === -1) {
|
if (
|
||||||
ffmpegCommandInsert += `-map -0:s:${subtitleIdx} `
|
inputs.commentary.toLowerCase() == "true" &&
|
||||||
response.infoLog += `☒Subtitle stream detected as being an unwanted language, removing. Subtitle stream 0:s:${subtitleIdx} - ${file.ffProbeData.streams[i].tags.language.toLowerCase()} \n`
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle" &&
|
||||||
convert = true
|
(file.ffProbeData.streams[i].tags.title
|
||||||
}
|
.toLowerCase()
|
||||||
} catch (err) {}
|
.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) {}
|
||||||
|
|
||||||
// Catch error here incase the title metadata is completely missing.
|
// Check if inputs.tag_language has something entered (Entered means user actually wants something to happen, empty would disable this) AND checks that stream is subtitle.
|
||||||
try {
|
if (
|
||||||
// Check if inputs.commentary is set to true AND if stream is subtitle AND then checks for stream titles with the following "commentary, description, sdh". Removing any streams that are applicable.
|
inputs.tag_language != "" &&
|
||||||
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'))) {
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle"
|
||||||
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`
|
// Catch error here incase the metadata is completely missing.
|
||||||
convert = true
|
try {
|
||||||
}
|
// Look for subtitle with "und" as metadata language.
|
||||||
} catch (err) {}
|
if (
|
||||||
|
file.ffProbeData.streams[i].tags.language
|
||||||
// Check if inputs.tag_language has something entered (Entered means user actually wants something to happen, empty would disable this) AND checks that stream is subtitle.
|
.toLowerCase()
|
||||||
if (inputs.tag_language != "" && file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle") {
|
.includes("und")
|
||||||
// Catch error here incase the metadata is completely missing.
|
) {
|
||||||
try {
|
ffmpegCommandInsert += `-metadata:s:s:${subtitleIdx} language=${inputs.tag_language} `;
|
||||||
// Look for subtitle with "und" as metadata language.
|
response.infoLog += `☒Subtitle stream detected as having unknown language tagged, tagging as ${inputs.tag_language}. \n`;
|
||||||
if (file.ffProbeData.streams[i].tags.language.toLowerCase().includes('und')) {
|
convert = true;
|
||||||
ffmpegCommandInsert += `-metadata:s:s:${subtitleIdx} language=${inputs.tag_language} `
|
|
||||||
response.infoLog += `☒Subtitle stream detected as having unknown language tagged, tagging as ${inputs.tag_language}. \n`
|
|
||||||
convert = true
|
|
||||||
}
|
|
||||||
} catch (err) {}
|
|
||||||
|
|
||||||
// Checks if the tags metadata is completely missing, if so this would cause playback to show language as "undefined". No catch error here otherwise it would never detect the metadata as missing.
|
|
||||||
if (typeof file.ffProbeData.streams[i].tags == 'undefined') {
|
|
||||||
ffmpegCommandInsert += `-metadata:s:s:${subtitleIdx} language=${inputs.tag_language} `
|
|
||||||
response.infoLog += `☒Subtitle stream detected as having no language tagged, tagging as ${inputs.tag_language}. \n`
|
|
||||||
convert = true
|
|
||||||
}
|
|
||||||
// Checks if the tags.language metadata is completely missing, if so this would cause playback to show language as "undefined". No catch error here otherwise it would never detect the metadata as missing.
|
|
||||||
else {
|
|
||||||
if (typeof file.ffProbeData.streams[i].tags.language == 'undefined') {
|
|
||||||
ffmpegCommandInsert += `-metadata:s:s:${subtitleIdx} language=${inputs.tag_language} `
|
|
||||||
response.infoLog += `☒Subtitle stream detected as having no language tagged, tagging as ${inputs.tag_language}. \n`
|
|
||||||
convert = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
// Check if stream type is subtitle and increment subtitleIdx if true.
|
// Checks if the tags metadata is completely missing, if so this would cause playback to show language as "undefined". No catch error here otherwise it would never detect the metadata as missing.
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle") {
|
if (typeof file.ffProbeData.streams[i].tags == "undefined") {
|
||||||
subtitleIdx++
|
ffmpegCommandInsert += `-metadata:s:s:${subtitleIdx} language=${inputs.tag_language} `;
|
||||||
|
response.infoLog += `☒Subtitle stream detected as having no language tagged, tagging as ${inputs.tag_language}. \n`;
|
||||||
|
convert = true;
|
||||||
|
}
|
||||||
|
// Checks if the tags.language metadata is completely missing, if so this would cause playback to show language as "undefined". No catch error here otherwise it would never detect the metadata as missing.
|
||||||
|
else {
|
||||||
|
if (typeof file.ffProbeData.streams[i].tags.language == "undefined") {
|
||||||
|
ffmpegCommandInsert += `-metadata:s:s:${subtitleIdx} language=${inputs.tag_language} `;
|
||||||
|
response.infoLog += `☒Subtitle stream detected as having no language tagged, tagging as ${inputs.tag_language}. \n`;
|
||||||
|
convert = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert file if convert variable is set to true.
|
// Check if stream type is subtitle and increment subtitleIdx if true.
|
||||||
if (convert === true) {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle") {
|
||||||
response.processFile = true;
|
subtitleIdx++;
|
||||||
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
|
}
|
||||||
|
|
||||||
|
// Convert file if convert variable is set to true.
|
||||||
|
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.details = details;
|
||||||
module.exports.plugin = plugin;
|
module.exports.plugin = plugin;
|
||||||
|
|
@ -1,137 +1,151 @@
|
||||||
function details() {
|
function details() {
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_MC93_Migz5ConvertAudio",
|
id: "Tdarr_Plugin_MC93_Migz5ConvertAudio",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
Name: "Migz-Convert audio streams",
|
Name: "Migz-Convert audio streams",
|
||||||
Type: "Audio",
|
Type: "Audio",
|
||||||
Operation: "Transcode",
|
Operation: "Transcode",
|
||||||
Description: `This plugin can convert any 2.0 audio track/s to AAC and can create downmixed audio tracks. \n\n`,
|
Description: `This plugin can convert any 2.0 audio track/s to AAC and can create downmixed audio tracks. \n\n`,
|
||||||
Version: "2.1",
|
Version: "2.1",
|
||||||
Link: "",
|
Link: "",
|
||||||
Tags: 'pre-processing,ffmpeg,audio only,configurable',
|
Tags: "pre-processing,ffmpeg,audio only,configurable",
|
||||||
Inputs: [{
|
Inputs: [
|
||||||
name: 'aac_stereo',
|
{
|
||||||
tooltip: `Specify if any 2.0 audio tracks should be converted to aac for maximum compatability with devices. Optional.
|
name: "aac_stereo",
|
||||||
|
tooltip: `Specify if any 2.0 audio tracks should be converted to aac for maximum compatability with devices. Optional.
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
true
|
true
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
false`
|
false`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'downmix',
|
name: "downmix",
|
||||||
tooltip: `Specify if downmixing should be used to create extra audio tracks. I.e if you have an 8ch but no 2ch or 6ch, create the missing audio tracks from the 8 ch. Likewise if you only have 6ch, create the missing 2ch from it. Optional.
|
tooltip: `Specify if downmixing should be used to create extra audio tracks. I.e if you have an 8ch but no 2ch or 6ch, create the missing audio tracks from the 8 ch. Likewise if you only have 6ch, create the missing 2ch from it. Optional.
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
true
|
true
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
false`
|
false`,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file, librarySettings, inputs) {
|
function plugin(file, librarySettings, inputs) {
|
||||||
var response = {
|
var response = {
|
||||||
processFile: false,
|
processFile: false,
|
||||||
container: '.' + file.container,
|
container: "." + file.container,
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: true,
|
FFmpegMode: true,
|
||||||
reQueueAfter: true,
|
reQueueAfter: true,
|
||||||
infoLog: '',
|
infoLog: "",
|
||||||
}
|
};
|
||||||
|
|
||||||
// Check if both inputs.aac_stereo AND inputs.downmix have been left empty. If they have then exit plugin.
|
// Check if both inputs.aac_stereo AND inputs.downmix have been left empty. If they have then exit plugin.
|
||||||
if (inputs && inputs.aac_stereo == "" && inputs.downmix == "") {
|
if (inputs && 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.infoLog +=
|
||||||
response.processFile = false
|
"☒Neither aac_stereo or downmix options have been configured within plugin settings, please configure required options. Skipping this plugin. \n";
|
||||||
return response
|
response.processFile = false;
|
||||||
}
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if file is a video. If it isn't then exit plugin.
|
// Check if file is a video. If it isn't then exit plugin.
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
console.log("File is not video")
|
console.log("File is not video");
|
||||||
response.infoLog += "☒File is not video. \n"
|
response.infoLog += "☒File is not video. \n";
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up required variables.
|
// Set up required variables.
|
||||||
var ffmpegCommandInsert = ''
|
var ffmpegCommandInsert = "";
|
||||||
var audioIdx = 0
|
var audioIdx = 0;
|
||||||
var has2Channel = false
|
var has2Channel = false;
|
||||||
var has6Channel = false
|
var has6Channel = false;
|
||||||
var has8Channel = false
|
var has8Channel = false;
|
||||||
var convert = false
|
var convert = false;
|
||||||
|
|
||||||
// Go through each stream in the file.
|
// Go through each stream in the file.
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
try {
|
try {
|
||||||
// Go through all audio streams and check if 2,6 & 8 channel tracks exist or not.
|
// Go through all audio streams and check if 2,6 & 8 channel tracks exist or not.
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
||||||
if (file.ffProbeData.streams[i].channels == "2") {
|
if (file.ffProbeData.streams[i].channels == "2") {
|
||||||
has2Channel = true
|
has2Channel = true;
|
||||||
}
|
|
||||||
if (file.ffProbeData.streams[i].channels == "6") {
|
|
||||||
has6Channel = true
|
|
||||||
}
|
|
||||||
if (file.ffProbeData.streams[i].channels == "8") {
|
|
||||||
has8Channel = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go through each stream in the file.
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
|
||||||
// Check if stream is audio.
|
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
|
||||||
// Catch error here incase user left inputs.downmix empty.
|
|
||||||
try {
|
|
||||||
// Check if inputs.downmix is set to true.
|
|
||||||
if (inputs.downmix.toLowerCase() == "true") {
|
|
||||||
// Check if file has 8 channel audio but no 6 channel, if so then create extra downmix from the 8 channel.
|
|
||||||
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 6 channel from 8 channel. \n"
|
|
||||||
convert = true
|
|
||||||
}
|
|
||||||
// Check if file has 6 channel audio but no 2 channel, if so then create extra downmix from the 6 channel.
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err) {}
|
|
||||||
|
|
||||||
// Catch error here incase user left inputs.downmix empty.
|
|
||||||
try {
|
|
||||||
// Check if inputs.aac_stereo is set to true.
|
|
||||||
if (inputs.aac_stereo.toLowerCase() == "true") {
|
|
||||||
// Check if codec_name for stream is NOT aac AND check if channel ammount is 2.
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err) {}
|
|
||||||
audioIdx++
|
|
||||||
}
|
}
|
||||||
|
if (file.ffProbeData.streams[i].channels == "6") {
|
||||||
|
has6Channel = true;
|
||||||
|
}
|
||||||
|
if (file.ffProbeData.streams[i].channels == "8") {
|
||||||
|
has8Channel = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go through each stream in the file.
|
||||||
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
// Check if stream is audio.
|
||||||
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
||||||
|
// Catch error here incase user left inputs.downmix empty.
|
||||||
|
try {
|
||||||
|
// Check if inputs.downmix is set to true.
|
||||||
|
if (inputs.downmix.toLowerCase() == "true") {
|
||||||
|
// Check if file has 8 channel audio but no 6 channel, if so then create extra downmix from the 8 channel.
|
||||||
|
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 6 channel from 8 channel. \n";
|
||||||
|
convert = true;
|
||||||
|
}
|
||||||
|
// Check if file has 6 channel audio but no 2 channel, if so then create extra downmix from the 6 channel.
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
|
// Catch error here incase user left inputs.downmix empty.
|
||||||
|
try {
|
||||||
|
// Check if inputs.aac_stereo is set to true.
|
||||||
|
if (inputs.aac_stereo.toLowerCase() == "true") {
|
||||||
|
// Check if codec_name for stream is NOT aac AND check if channel ammount is 2.
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
audioIdx++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Convert file if convert variable is set to true.
|
// Convert file if convert variable is set to true.
|
||||||
if (convert == true) {
|
if (convert == true) {
|
||||||
response.processFile = 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 `
|
response.preset = `, -map 0 -c:v copy -c:a copy ${ffmpegCommandInsert} -strict -2 -c:s copy -max_muxing_queue_size 4096 `;
|
||||||
} else {
|
} else {
|
||||||
response.infoLog += "☑File contains all required audio formats. \n"
|
response.infoLog += "☑File contains all required audio formats. \n";
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
}
|
}
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
}
|
}
|
||||||
module.exports.details = details;
|
module.exports.details = details;
|
||||||
module.exports.plugin = plugin;
|
module.exports.plugin = plugin;
|
||||||
|
|
@ -1,169 +1,187 @@
|
||||||
function details() {
|
function details() {
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_MC93_Migz6OrderStreams",
|
id: "Tdarr_Plugin_MC93_Migz6OrderStreams",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
Name: "Migz-Order Streams",
|
Name: "Migz-Order Streams",
|
||||||
Type: "Streams",
|
Type: "Streams",
|
||||||
Operation: "Order",
|
Operation: "Order",
|
||||||
Description: `Orders streams into Video first, then Audio (2ch, 6ch, 8ch) and finally Subtitles. \n\n`,
|
Description: `Orders streams into Video first, then Audio (2ch, 6ch, 8ch) and finally Subtitles. \n\n`,
|
||||||
Version: "1.1",
|
Version: "1.1",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_Migz6OrderStreams.js",
|
Link:
|
||||||
Tags: 'pre-processing,ffmpeg,'
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_Migz6OrderStreams.js",
|
||||||
}
|
Tags: "pre-processing,ffmpeg,",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
var response = {
|
var response = {
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
container: '.' + file.container,
|
container: "." + file.container,
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: true,
|
FFmpegMode: true,
|
||||||
infoLog: '',
|
infoLog: "",
|
||||||
}
|
};
|
||||||
|
|
||||||
// Set up required variables.
|
// Set up required variables.
|
||||||
var ffmpegCommandInsert = ''
|
var ffmpegCommandInsert = "";
|
||||||
var videoIdx = 0
|
var videoIdx = 0;
|
||||||
var audioIdx = 0
|
var audioIdx = 0;
|
||||||
var audio2Idx = 0
|
var audio2Idx = 0;
|
||||||
var audio6Idx = 0
|
var audio6Idx = 0;
|
||||||
var audio8Idx = 0
|
var audio8Idx = 0;
|
||||||
var subtitleIdx = 0
|
var subtitleIdx = 0;
|
||||||
var convert = false
|
var convert = false;
|
||||||
|
|
||||||
// Go through each stream in the file.
|
// Go through each stream in the file.
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
try {
|
try {
|
||||||
// Check if stream is video.
|
// Check if stream is video.
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "video") {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "video") {
|
||||||
// Check if audioIdx or subtitleIdx do NOT equal 0, if they do then it means a audio or subtitle track has already appeared before the video track so file needs to be organized.
|
// Check if audioIdx or subtitleIdx do NOT equal 0, if they do then it means a audio or subtitle track has already appeared before the video track so file needs to be organized.
|
||||||
if (audioIdx != "0" || subtitleIdx != "0") {
|
if (audioIdx != "0" || subtitleIdx != "0") {
|
||||||
convert = true
|
convert = true;
|
||||||
response.infoLog += "☒ Video not first. \n"
|
response.infoLog += "☒ Video not first. \n";
|
||||||
}
|
}
|
||||||
// Increment videoIdx.
|
// Increment videoIdx.
|
||||||
videoIdx++
|
videoIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if stream is audio.
|
// Check if stream is audio.
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
||||||
// Check if subtitleIdx does NOT equal 0, if it does then it means a subtitle track has already appeared before an audio track so file needs to be organized.
|
// Check if subtitleIdx does NOT equal 0, if it does then it means a subtitle track has already appeared before an audio track so file needs to be organized.
|
||||||
if (subtitleIdx != "0") {
|
if (subtitleIdx != "0") {
|
||||||
convert = true
|
convert = true;
|
||||||
response.infoLog += "☒ Audio not second. \n"
|
response.infoLog += "☒ Audio not second. \n";
|
||||||
}
|
}
|
||||||
// Increment audioIdx.
|
// Increment audioIdx.
|
||||||
audioIdx++
|
audioIdx++;
|
||||||
|
|
||||||
// Check if audio track is 2 channel.
|
// Check if audio track is 2 channel.
|
||||||
if (file.ffProbeData.streams[i].channels == "2") {
|
if (file.ffProbeData.streams[i].channels == "2") {
|
||||||
// Check if audio6Idx or audio8Idx do NOT equal 0, if they do then it means a 6 channel or 8 channel audio track has already appeared before the 2 channel audio track so file needs to be organized.
|
// Check if audio6Idx or audio8Idx do NOT equal 0, if they do then it means a 6 channel or 8 channel audio track has already appeared before the 2 channel audio track so file needs to be organized.
|
||||||
if (audio6Idx != "0" || audio8Idx != "0") {
|
if (audio6Idx != "0" || audio8Idx != "0") {
|
||||||
convert = true
|
convert = true;
|
||||||
response.infoLog += "☒ Audio 2ch not first. \n"
|
response.infoLog += "☒ Audio 2ch not first. \n";
|
||||||
}
|
}
|
||||||
// Increment audio2Idx.
|
// Increment audio2Idx.
|
||||||
audio2Idx++
|
audio2Idx++;
|
||||||
}
|
}
|
||||||
// Check if audio track is 6 channel.
|
// Check if audio track is 6 channel.
|
||||||
if (file.ffProbeData.streams[i].channels == "6") {
|
if (file.ffProbeData.streams[i].channels == "6") {
|
||||||
// Check if audio8Idx does NOT equal 0, if it does then it means a 8 channel audio track has already appeared before the 6 channel audio track so file needs to be organized.
|
// Check if audio8Idx does NOT equal 0, if it does then it means a 8 channel audio track has already appeared before the 6 channel audio track so file needs to be organized.
|
||||||
if (audio8Idx != "0") {
|
if (audio8Idx != "0") {
|
||||||
convert = true
|
convert = true;
|
||||||
response.infoLog += "☒ Audio 6ch not second. \n"
|
response.infoLog += "☒ Audio 6ch not second. \n";
|
||||||
}
|
}
|
||||||
// Increment audio6Idx.
|
// Increment audio6Idx.
|
||||||
audio6Idx++
|
audio6Idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if audio track is 8 channel.
|
// Check if audio track is 8 channel.
|
||||||
if (file.ffProbeData.streams[i].channels == "8") {
|
if (file.ffProbeData.streams[i].channels == "8") {
|
||||||
// Increment audio8Idx.
|
// Increment audio8Idx.
|
||||||
audio8Idx++
|
audio8Idx++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if stream is subtitle.
|
// Check if stream is subtitle.
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle") {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle") {
|
||||||
// Increment subtitleIdx
|
// Increment subtitleIdx
|
||||||
subtitleIdx++
|
subtitleIdx++;
|
||||||
}
|
}
|
||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Go through each stream in the file.
|
// Go through each stream in the file.
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
try {
|
try {
|
||||||
// Check if stream is video AND is not a mjpeg.
|
// Check if stream is video AND is not a mjpeg.
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "video" && file.ffProbeData.streams[i].codec_name.toLowerCase() != "mjpeg") {
|
if (
|
||||||
ffmpegCommandInsert += `-map 0:${i} `
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "video" &&
|
||||||
}
|
file.ffProbeData.streams[i].codec_name.toLowerCase() != "mjpeg"
|
||||||
} catch (err) {}
|
) {
|
||||||
}
|
ffmpegCommandInsert += `-map 0:${i} `;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
}
|
||||||
|
|
||||||
// Go through each stream in the file.
|
// Go through each stream in the file.
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
try {
|
try {
|
||||||
// Check if stream is audio AND 2 channel.
|
// Check if stream is audio AND 2 channel.
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" && file.ffProbeData.streams[i].channels == "2") {
|
if (
|
||||||
ffmpegCommandInsert += `-map 0:${i} `
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" &&
|
||||||
}
|
file.ffProbeData.streams[i].channels == "2"
|
||||||
} catch (err) {}
|
) {
|
||||||
}
|
ffmpegCommandInsert += `-map 0:${i} `;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
}
|
||||||
|
|
||||||
// Go through each stream in the file.
|
// Go through each stream in the file.
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
try {
|
try {
|
||||||
// Check if stream is audio AND 6 channel.
|
// Check if stream is audio AND 6 channel.
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" && file.ffProbeData.streams[i].channels == "6") {
|
if (
|
||||||
ffmpegCommandInsert += `-map 0:${i} `
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" &&
|
||||||
}
|
file.ffProbeData.streams[i].channels == "6"
|
||||||
} catch (err) {}
|
) {
|
||||||
}
|
ffmpegCommandInsert += `-map 0:${i} `;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
}
|
||||||
|
|
||||||
// Go through each stream in the file.
|
// Go through each stream in the file.
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
try {
|
try {
|
||||||
// Check if stream is audio AND 8 channel.
|
// Check if stream is audio AND 8 channel.
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" && file.ffProbeData.streams[i].channels == "8") {
|
if (
|
||||||
ffmpegCommandInsert += `-map 0:${i} `
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" &&
|
||||||
}
|
file.ffProbeData.streams[i].channels == "8"
|
||||||
} catch (err) {}
|
) {
|
||||||
}
|
ffmpegCommandInsert += `-map 0:${i} `;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
}
|
||||||
|
|
||||||
// Go through each stream in the file.
|
// Go through each stream in the file.
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
try {
|
try {
|
||||||
// Check if stream is audio AND not 2, 6 or 8 channel.
|
// Check if stream is audio AND not 2, 6 or 8 channel.
|
||||||
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") {
|
if (
|
||||||
ffmpegCommandInsert += `-map 0:${i} `
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" &&
|
||||||
}
|
file.ffProbeData.streams[i].channels != "2" &&
|
||||||
} catch (err) {}
|
file.ffProbeData.streams[i].channels != "6" &&
|
||||||
}
|
file.ffProbeData.streams[i].channels != "8"
|
||||||
|
) {
|
||||||
|
ffmpegCommandInsert += `-map 0:${i} `;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
}
|
||||||
|
|
||||||
// Go through each stream in the file.
|
// Go through each stream in the file.
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
try {
|
try {
|
||||||
// Check if stream is subtitle.
|
// Check if stream is subtitle.
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle") {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle") {
|
||||||
ffmpegCommandInsert += `-map 0:${i} `
|
ffmpegCommandInsert += `-map 0:${i} `;
|
||||||
}
|
}
|
||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert file if convert variable is set to true.
|
|
||||||
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
|
|
||||||
|
|
||||||
|
// Convert file if convert variable is set to true.
|
||||||
|
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.details = details;
|
||||||
module.exports.plugin = plugin;
|
module.exports.plugin = plugin;
|
||||||
|
|
@ -1,64 +1,69 @@
|
||||||
function details() {
|
function details() {
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_MC93_MigzImageRemoval",
|
id: "Tdarr_Plugin_MC93_MigzImageRemoval",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
Name: "Migz-Remove image formats from file",
|
Name: "Migz-Remove image formats from file",
|
||||||
Type: "Video",
|
Type: "Video",
|
||||||
Operation: "Clean",
|
Operation: "Clean",
|
||||||
Description: `Identify any unwanted image formats in the file and remove those streams. MJPEG & PNG \n\n`,
|
Description: `Identify any unwanted image formats in the file and remove those streams. MJPEG & PNG \n\n`,
|
||||||
Version: "1.1",
|
Version: "1.1",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_MigzImageRemoval.js",
|
Link:
|
||||||
Tags: 'pre-processing,ffmpeg,video only'
|
"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) {
|
function plugin(file, librarySettings, inputs) {
|
||||||
var response = {
|
var response = {
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
container: '.' + file.container,
|
container: "." + file.container,
|
||||||
FFmpegMode: true,
|
FFmpegMode: true,
|
||||||
reQueueAfter: true,
|
reQueueAfter: true,
|
||||||
infoLog: ''
|
infoLog: "",
|
||||||
}
|
};
|
||||||
|
|
||||||
// Check if file is a video. If it isn't then exit plugin.
|
// Check if file is a video. If it isn't then exit plugin.
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
response.processFile = false
|
response.processFile = false;
|
||||||
response.infoLog += "☒File is not a video. \n"
|
response.infoLog += "☒File is not a video. \n";
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up required variables.
|
// Set up required variables.
|
||||||
var videoIdx = 0
|
var videoIdx = 0;
|
||||||
var extraArguments = ""
|
var extraArguments = "";
|
||||||
var convert = false
|
var convert = false;
|
||||||
|
|
||||||
// Go through each stream in the file.
|
// Go through each stream in the file.
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
// Check if stream is video.
|
// Check if stream is video.
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "video") {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "video") {
|
||||||
// Check if stream codec is mjpeg or png. Remove if so.
|
// Check if stream codec is mjpeg or png. Remove if so.
|
||||||
if (file.ffProbeData.streams[i].codec_name == 'mjpeg' || file.ffProbeData.streams[i].codec_name == 'png') {
|
if (
|
||||||
convert = true
|
file.ffProbeData.streams[i].codec_name == "mjpeg" ||
|
||||||
extraArguments += `-map -v:${videoIdx} `
|
file.ffProbeData.streams[i].codec_name == "png"
|
||||||
}
|
) {
|
||||||
// Increment videoIdx.
|
convert = true;
|
||||||
videoIdx++
|
extraArguments += `-map -v:${videoIdx} `;
|
||||||
}
|
}
|
||||||
|
// Increment videoIdx.
|
||||||
|
videoIdx++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Convert file if convert variable is set to true.
|
// Convert file if convert variable is set to true.
|
||||||
if (convert === true) {
|
if (convert === true) {
|
||||||
response.preset += `,-map 0 -c copy -max_muxing_queue_size 4096 ${extraArguments}`
|
response.preset += `,-map 0 -c copy -max_muxing_queue_size 4096 ${extraArguments}`;
|
||||||
response.infoLog += `☒File has image format stream, removing. \n`
|
response.infoLog += `☒File has image format stream, removing. \n`;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
} else {
|
} else {
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
response.infoLog += "☑File doesn't contain any unwanted image format streams.\n"
|
response.infoLog +=
|
||||||
}
|
"☑File doesn't contain any unwanted image format streams.\n";
|
||||||
return response
|
}
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
module.exports.details = details;
|
module.exports.details = details;
|
||||||
module.exports.plugin = plugin;
|
module.exports.plugin = plugin;
|
||||||
|
|
@ -1,84 +1,94 @@
|
||||||
module.exports.details = function details() {
|
module.exports.details = function details() {
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_MC93_MigzPlex_Autoscan",
|
id: "Tdarr_Plugin_MC93_MigzPlex_Autoscan",
|
||||||
Stage: "Post-processing",
|
Stage: "Post-processing",
|
||||||
Name: "Send request for file to be scanned by plex_autoscan.",
|
Name: "Send request for file to be scanned by plex_autoscan.",
|
||||||
Type: "Video",
|
Type: "Video",
|
||||||
Operation: "",
|
Operation: "",
|
||||||
Description: `Send request for file to be scanned by plex_autoscan. https://github.com/l3uddz/plex_autoscan \n\n`,
|
Description: `Send request for file to be scanned by plex_autoscan. https://github.com/l3uddz/plex_autoscan \n\n`,
|
||||||
Version: "1.1",
|
Version: "1.1",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_MigzPlex_Autoscan.js",
|
Link:
|
||||||
Tags: "3rd party,post-processing,configurable",
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_MigzPlex_Autoscan.js",
|
||||||
|
Tags: "3rd party,post-processing,configurable",
|
||||||
|
|
||||||
Inputs: [{
|
Inputs: [
|
||||||
name: 'autoscan_address',
|
{
|
||||||
tooltip: `
|
name: "autoscan_address",
|
||||||
|
tooltip: `
|
||||||
Enter the IP address/URL for autoscan. Must include http(s)://
|
Enter the IP address/URL for autoscan. Must include http(s)://
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
http://192.168.0.10
|
http://192.168.0.10
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
https://subdomain.domain.tld`
|
https://subdomain.domain.tld`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'autoscan_port',
|
name: "autoscan_port",
|
||||||
tooltip: `
|
tooltip: `
|
||||||
Enter the port Autoscan is using, default is 3468
|
Enter the port Autoscan is using, default is 3468
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
3468`
|
3468`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'autoscan_passkey',
|
name: "autoscan_passkey",
|
||||||
tooltip: `
|
tooltip: `
|
||||||
|
|
||||||
Enter the autoscan passkey.
|
Enter the autoscan passkey.
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
9c4b81fe234e4d6eb9011cefe514d915`
|
9c4b81fe234e4d6eb9011cefe514d915`,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
module.exports.plugin = function plugin(file, librarySettings, inputs) {
|
module.exports.plugin = function plugin(file, librarySettings, inputs) {
|
||||||
|
// Check if all inputs have been configured. If they haven't then exit plugin.
|
||||||
|
if (
|
||||||
|
inputs &&
|
||||||
|
inputs.autoscan_address == "" &&
|
||||||
|
inputs.autoscan_port == "" &&
|
||||||
|
inputs.autoscan_passkey == ""
|
||||||
|
) {
|
||||||
|
response.infoLog +=
|
||||||
|
"☒Autoscan options have not been configured, please configure all options. Skipping this plugin. \n";
|
||||||
|
response.processFile = false;
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if all inputs have been configured. If they haven't then exit plugin.
|
// Take variable inputs and turn them into read only variable
|
||||||
if (inputs && inputs.autoscan_address == "" && inputs.autoscan_port == "" && inputs.autoscan_passkey == "") {
|
const request = require("request");
|
||||||
response.infoLog += "☒Autoscan options have not been configured, please configure all options. Skipping this plugin. \n"
|
const ADDRESS = inputs.autoscan_address;
|
||||||
response.processFile = false;
|
const PORT = inputs.autoscan_port;
|
||||||
return response
|
const PASSKEY = inputs.autoscan_passkey;
|
||||||
|
|
||||||
|
// Set up required variables.
|
||||||
|
var response = "";
|
||||||
|
filepath = `${file.file}`;
|
||||||
|
|
||||||
|
// Set content of request/post.
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// Take variable inputs and turn them into read only variable
|
console.log("request next");
|
||||||
const request = require('request')
|
console.log(request.post);
|
||||||
const ADDRESS = inputs.autoscan_address
|
};
|
||||||
const PORT = inputs.autoscan_port
|
|
||||||
const PASSKEY = inputs.autoscan_passkey
|
|
||||||
|
|
||||||
// Set up required variables.
|
|
||||||
var response = ""
|
|
||||||
filepath = `${file.file}`
|
|
||||||
|
|
||||||
// Set content of request/post.
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_a37x_Drawmonster_MP4_No_Title_Meta",
|
id: "Tdarr_Plugin_a37x_Drawmonster_MP4_No_Title_Meta",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
|
|
@ -11,72 +7,52 @@ function details() {
|
||||||
Description: `[Contains built-in filter] This plugin removes metadata (if a title exists). The output container is mp4. \n\n
|
Description: `[Contains built-in filter] This plugin removes metadata (if a title exists). The output container is mp4. \n\n
|
||||||
`,
|
`,
|
||||||
Version: "1.00",
|
Version: "1.00",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_a37x_Drawmonster_MP4_No_Title_Meta.js",
|
Link:
|
||||||
Tags:'pre-processing,ffmpeg',
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_a37x_Drawmonster_MP4_No_Title_Meta.js",
|
||||||
}
|
Tags: "pre-processing,ffmpeg",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
|
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
processFile: false,
|
||||||
|
preset: "",
|
||||||
|
container: ".mp4",
|
||||||
|
handBrakeMode: false,
|
||||||
|
FFmpegMode: false,
|
||||||
|
reQueueAfter: false,
|
||||||
|
infoLog: "",
|
||||||
|
};
|
||||||
|
|
||||||
processFile : false,
|
response.FFmpegMode = true;
|
||||||
preset : '',
|
|
||||||
container : '.mp4',
|
|
||||||
handBrakeMode : false,
|
|
||||||
FFmpegMode : false,
|
|
||||||
reQueueAfter : false,
|
|
||||||
infoLog : '',
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
response.FFmpegMode = true
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
|
console.log("File is not video");
|
||||||
|
|
||||||
|
response.infoLog += "☒File is not video \n";
|
||||||
console.log("File is not video")
|
|
||||||
|
|
||||||
response.infoLog += "☒File is not video \n"
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
var jsonString = JSON.stringify(file);
|
||||||
|
|
||||||
var jsonString = JSON.stringify(file)
|
///
|
||||||
|
|
||||||
|
///
|
||||||
|
if (file.meta.Title != undefined) {
|
||||||
|
response.infoLog += "☒File has title metadata \n";
|
||||||
|
response.preset = ",-map_metadata -1 -map 0 -c copy";
|
||||||
///
|
|
||||||
|
|
||||||
|
|
||||||
///
|
|
||||||
if(file.meta.Title != undefined ){
|
|
||||||
|
|
||||||
response.infoLog += "☒File has title metadata \n"
|
|
||||||
response.preset = ',-map_metadata -1 -map 0 -c copy'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
return response
|
return response;
|
||||||
}else{
|
} else {
|
||||||
response.infoLog += "☑File has no title metadata \n"
|
response.infoLog += "☑File has no title metadata \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
response.infoLog += "☑File meets conditions! \n"
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
response.infoLog += "☑File meets conditions! \n";
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module.exports.details = function details() {
|
module.exports.details = function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_a9hd_FFMPEG_Transcode_Specific_Audio_Stream_Codecs",
|
id: "Tdarr_Plugin_a9hd_FFMPEG_Transcode_Specific_Audio_Stream_Codecs",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
|
|
@ -12,10 +8,10 @@ module.exports.details = function details() {
|
||||||
Description: `[TESTING][Contains built-in filter] Transcode audio streams with specific codecs into another codec. \n\n`,
|
Description: `[TESTING][Contains built-in filter] Transcode audio streams with specific codecs into another codec. \n\n`,
|
||||||
Version: "1.00",
|
Version: "1.00",
|
||||||
Link: "",
|
Link: "",
|
||||||
Tags:'pre-processing,audio only,ffmpeg,configurable',
|
Tags: "pre-processing,audio only,ffmpeg,configurable",
|
||||||
Inputs: [
|
Inputs: [
|
||||||
{
|
{
|
||||||
name: 'codecs_to_transcode',
|
name: "codecs_to_transcode",
|
||||||
tooltip: `Specifiy the codecs which you'd like to transcode
|
tooltip: `Specifiy the codecs which you'd like to transcode
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
|
|
@ -30,10 +26,10 @@ module.exports.details = function details() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
`
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'codec',
|
name: "codec",
|
||||||
tooltip: `Specify the codec you'd like to transcode into:
|
tooltip: `Specify the codec you'd like to transcode into:
|
||||||
|
|
||||||
\\n aac
|
\\n aac
|
||||||
|
|
@ -52,98 +48,74 @@ module.exports.details = function details() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
`
|
`,
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
};
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.plugin = function plugin(file, librarySettings, inputs) {
|
module.exports.plugin = function plugin(file, librarySettings, inputs) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
container: '.mp4',
|
container: ".mp4",
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: false,
|
FFmpegMode: false,
|
||||||
reQueueAfter: false,
|
reQueueAfter: false,
|
||||||
infoLog: '',
|
infoLog: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (inputs.codecs_to_transcode === undefined || inputs.codec === undefined) {
|
||||||
|
response.processFile = false;
|
||||||
|
response.infoLog += "☒ Inputs not entered! \n";
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inputs.codecs_to_transcode === undefined
|
var encoder = inputs.codec;
|
||||||
|| inputs.codec === undefined
|
|
||||||
) {
|
|
||||||
|
|
||||||
response.processFile = false
|
if (encoder == "mp3") {
|
||||||
response.infoLog += "☒ Inputs not entered! \n"
|
encoder = `libmp3lame`;
|
||||||
return response
|
} else if (encoder == "dts") {
|
||||||
|
encoder = `dca`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var codecs_to_transcode = inputs.codecs_to_transcode.split(",");
|
||||||
|
var hasStreamsToTranscode = false;
|
||||||
|
|
||||||
var encoder = inputs.codec
|
var ffmpegCommand = `, -c copy -map 0:v `;
|
||||||
|
|
||||||
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++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
if (
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" &&
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" &&
|
||||||
file.ffProbeData.streams[i].codec_name &&
|
file.ffProbeData.streams[i].codec_name &&
|
||||||
codecs_to_transcode.includes(file.ffProbeData.streams[i].codec_name.toLowerCase())
|
codecs_to_transcode.includes(
|
||||||
|
file.ffProbeData.streams[i].codec_name.toLowerCase()
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
|
ffmpegCommand += ` -map 0:${i} -c:${i} ${encoder} `;
|
||||||
ffmpegCommand += ` -map 0:${i} -c:${i} ${encoder} `
|
hasStreamsToTranscode = true;
|
||||||
hasStreamsToTranscode = true
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ffmpegCommand += ` -map 0:s? -map 0:d? `;
|
||||||
|
|
||||||
ffmpegCommand += ` -map 0:s? -map 0:d? `
|
console.log;
|
||||||
|
|
||||||
console.log
|
|
||||||
|
|
||||||
|
|
||||||
if (hasStreamsToTranscode == false) {
|
if (hasStreamsToTranscode == false) {
|
||||||
|
response.processFile = false;
|
||||||
response.processFile = false
|
response.infoLog +=
|
||||||
response.infoLog += "☑ File does not have any streams that need to be transcoded! \n"
|
"☑ File does not have any streams that need to be transcoded! \n";
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = ffmpegCommand
|
response.preset = ffmpegCommand;
|
||||||
response.container = '.' + file.container
|
response.container = "." + file.container;
|
||||||
response.handBrakeMode = false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += `☒ File has streams which aren't in desired codec! \n`
|
response.infoLog += `☒ File has streams which aren't in desired codec! \n`;
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_b38x_Nosirus_h265_aac_no_meta",
|
id: "Tdarr_Plugin_b38x_Nosirus_h265_aac_no_meta",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
|
|
@ -11,121 +7,98 @@ 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
|
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",
|
Version: "1.01",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_b38x_Nosirus_h265_aac_no_meta.js",
|
Link:
|
||||||
Tags:'pre-processing,ffmpeg,h265,',
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_b38x_Nosirus_h265_aac_no_meta.js",
|
||||||
}
|
Tags: "pre-processing,ffmpeg,h265,",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
|
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
container: '.mp4',
|
container: ".mp4",
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: false,
|
FFmpegMode: false,
|
||||||
reQueueAfter: false,
|
reQueueAfter: false,
|
||||||
infoLog: '',
|
infoLog: "",
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
|
console.log("File is not video");
|
||||||
|
|
||||||
|
response.infoLog += "☒File is not video \n";
|
||||||
console.log("File is not video")
|
|
||||||
|
|
||||||
response.infoLog += "☒File is not video \n"
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
if (file.ffProbeData.streams[0].codec_name != "hevc") {
|
||||||
|
|
||||||
if(file.ffProbeData.streams[0].codec_name != 'hevc'){
|
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = ', -map 0 -c copy -c:v:0 libx265 -preset:v slow -pix_fmt yuv420p10le -x265-params "crf=22:aq-mode=3"'
|
response.preset =
|
||||||
response.container = '.mkv'
|
', -map 0 -c copy -c:v:0 libx265 -preset:v slow -pix_fmt yuv420p10le -x265-params "crf=22:aq-mode=3"';
|
||||||
response.FFmpegMode = true
|
response.container = ".mkv";
|
||||||
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File is not in hevc! \n"
|
response.infoLog += "☒File is not in hevc! \n";
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
|
response.infoLog += "☑File is already in hevc! \n";
|
||||||
|
}
|
||||||
|
|
||||||
}else{
|
var audioIdx = -1;
|
||||||
response.infoLog += "☑File is already in hevc! \n"
|
var ffmpegCommandInsert = "";
|
||||||
}
|
var hasnonAACTrack = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var audioIdx = -1
|
|
||||||
var ffmpegCommandInsert = ''
|
|
||||||
var hasnonAACTrack = false
|
|
||||||
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
||||||
audioIdx++
|
audioIdx++;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (file.ffProbeData.streams[i].codec_name !== 'aac' && file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" ) {
|
if (
|
||||||
ffmpegCommandInsert += ` -c:a:${audioIdx} aac -vbr 4 `
|
file.ffProbeData.streams[i].codec_name !== "aac" &&
|
||||||
hasnonAACTrack = true
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio"
|
||||||
|
) {
|
||||||
|
ffmpegCommandInsert += ` -c:a:${audioIdx} aac -vbr 4 `;
|
||||||
|
hasnonAACTrack = true;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var ffmpegCommand = `,-map 0 -c:v copy -c:a copy ${ffmpegCommandInsert} -c:s copy -c:d copy`
|
var ffmpegCommand = `,-map 0 -c:v copy -c:a copy ${ffmpegCommandInsert} -c:s copy -c:d copy`;
|
||||||
|
|
||||||
if (hasnonAACTrack == true) {
|
if (hasnonAACTrack == true) {
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = ffmpegCommand
|
response.preset = ffmpegCommand;
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode = false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒ File has audio which is not in aac! \n"
|
response.infoLog += "☒ File has audio which is not in aac! \n";
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
response.infoLog += "☑ All audio streams are in aac! \n"
|
response.infoLog += "☑ All audio streams are in aac! \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (file.meta.Title != undefined) {
|
if (file.meta.Title != undefined) {
|
||||||
|
response.infoLog += "☒File has title metadata \n";
|
||||||
response.infoLog += "☒File has title metadata \n"
|
response.preset =
|
||||||
response.preset = ',-metadata title="" -metadata comment="" -map 0 -c copy'
|
',-metadata title="" -metadata comment="" -map 0 -c copy';
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
} else {
|
} else {
|
||||||
response.infoLog += "☑File has no title metadata \n"
|
response.infoLog += "☑File has no title metadata \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
response.infoLog += "☑File meets conditions! \n"
|
response.infoLog += "☑File meets conditions! \n";
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_b39x_the1poet_surround_sound_to_ac3",
|
id: "Tdarr_Plugin_b39x_the1poet_surround_sound_to_ac3",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
|
|
@ -11,92 +7,73 @@ 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
|
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",
|
Version: "1.00",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_b39x_the1poet_surround_sound_to_ac3.js",
|
Link:
|
||||||
Tags:'pre-processing,ffmpeg,audio only,',
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_b39x_the1poet_surround_sound_to_ac3.js",
|
||||||
}
|
Tags: "pre-processing,ffmpeg,audio only,",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
|
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
container: '.mp4',
|
container: ".mp4",
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: false,
|
FFmpegMode: false,
|
||||||
reQueueAfter: false,
|
reQueueAfter: false,
|
||||||
infoLog: '',
|
infoLog: "",
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
|
console.log("File is not video");
|
||||||
|
|
||||||
|
response.infoLog += "☒File is not video \n";
|
||||||
console.log("File is not video")
|
|
||||||
|
|
||||||
response.infoLog += "☒File is not video \n"
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
var audioIdx = -1;
|
||||||
|
var ffmpegCommandInsert = "";
|
||||||
var audioIdx = -1
|
var hasnonAC3SurroundTrack = false;
|
||||||
var ffmpegCommandInsert = ''
|
|
||||||
var hasnonAC3SurroundTrack = false
|
|
||||||
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
||||||
audioIdx++
|
audioIdx++;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ( file.ffProbeData.streams[i].channels >= 6 && file.ffProbeData.streams[i].codec_name !== 'ac3' && file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" ) {
|
if (
|
||||||
ffmpegCommandInsert += ` -c:a:${audioIdx} ac3 `
|
file.ffProbeData.streams[i].channels >= 6 &&
|
||||||
hasnonAC3SurroundTrack = true
|
file.ffProbeData.streams[i].codec_name !== "ac3" &&
|
||||||
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio"
|
||||||
|
) {
|
||||||
|
ffmpegCommandInsert += ` -c:a:${audioIdx} ac3 `;
|
||||||
|
hasnonAC3SurroundTrack = true;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var ffmpegCommand = `,-map 0 -c:v copy -c:a copy ${ffmpegCommandInsert} -c:s copy -c:d copy`
|
var ffmpegCommand = `,-map 0 -c:v copy -c:a copy ${ffmpegCommandInsert} -c:s copy -c:d copy`;
|
||||||
|
|
||||||
if (hasnonAC3SurroundTrack == true) {
|
if (hasnonAC3SurroundTrack == true) {
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = ffmpegCommand
|
response.preset = ffmpegCommand;
|
||||||
response.container = '.' + file.container
|
response.container = "." + file.container;
|
||||||
response.handBrakeMode = false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒ File has surround audio which is not in ac3! \n"
|
response.infoLog += "☒ File has surround audio which is not in ac3! \n";
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
response.infoLog += "☑ All surround audio streams are in aac! \n"
|
response.infoLog += "☑ All surround audio streams are in aac! \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
response.infoLog += "☑File meets conditions! \n";
|
||||||
|
return response;
|
||||||
|
|
||||||
|
|
||||||
response.infoLog += "☑File meets conditions! \n"
|
|
||||||
return response
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,20 @@
|
||||||
module.exports.details = function details() {
|
module.exports.details = function details() {
|
||||||
|
return {
|
||||||
|
id: "Tdarr_Plugin_c0r1_SetDefaultAudioStream",
|
||||||
|
Stage: "Pre-processing",
|
||||||
|
Name: "Set Default Audio Stream (Based On Channel Count)",
|
||||||
|
Type: "Audio",
|
||||||
|
Operation: "Transcode",
|
||||||
|
Description: `This plugin will set an audio channel (2.0, 5.1, 7.1) to default and remove default from all other audio streams \n\n`,
|
||||||
|
Version: "0.1.0a",
|
||||||
|
Link:
|
||||||
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_c0r1_SetDefaultAudioStream.js",
|
||||||
|
Tags: "audio only,ffmpeg,configurable",
|
||||||
|
|
||||||
return {
|
Inputs: [
|
||||||
id: "Tdarr_Plugin_c0r1_SetDefaultAudioStream",
|
{
|
||||||
Stage: "Pre-processing",
|
name: "channels",
|
||||||
Name: "Set Default Audio Stream (Based On Channel Count)",
|
tooltip: `Desired audio channel number.
|
||||||
Type: "Audio",
|
|
||||||
Operation: "Transcode",
|
|
||||||
Description: `This plugin will set an audio channel (2.0, 5.1, 7.1) to default and remove default from all other audio streams \n\n`,
|
|
||||||
Version: "0.1.0a",
|
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_c0r1_SetDefaultAudioStream.js",
|
|
||||||
Tags:"audio only,ffmpeg,configurable",
|
|
||||||
|
|
||||||
Inputs: [
|
|
||||||
{
|
|
||||||
name: 'channels',
|
|
||||||
tooltip: `Desired audio channel number.
|
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
|
|
||||||
|
|
@ -26,84 +26,86 @@ module.exports.details = function details() {
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
|
|
||||||
8`
|
8`,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.plugin = function plugin(file, librarySettings, inputs) {
|
module.exports.plugin = function plugin(file, librarySettings, inputs) {
|
||||||
var response = {
|
var response = {
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
container: '.' + file.container,
|
container: "." + file.container,
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: true,
|
FFmpegMode: true,
|
||||||
infoLog: '',
|
infoLog: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
var shouldProcess = false;
|
||||||
|
var defaultAudioStreams = 0;
|
||||||
|
var matchingAudioStreams = 0;
|
||||||
|
var defaultSet = false;
|
||||||
|
var ffmpegCommandInsert = "";
|
||||||
|
|
||||||
|
// Check if default audio stream matches user's channel selection
|
||||||
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
if (
|
||||||
|
file.ffProbeData.streams[i].codec_type.toLowerCase() === "audio" &&
|
||||||
|
file.ffProbeData.streams[i].channels == inputs.channels
|
||||||
|
) {
|
||||||
|
matchingAudioStreams++;
|
||||||
|
if (file.ffProbeData.streams[i].disposition.default === 1) {
|
||||||
|
defaultAudioStreams++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var shouldProcess = false
|
// build command
|
||||||
var defaultAudioStreams = 0
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
var matchingAudioStreams = 0
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() === "audio") {
|
||||||
var defaultSet = false
|
if (file.ffProbeData.streams[i].channels == inputs.channels) {
|
||||||
var ffmpegCommandInsert = ''
|
if (!defaultSet) {
|
||||||
|
ffmpegCommandInsert += `-disposition:${i} default `;
|
||||||
|
defaultSet = true;
|
||||||
// Check if default audio stream matches user's channel selection
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
|
||||||
if(file.ffProbeData.streams[i].codec_type.toLowerCase() === "audio" &&
|
|
||||||
file.ffProbeData.streams[i].channels == inputs.channels)
|
|
||||||
{
|
|
||||||
matchingAudioStreams++
|
|
||||||
if(file.ffProbeData.streams[i].disposition.default === 1){
|
|
||||||
defaultAudioStreams++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// build command
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
|
||||||
if(file.ffProbeData.streams[i].codec_type.toLowerCase() === "audio")
|
|
||||||
{
|
|
||||||
if(file.ffProbeData.streams[i].channels == inputs.channels)
|
|
||||||
{
|
|
||||||
if(!defaultSet){
|
|
||||||
ffmpegCommandInsert += `-disposition:${i} default `
|
|
||||||
defaultSet = true
|
|
||||||
} else {
|
|
||||||
ffmpegCommandInsert += `-disposition:${i} 0 `
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ffmpegCommandInsert += `-disposition:${i} 0 `
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only process when there is a matching stream and
|
|
||||||
// when there is either no default or more than 1 default stream set
|
|
||||||
if(matchingAudioStreams >= 1 && defaultAudioStreams !== 1) {
|
|
||||||
shouldProcess = true;
|
|
||||||
response.infoLog += "☒ Matching audio stream is not set to default. \n"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldProcess) {
|
|
||||||
response.processFile = true;
|
|
||||||
response.reQueueAfter = true;
|
|
||||||
response.preset = `,-map 0 -c copy ${ffmpegCommandInsert}`;
|
|
||||||
response.infoLog += "☒ Setting " + inputs.channels + " channel matching audio stream to default. Remove default from all other audio streams \n"
|
|
||||||
} else {
|
|
||||||
if(matchingAudioStreams < 1){
|
|
||||||
response.infoLog += "☑ No " + inputs.channels + " channel audio stream exists. \n "
|
|
||||||
} else if (defaultAudioStreams === 1){
|
|
||||||
response.infoLog += "☑ Default " + inputs.channels + " channel audio stream already exists. \n "
|
|
||||||
} else {
|
} else {
|
||||||
response.infoLog += "☑ Unexpected: Did not process \n "
|
ffmpegCommandInsert += `-disposition:${i} 0 `;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
response.processFile = false;
|
ffmpegCommandInsert += `-disposition:${i} 0 `;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return response
|
}
|
||||||
|
|
||||||
}
|
// Only process when there is a matching stream and
|
||||||
|
// when there is either no default or more than 1 default stream set
|
||||||
|
if (matchingAudioStreams >= 1 && defaultAudioStreams !== 1) {
|
||||||
|
shouldProcess = true;
|
||||||
|
response.infoLog += "☒ Matching audio stream is not set to default. \n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldProcess) {
|
||||||
|
response.processFile = true;
|
||||||
|
response.reQueueAfter = true;
|
||||||
|
response.preset = `,-map 0 -c copy ${ffmpegCommandInsert}`;
|
||||||
|
response.infoLog +=
|
||||||
|
"☒ Setting " +
|
||||||
|
inputs.channels +
|
||||||
|
" channel matching audio stream to default. Remove default from all other audio streams \n";
|
||||||
|
} else {
|
||||||
|
if (matchingAudioStreams < 1) {
|
||||||
|
response.infoLog +=
|
||||||
|
"☑ No " + inputs.channels + " channel audio stream exists. \n ";
|
||||||
|
} else if (defaultAudioStreams === 1) {
|
||||||
|
response.infoLog +=
|
||||||
|
"☑ Default " +
|
||||||
|
inputs.channels +
|
||||||
|
" channel audio stream already exists. \n ";
|
||||||
|
} else {
|
||||||
|
response.infoLog += "☑ Unexpected: Did not process \n ";
|
||||||
|
}
|
||||||
|
|
||||||
|
response.processFile = false;
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -4,189 +4,193 @@ function details() {
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
Name: "Tiered FFMPEG NVENC settings depending on resolution",
|
Name: "Tiered FFMPEG NVENC settings depending on resolution",
|
||||||
Type: "Video",
|
Type: "Video",
|
||||||
Operation:"Transcode",
|
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`,
|
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.09",
|
Version: "1.09",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_d5d3_iiDrakeii_FFMPEG_NVENC_Tiered_MKV.js",
|
Link:
|
||||||
Tags:'pre-processing,ffmpeg,video only,nvenc h265',
|
"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",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
var transcode = 0; //if this var changes to 1 the file will be transcoded
|
var transcode = 0; //if this var changes to 1 the file will be transcoded
|
||||||
var bitrateprobe = 0; //bitrate from ffprobe
|
var bitrateprobe = 0; //bitrate from ffprobe
|
||||||
var bitratetarget = 0;
|
var bitratetarget = 0;
|
||||||
var bitratemax = 0;
|
var bitratemax = 0;
|
||||||
var bitratecheck = 0;
|
var bitratecheck = 0;
|
||||||
var subcli = `-c:s copy`;
|
var subcli = `-c:s copy`;
|
||||||
var maxmux = '';
|
var maxmux = "";
|
||||||
var map = '-map 0'
|
var map = "-map 0";
|
||||||
//default values that will be returned
|
//default values that will be returned
|
||||||
var response = {
|
var response = {
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
container: '.mkv',
|
container: ".mkv",
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: false,
|
FFmpegMode: false,
|
||||||
reQueueAfter: true,
|
reQueueAfter: true,
|
||||||
infoLog: '',
|
infoLog: "",
|
||||||
maxmux: false,
|
maxmux: false,
|
||||||
}
|
};
|
||||||
|
|
||||||
//check if the file is a video, if not the function will be stopped immediately
|
//check if the file is a video, if not the function will be stopped immediately
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
response.processFile = false
|
response.processFile = false;
|
||||||
response.infoLog += "☒File is not a video! \n"
|
response.infoLog += "☒File is not a video! \n";
|
||||||
return response
|
return response;
|
||||||
}
|
} else {
|
||||||
else {
|
bitrateprobe = file.ffProbeData.streams[0].bit_rate;
|
||||||
bitrateprobe = file.ffProbeData.streams[0].bit_rate
|
response.infoLog += "☑File is a video! \n";
|
||||||
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
|
//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') {
|
if (file.ffProbeData.streams[0].codec_name == "hevc") {
|
||||||
response.processFile = false
|
response.processFile = false;
|
||||||
response.infoLog += "☑File is already in hevc! \n"
|
response.infoLog += "☑File is already in hevc! \n";
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
//codec will be checked so it can be transcoded correctly
|
//codec will be checked so it can be transcoded correctly
|
||||||
if (file.video_codec_name == 'h263') {
|
if (file.video_codec_name == "h263") {
|
||||||
response.preset = `-c:v h263_cuvid`
|
response.preset = `-c:v h263_cuvid`;
|
||||||
}
|
} else if (file.video_codec_name == "h264") {
|
||||||
else if (file.video_codec_name == 'h264') {
|
if (file.ffProbeData.streams[0].profile != "High 10") {
|
||||||
if (file.ffProbeData.streams[0].profile != 'High 10') { //Remove HW Decoding for High 10 Profile
|
//Remove HW Decoding for High 10 Profile
|
||||||
response.preset = `-c:v h264_cuvid`
|
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 == 'mjpeg') {
|
// skipping this one because it's empty
|
||||||
response.preset = `c:v mjpeg_cuvid`
|
// else if (file.video_codec_name == 'mpeg4') {
|
||||||
}
|
// response.preset = ``
|
||||||
else if (file.video_codec_name == 'mpeg1') {
|
// }
|
||||||
response.preset = `-c:v mpeg1_cuvid`
|
else if (file.video_codec_name == "vc1") {
|
||||||
}
|
response.preset = `-c:v vc1_cuvid`;
|
||||||
else if (file.video_codec_name == 'mpeg2') {
|
} else if (file.video_codec_name == "vp8") {
|
||||||
response.preset = `-c:v mpeg2_cuvid`
|
response.preset = `-c:v vp8_cuvid`;
|
||||||
}
|
} else if (file.video_codec_name == "vp9") {
|
||||||
// skipping this one because it's empty
|
response.preset = `-c:v vp9_cuvid`;
|
||||||
// else if (file.video_codec_name == 'mpeg4') {
|
|
||||||
// response.preset = ``
|
|
||||||
// }
|
|
||||||
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`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Set Subtitle Var before adding encode cli
|
//Set Subtitle Var before adding encode cli
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
try {
|
try {
|
||||||
if (file.ffProbeData.streams[i].codec_name.toLowerCase() == "mov_text" && file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle" ) {
|
if (
|
||||||
subcli = `-c:s srt`
|
file.ffProbeData.streams[i].codec_name.toLowerCase() == "mov_text" &&
|
||||||
}
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle"
|
||||||
}
|
) {
|
||||||
catch (err) { }
|
subcli = `-c:s srt`;
|
||||||
//mitigate TrueHD audio causing Too many packets error
|
}
|
||||||
try {
|
} catch (err) {}
|
||||||
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" ) {
|
//mitigate TrueHD audio causing Too many packets error
|
||||||
maxmux = ` -max_muxing_queue_size 9999`
|
try {
|
||||||
}
|
if (
|
||||||
}
|
file.ffProbeData.streams[i].codec_name.toLowerCase() == "truehd" ||
|
||||||
catch (err) { }
|
(file.ffProbeData.streams[i].codec_name.toLowerCase() == "dts" &&
|
||||||
//mitigate errors due to embeded pictures
|
file.ffProbeData.streams[i].profile.toLowerCase() == "dts-hd ma") ||
|
||||||
try {
|
(file.ffProbeData.streams[i].codec_name.toLowerCase() == "aac" &&
|
||||||
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" ) {
|
file.ffProbeData.streams[i].sample_rate.toLowerCase() == "44100" &&
|
||||||
map = `-map 0:v:0 -map 0:a -map 0:s?`
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio")
|
||||||
}
|
) {
|
||||||
}
|
maxmux = ` -max_muxing_queue_size 9999`;
|
||||||
catch (err) { }
|
}
|
||||||
|
} 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
|
//file will be encoded if the resolution is 480p or 576p
|
||||||
//codec will be checked so it can be transcoded correctly
|
//codec will be checked so it can be transcoded correctly
|
||||||
if (file.video_resolution === "480p" || file.video_resolution === "576p" ) {
|
if (file.video_resolution === "480p" || file.video_resolution === "576p") {
|
||||||
bitratecheck = 1000000;
|
bitratecheck = 1000000;
|
||||||
if(bitrateprobe != null && bitrateprobe < bitratecheck) {
|
if (bitrateprobe != null && bitrateprobe < bitratecheck) {
|
||||||
bitratetarget = parseInt((bitrateprobe * .8) / 1000); // Lower Bitrate to 60% of original and convert to KB
|
bitratetarget = parseInt((bitrateprobe * 0.8) / 1000); // Lower Bitrate to 60% of original and convert to KB
|
||||||
bitratemax = bitratetarget + 500; // Set max bitrate to 6MB Higher
|
bitratemax = bitratetarget + 500; // Set max bitrate to 6MB Higher
|
||||||
}
|
} else {
|
||||||
else {
|
bitratetarget = 1000;
|
||||||
bitratetarget = 1000;
|
bitratemax = 1500;
|
||||||
bitratemax = 1500;
|
|
||||||
}
|
}
|
||||||
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}`;
|
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;
|
transcode = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//file will be encoded if the resolution is 720p
|
//file will be encoded if the resolution is 720p
|
||||||
//codec will be checked so it can be transcoded correctly
|
//codec will be checked so it can be transcoded correctly
|
||||||
if(file.video_resolution === "720p") {
|
if (file.video_resolution === "720p") {
|
||||||
bitratecheck = 2000000;
|
bitratecheck = 2000000;
|
||||||
if(bitrateprobe != null && bitrateprobe < bitratecheck) {
|
if (bitrateprobe != null && bitrateprobe < bitratecheck) {
|
||||||
bitratetarget = parseInt((bitrateprobe * .8) / 1000); // Lower Bitrate to 60% of original and convert to KB
|
bitratetarget = parseInt((bitrateprobe * 0.8) / 1000); // Lower Bitrate to 60% of original and convert to KB
|
||||||
bitratemax = bitratetarget + 2000; // Set max bitrate to 6MB Higher
|
bitratemax = bitratetarget + 2000; // Set max bitrate to 6MB Higher
|
||||||
}
|
} else {
|
||||||
else {
|
bitratetarget = 2000;
|
||||||
bitratetarget = 2000;
|
bitratemax = 4000;
|
||||||
bitratemax = 4000;
|
|
||||||
}
|
}
|
||||||
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}`;
|
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;
|
transcode = 1;
|
||||||
}
|
}
|
||||||
//file will be encoded if the resolution is 1080p
|
//file will be encoded if the resolution is 1080p
|
||||||
//codec will be checked so it can be transcoded correctly
|
//codec will be checked so it can be transcoded correctly
|
||||||
if(file.video_resolution === "1080p") {
|
if (file.video_resolution === "1080p") {
|
||||||
bitratecheck = 2500000;
|
bitratecheck = 2500000;
|
||||||
if(bitrateprobe != null && bitrateprobe < bitratecheck) {
|
if (bitrateprobe != null && bitrateprobe < bitratecheck) {
|
||||||
bitratetarget = parseInt((bitrateprobe * .8) / 1000); // Lower Bitrate to 60% of original and convert to KB
|
bitratetarget = parseInt((bitrateprobe * 0.8) / 1000); // Lower Bitrate to 60% of original and convert to KB
|
||||||
bitratemax = bitratetarget + 2500; // Set max bitrate to 6MB Higher
|
bitratemax = bitratetarget + 2500; // Set max bitrate to 6MB Higher
|
||||||
}
|
} else {
|
||||||
else {
|
bitratetarget = 2500;
|
||||||
bitratetarget = 2500;
|
bitratemax = 5000;
|
||||||
bitratemax = 5000;
|
|
||||||
}
|
}
|
||||||
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}`;
|
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;
|
transcode = 1;
|
||||||
}
|
}
|
||||||
//file will be encoded if the resolution is 4K
|
//file will be encoded if the resolution is 4K
|
||||||
//codec will be checked so it can be transcoded correctly
|
//codec will be checked so it can be transcoded correctly
|
||||||
if(file.video_resolution === "4KUHD") {
|
if (file.video_resolution === "4KUHD") {
|
||||||
bitratecheck = 14000000;
|
bitratecheck = 14000000;
|
||||||
if(bitrateprobe != null && bitrateprobe < bitratecheck) {
|
if (bitrateprobe != null && bitrateprobe < bitratecheck) {
|
||||||
bitratetarget = parseInt((bitrateprobe * .7) / 1000); // Lower Bitrate to 60% of original and convert to KB
|
bitratetarget = parseInt((bitrateprobe * 0.7) / 1000); // Lower Bitrate to 60% of original and convert to KB
|
||||||
bitratemax = bitratetarget + 6000; // Set max bitrate to 6MB Higher
|
bitratemax = bitratetarget + 6000; // Set max bitrate to 6MB Higher
|
||||||
|
} else {
|
||||||
|
bitratetarget = 14000;
|
||||||
|
bitratemax = 20000;
|
||||||
}
|
}
|
||||||
else {
|
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}`;
|
||||||
bitratetarget = 14000;
|
transcode = 1;
|
||||||
bitratemax = 20000;
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
//check if the file is eligible for transcoding
|
//check if the file is eligible for transcoding
|
||||||
//if true the neccessary response values will be changed
|
//if true the neccessary response values will be changed
|
||||||
if (transcode == 1) {
|
if (transcode == 1) {
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += `☒File is ${file.video_resolution}!\n`
|
response.infoLog += `☒File is ${file.video_resolution}!\n`;
|
||||||
response.infoLog += `☒File is not hevc!\n`
|
response.infoLog += `☒File is not hevc!\n`;
|
||||||
response.infoLog += `☒File bitrate is ${parseInt(bitrateprobe / 1000)}kb!\n`
|
response.infoLog += `☒File bitrate is ${parseInt(
|
||||||
if(bitrateprobe < bitratecheck) {
|
bitrateprobe / 1000
|
||||||
response.infoLog += `File bitrate is LOWER than the Default Target Bitrate!\n`
|
)}kb!\n`;
|
||||||
}
|
if (bitrateprobe < bitratecheck) {
|
||||||
else {
|
response.infoLog += `File bitrate is LOWER than the Default Target Bitrate!\n`;
|
||||||
response.infoLog += `File bitrate is HIGHER than the Default Target Bitrate!\n`
|
} else {
|
||||||
}
|
response.infoLog += `File bitrate is HIGHER than the Default Target Bitrate!\n`;
|
||||||
response.infoLog += `☒Target Bitrate set to ${bitratetarget}kb!\n`
|
}
|
||||||
response.infoLog += `File is being transcoded!\n`
|
response.infoLog += `☒Target Bitrate set to ${bitratetarget}kb!\n`;
|
||||||
|
response.infoLog += `File is being transcoded!\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
module.exports.details = details;
|
module.exports.details = details;
|
||||||
module.exports.plugin = plugin;
|
module.exports.plugin = plugin;
|
||||||
|
|
|
||||||
|
|
@ -4,75 +4,75 @@ function details() {
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
Name: "Mjpeg Stream False Not A Video Fixer",
|
Name: "Mjpeg Stream False Not A Video Fixer",
|
||||||
Type: "Video",
|
Type: "Video",
|
||||||
Operation:"",
|
Operation: "",
|
||||||
Description: `Checks if file is not a video file due to Mjpeg stream. Removes Mjpeg Stream \n\n`,
|
Description: `Checks if file is not a video file due to Mjpeg stream. Removes Mjpeg Stream \n\n`,
|
||||||
Version: "1.00",
|
Version: "1.00",
|
||||||
Tags:'pre-processing,ffmpeg,'
|
Tags: "pre-processing,ffmpeg,",
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
var transcode = 0; //if this var changes to 1 the file will be transcoded
|
var transcode = 0; //if this var changes to 1 the file will be transcoded
|
||||||
//default values that will be returned
|
//default values that will be returned
|
||||||
var response = {
|
var response = {
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
container: '.mp4',
|
container: ".mp4",
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: false,
|
FFmpegMode: false,
|
||||||
reQueueAfter: true,
|
reQueueAfter: true,
|
||||||
infoLog: ''
|
infoLog: "",
|
||||||
}
|
};
|
||||||
response.container = '.' + file.container
|
response.container = "." + file.container;
|
||||||
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
//check for mjpeg streams and set the preset if mjpeg streams are found
|
//check for mjpeg streams and set the preset if mjpeg streams are found
|
||||||
try {
|
try {
|
||||||
if ((file.ffProbeData.streams[i].codec_name.toLowerCase() == "mjpeg") && file.ffProbeData.streams[i].codec_type.toLowerCase() == "video" ) {
|
if (
|
||||||
response.preset = `,-map 0 -map -0:v:1 -c:v copy -c:a copy -c:s copy`
|
file.ffProbeData.streams[i].codec_name.toLowerCase() == "mjpeg" &&
|
||||||
response.infoLog = "☒File is not a video but has Mjpeg Stream! \n"
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "video"
|
||||||
}
|
) {
|
||||||
}
|
response.preset = `,-map 0 -map -0:v:1 -c:v copy -c:a copy -c:s copy`;
|
||||||
catch (err) { }
|
response.infoLog = "☒File is not a video but has Mjpeg Stream! \n";
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
}
|
}
|
||||||
//If preset is not set check if file is video and stop (reque if it is a video)
|
//If preset is not set check if file is video and stop (reque if it is a video)
|
||||||
if (response.preset != `,-map 0 -map -0:v:1 -c:v copy -c:a copy -c:s copy`) {
|
if (response.preset != `,-map 0 -map -0:v:1 -c:v copy -c:a copy -c:s copy`) {
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
console.log("File is not video!")
|
console.log("File is not video!");
|
||||||
response.infoLog += " File is not video\n"
|
response.infoLog += " File is not video\n";
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
}
|
} else {
|
||||||
else {
|
response.infoLog += "☑File is a video Without Mjpeg! \n";
|
||||||
response.infoLog += "☑File is a video Without Mjpeg! \n"
|
response.processFile = false;
|
||||||
response.processFile = false
|
response.reQueueAfter = true;
|
||||||
response.reQueueAfter = true
|
return response;
|
||||||
return response
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//Process mjpeg removal if video found to not be a video and have mjpeg stream
|
//Process mjpeg removal if video found to not be a video and have mjpeg stream
|
||||||
else {
|
else {
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
transcode = 1
|
transcode = 1;
|
||||||
}
|
} else {
|
||||||
else {
|
response.infoLog += "☑File is a video With Mjpeg! \n";
|
||||||
response.infoLog += "☑File is a video With Mjpeg! \n"
|
response.processFile = false;
|
||||||
response.processFile = false
|
response.reQueueAfter = true;
|
||||||
response.reQueueAfter = true
|
return response;
|
||||||
return response
|
}
|
||||||
}
|
}
|
||||||
}
|
//check if the file is eligible for transcoding
|
||||||
//check if the file is eligible for transcoding
|
//if true the neccessary response values will be changed
|
||||||
//if true the neccessary response values will be changed
|
|
||||||
if (transcode == 1) {
|
if (transcode == 1) {
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += `Mjpeg Stream is being removed!\n`
|
response.infoLog += `Mjpeg Stream is being removed!\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
module.exports.details = details;
|
module.exports.details = details;
|
||||||
module.exports.plugin = plugin;
|
module.exports.plugin = plugin;
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,17 @@ function details() {
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_da11_Dallas_FFmpeg_Presets_H264_MP4",
|
id: "Tdarr_Plugin_da11_Dallas_FFmpeg_Presets_H264_MP4",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
Name: "Dallas FFmpeg h264 mp4. Video: h264/mp4, Subs: Convert to mov_text or drop, Audio: aac",
|
Name:
|
||||||
|
"Dallas FFmpeg h264 mp4. Video: h264/mp4, Subs: Convert to mov_text or drop, Audio: aac",
|
||||||
Type: "Video",
|
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`,
|
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",
|
Version: "1.00",
|
||||||
Link: "https://github.com/JackDallas/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_da11_Dallas_FFmpeg_Presets_H264_MP4.js",
|
Link:
|
||||||
Tags:'pre-processing,ffmpeg,h264,video only,configurable',
|
"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: [
|
Inputs: [
|
||||||
{
|
{
|
||||||
name: 'FFmpeg_preset',
|
name: "FFmpeg_preset",
|
||||||
tooltip: `Select the FFmpeg preset you wish to use,(slow,medium,fast,veryfast).
|
tooltip: `Select the FFmpeg preset you wish to use,(slow,medium,fast,veryfast).
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
|
|
@ -23,24 +25,21 @@ function details() {
|
||||||
fast
|
fast
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
veryfast`
|
veryfast`,
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const presets = [
|
const presets = ["slow", "medium", "fast", "veryfast"];
|
||||||
"slow", "medium", "fast", "veryfast"
|
|
||||||
];
|
|
||||||
|
|
||||||
// Normalizes the preset or if invalid returns null
|
// Normalizes the preset or if invalid returns null
|
||||||
function getPreset(preset) {
|
function getPreset(preset) {
|
||||||
if (!preset)
|
if (!preset) return null;
|
||||||
return null;
|
|
||||||
|
|
||||||
preset = preset.toLowerCase();
|
preset = preset.toLowerCase();
|
||||||
// Strip Spaces
|
// Strip Spaces
|
||||||
preset = preset.replace(/\s+/g, '');
|
preset = preset.replace(/\s+/g, "");
|
||||||
|
|
||||||
if (presets.includes(preset)) {
|
if (presets.includes(preset)) {
|
||||||
return preset;
|
return preset;
|
||||||
|
|
@ -55,16 +54,16 @@ const BAD = false;
|
||||||
function plugin(file, librarySettings, inputs) {
|
function plugin(file, librarySettings, inputs) {
|
||||||
var response = {
|
var response = {
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
container: '.mp4',
|
container: ".mp4",
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: false,
|
FFmpegMode: false,
|
||||||
reQueueAfter: false,
|
reQueueAfter: false,
|
||||||
infoLog: '',
|
infoLog: "",
|
||||||
addInfo(status, info) {
|
addInfo(status, info) {
|
||||||
this.infoLog += (status ? "☑" : "☒") + " " + info + "\n";
|
this.infoLog += (status ? "☑" : "☒") + " " + info + "\n";
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
// Check the file is a video
|
// Check the file is a video
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
|
|
@ -78,12 +77,15 @@ function plugin(file, librarySettings, inputs) {
|
||||||
let preset = getPreset(inputs.FFmpeg_preset);
|
let preset = getPreset(inputs.FFmpeg_preset);
|
||||||
|
|
||||||
if (preset === null) {
|
if (preset === null) {
|
||||||
response.addInfo(BAD, `Invalid Preset, \"${inputs.FFmpeg_preset}\" please select from (slow,medium,fast,veryfast)`);
|
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`
|
throw `Error: Invalid Preset, \"${inputs.FFmpeg_preset}\" please select from (slow,medium,fast,veryfast) \n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
var jsonString = JSON.stringify(file)
|
var jsonString = JSON.stringify(file);
|
||||||
|
|
||||||
var hasSubs = false;
|
var hasSubs = false;
|
||||||
var hasBadSubs = false;
|
var hasBadSubs = false;
|
||||||
|
|
@ -94,12 +96,15 @@ function plugin(file, librarySettings, inputs) {
|
||||||
try {
|
try {
|
||||||
let streamData = file.ffProbeData.streams[i];
|
let streamData = file.ffProbeData.streams[i];
|
||||||
if (streamData.codec_type.toLowerCase() == "subtitle") {
|
if (streamData.codec_type.toLowerCase() == "subtitle") {
|
||||||
if (streamData.codec_name === "hdmv_pgs_subtitle" || streamData.codec_name === "dvd_subtitle") {
|
if (
|
||||||
|
streamData.codec_name === "hdmv_pgs_subtitle" ||
|
||||||
|
streamData.codec_name === "dvd_subtitle"
|
||||||
|
) {
|
||||||
hasBadSubs = true;
|
hasBadSubs = true;
|
||||||
// Drop incompatible subs
|
// Drop incompatible subs
|
||||||
subMap += " -map -0:" + streamData.index + " ";
|
subMap += " -map -0:" + streamData.index + " ";
|
||||||
} else if (streamData.codec_name != "mov_text") {
|
} else if (streamData.codec_name != "mov_text") {
|
||||||
hasSubs = true
|
hasSubs = true;
|
||||||
// Keep compatible subs
|
// Keep compatible subs
|
||||||
subMap += " -map 0:" + streamData.index + " ";
|
subMap += " -map 0:" + streamData.index + " ";
|
||||||
}
|
}
|
||||||
|
|
@ -112,9 +117,13 @@ function plugin(file, librarySettings, inputs) {
|
||||||
if (hasBadSubs)
|
if (hasBadSubs)
|
||||||
response.addInfo(BAD, "File contains unsupported sub(s), dropping these!");
|
response.addInfo(BAD, "File contains unsupported sub(s), dropping these!");
|
||||||
|
|
||||||
if (file.ffProbeData.streams[0].codec_name != 'h264') {
|
if (file.ffProbeData.streams[0].codec_name != "h264") {
|
||||||
response.addInfo(BAD, "File is not in 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.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.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true;
|
response.FFmpegMode = true;
|
||||||
|
|
@ -123,18 +132,26 @@ function plugin(file, librarySettings, inputs) {
|
||||||
response.addInfo(GOOD, "File is already in h264!");
|
response.addInfo(GOOD, "File is already in h264!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((file.meta.Title != undefined) && !jsonString.includes("aac") && hasSubs) {
|
if (file.meta.Title != undefined && !jsonString.includes("aac") && hasSubs) {
|
||||||
response.addInfo(BAD, "File has title metadata and no aac and subs");
|
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.preset =
|
||||||
|
", -map_metadata -1 -map 0:v " +
|
||||||
|
subMap +
|
||||||
|
" -map 0:a -c:v copy -c:a aac -strict -2 " +
|
||||||
|
subType;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true;
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!jsonString.includes("aac") && hasSubs) {
|
if (!jsonString.includes("aac") && hasSubs) {
|
||||||
response.addInfo(BAD, "File has no aac track and has subs");
|
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.preset =
|
||||||
|
", -map 0:v " +
|
||||||
|
subMap +
|
||||||
|
" -map 0:a -c:v copy -c:a aac -strict -2 " +
|
||||||
|
subType;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true;
|
response.FFmpegMode = true;
|
||||||
|
|
@ -143,7 +160,11 @@ function plugin(file, librarySettings, inputs) {
|
||||||
|
|
||||||
if (file.meta.Title != undefined && hasSubs) {
|
if (file.meta.Title != undefined && hasSubs) {
|
||||||
response.addInfo(BAD, "File has title and has subs");
|
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.preset =
|
||||||
|
", -map_metadata -1 -map 0:v " +
|
||||||
|
subMap +
|
||||||
|
" -map 0:a -c:v copy -c:a copy " +
|
||||||
|
subType;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true;
|
response.FFmpegMode = true;
|
||||||
|
|
@ -152,7 +173,11 @@ function plugin(file, librarySettings, inputs) {
|
||||||
|
|
||||||
if (file.meta.Title != undefined) {
|
if (file.meta.Title != undefined) {
|
||||||
response.addInfo(BAD, "File has title metadata");
|
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.preset =
|
||||||
|
", -map_metadata -1 -map 0:v " +
|
||||||
|
subMap +
|
||||||
|
" -map 0:a -c:v copy -c:a copy " +
|
||||||
|
subType;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true;
|
response.FFmpegMode = true;
|
||||||
|
|
@ -163,7 +188,11 @@ function plugin(file, librarySettings, inputs) {
|
||||||
|
|
||||||
if (!jsonString.includes("aac")) {
|
if (!jsonString.includes("aac")) {
|
||||||
response.addInfo(BAD, "File has no aac track");
|
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.preset =
|
||||||
|
", -map 0:v " +
|
||||||
|
subMap +
|
||||||
|
" -map 0:a -c:v copy -c:a aac -strict -2 " +
|
||||||
|
subType;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true;
|
response.FFmpegMode = true;
|
||||||
|
|
@ -178,16 +207,17 @@ function plugin(file, librarySettings, inputs) {
|
||||||
} else {
|
} else {
|
||||||
response.addInfo(BAD, "File has compatible subs, copying...");
|
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.preset =
|
||||||
|
", -map 0:v " + subMap + " -map 0:a -c:v copy -c:a copy " + subType;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
} else {
|
} else {
|
||||||
response.addInfo(GOOD, "File has no/compatible subs");
|
response.addInfo(GOOD, "File has no/compatible subs");
|
||||||
}
|
}
|
||||||
|
|
||||||
response.addInfo(GOOD, "File meets conditions!");
|
response.addInfo(GOOD, "File meets conditions!");
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.details = details;
|
module.exports.details = details;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_e3jc_Tharic_H.264_MKV_480p30_No_Subs_No_Title_Meta",
|
id: "Tdarr_Plugin_e3jc_Tharic_H.264_MKV_480p30_No_Subs_No_Title_Meta",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
|
|
@ -11,156 +7,123 @@ 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
|
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",
|
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:
|
||||||
Tags:'pre-processing,handbrake,ffmpeg,h264'
|
"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",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
|
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
processFile: false,
|
||||||
|
preset: "",
|
||||||
|
container: ".mp4",
|
||||||
|
handBrakeMode: false,
|
||||||
|
FFmpegMode: false,
|
||||||
|
reQueueAfter: false,
|
||||||
|
infoLog: "",
|
||||||
|
};
|
||||||
|
|
||||||
processFile : false,
|
response.FFmpegMode = true;
|
||||||
preset : '',
|
|
||||||
container : '.mp4',
|
|
||||||
handBrakeMode : false,
|
|
||||||
FFmpegMode : false,
|
|
||||||
reQueueAfter : false,
|
|
||||||
infoLog : '',
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
response.FFmpegMode = true
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
|
console.log("File is not video");
|
||||||
|
|
||||||
|
response.infoLog += "☒File is not video \n";
|
||||||
console.log("File is not video")
|
|
||||||
|
|
||||||
response.infoLog += "☒File is not video \n"
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
var jsonString = JSON.stringify(file);
|
||||||
|
|
||||||
var jsonString = JSON.stringify(file)
|
var hasSubs = false;
|
||||||
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle"
|
||||||
|
) {
|
||||||
|
hasSubs = true;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
var hasSubs = false
|
if (
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
file.ffProbeData.streams[0].codec_name != "h264" ||
|
||||||
|
file.ffProbeData.streams[0].width > 720 ||
|
||||||
try {
|
file.ffProbeData.streams[0].height > 480
|
||||||
|
) {
|
||||||
if(file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle"){
|
|
||||||
|
|
||||||
hasSubs = true
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (err) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
if(file.ffProbeData.streams[0].codec_name != 'h264' || file.ffProbeData.streams[0].width > 720 || file.ffProbeData.streams[0].height > 480 ){
|
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = '-Z "H.264 MKV 480p30"'
|
response.preset = '-Z "H.264 MKV 480p30"';
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode =true
|
response.handBrakeMode = true;
|
||||||
response.FFmpegMode = false
|
response.FFmpegMode = false;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File is not h264 480p! \n"
|
response.infoLog += "☒File is not h264 480p! \n";
|
||||||
return response
|
return response;
|
||||||
}else{
|
} else {
|
||||||
|
response.infoLog += "☑File is h264 480p! \n";
|
||||||
response.infoLog += "☑File is h264 480p! \n"
|
}
|
||||||
|
//
|
||||||
}
|
|
||||||
//
|
|
||||||
|
|
||||||
if(file.meta.Title != "undefined" && hasSubs){
|
|
||||||
|
|
||||||
|
if (file.meta.Title != "undefined" && hasSubs) {
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = ',-sn -map_metadata -1 -map 0 -c copy'
|
response.preset = ",-sn -map_metadata -1 -map 0 -c copy";
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode =false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File has title and has subs \n"
|
response.infoLog += "☒File has title and has subs \n";
|
||||||
return response
|
return response;
|
||||||
}else{
|
} else {
|
||||||
response.infoLog += "☑File has no title and has no subs \n"
|
response.infoLog += "☑File has no title and has no subs \n";
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(file.meta.Title != undefined ){
|
|
||||||
|
|
||||||
|
if (file.meta.Title != undefined) {
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = ',-map_metadata -1 -map 0 -c copy'
|
response.preset = ",-map_metadata -1 -map 0 -c copy";
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode =false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File has title metadata \n"
|
response.infoLog += "☒File has title metadata \n";
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
|
response.infoLog += "☑File has no title metadata \n";
|
||||||
}else{
|
}
|
||||||
response.infoLog += "☑File has no title metadata \n"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(hasSubs){
|
|
||||||
|
|
||||||
|
if (hasSubs) {
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = ',-sn -map 0 -c copy'
|
response.preset = ",-sn -map 0 -c copy";
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode =false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File has subs \n"
|
response.infoLog += "☒File has subs \n";
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
}else{
|
response.infoLog += "☑File has no subs \n";
|
||||||
response.infoLog += "☑File has no subs \n"
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if( file.container != 'mkv'){
|
|
||||||
|
|
||||||
|
|
||||||
|
if (file.container != "mkv") {
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = ', -map 0 -c copy'
|
response.preset = ", -map 0 -c copy";
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode =false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File is not in mkv container! \n"
|
response.infoLog += "☒File is not in mkv container! \n";
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
|
response.infoLog += "☑File is in mkv container! \n";
|
||||||
}else{
|
}
|
||||||
|
|
||||||
response.infoLog += "☑File is in mkv container! \n"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
response.processFile = false;
|
|
||||||
response.infoLog += "☑File meets conditions! \n"
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
response.processFile = false;
|
||||||
|
response.infoLog += "☑File meets conditions! \n";
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_e3jd_Tharic_H.264_MKV_720p30_No_Subs_No_Title_Meta",
|
id: "Tdarr_Plugin_e3jd_Tharic_H.264_MKV_720p30_No_Subs_No_Title_Meta",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
|
|
@ -11,156 +7,123 @@ 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
|
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",
|
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:
|
||||||
Tags:'pre-processing,handbrake,ffmpeg,h264'
|
"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",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
|
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
processFile: false,
|
||||||
|
preset: "",
|
||||||
|
container: ".mp4",
|
||||||
|
handBrakeMode: false,
|
||||||
|
FFmpegMode: false,
|
||||||
|
reQueueAfter: false,
|
||||||
|
infoLog: "",
|
||||||
|
};
|
||||||
|
|
||||||
processFile : false,
|
response.FFmpegMode = true;
|
||||||
preset : '',
|
|
||||||
container : '.mp4',
|
|
||||||
handBrakeMode : false,
|
|
||||||
FFmpegMode : false,
|
|
||||||
reQueueAfter : false,
|
|
||||||
infoLog : '',
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
response.FFmpegMode = true
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
|
console.log("File is not video");
|
||||||
|
|
||||||
|
response.infoLog += "☒File is not video \n";
|
||||||
console.log("File is not video")
|
|
||||||
|
|
||||||
response.infoLog += "☒File is not video \n"
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
var jsonString = JSON.stringify(file);
|
||||||
|
|
||||||
var jsonString = JSON.stringify(file)
|
var hasSubs = false;
|
||||||
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle"
|
||||||
|
) {
|
||||||
|
hasSubs = true;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
var hasSubs = false
|
if (
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
file.ffProbeData.streams[0].codec_name != "h264" ||
|
||||||
|
file.ffProbeData.streams[0].width > 1280 ||
|
||||||
try {
|
file.ffProbeData.streams[0].height > 720
|
||||||
|
) {
|
||||||
if(file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle"){
|
|
||||||
|
|
||||||
hasSubs = true
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (err) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
if(file.ffProbeData.streams[0].codec_name != 'h264' || file.ffProbeData.streams[0].width > 1280 || file.ffProbeData.streams[0].height > 720 ){
|
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = '-Z "H.264 MKV 720p30"'
|
response.preset = '-Z "H.264 MKV 720p30"';
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode =true
|
response.handBrakeMode = true;
|
||||||
response.FFmpegMode = false
|
response.FFmpegMode = false;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File is not h264 720p! \n"
|
response.infoLog += "☒File is not h264 720p! \n";
|
||||||
return response
|
return response;
|
||||||
}else{
|
} else {
|
||||||
|
response.infoLog += "☑File is h264 720p! \n";
|
||||||
response.infoLog += "☑File is h264 720p! \n"
|
}
|
||||||
|
//
|
||||||
}
|
|
||||||
//
|
|
||||||
|
|
||||||
if(file.meta.Title != "undefined" && hasSubs){
|
|
||||||
|
|
||||||
|
if (file.meta.Title != "undefined" && hasSubs) {
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = ',-sn -map_metadata -1 -map 0 -c copy'
|
response.preset = ",-sn -map_metadata -1 -map 0 -c copy";
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode =false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File has title and has subs \n"
|
response.infoLog += "☒File has title and has subs \n";
|
||||||
return response
|
return response;
|
||||||
}else{
|
} else {
|
||||||
response.infoLog += "☑File has no title and has no subs \n"
|
response.infoLog += "☑File has no title and has no subs \n";
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(file.meta.Title != undefined ){
|
|
||||||
|
|
||||||
|
if (file.meta.Title != undefined) {
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = ',-map_metadata -1 -map 0 -c copy'
|
response.preset = ",-map_metadata -1 -map 0 -c copy";
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode =false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File has title metadata \n"
|
response.infoLog += "☒File has title metadata \n";
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
|
response.infoLog += "☑File has no title metadata \n";
|
||||||
}else{
|
}
|
||||||
response.infoLog += "☑File has no title metadata \n"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(hasSubs){
|
|
||||||
|
|
||||||
|
if (hasSubs) {
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = ',-sn -map 0 -c copy'
|
response.preset = ",-sn -map 0 -c copy";
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode =false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File has subs \n"
|
response.infoLog += "☒File has subs \n";
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
}else{
|
response.infoLog += "☑File has no subs \n";
|
||||||
response.infoLog += "☑File has no subs \n"
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if( file.container != 'mkv'){
|
|
||||||
|
|
||||||
|
|
||||||
|
if (file.container != "mkv") {
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = ', -map 0 -c copy'
|
response.preset = ", -map 0 -c copy";
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode =false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File is not in mkv container! \n"
|
response.infoLog += "☒File is not in mkv container! \n";
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
|
response.infoLog += "☑File is in mkv container! \n";
|
||||||
}else{
|
}
|
||||||
|
|
||||||
response.infoLog += "☑File is in mkv container! \n"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
response.processFile = false;
|
|
||||||
response.infoLog += "☑File meets conditions! \n"
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
response.processFile = false;
|
||||||
|
response.infoLog += "☑File meets conditions! \n";
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_e3je_Tharic_H.264_MKV_1080p30_No_Subs_No_Title_Meta",
|
id: "Tdarr_Plugin_e3je_Tharic_H.264_MKV_1080p30_No_Subs_No_Title_Meta",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
|
|
@ -11,156 +7,123 @@ 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
|
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",
|
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:
|
||||||
Tags:'pre-processing,handbrake,ffmpeg,h264'
|
"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",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
|
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
processFile: false,
|
||||||
|
preset: "",
|
||||||
|
container: ".mp4",
|
||||||
|
handBrakeMode: false,
|
||||||
|
FFmpegMode: false,
|
||||||
|
reQueueAfter: false,
|
||||||
|
infoLog: "",
|
||||||
|
};
|
||||||
|
|
||||||
processFile : false,
|
response.FFmpegMode = true;
|
||||||
preset : '',
|
|
||||||
container : '.mp4',
|
|
||||||
handBrakeMode : false,
|
|
||||||
FFmpegMode : false,
|
|
||||||
reQueueAfter : false,
|
|
||||||
infoLog : '',
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
response.FFmpegMode = true
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
|
console.log("File is not video");
|
||||||
|
|
||||||
|
response.infoLog += "☒File is not video \n";
|
||||||
console.log("File is not video")
|
|
||||||
|
|
||||||
response.infoLog += "☒File is not video \n"
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
var jsonString = JSON.stringify(file);
|
||||||
|
|
||||||
var jsonString = JSON.stringify(file)
|
var hasSubs = false;
|
||||||
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle"
|
||||||
|
) {
|
||||||
|
hasSubs = true;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
var hasSubs = false
|
if (
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
file.ffProbeData.streams[0].codec_name != "h264" ||
|
||||||
|
file.ffProbeData.streams[0].width > 1920 ||
|
||||||
try {
|
file.ffProbeData.streams[0].height > 1080
|
||||||
|
) {
|
||||||
if(file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle"){
|
|
||||||
|
|
||||||
hasSubs = true
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (err) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
if(file.ffProbeData.streams[0].codec_name != 'h264' || file.ffProbeData.streams[0].width > 1920 || file.ffProbeData.streams[0].height > 1080 ){
|
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = '-Z "H.264 MKV 1080p30"'
|
response.preset = '-Z "H.264 MKV 1080p30"';
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode =true
|
response.handBrakeMode = true;
|
||||||
response.FFmpegMode = false
|
response.FFmpegMode = false;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File is not h264 1080p! \n"
|
response.infoLog += "☒File is not h264 1080p! \n";
|
||||||
return response
|
return response;
|
||||||
}else{
|
} else {
|
||||||
|
response.infoLog += "☑File is h264 1080p!";
|
||||||
response.infoLog += "☑File is h264 1080p!"
|
}
|
||||||
|
//
|
||||||
}
|
|
||||||
//
|
|
||||||
|
|
||||||
if(file.meta.Title != "undefined" && hasSubs){
|
|
||||||
|
|
||||||
|
if (file.meta.Title != "undefined" && hasSubs) {
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = ',-sn -map_metadata -1 -map 0 -c copy'
|
response.preset = ",-sn -map_metadata -1 -map 0 -c copy";
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode =false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File has title and has subs \n"
|
response.infoLog += "☒File has title and has subs \n";
|
||||||
return response
|
return response;
|
||||||
}else{
|
} else {
|
||||||
response.infoLog += "☑File has no title and has no subs \n"
|
response.infoLog += "☑File has no title and has no subs \n";
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(file.meta.Title != undefined ){
|
|
||||||
|
|
||||||
|
if (file.meta.Title != undefined) {
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = ',-map_metadata -1 -map 0 -c copy'
|
response.preset = ",-map_metadata -1 -map 0 -c copy";
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode =false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File has title metadata \n"
|
response.infoLog += "☒File has title metadata \n";
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
|
response.infoLog += "☑File has no title metadata \n";
|
||||||
}else{
|
}
|
||||||
response.infoLog += "☑File has no title metadata \n"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(hasSubs){
|
|
||||||
|
|
||||||
|
if (hasSubs) {
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = ',-sn -map 0 -c copy'
|
response.preset = ",-sn -map 0 -c copy";
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode =false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File has subs \n"
|
response.infoLog += "☒File has subs \n";
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
}else{
|
response.infoLog += "☑File has no subs \n";
|
||||||
response.infoLog += "☑File has no subs \n"
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if( file.container != 'mkv'){
|
|
||||||
|
|
||||||
|
|
||||||
|
if (file.container != "mkv") {
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = ', -map 0 -c copy'
|
response.preset = ", -map 0 -c copy";
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode =false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File is not in mkv container! \n"
|
response.infoLog += "☒File is not in mkv container! \n";
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
|
response.infoLog += "☑File is in mkv container! \n";
|
||||||
}else{
|
}
|
||||||
|
|
||||||
response.infoLog += "☑File is in mkv container! \n"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
response.processFile = false;
|
|
||||||
response.infoLog += "☑File meets conditions! \n"
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
response.processFile = false;
|
||||||
|
response.infoLog += "☑File meets conditions! \n";
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,143 +1,154 @@
|
||||||
const fs = require('fs');
|
const fs = require("fs");
|
||||||
const execSync = require('child_process').execSync;
|
const execSync = require("child_process").execSync;
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_e5c3_CnT_Add_Subtitles",
|
id: "Tdarr_Plugin_e5c3_CnT_Add_Subtitles",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
Name: "Add subtitles to MKV files",
|
Name: "Add subtitles to MKV files",
|
||||||
Type: "Video",
|
Type: "Video",
|
||||||
Operation:"Remux",
|
Operation: "Remux",
|
||||||
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`,
|
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",
|
Version: "1.3",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_e5c3_CnT_Add_Subtitles.js",
|
Link:
|
||||||
Tags:'pre-processing,ffmpeg,subtitle only,configurable',
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_e5c3_CnT_Add_Subtitles.js",
|
||||||
Inputs: [
|
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) \\nExample:\\n yes`
|
name: "install_packages",
|
||||||
},
|
tooltip: `Please change this to "yes", it allows the plugin to install the required nodemodule. (iso-639-2) \\nExample:\\n yes`,
|
||||||
{
|
},
|
||||||
name: 'container',
|
{
|
||||||
tooltip: `Enter the output container of the new file.\\n Default: .mkv\\nExample:\\n.mkv`
|
name: "container",
|
||||||
},
|
tooltip: `Enter the output container of the new file.\\n Default: .mkv\\nExample:\\n.mkv`,
|
||||||
]
|
},
|
||||||
}
|
],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file, librarySettings, inputs, otherArguments) {
|
function plugin(file, librarySettings, inputs, otherArguments) {
|
||||||
//default response
|
//default response
|
||||||
var response = {
|
var response = {
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: `,`,
|
preset: `,`,
|
||||||
container: '.mkv',
|
container: ".mkv",
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: false,
|
FFmpegMode: false,
|
||||||
reQueueAfter: false,
|
reQueueAfter: false,
|
||||||
infoLog: `Searching new subtitles...\n`,
|
infoLog: `Searching new subtitles...\n`,
|
||||||
}
|
};
|
||||||
|
|
||||||
if (inputs.container !== undefined) {
|
if (inputs.container !== undefined) {
|
||||||
response.container = inputs.container;
|
response.container = inputs.container;
|
||||||
console.log(`Changed container to: ` + inputs.container);
|
console.log(`Changed container to: ` + inputs.container);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inputs.install_packages == "yes") {
|
if (inputs.install_packages == "yes") {
|
||||||
if (!fs.existsSync(`${otherArguments.homePath}/Tdarr/node_modules/iso-639-2`)) {
|
if (
|
||||||
execSync(`cd ${otherArguments.homePath}/Tdarr \n npm install iso-639-2`);
|
!fs.existsSync(`${otherArguments.homePath}/Tdarr/node_modules/iso-639-2`)
|
||||||
}
|
) {
|
||||||
|
execSync(`cd ${otherArguments.homePath}/Tdarr \n npm install iso-639-2`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
response.infoLog = `Please take a look at the input options\n A extra nodemodule is required.`;
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fs.existsSync(`/home/Tdarr/Documents/Tdarr/node_modules/iso-639-2`)) {
|
||||||
|
var iso6392 = require("/home/Tdarr/Documents/Tdarr/node_modules/iso-639-2");
|
||||||
|
} else {
|
||||||
|
response.infoLog += `Nodemodule iso-639-2 isn't installed!\nTry Again`;
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
var i = 0; //int for counting lang[position]
|
||||||
|
var found_subtitle_stream = 0;
|
||||||
|
var sub = 0; //becomes first subtitle stream
|
||||||
|
var lang = iso6392; //languages to check against
|
||||||
|
var path = file.meta.Directory; //path of media folder
|
||||||
|
var exist = 0; //if the language exists should be added this becomes 1
|
||||||
|
var new_subs = 0; //count the new subs
|
||||||
|
var added_subs = 0; //counts the amount of subs that have been mapped
|
||||||
|
var preset_import = "";
|
||||||
|
var preset_meta = "";
|
||||||
|
|
||||||
|
//find first subtitle stream
|
||||||
|
while (found_subtitle_stream == 0 && sub < file.ffProbeData.streams.length) {
|
||||||
|
if (file.ffProbeData.streams[sub].codec_type.toLowerCase() == "subtitle") {
|
||||||
|
found_subtitle_stream = 1;
|
||||||
} else {
|
} else {
|
||||||
response.infoLog = `Please take a look at the input options\n A extra nodemodule is required.`
|
sub++;
|
||||||
return response;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (fs.existsSync(`/home/Tdarr/Documents/Tdarr/node_modules/iso-639-2`)) {
|
response.infoLog += `Path: ${path}\n`;
|
||||||
var iso6392 = require('/home/Tdarr/Documents/Tdarr/node_modules/iso-639-2');
|
for (i = 0; i < lang.length; i++) {
|
||||||
} else {
|
//check if srt file exists in folder
|
||||||
response.infoLog += `Nodemodule iso-639-2 isn't installed!\nTry Again`
|
if (fs.existsSync(`${path}/${lang[i].iso6392B}.srt`)) {
|
||||||
return response;
|
response.infoLog += `Found subtitle ${lang[i].name}.srt\n`;
|
||||||
}
|
|
||||||
|
|
||||||
var i = 0; //int for counting lang[position]
|
if (found_subtitle_stream == 1) {
|
||||||
var found_subtitle_stream = 0;
|
//check if language already exists
|
||||||
var sub = 0; //becomes first subtitle stream
|
for (
|
||||||
var lang = iso6392; //languages to check against
|
sub_stream = sub;
|
||||||
var path = file.meta.Directory; //path of media folder
|
sub_stream < file.ffProbeData.streams.length;
|
||||||
var exist = 0; //if the language exists should be added this becomes 1
|
sub_stream++
|
||||||
var new_subs = 0 //count the new subs
|
) {
|
||||||
var added_subs = 0; //counts the amount of subs that have been mapped
|
//response.infoLog += `does ${lang[i].name} exist in stream ${sub_stream}?\n`
|
||||||
var preset_import = '';
|
if (file.ffProbeData.streams[sub_stream].tags.language) {
|
||||||
var preset_meta = '';
|
if (
|
||||||
|
file.ffProbeData.streams[
|
||||||
//find first subtitle stream
|
sub_stream
|
||||||
while (found_subtitle_stream == 0 && sub < file.ffProbeData.streams.length) {
|
].tags.language.toLowerCase() == lang[i].iso6392B
|
||||||
if (file.ffProbeData.streams[sub].codec_type.toLowerCase() == "subtitle") {
|
) {
|
||||||
found_subtitle_stream = 1;
|
//response.infoLog += `YES\n`
|
||||||
} else {
|
exist = 1;
|
||||||
sub++;
|
response.infoLog += `Language already exists in stream ${sub_stream}\n It will not be added\n`;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
response.infoLog += `Path: ${path}\n`;
|
|
||||||
for (i = 0; i < lang.length; i++) {
|
|
||||||
//check if srt file exists in folder
|
|
||||||
if (fs.existsSync(`${path}/${lang[i].iso6392B}.srt`)) {
|
|
||||||
response.infoLog += `Found subtitle ${lang[i].name}.srt\n`;
|
|
||||||
|
|
||||||
if (found_subtitle_stream == 1) {
|
|
||||||
//check if language already exists
|
|
||||||
for (sub_stream = sub; sub_stream < file.ffProbeData.streams.length; sub_stream++) {
|
|
||||||
//response.infoLog += `does ${lang[i].name} exist in stream ${sub_stream}?\n`
|
|
||||||
if (file.ffProbeData.streams[sub_stream].tags.language) {
|
|
||||||
if (file.ffProbeData.streams[sub_stream].tags.language.toLowerCase() == lang[i].iso6392B) {
|
|
||||||
//response.infoLog += `YES\n`
|
|
||||||
exist = 1;
|
|
||||||
response.infoLog += `Language already exists in stream ${sub_stream}\n It will not be added\n`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
exist = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//add if it hasn't found the language
|
|
||||||
if (exist != 1) {
|
|
||||||
preset_import += ` -sub_charenc "UTF-8" -f srt -i "${path}/${lang[i].iso6392B}.srt"`;
|
|
||||||
preset_meta += ` -metadata:s:s:${new_subs} language=${lang[i].iso6392B}`;
|
|
||||||
new_subs++;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//else {
|
} else {
|
||||||
// response.infoLog += `did not find sub ${lang[i].iso6392B}.srt\n`
|
|
||||||
//}
|
|
||||||
exist = 0;
|
exist = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//add if it hasn't found the language
|
||||||
|
if (exist != 1) {
|
||||||
|
preset_import += ` -sub_charenc "UTF-8" -f srt -i "${path}/${lang[i].iso6392B}.srt"`;
|
||||||
|
preset_meta += ` -metadata:s:s:${new_subs} language=${lang[i].iso6392B}`;
|
||||||
|
new_subs++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
//else {
|
||||||
|
// response.infoLog += `did not find sub ${lang[i].iso6392B}.srt\n`
|
||||||
|
//}
|
||||||
|
exist = 0;
|
||||||
|
}
|
||||||
|
|
||||||
response.preset += ` ${preset_import}${preset_meta} -map 0:v -map 0:a`
|
response.preset += ` ${preset_import}${preset_meta} -map 0:v -map 0:a`;
|
||||||
|
|
||||||
//map new subs
|
//map new subs
|
||||||
while (added_subs < new_subs) {
|
while (added_subs < new_subs) {
|
||||||
added_subs++;
|
added_subs++;
|
||||||
response.preset += ` -map ${added_subs}:s`;
|
response.preset += ` -map ${added_subs}:s`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if new subs have been found they will be added
|
||||||
|
if (new_subs > 0) {
|
||||||
|
response.FFmpegMode = true;
|
||||||
|
response.processFile = true;
|
||||||
|
response.reQueueAfter = true;
|
||||||
|
if (found_subtitle_stream == 1) {
|
||||||
|
response.preset += ` -map 0:s `;
|
||||||
}
|
}
|
||||||
|
response.preset += ` -c copy`;
|
||||||
|
response.infoLog += `${new_subs} new subs will be added\n`;
|
||||||
|
} else {
|
||||||
|
response.infoLog += `No new subtitle languages were found\n`;
|
||||||
|
}
|
||||||
|
|
||||||
//if new subs have been found they will be added
|
//response.infoLog += `The ffmpeg string is: ${response.preset}\n`
|
||||||
if (new_subs > 0) {
|
|
||||||
response.FFmpegMode = true;
|
|
||||||
response.processFile = true;
|
|
||||||
response.reQueueAfter = true;
|
|
||||||
if (found_subtitle_stream == 1) {
|
|
||||||
response.preset += ` -map 0:s `;
|
|
||||||
}
|
|
||||||
response.preset += ` -c copy`;
|
|
||||||
response.infoLog += `${new_subs} new subs will be added\n`;
|
|
||||||
} else {
|
|
||||||
response.infoLog += `No new subtitle languages were found\n`;
|
|
||||||
}
|
|
||||||
|
|
||||||
//response.infoLog += `The ffmpeg string is: ${response.preset}\n`
|
return response;
|
||||||
|
|
||||||
return response
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.details = details;
|
module.exports.details = details;
|
||||||
|
|
|
||||||
|
|
@ -1,137 +1,168 @@
|
||||||
const exec = require('child_process').exec;
|
const exec = require("child_process").exec;
|
||||||
const fs = require('fs');
|
const fs = require("fs");
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_e5c3_CnT_Keep_Preferred_Audio",
|
id: "Tdarr_Plugin_e5c3_CnT_Keep_Preferred_Audio",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
Name: "Keep Preffered Audio",
|
Name: "Keep Preffered Audio",
|
||||||
Type: "Audio",
|
Type: "Audio",
|
||||||
Operation:"Remove Audio",
|
Operation: "Remove Audio",
|
||||||
Description: "Plugin that checks for unwanted audio, per 1.104 beta you can change the languages yourself from within Tdarr!\nUntill you enter a value it keep english tracks by default.\nUndefined languages are kept to prevent videos without sound.\nIf you would like to keep track of the languages you have for each file you can use the 'special' option.\nCreated by @control#0405",
|
Description:
|
||||||
Version: "1.2",
|
"Plugin that checks for unwanted audio, per 1.104 beta you can change the languages yourself from within Tdarr!\nUntill you enter a value it keep english tracks by default.\nUndefined languages are kept to prevent videos without sound.\nIf you would like to keep track of the languages you have for each file you can use the 'special' option.\nCreated by @control#0405",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_e5c3_CnT_Keep_Preferred_Audio.js",
|
Version: "1.2",
|
||||||
Tags: 'pre-processing,ffmpeg,configurable,audio only',
|
Link:
|
||||||
Inputs: [
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_e5c3_CnT_Keep_Preferred_Audio.js",
|
||||||
{
|
Tags: "pre-processing,ffmpeg,configurable,audio only",
|
||||||
name: 'languages',
|
Inputs: [
|
||||||
tooltip: `Desired Languages you would like to keep, language format has to be according to the iso-639-2 standard: https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes\\nExample:\\eng,dut`
|
{
|
||||||
},
|
name: "languages",
|
||||||
{
|
tooltip: `Desired Languages you would like to keep, language format has to be according to the iso-639-2 standard: https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes\\nExample:\\eng,dut`,
|
||||||
name: 'special',
|
},
|
||||||
tooltip: `This is if you want a specific language to be logged to a file in your Tdarr documents folder.\\nIt will add the name of the file that is being processed if this language(s) has been found.\\nThe file is created the first time it finds a file with the language.\\nThe languages don't have to be in "languages".\\nExample:\\eng,dut`
|
{
|
||||||
},
|
name: "special",
|
||||||
{
|
tooltip: `This is if you want a specific language to be logged to a file in your Tdarr documents folder.\\nIt will add the name of the file that is being processed if this language(s) has been found.\\nThe file is created the first time it finds a file with the language.\\nThe languages don't have to be in "languages".\\nExample:\\eng,dut`,
|
||||||
name: 'container',
|
},
|
||||||
tooltip: `Enter the output container of the new file.\\n Default: .mkv\\nExample:\\n.mkv`
|
{
|
||||||
},
|
name: "container",
|
||||||
]
|
tooltip: `Enter the output container of the new file.\\n Default: .mkv\\nExample:\\n.mkv`,
|
||||||
}
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file, librarySettings, inputs, otherArguments) {
|
function plugin(file, librarySettings, inputs, otherArguments) {
|
||||||
if (inputs.languages == "" || typeof inputs.special == 'undefined') {
|
if (inputs.languages == "" || typeof inputs.special == "undefined") {
|
||||||
var languages = ["eng", "en"]; //these languages should be kept, named according to ISO 639-2 language scheme
|
var languages = ["eng", "en"]; //these languages should be kept, named according to ISO 639-2 language scheme
|
||||||
} else {
|
} else {
|
||||||
var languages = inputs.languages.toLowerCase().split(','); //these languages should be kept, named according to ISO 639-2 language scheme
|
var languages = inputs.languages.toLowerCase().split(","); //these languages should be kept, named according to ISO 639-2 language scheme
|
||||||
}
|
}
|
||||||
if (inputs.special == "" || typeof inputs.special == 'undefined') {
|
if (inputs.special == "" || typeof inputs.special == "undefined") {
|
||||||
var special = ``;
|
var special = ``;
|
||||||
} else {
|
} else {
|
||||||
var special = inputs.special.toLowerCase().split(',');
|
var special = inputs.special.toLowerCase().split(",");
|
||||||
}
|
}
|
||||||
if (languages.length >= special.length) {
|
if (languages.length >= special.length) {
|
||||||
var length = languages.length;
|
var length = languages.length;
|
||||||
} else {
|
} else {
|
||||||
var length = special.length;
|
var length = special.length;
|
||||||
}
|
}
|
||||||
console.log(languages);
|
console.log(languages);
|
||||||
var transcode = 0; //if this becomes '1' it will be transcoded
|
var transcode = 0; //if this becomes '1' it will be transcoded
|
||||||
var sourcename = file.meta.FileName.substring(0, file.meta.FileName.lastIndexOf(".")); //filename without extension
|
var sourcename = file.meta.FileName.substring(
|
||||||
var specialcheck = ``; //contains the txt string if special language was found
|
0,
|
||||||
var wanted = 0;
|
file.meta.FileName.lastIndexOf(".")
|
||||||
var audio = 0;
|
); //filename without extension
|
||||||
|
var specialcheck = ``; //contains the txt string if special language was found
|
||||||
|
var wanted = 0;
|
||||||
|
var audio = 0;
|
||||||
|
|
||||||
//default response
|
//default response
|
||||||
var response = {
|
var response = {
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: `, -map 0:v`,
|
preset: `, -map 0:v`,
|
||||||
container: '.mkv',
|
container: ".mkv",
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: false,
|
FFmpegMode: false,
|
||||||
reQueueAfter: false,
|
reQueueAfter: false,
|
||||||
infoLog: 'Removing unwanted audio...\n',
|
infoLog: "Removing unwanted audio...\n",
|
||||||
};
|
};
|
||||||
|
|
||||||
if (inputs.container !== undefined) {
|
if (inputs.container !== undefined) {
|
||||||
response.container = inputs.container;
|
response.container = inputs.container;
|
||||||
console.log(`Container was set to: ` + inputs.container);
|
console.log(`Container was set to: ` + inputs.container);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
||||||
//check for non-english tracks
|
//check for non-english tracks
|
||||||
console.log(`Audio track ${i}`);
|
console.log(`Audio track ${i}`);
|
||||||
console.log("type: " + typeof file.ffProbeData.streams[i].tags);
|
console.log("type: " + typeof file.ffProbeData.streams[i].tags);
|
||||||
if (typeof file.ffProbeData.streams[i].tags !== 'undefined' || file.ffProbeData.streams[i].tags) {
|
if (
|
||||||
console.log("Type: " + typeof file.ffProbeData.streams[i].tags.language)
|
typeof file.ffProbeData.streams[i].tags !== "undefined" ||
|
||||||
if (typeof file.ffProbeData.streams[i].tags.language !== 'undefined' || file.ffProbeData.streams[i].tags.language) {
|
file.ffProbeData.streams[i].tags
|
||||||
for (l = 0; l < length; l++) {
|
) {
|
||||||
if (file.ffProbeData.streams[i].tags.language == special[l]) {
|
console.log(
|
||||||
if (!fs.existsSync(otherArguments.homePath + `/Tdarr/special_audio_${special[l]}.txt`)) { //create txt file if it doesn't exist yet
|
"Type: " + typeof file.ffProbeData.streams[i].tags.language
|
||||||
exec(`echo "${sourcename}" >> ${otherArguments.homePath}/Tdarr/special_audio_${special[l]}.txt`); //first file will be added and file is created
|
);
|
||||||
console.log(`added to txt: ` + sourcename);
|
if (
|
||||||
} else {
|
typeof file.ffProbeData.streams[i].tags.language !== "undefined" ||
|
||||||
specialcheck = fs.readFileSync(otherArguments.homePath + `/Tdarr/special_audio_${special[l]}.txt`).toString(); //create string from existing file
|
file.ffProbeData.streams[i].tags.language
|
||||||
if (!specialcheck.includes(sourcename)) { //only add the filename if it wasn't added already
|
) {
|
||||||
exec(`echo "${sourcename}" >> ${otherArguments.homePath}/Tdarr/special_audio_${special[l]}.txt`);
|
for (l = 0; l < length; l++) {
|
||||||
console.log(`added to txt: ` + sourcename);
|
if (file.ffProbeData.streams[i].tags.language == special[l]) {
|
||||||
}
|
if (
|
||||||
}
|
!fs.existsSync(
|
||||||
|
otherArguments.homePath +
|
||||||
response.preset += ` -map 0:${i}`;
|
`/Tdarr/special_audio_${special[l]}.txt`
|
||||||
response.infoLog += `Found special ${special[l]}: ${i}\n`;
|
)
|
||||||
wanted++;
|
) {
|
||||||
break;
|
//create txt file if it doesn't exist yet
|
||||||
} else if (file.ffProbeData.streams[i].tags.language == languages[l]) {
|
exec(
|
||||||
response.preset += ` -map 0:${i}`;
|
`echo "${sourcename}" >> ${otherArguments.homePath}/Tdarr/special_audio_${special[l]}.txt`
|
||||||
response.infoLog += `Found wanted ${languages[l]}: ${i}\n`;
|
); //first file will be added and file is created
|
||||||
wanted++;
|
console.log(`added to txt: ` + sourcename);
|
||||||
break;
|
} else {
|
||||||
} else if (i == length-1) {
|
specialcheck = fs
|
||||||
response.infoLog += `Found unwanted: ${file.ffProbeData.streams[i].tags.language}: ${i}\n`;
|
.readFileSync(
|
||||||
}
|
otherArguments.homePath +
|
||||||
}
|
`/Tdarr/special_audio_${special[l]}.txt`
|
||||||
} else {
|
)
|
||||||
response.preset += ` -map 0:${i}`;
|
.toString(); //create string from existing file
|
||||||
response.infoLog += `Added undefined: ${i}\n`;
|
if (!specialcheck.includes(sourcename)) {
|
||||||
wanted++;
|
//only add the filename if it wasn't added already
|
||||||
|
exec(
|
||||||
|
`echo "${sourcename}" >> ${otherArguments.homePath}/Tdarr/special_audio_${special[l]}.txt`
|
||||||
|
);
|
||||||
|
console.log(`added to txt: ` + sourcename);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
response.preset += ` -map 0:${i}`;
|
|
||||||
response.infoLog += `Added undefined: ${i}\n`;
|
response.preset += ` -map 0:${i}`;
|
||||||
wanted++;
|
response.infoLog += `Found special ${special[l]}: ${i}\n`;
|
||||||
|
wanted++;
|
||||||
|
break;
|
||||||
|
} else if (
|
||||||
|
file.ffProbeData.streams[i].tags.language == languages[l]
|
||||||
|
) {
|
||||||
|
response.preset += ` -map 0:${i}`;
|
||||||
|
response.infoLog += `Found wanted ${languages[l]}: ${i}\n`;
|
||||||
|
wanted++;
|
||||||
|
break;
|
||||||
|
} else if (i == length - 1) {
|
||||||
|
response.infoLog += `Found unwanted: ${file.ffProbeData.streams[i].tags.language}: ${i}\n`;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
audio++;
|
} else {
|
||||||
|
response.preset += ` -map 0:${i}`;
|
||||||
|
response.infoLog += `Added undefined: ${i}\n`;
|
||||||
|
wanted++;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
response.preset += ` -map 0:${i}`;
|
||||||
|
response.infoLog += `Added undefined: ${i}\n`;
|
||||||
|
wanted++;
|
||||||
|
}
|
||||||
|
|
||||||
if (audio > wanted && wanted > 0) {
|
audio++;
|
||||||
transcode = 1;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (transcode == 1) {
|
if (audio > wanted && wanted > 0) {
|
||||||
response.infoLog += `Found unwanted audio\nIt will be removed\n`;
|
transcode = 1;
|
||||||
response.processFile = true;
|
}
|
||||||
response.FFmpegMode = true;
|
|
||||||
response.preset += ` -map 0:s? -c copy`;
|
|
||||||
response.reQueueAfter = true;
|
|
||||||
} else {
|
|
||||||
response.infoLog += `No unwanted audio found!\n`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return response
|
if (transcode == 1) {
|
||||||
|
response.infoLog += `Found unwanted audio\nIt will be removed\n`;
|
||||||
|
response.processFile = true;
|
||||||
|
response.FFmpegMode = true;
|
||||||
|
response.preset += ` -map 0:s? -c copy`;
|
||||||
|
response.reQueueAfter = true;
|
||||||
|
} else {
|
||||||
|
response.infoLog += `No unwanted audio found!\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.details = details;
|
module.exports.details = details;
|
||||||
|
|
|
||||||
|
|
@ -1,395 +1,451 @@
|
||||||
const fs = require('fs');
|
const fs = require("fs");
|
||||||
const execSync = require('child_process').execSync;
|
const execSync = require("child_process").execSync;
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_e5c3_CnT_Remove_Letterbox",
|
id: "Tdarr_Plugin_e5c3_CnT_Remove_Letterbox",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
Name: "Remove letterbox",
|
Name: "Remove letterbox",
|
||||||
Type: "Video",
|
Type: "Video",
|
||||||
Operation:"Transcode",
|
Operation: "Transcode",
|
||||||
Description: `Uses iiDrakeii's filter, and crops video files when letterboxing is detected.\nThis uses the FFMPEG NVENC transcoding(hw).\nIf a file is 4K it will be scaled down to 1080p.\nNow with user definable bitrates!(since 1.104 beta)\nCreated by @control#0405`,
|
Description: `Uses iiDrakeii's filter, and crops video files when letterboxing is detected.\nThis uses the FFMPEG NVENC transcoding(hw).\nIf a file is 4K it will be scaled down to 1080p.\nNow with user definable bitrates!(since 1.104 beta)\nCreated by @control#0405`,
|
||||||
Version: "1.3",
|
Version: "1.3",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_e5c3_CnT_Remove_Letterbox.js",
|
Link:
|
||||||
Tags: 'pre-processing,ffmpeg,nvenc h265,configurable,h265,video only',
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_e5c3_CnT_Remove_Letterbox.js",
|
||||||
Inputs: [
|
Tags: "pre-processing,ffmpeg,nvenc h265,configurable,h265,video only",
|
||||||
{
|
Inputs: [
|
||||||
name: 'bitrate',
|
{
|
||||||
tooltip: `Desired bitrate for a 1080p video, minimum transcode size is based of this too!\\n 720p will be half of 1080p, 480p will be half of 720p.\\nThe default is '3000', this value is based of movies.\\nI would suggest 1500-2000 for series.\\nExample:\\n3000`
|
name: "bitrate",
|
||||||
},
|
tooltip: `Desired bitrate for a 1080p video, minimum transcode size is based of this too!\\n 720p will be half of 1080p, 480p will be half of 720p.\\nThe default is '3000', this value is based of movies.\\nI would suggest 1500-2000 for series.\\nExample:\\n3000`,
|
||||||
{
|
},
|
||||||
name: 'container',
|
{
|
||||||
tooltip: `Enter the output container of the new file.\\n Default: .mkv\\nExample:\\n.mkv`
|
name: "container",
|
||||||
},
|
tooltip: `Enter the output container of the new file.\\n Default: .mkv\\nExample:\\n.mkv`,
|
||||||
]
|
},
|
||||||
}
|
],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file, librarySettings, inputs, otherArguments) {
|
function plugin(file, librarySettings, inputs, otherArguments) {
|
||||||
if (inputs.bitrate == "" || inputs.bitrate == 'undefined') {
|
if (inputs.bitrate == "" || inputs.bitrate == "undefined") {
|
||||||
var min_bitrate = 6600;
|
var min_bitrate = 6600;
|
||||||
var avg_rate = 3000;
|
var avg_rate = 3000;
|
||||||
var max_rate = 6000;
|
var max_rate = 6000;
|
||||||
|
} else {
|
||||||
|
var min_bitrate = inputs.bitrate * 2.2;
|
||||||
|
var avg_rate = inputs.bitrate;
|
||||||
|
var max_rate = inputs.bitrate * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//default values that will be returned
|
||||||
|
var response = {
|
||||||
|
processFile: false,
|
||||||
|
preset: "",
|
||||||
|
container: ".mkv",
|
||||||
|
handBrakeMode: false,
|
||||||
|
FFmpegMode: true,
|
||||||
|
reQueueAfter: true,
|
||||||
|
infoLog: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (inputs.container !== undefined) {
|
||||||
|
response.container = inputs.container;
|
||||||
|
console.log(`Container was set to: ` + inputs.container);
|
||||||
|
}
|
||||||
|
|
||||||
|
var source = file.meta.SourceFile; //source file
|
||||||
|
var stats = fs.statSync(source);
|
||||||
|
var size = stats["size"] / 1000000000;
|
||||||
|
size = size.toFixed(2);
|
||||||
|
var decoder = decoder_string(file); //decoder, before the input
|
||||||
|
var encoder = encoder_string_full(
|
||||||
|
highres(file),
|
||||||
|
crop_decider(file, generate_crop_values(file, otherArguments).crop_height)
|
||||||
|
.crop,
|
||||||
|
encoder_string(file, avg_rate, max_rate, response.container)
|
||||||
|
); //encoder
|
||||||
|
var process = 0; //decides if it should be processed
|
||||||
|
|
||||||
|
var returns = {
|
||||||
|
create_crop: generate_crop_values(file, otherArguments),
|
||||||
|
crop: crop_decider(
|
||||||
|
file,
|
||||||
|
generate_crop_values(file, otherArguments).crop_height
|
||||||
|
),
|
||||||
|
size: size_check(file, min_bitrate),
|
||||||
|
};
|
||||||
|
|
||||||
|
var log = {
|
||||||
|
size: returns.size.log,
|
||||||
|
hevc: ``,
|
||||||
|
resolution: ``,
|
||||||
|
crop: returns.crop.log,
|
||||||
|
createcrop: returns.create_crop.log,
|
||||||
|
};
|
||||||
|
|
||||||
|
//filters
|
||||||
|
if (size_check(file, min_bitrate).size == 1) {
|
||||||
|
if (hevc(file) == 1) {
|
||||||
|
log.hevc = `☑ - Video is not HEVC \n`;
|
||||||
|
process = 1;
|
||||||
} else {
|
} else {
|
||||||
var min_bitrate = inputs.bitrate*2.2;
|
log.hevc += "☒ - File is already in HEVC \n";
|
||||||
var avg_rate = inputs.bitrate;
|
|
||||||
var max_rate = inputs.bitrate*2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//default values that will be returned
|
if (highres(file) == 1) {
|
||||||
var response = {
|
process = 1;
|
||||||
processFile: false,
|
log.resolution += `☑ - Resolution > 1080p.\n File will be transcoded to 1080p \n`;
|
||||||
preset: '',
|
|
||||||
container: '.mkv',
|
|
||||||
handBrakeMode: false,
|
|
||||||
FFmpegMode: true,
|
|
||||||
reQueueAfter: true,
|
|
||||||
infoLog: ''
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inputs.container !== undefined) {
|
|
||||||
response.container = inputs.container;
|
|
||||||
console.log(`Container was set to: ` + inputs.container);
|
|
||||||
}
|
|
||||||
|
|
||||||
var source = file.meta.SourceFile; //source file
|
|
||||||
var stats = fs.statSync(source);
|
|
||||||
var size = stats["size"]/1000000000;
|
|
||||||
size = size.toFixed(2);
|
|
||||||
var decoder = decoder_string(file); //decoder, before the input
|
|
||||||
var encoder = encoder_string_full(highres(file), crop_decider(file, generate_crop_values(file, otherArguments).crop_height).crop, encoder_string(file, avg_rate, max_rate, response.container)); //encoder
|
|
||||||
var process = 0; //decides if it should be processed
|
|
||||||
|
|
||||||
var returns = {
|
|
||||||
create_crop: generate_crop_values(file, otherArguments),
|
|
||||||
crop: crop_decider(file, generate_crop_values(file, otherArguments).crop_height),
|
|
||||||
size: size_check(file, min_bitrate)
|
|
||||||
}
|
|
||||||
|
|
||||||
var log = {
|
|
||||||
size: returns.size.log,
|
|
||||||
hevc: ``,
|
|
||||||
resolution: ``,
|
|
||||||
crop: returns.crop.log,
|
|
||||||
createcrop: returns.create_crop.log
|
|
||||||
}
|
|
||||||
|
|
||||||
//filters
|
|
||||||
if (size_check(file, min_bitrate).size == 1) {
|
|
||||||
if (hevc(file) == 1) {
|
|
||||||
log.hevc = `☑ - Video is not HEVC \n`;
|
|
||||||
process = 1;
|
|
||||||
} else {
|
|
||||||
log.hevc += "☒ - File is already in HEVC \n"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (highres(file) == 1) {
|
|
||||||
process = 1;
|
|
||||||
log.resolution += `☑ - Resolution > 1080p.\n File will be transcoded to 1080p \n`;
|
|
||||||
} else {
|
|
||||||
log.resolution += `☒ - Resolution <= 1080p \n`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (crop_decider(file, generate_crop_values(file, otherArguments).crop_height).crop != "0") {
|
|
||||||
process = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
response.infoLog += log.createcrop +
|
|
||||||
log.crop +
|
|
||||||
log.resolution +
|
|
||||||
log.size +
|
|
||||||
log.hevc;
|
|
||||||
response.preset = `${decoder}, -map 0:v:0 -map 0:a -map 0:s? ${encoder}`
|
|
||||||
|
|
||||||
//change response
|
|
||||||
if (process == 1) {
|
|
||||||
response.processFile = true;
|
|
||||||
response.infoLog += `File will be processed\n`;
|
|
||||||
} else if (file.forceProcessing === true) {
|
|
||||||
response.processFile = true;
|
|
||||||
response.infoLog += `Force processing!\n`;
|
|
||||||
} else {
|
} else {
|
||||||
response.infoLog += `Processing not necessary\n`;
|
log.resolution += `☒ - Resolution <= 1080p \n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return response;
|
if (
|
||||||
|
crop_decider(file, generate_crop_values(file, otherArguments).crop_height)
|
||||||
|
.crop != "0"
|
||||||
|
) {
|
||||||
|
process = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response.infoLog +=
|
||||||
|
log.createcrop + log.crop + log.resolution + log.size + log.hevc;
|
||||||
|
response.preset = `${decoder}, -map 0:v:0 -map 0:a -map 0:s? ${encoder}`;
|
||||||
|
|
||||||
|
//change response
|
||||||
|
if (process == 1) {
|
||||||
|
response.processFile = true;
|
||||||
|
response.infoLog += `File will be processed\n`;
|
||||||
|
} else if (file.forceProcessing === true) {
|
||||||
|
response.processFile = true;
|
||||||
|
response.infoLog += `Force processing!\n`;
|
||||||
|
} else {
|
||||||
|
response.infoLog += `Processing not necessary\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
function highres(file) {
|
function highres(file) {
|
||||||
//if file is larger than 1080p it should be transcoded
|
//if file is larger than 1080p it should be transcoded
|
||||||
if (file.meta.ImageWidth > 1920) {
|
if (file.meta.ImageWidth > 1920) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function generate_crop_values(file, otherArguments) {
|
function generate_crop_values(file, otherArguments) {
|
||||||
var source = file.meta.SourceFile; //source file
|
var source = file.meta.SourceFile; //source file
|
||||||
var dir = file.meta.Directory; //source directory
|
var dir = file.meta.Directory; //source directory
|
||||||
var sourcename = file.meta.FileName.substring(0, file.meta.FileName.lastIndexOf(".")); //filename without extension
|
var sourcename = file.meta.FileName.substring(
|
||||||
var cropfile = `${dir}/${sourcename}.txt`; //location and name of the crop file
|
0,
|
||||||
var returns = {
|
file.meta.FileName.lastIndexOf(".")
|
||||||
crop_height: 0, //return value for this function, required for crop_decider
|
); //filename without extension
|
||||||
log: ``
|
var cropfile = `${dir}/${sourcename}.txt`; //location and name of the crop file
|
||||||
}
|
var returns = {
|
||||||
|
crop_height: 0, //return value for this function, required for crop_decider
|
||||||
|
log: ``,
|
||||||
|
};
|
||||||
|
|
||||||
//create crop value
|
//create crop value
|
||||||
if (!fs.existsSync(`${cropfile}`)) {
|
if (!fs.existsSync(`${cropfile}`)) {
|
||||||
returns.log += `Creating crop values...\n`;
|
returns.log += `Creating crop values...\n`;
|
||||||
execSync(`${otherArguments.ffmpegPath} -ss 300 -i \"${source}\" -frames:v 240 -vf cropdetect -f null - 2>&1 | awk \'/crop/ { print $NF }\' | tail -240 > \"${cropfile}\"`);
|
execSync(
|
||||||
execSync(`${otherArguments.ffmpegPath} -ss 1200 -i \"${source}\" -frames:v 240 -vf cropdetect -f null - 2>&1 | awk \'/crop/ { print $NF }\' | tail -240 >> \"${cropfile}\"`);
|
`${otherArguments.ffmpegPath} -ss 300 -i \"${source}\" -frames:v 240 -vf cropdetect -f null - 2>&1 | awk \'/crop/ { print $NF }\' | tail -240 > \"${cropfile}\"`
|
||||||
} else {
|
);
|
||||||
returns.log += `Crop values already exist\n`;
|
execSync(
|
||||||
}
|
`${otherArguments.ffmpegPath} -ss 1200 -i \"${source}\" -frames:v 240 -vf cropdetect -f null - 2>&1 | awk \'/crop/ { print $NF }\' | tail -240 >> \"${cropfile}\"`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
returns.log += `Crop values already exist\n`;
|
||||||
|
}
|
||||||
|
|
||||||
//get data from copvalue.txt
|
//get data from copvalue.txt
|
||||||
var data = fs.readFileSync(`${cropfile}`).toString().split("\n"); //full data from cropvalue.txt
|
var data = fs.readFileSync(`${cropfile}`).toString().split("\n"); //full data from cropvalue.txt
|
||||||
|
|
||||||
//get height of the supposed cropped video
|
//get height of the supposed cropped video
|
||||||
//var crop_height = parseInt(data[0].substring(10, 14));
|
//var crop_height = parseInt(data[0].substring(10, 14));
|
||||||
for (var c = 0; c < data.length; c++) {
|
for (var c = 0; c < data.length; c++) {
|
||||||
crop = data[c].split(":");
|
crop = data[c].split(":");
|
||||||
crop_height = Math.abs(parseInt(crop[1]));
|
crop_height = Math.abs(parseInt(crop[1]));
|
||||||
if (crop_height > returns.crop_height) {
|
if (crop_height > returns.crop_height) {
|
||||||
returns.crop_height = crop_height;
|
returns.crop_height = crop_height;
|
||||||
returns.log += `New cropheight: ${crop_height}\n`;
|
returns.log += `New cropheight: ${crop_height}\n`;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return returns;
|
}
|
||||||
|
return returns;
|
||||||
}
|
}
|
||||||
|
|
||||||
function hevc(file) {
|
function hevc(file) {
|
||||||
//check if the file is already hevc, it will not be transcoded if true
|
//check if the file is already hevc, it will not be transcoded if true
|
||||||
if (file.ffProbeData.streams[0].codec_name) {
|
if (file.ffProbeData.streams[0].codec_name) {
|
||||||
if ("hevc".toLowerCase().includes(file.ffProbeData.streams[0].codec_name.toLowerCase())) {
|
if (
|
||||||
return 0;
|
"hevc"
|
||||||
} else {
|
.toLowerCase()
|
||||||
return 1;
|
.includes(file.ffProbeData.streams[0].codec_name.toLowerCase())
|
||||||
}
|
) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function decoder_string(file) {
|
function decoder_string(file) {
|
||||||
var decoder = ``; //decoder, before the input
|
var decoder = ``; //decoder, before the input
|
||||||
|
|
||||||
//use the correct decoder
|
//use the correct decoder
|
||||||
if (file.video_codec_name == 'h263') {
|
if (file.video_codec_name == "h263") {
|
||||||
decoder = `-c:v h263_cuvid`
|
decoder = `-c:v h263_cuvid`;
|
||||||
}
|
} else if (file.video_codec_name == "h264") {
|
||||||
else if (file.video_codec_name == 'h264') {
|
if (file.ffProbeData.streams[0].profile != "High 10") {
|
||||||
if (file.ffProbeData.streams[0].profile != 'High 10') { //Remove HW Decoding for High 10 Profile
|
//Remove HW Decoding for High 10 Profile
|
||||||
decoder = `-c:v h264_cuvid`
|
decoder = `-c:v h264_cuvid`;
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (file.video_codec_name == 'mjpeg') {
|
|
||||||
decoder = `c:v mjpeg_cuvid`
|
|
||||||
}
|
|
||||||
else if (file.video_codec_name == 'mpeg1') {
|
|
||||||
decoder = `-c:v mpeg1_cuvid`
|
|
||||||
}
|
|
||||||
else if (file.video_codec_name == 'mpeg2') {
|
|
||||||
decoder = `-c:v mpeg2_cuvid`
|
|
||||||
}
|
|
||||||
else if (file.video_codec_name == 'vc1') {
|
|
||||||
decoder = `-c:v vc1_cuvid`
|
|
||||||
}
|
|
||||||
else if (file.video_codec_name == 'vp8') {
|
|
||||||
decoder = `-c:v vp8_cuvid`
|
|
||||||
}
|
|
||||||
else if (file.video_codec_name == 'vp9') {
|
|
||||||
decoder = `-c:v vp9_cuvid`
|
|
||||||
}
|
}
|
||||||
|
} else if (file.video_codec_name == "mjpeg") {
|
||||||
|
decoder = `c:v mjpeg_cuvid`;
|
||||||
|
} else if (file.video_codec_name == "mpeg1") {
|
||||||
|
decoder = `-c:v mpeg1_cuvid`;
|
||||||
|
} else if (file.video_codec_name == "mpeg2") {
|
||||||
|
decoder = `-c:v mpeg2_cuvid`;
|
||||||
|
} else if (file.video_codec_name == "vc1") {
|
||||||
|
decoder = `-c:v vc1_cuvid`;
|
||||||
|
} else if (file.video_codec_name == "vp8") {
|
||||||
|
decoder = `-c:v vp8_cuvid`;
|
||||||
|
} else if (file.video_codec_name == "vp9") {
|
||||||
|
decoder = `-c:v vp9_cuvid`;
|
||||||
|
}
|
||||||
|
|
||||||
return decoder;
|
return decoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
function crop_decider(file, crop_height) {
|
function crop_decider(file, crop_height) {
|
||||||
var returns = {
|
var returns = {
|
||||||
crop: `0`, //sets the crop filter
|
crop: `0`, //sets the crop filter
|
||||||
log: ``,
|
log: ``,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
if (file.ffProbeData.streams[i].width !== undefined) {
|
||||||
|
var imageWidth = file.ffProbeData.streams[i].width;
|
||||||
|
var imageHeight = file.ffProbeData.streams[i].height;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
var min_crop = parseInt(imageHeight * 0.98); //if the crop value is larger than this the file won't be cropped
|
||||||
if (file.ffProbeData.streams[i].width !== undefined) {
|
|
||||||
var imageWidth = file.ffProbeData.streams[i].width;
|
//tree for resolution : quality
|
||||||
var imageHeight = file.ffProbeData.streams[i].height;
|
if (imageWidth >= 1300) {
|
||||||
break;
|
//file will be encoded if the resolution is 1080p, or greater (it will be downscaled)
|
||||||
}
|
//crop only if it is a larger crop than 1%;
|
||||||
|
if (crop_height < min_crop) {
|
||||||
|
var crop_hdis = parseInt((imageHeight - crop_height) / 2);
|
||||||
|
if (crop_height >= 790) {
|
||||||
|
returns.crop = `-filter:0 crop=${imageWidth}:${crop_height}:0:${crop_hdis}`;
|
||||||
|
returns.log += `☑ - crop is larger than 1%\n`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
returns.log += `☒ - Crop is not necessary\n`;
|
||||||
}
|
}
|
||||||
|
} else if (imageWidth < 1300 && file.meta.ImageWidth >= 770) {
|
||||||
var min_crop = parseInt(imageHeight*.98); //if the crop value is larger than this the file won't be cropped
|
//crop only if it is a larger crop than 1%;
|
||||||
|
if (crop_height < min_crop) {
|
||||||
//tree for resolution : quality
|
var crop_hdis = parseInt((imageHeight - crop_height) / 2);
|
||||||
if (imageWidth >= 1300) { //file will be encoded if the resolution is 1080p, or greater (it will be downscaled)
|
if (crop_height >= 530) {
|
||||||
//crop only if it is a larger crop than 1%;
|
returns.crop = `-filter:0 crop=${imageWidth}:${crop_height}:0:${crop_hdis}`;
|
||||||
if (crop_height < min_crop) {
|
returns.log += `☑ - crop is larger than 1%\n`;
|
||||||
var crop_hdis = parseInt((imageHeight-crop_height)/2);
|
}
|
||||||
if (crop_height >= 790) {
|
} else {
|
||||||
returns.crop = `-filter:0 crop=${imageWidth}:${crop_height}:0:${crop_hdis}`;
|
returns.log += `☒ - Crop is not necessary\n`;
|
||||||
returns.log += `☑ - crop is larger than 1%\n`;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
returns.log += `☒ - Crop is not necessary\n`;
|
|
||||||
}
|
|
||||||
} else if(imageWidth < 1300 && file.meta.ImageWidth >= 770) {
|
|
||||||
//crop only if it is a larger crop than 1%;
|
|
||||||
if (crop_height < min_crop) {
|
|
||||||
var crop_hdis = parseInt((imageHeight-crop_height)/2);
|
|
||||||
if (crop_height >= 530) {
|
|
||||||
returns.crop = `-filter:0 crop=${imageWidth}:${crop_height}:0:${crop_hdis}`;
|
|
||||||
returns.log += `☑ - crop is larger than 1%\n`;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
returns.log += `☒ - Crop is not necessary\n`;
|
|
||||||
}
|
|
||||||
} else if(imageWidth < 770) { //file won't be cropped at this resolution
|
|
||||||
returns.log += `No crop: Resolution < 720p\n`;
|
|
||||||
}
|
}
|
||||||
|
} else if (imageWidth < 770) {
|
||||||
|
//file won't be cropped at this resolution
|
||||||
|
returns.log += `No crop: Resolution < 720p\n`;
|
||||||
|
}
|
||||||
|
|
||||||
return returns;
|
return returns;
|
||||||
}
|
}
|
||||||
|
|
||||||
function size_check(file, min_bitrate) {
|
function size_check(file, min_bitrate) {
|
||||||
var duration = file.meta.Duration; //duration of video in seconds
|
var duration = file.meta.Duration; //duration of video in seconds
|
||||||
var source = file.meta.SourceFile; //source file
|
var source = file.meta.SourceFile; //source file
|
||||||
var stats = fs.statSync(source);
|
var stats = fs.statSync(source);
|
||||||
var size = stats["size"]/1000000000;
|
var size = stats["size"] / 1000000000;
|
||||||
size = size.toFixed(2);
|
size = size.toFixed(2);
|
||||||
var returns = {
|
var returns = {
|
||||||
size: 0,
|
size: 0,
|
||||||
log: ``
|
log: ``,
|
||||||
|
};
|
||||||
|
|
||||||
|
//tree for resolution : quality
|
||||||
|
if (file.video_resolution === "1080p" || file.video_resolution === "4KUHD") {
|
||||||
|
//file will be encoded if the resolution is 1080p, or greater (it will be downscaled)
|
||||||
|
var min_transcode_size = (min_bitrate * duration * 0.125) / 1000000; //minimum size in GB for transcode
|
||||||
|
min_transcode_size = min_transcode_size.toFixed(2);
|
||||||
|
|
||||||
|
//check if file is large enough for transcode
|
||||||
|
if (size >= (min_bitrate * duration * 0.125) / 1000000) {
|
||||||
|
returns.log += `☑ - ${size}GB > ${min_transcode_size}GB\n`;
|
||||||
|
returns.size = 1;
|
||||||
|
} else {
|
||||||
|
returns.log += `☒ - ${size}GB < ${min_transcode_size}GB\n`;
|
||||||
}
|
}
|
||||||
|
} else if (file.video_resolution === "720p") {
|
||||||
|
//file will be encoded if the resolution is 720p
|
||||||
|
var min_transcode_size = ((min_bitrate / 2) * duration * 0.125) / 1000000; //minimum size in GB for transcode
|
||||||
|
min_transcode_size = min_transcode_size.toFixed(2);
|
||||||
|
|
||||||
//tree for resolution : quality
|
//check if file is large enough for transcode
|
||||||
if (file.video_resolution === "1080p" || file.video_resolution === "4KUHD") { //file will be encoded if the resolution is 1080p, or greater (it will be downscaled)
|
if (size >= ((min_bitrate / 2) * duration * 0.125) / 1000000) {
|
||||||
var min_transcode_size = (min_bitrate * duration * 0.125)/1000000; //minimum size in GB for transcode
|
returns.log += `☑ - ${size}GB > ${min_transcode_size}GB\n`;
|
||||||
min_transcode_size = min_transcode_size.toFixed(2);
|
returns.size = 1;
|
||||||
|
} else {
|
||||||
//check if file is large enough for transcode
|
returns.log += `☒ - ${size}GB < ${min_transcode_size}GB\n`;
|
||||||
if (size >= (min_bitrate * duration * 0.125)/1000000) {
|
|
||||||
returns.log += `☑ - ${size}GB > ${min_transcode_size}GB\n`;
|
|
||||||
returns.size = 1;
|
|
||||||
} else {
|
|
||||||
returns.log += `☒ - ${size}GB < ${min_transcode_size}GB\n`;
|
|
||||||
}
|
|
||||||
} else if(file.video_resolution === "720p") { //file will be encoded if the resolution is 720p
|
|
||||||
var min_transcode_size = ((min_bitrate/2) * duration * 0.125)/1000000; //minimum size in GB for transcode
|
|
||||||
min_transcode_size = min_transcode_size.toFixed(2);
|
|
||||||
|
|
||||||
//check if file is large enough for transcode
|
|
||||||
if (size >= ((min_bitrate/2) * duration * 0.125)/1000000) {
|
|
||||||
returns.log += `☑ - ${size}GB > ${min_transcode_size}GB\n`;
|
|
||||||
returns.size = 1;
|
|
||||||
} else {
|
|
||||||
returns.log += `☒ - ${size}GB < ${min_transcode_size}GB\n`;
|
|
||||||
}
|
|
||||||
} else if(file.video_resolution === "480p" || file.video_resolution === "576p") { //file will be encoded if the resolution is 480p or 576p
|
|
||||||
var min_transcode_size = ((min_bitrate/4) * duration * 0.125)/1000000; //minimum size in GB for transcode
|
|
||||||
min_transcode_size = min_transcode_size.toFixed(2);
|
|
||||||
|
|
||||||
//check if file is large enough for transcode
|
|
||||||
if (size >= ((min_bitrate/4) * duration * 0.125)/1000000) {
|
|
||||||
returns.log += `☑ - ${size}GB > ${min_transcode_size}GB\n`;
|
|
||||||
returns.size = 1;
|
|
||||||
} else {
|
|
||||||
returns.log += `☒ - ${size}GB < ${min_transcode_size}GB\n`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else if (
|
||||||
|
file.video_resolution === "480p" ||
|
||||||
|
file.video_resolution === "576p"
|
||||||
|
) {
|
||||||
|
//file will be encoded if the resolution is 480p or 576p
|
||||||
|
var min_transcode_size = ((min_bitrate / 4) * duration * 0.125) / 1000000; //minimum size in GB for transcode
|
||||||
|
min_transcode_size = min_transcode_size.toFixed(2);
|
||||||
|
|
||||||
return returns;
|
//check if file is large enough for transcode
|
||||||
|
if (size >= ((min_bitrate / 4) * duration * 0.125) / 1000000) {
|
||||||
|
returns.log += `☑ - ${size}GB > ${min_transcode_size}GB\n`;
|
||||||
|
returns.size = 1;
|
||||||
|
} else {
|
||||||
|
returns.log += `☒ - ${size}GB < ${min_transcode_size}GB\n`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return returns;
|
||||||
}
|
}
|
||||||
|
|
||||||
function error_fix(file, container) {
|
function error_fix(file, container) {
|
||||||
var fix = {
|
var fix = {
|
||||||
sub_codec: 0, //changes to 1 if unwanted codec is found
|
sub_codec: 0, //changes to 1 if unwanted codec is found
|
||||||
muxing: 0
|
muxing: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
//these subtitle codecs don't fit in a mkv container
|
||||||
|
if (
|
||||||
|
file.ffProbeData.streams[i].codec_name &&
|
||||||
|
file.ffProbeData.streams[i].codec_type
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
file.ffProbeData.streams[i].codec_name.toLowerCase() == "eia_608" ||
|
||||||
|
(file.ffProbeData.streams[i].codec_name.toLowerCase() == "mov_text" &&
|
||||||
|
file.ffProbeData.streams[i].codec_type
|
||||||
|
.toLowerCase()
|
||||||
|
.includes("sub") &&
|
||||||
|
container == ".mkv")
|
||||||
|
) {
|
||||||
|
fix.sub_codec = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//mitigate TrueHD audio causing Too many packets error
|
||||||
|
if (
|
||||||
|
file.ffProbeData.streams[i].codec_name.toLowerCase() == "truehd" ||
|
||||||
|
(file.ffProbeData.streams[i].codec_name.toLowerCase() == "dts" &&
|
||||||
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio")
|
||||||
|
) {
|
||||||
|
fix.muxing = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
return fix;
|
||||||
|
|
||||||
//these subtitle codecs don't fit in a mkv container
|
|
||||||
if (file.ffProbeData.streams[i].codec_name && file.ffProbeData.streams[i].codec_type) {
|
|
||||||
if (file.ffProbeData.streams[i].codec_name.toLowerCase() == "eia_608" || file.ffProbeData.streams[i].codec_name.toLowerCase() == "mov_text" && file.ffProbeData.streams[i].codec_type.toLowerCase().includes("sub") && container == '.mkv') {
|
|
||||||
fix.sub_codec = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//mitigate TrueHD audio causing Too many packets error
|
|
||||||
if (file.ffProbeData.streams[i].codec_name.toLowerCase() == "truehd" || file.ffProbeData.streams[i].codec_name.toLowerCase() == "dts" && file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" ) {
|
|
||||||
fix.muxing = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return fix;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function encoder_string(file, avg_rate, max_rate, container) {
|
function encoder_string(file, avg_rate, max_rate, container) {
|
||||||
var encoder = ``; //encoder
|
var encoder = ``; //encoder
|
||||||
var fix = error_fix(file, container);
|
var fix = error_fix(file, container);
|
||||||
var sub = ``;
|
var sub = ``;
|
||||||
|
|
||||||
//tree for resolution : quality
|
//tree for resolution : quality
|
||||||
if (file.video_resolution === "1080p" || file.video_resolution === "4KUHD") { //file will be encoded if the resolution is 1080p, or greater (it will be downscaled)
|
if (file.video_resolution === "1080p" || file.video_resolution === "4KUHD") {
|
||||||
encoder += ` -pix_fmt p010le -rc:v vbr_hq -qmin 0 -cq:v 26 -b:v ${avg_rate}k -maxrate:v ${max_rate}k`; //-qp 26
|
//file will be encoded if the resolution is 1080p, or greater (it will be downscaled)
|
||||||
} else if(file.video_resolution === "720p") { //file will be encoded if the resolution is 720p
|
encoder += ` -pix_fmt p010le -rc:v vbr_hq -qmin 0 -cq:v 26 -b:v ${avg_rate}k -maxrate:v ${max_rate}k`; //-qp 26
|
||||||
encoder += ` -pix_fmt p010le -rc:v vbr_hq -qmin 0 -cq:v 26 -b:v ${avg_rate/2}k -maxrate:v ${max_rate/2}k`; //-qp 28
|
} else if (file.video_resolution === "720p") {
|
||||||
} else if(file.video_resolution === "480p" || file.video_resolution === "576p") { //file will be encoded if the resolution is 480p or 576p
|
//file will be encoded if the resolution is 720p
|
||||||
encoder += ` -pix_fmt p010le -rc:v vbr_hq -qmin 0 -cq:v 26 -b:v ${avg_rate/4}k -maxrate:v ${max_rate/4}k`; //-qp 30
|
encoder += ` -pix_fmt p010le -rc:v vbr_hq -qmin 0 -cq:v 26 -b:v ${
|
||||||
} else { //fallback option to 1080p quality
|
avg_rate / 2
|
||||||
encoder += ` -pix_fmt p010le -rc:v vbr_hq -qmin 0 -cq:v 26 -b:v ${avg_rate}k -maxrate:v ${max_rate}k`; //-qp 26
|
}k -maxrate:v ${max_rate / 2}k`; //-qp 28
|
||||||
}
|
} else if (
|
||||||
encoder += ` -c:v hevc_nvenc -preset slow -rc-lookahead 32 -spatial_aq:v 1 -aq-strength:v 8 -a53cc 0 -dn`;
|
file.video_resolution === "480p" ||
|
||||||
|
file.video_resolution === "576p"
|
||||||
|
) {
|
||||||
|
//file will be encoded if the resolution is 480p or 576p
|
||||||
|
encoder += ` -pix_fmt p010le -rc:v vbr_hq -qmin 0 -cq:v 26 -b:v ${
|
||||||
|
avg_rate / 4
|
||||||
|
}k -maxrate:v ${max_rate / 4}k`; //-qp 30
|
||||||
|
} else {
|
||||||
|
//fallback option to 1080p quality
|
||||||
|
encoder += ` -pix_fmt p010le -rc:v vbr_hq -qmin 0 -cq:v 26 -b:v ${avg_rate}k -maxrate:v ${max_rate}k`; //-qp 26
|
||||||
|
}
|
||||||
|
encoder += ` -c:v hevc_nvenc -preset slow -rc-lookahead 32 -spatial_aq:v 1 -aq-strength:v 8 -a53cc 0 -dn`;
|
||||||
|
|
||||||
if (fix.sub_codec == 1) {
|
if (fix.sub_codec == 1) {
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
if (file.ffProbeData.streams[i].codec_name) {
|
if (file.ffProbeData.streams[i].codec_name) {
|
||||||
if (file.ffProbeData.streams[i].codec_name.toLowerCase() == "eia_608" || file.ffProbeData.streams[i].codec_name.toLowerCase() == "mov_text" && file.ffProbeData.streams[i].codec_type.toLowerCase().includes("sub")) {
|
if (
|
||||||
sub += ` -c:${i} ass`;
|
file.ffProbeData.streams[i].codec_name.toLowerCase() == "eia_608" ||
|
||||||
} else {
|
(file.ffProbeData.streams[i].codec_name.toLowerCase() == "mov_text" &&
|
||||||
if (file.ffProbeData.streams[i].codec_type) {
|
file.ffProbeData.streams[i].codec_type
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase().includes("sub")) {
|
.toLowerCase()
|
||||||
sub += ` -c:${i} copy`;
|
.includes("sub"))
|
||||||
}
|
) {
|
||||||
}
|
sub += ` -c:${i} ass`;
|
||||||
}
|
} else {
|
||||||
|
if (file.ffProbeData.streams[i].codec_type) {
|
||||||
|
if (
|
||||||
|
file.ffProbeData.streams[i].codec_type
|
||||||
|
.toLowerCase()
|
||||||
|
.includes("sub")
|
||||||
|
) {
|
||||||
|
sub += ` -c:${i} copy`;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
sub = ` -c:s copy`
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
sub = ` -c:s copy`;
|
||||||
|
}
|
||||||
|
|
||||||
if (fix.muxing == 1) {
|
if (fix.muxing == 1) {
|
||||||
encoder += ` -max_muxing_queue_size 2048`;
|
encoder += ` -max_muxing_queue_size 2048`;
|
||||||
}
|
}
|
||||||
return encoder + ` -c:a copy` + sub;
|
return encoder + ` -c:a copy` + sub;
|
||||||
}
|
}
|
||||||
|
|
||||||
function encoder_string_full(highres, crop, encoder) {
|
function encoder_string_full(highres, crop, encoder) {
|
||||||
console.log(`crop filter: ` + crop);
|
console.log(`crop filter: ` + crop);
|
||||||
|
|
||||||
if (highres == 1 && crop != "0") {
|
if (highres == 1 && crop != "0") {
|
||||||
return crop + `,scale=-1:1920 ` + encoder;
|
return crop + `,scale=-1:1920 ` + encoder;
|
||||||
} else if (highres == 1) {
|
} else if (highres == 1) {
|
||||||
return `-filter:0 scale=-1:1920 ` + encoder;
|
return `-filter:0 scale=-1:1920 ` + encoder;
|
||||||
} else if (crop != "0") {
|
} else if (crop != "0") {
|
||||||
return crop + encoder;
|
return crop + encoder;
|
||||||
} else {
|
} else {
|
||||||
return encoder;
|
return encoder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function execCommand(cmd) {
|
function execCommand(cmd) {
|
||||||
const exec = require('child_process').exec;
|
const exec = require("child_process").exec;
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
exec(cmd, (error, stdout, stderr) => {
|
exec(cmd, (error, stdout, stderr) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
console.warn(error);
|
console.warn(error);
|
||||||
}
|
}
|
||||||
resolve(stdout? stdout : stderr);
|
resolve(stdout ? stdout : stderr);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.details = details;
|
module.exports.details = details;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_fd5T_Sparticus_4K_AC3_No_Subs",
|
id: "Tdarr_Plugin_fd5T_Sparticus_4K_AC3_No_Subs",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
|
|
@ -10,192 +6,181 @@ function details() {
|
||||||
Type: "Video",
|
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",
|
Version: "1.04",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_fd5T_Sparticus_4K_AC3_No_Subs.js",
|
Link:
|
||||||
Tags:'pre-processing,ffmpeg',
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_fd5T_Sparticus_4K_AC3_No_Subs.js",
|
||||||
}
|
Tags: "pre-processing,ffmpeg",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
|
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
container: '.mp4',
|
container: ".mp4",
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: false,
|
FFmpegMode: false,
|
||||||
reQueueAfter: false,
|
reQueueAfter: false,
|
||||||
infoLog: '',
|
infoLog: "",
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
response.container = '.' + file.container
|
|
||||||
response.FFmpegMode = true
|
|
||||||
|
|
||||||
|
response.container = "." + file.container;
|
||||||
|
response.FFmpegMode = true;
|
||||||
|
|
||||||
if (file.fileMedium !== "video" || file.video_resolution !== "4KUHD") {
|
if (file.fileMedium !== "video" || file.video_resolution !== "4KUHD") {
|
||||||
|
console.log("File is not a 4K video");
|
||||||
|
|
||||||
|
response.infoLog += "☒File is not a 4K video \n";
|
||||||
console.log("File is not a 4K video")
|
|
||||||
|
|
||||||
response.infoLog += "☒File is not a 4K video \n"
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
var ac3TrackCount = 0;
|
||||||
|
var AC3CommentaryCount = 0;
|
||||||
|
|
||||||
|
var hasSubs = false;
|
||||||
|
|
||||||
var ac3TrackCount = 0
|
var commentaryStreamIdx = false;
|
||||||
var AC3CommentaryCount = 0
|
var audioIdx = -1;
|
||||||
|
|
||||||
var hasSubs = false
|
|
||||||
|
|
||||||
var commentaryStreamIdx = false
|
|
||||||
var audioIdx = -1
|
|
||||||
|
|
||||||
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
|
||||||
|
|
||||||
//keep track of audio streams for when removing commentary track
|
//keep track of audio streams for when removing commentary track
|
||||||
try {
|
try {
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
||||||
audioIdx++
|
audioIdx++;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
|
|
||||||
//check if commentary track and assing audio stream number
|
//check if commentary track and assing audio stream number
|
||||||
try {
|
try {
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" && file.ffProbeData.streams[i].tags.title.toLowerCase().includes("commentary")) {
|
if (
|
||||||
commentaryStreamIdx = audioIdx
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" &&
|
||||||
|
file.ffProbeData.streams[i].tags.title
|
||||||
|
.toLowerCase()
|
||||||
|
.includes("commentary")
|
||||||
|
) {
|
||||||
|
commentaryStreamIdx = audioIdx;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
|
//check if commentary AC3 track
|
||||||
//check if commentary AC3 track
|
|
||||||
try {
|
try {
|
||||||
|
if (
|
||||||
if (file.ffProbeData.streams[i].codec_name.toLowerCase() == "ac3" && file.ffProbeData.streams[i].tags.title.toLowerCase().includes("commentary")) {
|
file.ffProbeData.streams[i].codec_name.toLowerCase() == "ac3" &&
|
||||||
AC3CommentaryCount++
|
file.ffProbeData.streams[i].tags.title
|
||||||
|
.toLowerCase()
|
||||||
|
.includes("commentary")
|
||||||
|
) {
|
||||||
|
AC3CommentaryCount++;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
|
|
||||||
//check if AC3 track
|
//check if AC3 track
|
||||||
try {
|
try {
|
||||||
if (file.ffProbeData.streams[i].codec_name.toLowerCase() == "ac3") {
|
if (file.ffProbeData.streams[i].codec_name.toLowerCase() == "ac3") {
|
||||||
ac3TrackCount++
|
ac3TrackCount++;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
//check if subs track
|
//check if subs track
|
||||||
try {
|
try {
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle") {
|
if (
|
||||||
hasSubs = true
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle"
|
||||||
|
) {
|
||||||
|
hasSubs = true;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hasOnlyAC3TrackCommentaries;
|
||||||
var hasOnlyAC3TrackCommentaries
|
|
||||||
|
|
||||||
|
|
||||||
if (ac3TrackCount > 0 && AC3CommentaryCount == ac3TrackCount) {
|
if (ac3TrackCount > 0 && AC3CommentaryCount == ac3TrackCount) {
|
||||||
hasOnlyAC3TrackCommentaries = true
|
hasOnlyAC3TrackCommentaries = true;
|
||||||
} else {
|
} else {
|
||||||
hasOnlyAC3TrackCommentaries = false
|
hasOnlyAC3TrackCommentaries = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hasNoAC3Track;
|
||||||
var hasNoAC3Track
|
|
||||||
|
|
||||||
if (ac3TrackCount == 0) {
|
if (ac3TrackCount == 0) {
|
||||||
hasNoAC3Track = true
|
hasNoAC3Track = true;
|
||||||
} else {
|
} else {
|
||||||
hasNoAC3Track = false
|
hasNoAC3Track = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//max 5.1 audio in AC3 output
|
//max 5.1 audio in AC3 output
|
||||||
var channels = file.ffProbeData.streams[1].channels
|
var channels = file.ffProbeData.streams[1].channels;
|
||||||
if (channels > 6) {
|
if (channels > 6) {
|
||||||
channels = 6
|
channels = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (hasOnlyAC3TrackCommentaries && hasSubs) {
|
if (hasOnlyAC3TrackCommentaries && hasSubs) {
|
||||||
response.infoLog += "☒File has no AC3 main track (has AC3 commentary) and has subs \n"
|
response.infoLog +=
|
||||||
response.preset = ',-sn -map 0:v -map 0:a:0 -map 0:a -map 0:d? -c copy -c:a:0 ac3 -ac ' + channels
|
"☒File has no AC3 main track (has AC3 commentary) and has subs \n";
|
||||||
|
response.preset =
|
||||||
|
",-sn -map 0:v -map 0:a:0 -map 0:a -map 0:d? -c copy -c:a:0 ac3 -ac " +
|
||||||
|
channels;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasNoAC3Track && hasSubs) {
|
if (hasNoAC3Track && hasSubs) {
|
||||||
response.infoLog += "☒File has no AC3 main track and has subs \n"
|
response.infoLog += "☒File has no AC3 main track and has subs \n";
|
||||||
response.preset = ',-sn -map 0:v -map 0:a:0 -map 0:a -map 0:d? -c copy -c:a:0 ac3 -ac ' + channels
|
response.preset =
|
||||||
|
",-sn -map 0:v -map 0:a:0 -map 0:a -map 0:d? -c copy -c:a:0 ac3 -ac " +
|
||||||
|
channels;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commentaryStreamIdx !== false) {
|
if (commentaryStreamIdx !== false) {
|
||||||
|
response.infoLog += `☒File has AC3 commentary track in stream ${commentaryStreamIdx} \n`;
|
||||||
response.infoLog += `☒File has AC3 commentary track in stream ${commentaryStreamIdx} \n`
|
response.preset = `,-map 0 -map -0:a:${commentaryStreamIdx} -codec copy`;
|
||||||
response.preset = `,-map 0 -map -0:a:${commentaryStreamIdx} -codec copy`
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!!hasOnlyAC3TrackCommentaries == true) {
|
if (!!hasOnlyAC3TrackCommentaries == true) {
|
||||||
response.infoLog += "☒File has no AC3 main track (has AC3 commentary)! \n"
|
response.infoLog +=
|
||||||
response.preset = ',-map 0:v -map 0:a:0 -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ac3 -ac ' + channels
|
"☒File has no AC3 main track (has AC3 commentary)! \n";
|
||||||
|
response.preset =
|
||||||
|
",-map 0:v -map 0:a:0 -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ac3 -ac " +
|
||||||
|
channels;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
response.infoLog += "☑File does not have only AC3 track commentaries! \n"
|
response.infoLog += "☑File does not have only AC3 track commentaries! \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (hasNoAC3Track) {
|
if (hasNoAC3Track) {
|
||||||
response.infoLog += "☒File has no AC3 track! \n"
|
response.infoLog += "☒File has no AC3 track! \n";
|
||||||
response.preset = ',-map 0:v -map 0:a:0 -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ac3 -ac ' + channels
|
response.preset =
|
||||||
|
",-map 0:v -map 0:a:0 -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ac3 -ac " +
|
||||||
|
channels;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
return response
|
return response;
|
||||||
} else {
|
} else {
|
||||||
response.infoLog += "☑File has AC3 track! \n"
|
response.infoLog += "☑File has AC3 track! \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (hasSubs) {
|
if (hasSubs) {
|
||||||
response.infoLog += "☒File has subs! \n"
|
response.infoLog += "☒File has subs! \n";
|
||||||
response.preset = ',-sn -map 0 -c copy'
|
response.preset = ",-sn -map 0 -c copy";
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
return response
|
return response;
|
||||||
} else {
|
} else {
|
||||||
response.infoLog += "☑File has no subs \n"
|
response.infoLog += "☑File has no subs \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
response.infoLog += "☑File meets conditions! \n";
|
||||||
response.infoLog += "☑File meets conditions! \n"
|
return response;
|
||||||
return response
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_hk75_Drawmonster_MP4_AAC_No_Subs_No_metaTitle",
|
id: "Tdarr_Plugin_hk75_Drawmonster_MP4_AAC_No_Subs_No_metaTitle",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
|
|
@ -11,211 +7,164 @@ 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
|
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",
|
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:
|
||||||
Tags:'pre-processing,ffmpeg',
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_hk75_Drawmonster_MP4_AAC_No_Subs_No_metaTitle.js",
|
||||||
}
|
Tags: "pre-processing,ffmpeg",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
|
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
processFile: false,
|
||||||
|
preset: "",
|
||||||
|
container: ".mp4",
|
||||||
|
handBrakeMode: false,
|
||||||
|
FFmpegMode: false,
|
||||||
|
reQueueAfter: false,
|
||||||
|
infoLog: "",
|
||||||
|
};
|
||||||
|
|
||||||
processFile : false,
|
response.FFmpegMode = true;
|
||||||
preset : '',
|
|
||||||
container : '.mp4',
|
|
||||||
handBrakeMode : false,
|
|
||||||
FFmpegMode : false,
|
|
||||||
reQueueAfter : false,
|
|
||||||
infoLog : '',
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
response.FFmpegMode = true
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
|
console.log("File is not video");
|
||||||
|
|
||||||
|
response.infoLog += "☒File is not video \n";
|
||||||
console.log("File is not video")
|
|
||||||
|
|
||||||
response.infoLog += "☒File is not video \n"
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
var hasPreferredLangTrack = false;
|
||||||
|
var hasPreferredLangInRequiredCodecs = false;
|
||||||
|
var hasAnyInRequiredCodecs = false;
|
||||||
|
|
||||||
|
var audioIdx = -1;
|
||||||
|
var engTrackIdx = -1;
|
||||||
|
|
||||||
var hasPreferredLangTrack = false
|
var requiredAudioCodecs = "aac";
|
||||||
var hasPreferredLangInRequiredCodecs = false
|
var preferredLangTrack = "eng";
|
||||||
var hasAnyInRequiredCodecs = false
|
var preferredCodec = "aac";
|
||||||
|
|
||||||
var audioIdx = -1
|
var hasSubs = false;
|
||||||
var engTrackIdx = -1
|
|
||||||
|
|
||||||
var requiredAudioCodecs = "aac"
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
var preferredLangTrack = "eng"
|
try {
|
||||||
var preferredCodec = "aac"
|
if (
|
||||||
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle"
|
||||||
|
) {
|
||||||
|
hasSubs = true;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
|
||||||
var hasSubs = false
|
|
||||||
|
|
||||||
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
if(file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle"){
|
|
||||||
|
|
||||||
hasSubs = true
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (err) { }
|
|
||||||
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
||||||
audioIdx++
|
audioIdx++;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (requiredAudioCodecs.includes(file.ffProbeData.streams[i].codec_name)) {
|
if (
|
||||||
hasAnyInRequiredCodecs = true
|
requiredAudioCodecs.includes(file.ffProbeData.streams[i].codec_name)
|
||||||
|
) {
|
||||||
|
hasAnyInRequiredCodecs = true;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ((requiredAudioCodecs.includes(file.ffProbeData.streams[i].codec_name)) && file.ffProbeData.streams[i].tags.language.toLowerCase().includes(preferredLangTrack)) {
|
if (
|
||||||
hasPreferredLangInRequiredCodecs = true
|
requiredAudioCodecs.includes(
|
||||||
|
file.ffProbeData.streams[i].codec_name
|
||||||
|
) &&
|
||||||
|
file.ffProbeData.streams[i].tags.language
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(preferredLangTrack)
|
||||||
|
) {
|
||||||
|
hasPreferredLangInRequiredCodecs = true;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (file.ffProbeData.streams[i].tags.language.toLowerCase().includes(preferredLangTrack) && file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
if (
|
||||||
hasPreferredLangTrack = true
|
file.ffProbeData.streams[i].tags.language
|
||||||
engTrackIdx = audioIdx
|
.toLowerCase()
|
||||||
|
.includes(preferredLangTrack) &&
|
||||||
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio"
|
||||||
|
) {
|
||||||
|
hasPreferredLangTrack = true;
|
||||||
|
engTrackIdx = audioIdx;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (hasPreferredLangInRequiredCodecs) {
|
|
||||||
|
|
||||||
response.infoLog += `☑File already has ${preferredLangTrack} language track in ${requiredAudioCodecs}! \n`
|
|
||||||
|
|
||||||
|
if (hasPreferredLangInRequiredCodecs) {
|
||||||
|
response.infoLog += `☑File already has ${preferredLangTrack} language track in ${requiredAudioCodecs}! \n`;
|
||||||
} else if (hasPreferredLangTrack) {
|
} else if (hasPreferredLangTrack) {
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = `,-map 0:v -map 0:a:${engTrackIdx} -map 0:a -c copy -c:a:0 ${preferredCodec} -b:a:0 192k -ac 2 -strict -2`
|
response.preset = `,-map 0:v -map 0:a:${engTrackIdx} -map 0:a -c copy -c:a:0 ${preferredCodec} -b:a:0 192k -ac 2 -strict -2`;
|
||||||
response.container = '.mp4'
|
response.container = ".mp4";
|
||||||
response.handBrakeMode = false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += `☒File has ${preferredLangTrack} language track but not in ${requiredAudioCodecs}! \n`
|
response.infoLog += `☒File has ${preferredLangTrack} language track but not in ${requiredAudioCodecs}! \n`;
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else if (!hasAnyInRequiredCodecs) {
|
} else if (!hasAnyInRequiredCodecs) {
|
||||||
|
|
||||||
if (audioIdx == -1) {
|
if (audioIdx == -1) {
|
||||||
response.infoLog += `☒File does not have any audio streams. Can't create ${preferredCodec} track. \n`
|
response.infoLog += `☒File does not have any audio streams. Can't create ${preferredCodec} track. \n`;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = `,-map 0:v -map 0:a:0 -map 0:a -c copy -c:a:0 ${preferredCodec} -b:a:0 192k -ac 2 -strict -2`
|
response.preset = `,-map 0:v -map 0:a:0 -map 0:a -c copy -c:a:0 ${preferredCodec} -b:a:0 192k -ac 2 -strict -2`;
|
||||||
response.container = '.mp4'
|
response.container = ".mp4";
|
||||||
response.handBrakeMode = false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += `☒File has no language track in ${requiredAudioCodecs}. No ${preferredLangTrack} track marked so transcoding audio track 1 into ${preferredCodec}! \n`
|
response.infoLog += `☒File has no language track in ${requiredAudioCodecs}. No ${preferredLangTrack} track marked so transcoding audio track 1 into ${preferredCodec}! \n`;
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (file.meta.Title != "undefined" && hasSubs) {
|
||||||
|
response.infoLog += "☒File has title and has subs \n";
|
||||||
|
response.preset = ",-sn -map_metadata -1 -c:v copy -c:a copy";
|
||||||
|
|
||||||
if(file.meta.Title != "undefined" && hasSubs){
|
|
||||||
|
|
||||||
response.infoLog += "☒File has title and has subs \n"
|
|
||||||
response.preset = ',-sn -map_metadata -1 -c:v copy -c:a copy'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
if (file.meta.Title != undefined) {
|
||||||
///
|
response.infoLog += "☒File has title metadata \n";
|
||||||
if(file.meta.Title != undefined ){
|
response.preset = ",-map_metadata -1 -c:v copy -c:a copy";
|
||||||
|
|
||||||
response.infoLog += "☒File has title metadata \n"
|
|
||||||
response.preset = ',-map_metadata -1 -c:v copy -c:a copy'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
return response
|
return response;
|
||||||
}else{
|
} else {
|
||||||
response.infoLog += "☑File has no title metadata \n"
|
response.infoLog += "☑File has no title metadata \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasSubs) {
|
||||||
|
response.infoLog += "☒File has subs \n";
|
||||||
if(hasSubs){
|
response.preset = ",-sn -c:v copy -c:a copy";
|
||||||
|
|
||||||
response.infoLog += "☒File has subs \n"
|
|
||||||
response.preset = ',-sn -c:v copy -c:a copy'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
|
response.infoLog += "☑File has no subs \n";
|
||||||
|
}
|
||||||
|
|
||||||
}else{
|
if (file.container != "mp4") {
|
||||||
response.infoLog += "☑File has no subs \n"
|
response.infoLog += "☒File is not in mp4 container! \n";
|
||||||
}
|
response.preset = ", -c:v copy -c:a copy";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if( file.container != 'mp4'){
|
|
||||||
response.infoLog += "☒File is not in mp4 container! \n"
|
|
||||||
response.preset = ', -c:v copy -c:a copy'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
return response
|
return response;
|
||||||
}else{
|
} else {
|
||||||
response.infoLog += "☑File is in mp4 container! \n"
|
response.infoLog += "☑File is in mp4 container! \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
response.infoLog += "☑File meets conditions! \n"
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
response.infoLog += "☑File meets conditions! \n";
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_hk76_GilbN_MP4_AAC_No_metaTitle",
|
id: "Tdarr_Plugin_hk76_GilbN_MP4_AAC_No_metaTitle",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
|
|
@ -11,93 +7,70 @@ 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
|
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",
|
Version: "1.01",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_hk76_GilbN_MP4_AAC_No_metaTitle.js",
|
Link:
|
||||||
Tags:'pre-processing,ffmpeg',
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_hk76_GilbN_MP4_AAC_No_metaTitle.js",
|
||||||
}
|
Tags: "pre-processing,ffmpeg",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
|
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
container: '.mp4',
|
container: ".mp4",
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: false,
|
FFmpegMode: false,
|
||||||
reQueueAfter: false,
|
reQueueAfter: false,
|
||||||
infoLog: '',
|
infoLog: "",
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
response.FFmpegMode = true
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
response.FFmpegMode = true;
|
||||||
|
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
|
console.log("File is not video");
|
||||||
|
|
||||||
|
response.infoLog += "☒File is not video \n";
|
||||||
console.log("File is not video")
|
|
||||||
|
|
||||||
response.infoLog += "☒File is not video \n"
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
var jsonString = JSON.stringify(file);
|
||||||
|
|
||||||
var jsonString = JSON.stringify(file)
|
if (file.container != "mp4") {
|
||||||
|
response.infoLog += "☒File is not in mp4 container! \n";
|
||||||
if (file.container != 'mp4') {
|
response.preset = ", -map 0 -c copy";
|
||||||
|
|
||||||
response.infoLog += "☒File is not in mp4 container! \n"
|
|
||||||
response.preset = ', -map 0 -c copy'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
response.infoLog += "☑File is in mp4 container! \n"
|
response.infoLog += "☑File is in mp4 container! \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (file.meta.Title != undefined) {
|
if (file.meta.Title != undefined) {
|
||||||
|
response.infoLog += "☒File has title metadata \n";
|
||||||
response.infoLog += "☒File has title metadata \n"
|
response.preset = ",-map_metadata -1 -map 0 -c copy";
|
||||||
response.preset = ',-map_metadata -1 -map 0 -c copy'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
return response
|
return response;
|
||||||
} else {
|
} else {
|
||||||
response.infoLog += "☑File has no title metadata \n"
|
response.infoLog += "☑File has no title metadata \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!jsonString.includes("aac")) {
|
if (!jsonString.includes("aac")) {
|
||||||
|
response.infoLog += "☒File has no aac track";
|
||||||
response.infoLog += "☒File has no aac track"
|
response.preset =
|
||||||
response.preset = ',-map 0:v -map 0:a:0 -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 aac -b:a:0 192k -ac 2'
|
",-map 0:v -map 0:a:0 -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 aac -b:a:0 192k -ac 2";
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
response.infoLog += "☑File has aac track \n"
|
response.infoLog += "☑File has aac track \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
response.infoLog += "☑File meets conditions! \n";
|
||||||
|
return response;
|
||||||
|
|
||||||
|
|
||||||
response.infoLog += "☑File meets conditions! \n"
|
|
||||||
return response
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
function details() {
|
function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_lmg1_Reorder_Streams",
|
id: "Tdarr_Plugin_lmg1_Reorder_Streams",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
|
|
@ -8,59 +7,48 @@ function details() {
|
||||||
Description: `[Contains built-in filter] This plugin will move the video stream to the front so Tdarr will recognize the codec correctly.\n\n`,
|
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",
|
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',
|
Tags: "pre-processing,ffmpeg",
|
||||||
}
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
processFile: false,
|
||||||
processFile : false,
|
preset: "",
|
||||||
preset : '',
|
container: ".mp4",
|
||||||
container : '.mp4',
|
handBrakeMode: false,
|
||||||
handBrakeMode : false,
|
FFmpegMode: false,
|
||||||
FFmpegMode : false,
|
reQueueAfter: false,
|
||||||
reQueueAfter : false,
|
infoLog: "",
|
||||||
infoLog : '',
|
};
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
|
console.log("File is not video");
|
||||||
|
|
||||||
console.log("File is not video")
|
response.infoLog += " File is not video\n";
|
||||||
|
|
||||||
response.infoLog += " File is not video\n"
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
response.FFmpegMode = true;
|
||||||
|
response.container = "." + file.container;
|
||||||
|
|
||||||
response.FFmpegMode = true
|
if (file.ffProbeData.streams[0].codec_type != "video") {
|
||||||
response.container = '.' + file.container
|
response.infoLog += "Video is not in the first stream";
|
||||||
|
response.preset =
|
||||||
if(file.ffProbeData.streams[0].codec_type != 'video') {
|
",-map 0:v? -map 0:a? -map 0:s? -map 0:d? -map 0:t? -c copy";
|
||||||
|
|
||||||
response.infoLog += "Video is not in the first stream"
|
|
||||||
response.preset = ',-map 0:v? -map 0:a? -map 0:s? -map 0:d? -map 0:t? -c copy'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
response.infoLog += "File has video in first stream\n";
|
||||||
response.infoLog += "File has video in first stream\n"
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response.infoLog += " File meets conditions!\n"
|
response.infoLog += " File meets conditions!\n";
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_nc7x_Drawmonster_No_Title_Meta",
|
id: "Tdarr_Plugin_nc7x_Drawmonster_No_Title_Meta",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
|
|
@ -11,63 +7,50 @@ 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
|
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",
|
Version: "1.00",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_nc7x_Drawmonster_No_Title_Meta.js",
|
Link:
|
||||||
Tags:'pre-processing,ffmpeg',
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_nc7x_Drawmonster_No_Title_Meta.js",
|
||||||
}
|
Tags: "pre-processing,ffmpeg",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
|
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
container: '.mp4',
|
container: ".mp4",
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: false,
|
FFmpegMode: false,
|
||||||
reQueueAfter: false,
|
reQueueAfter: false,
|
||||||
infoLog: '',
|
infoLog: "",
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|
||||||
response.container = '.' + file.container
|
|
||||||
response.FFmpegMode = true
|
|
||||||
|
|
||||||
|
response.container = "." + file.container;
|
||||||
|
response.FFmpegMode = true;
|
||||||
|
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
|
console.log("File is not video");
|
||||||
|
|
||||||
|
response.infoLog += "☒File is not video \n";
|
||||||
console.log("File is not video")
|
|
||||||
|
|
||||||
response.infoLog += "☒File is not video \n"
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
// var jsonString = JSON.stringify(file)
|
||||||
// var jsonString = JSON.stringify(file)
|
|
||||||
|
|
||||||
|
|
||||||
if (file.meta.Title != undefined) {
|
if (file.meta.Title != undefined) {
|
||||||
|
response.infoLog += "☒File has title metadata \n";
|
||||||
response.infoLog += "☒File has title metadata \n"
|
response.preset = ",-map_metadata -1 -map 0 -c copy";
|
||||||
response.preset = ',-map_metadata -1 -map 0 -c copy'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
return response
|
return response;
|
||||||
} else {
|
} else {
|
||||||
response.infoLog += "☑File has no title metadata \n"
|
response.infoLog += "☑File has no title metadata \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
response.infoLog += "☑File meets conditions! \n";
|
||||||
response.infoLog += "☑File meets conditions! \n"
|
return response;
|
||||||
return response
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,61 +4,62 @@ function details() {
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
Name: "FFMPEG HQ 10-bit HEVC MKV for Animation",
|
Name: "FFMPEG HQ 10-bit HEVC MKV for Animation",
|
||||||
Type: "Video",
|
Type: "Video",
|
||||||
Operation:"Transcode",
|
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`,
|
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",
|
Version: "1.1",
|
||||||
Link: "",
|
Link: "",
|
||||||
Tags:"pre-processing,ffmpeg,h265,aac,10bit,anime,"
|
Tags: "pre-processing,ffmpeg,h265,aac,10bit,anime,",
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
var transcode = 0; //if this var changes to 1 the file will be transcoded
|
var transcode = 0; //if this var changes to 1 the file will be transcoded
|
||||||
|
|
||||||
//default values that will be returned
|
//default values that will be returned
|
||||||
var response = {
|
var response = {
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
container: '.mkv',
|
container: ".mkv",
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: true,
|
FFmpegMode: true,
|
||||||
reQueueAfter: true,
|
reQueueAfter: true,
|
||||||
infoLog: ''
|
infoLog: "",
|
||||||
}
|
};
|
||||||
|
|
||||||
//check if the file is a video, if not the function will be stopped immediately
|
//check if the file is a video, if not the function will be stopped immediately
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
response.processFile = false
|
response.processFile = false;
|
||||||
response.infoLog += "☒File is not a video! \n"
|
response.infoLog += "☒File is not a video! \n";
|
||||||
return response
|
return response;
|
||||||
} else {
|
} else {
|
||||||
response.infoLog += "☑File is a video! \n"
|
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
|
//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') {
|
if (file.ffProbeData.streams[0].codec_name == "hevc") {
|
||||||
response.processFile = false
|
response.processFile = false;
|
||||||
response.infoLog += "☑File is already in hevc! \n"
|
response.infoLog += "☑File is already in hevc! \n";
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Transcoding options
|
//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'
|
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;
|
transcode = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if the file is eligible for transcoding
|
//check if the file is eligible for transcoding
|
||||||
//if true the neccessary response values will be changed
|
//if true the neccessary response values will be changed
|
||||||
if (transcode == 1) {
|
if (transcode == 1) {
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += `☒File is ${file.video_resolution} but is not hevc!\n`
|
response.infoLog += `☒File is ${file.video_resolution} but is not hevc!\n`;
|
||||||
response.infoLog += `☒File will be transcoded!\n`
|
response.infoLog += `☒File will be transcoded!\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.details = details;
|
module.exports.details = details;
|
||||||
|
|
|
||||||
|
|
@ -4,166 +4,169 @@ function details() {
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
Name: "FFmpeg Tiered HEVC MKV",
|
Name: "FFmpeg Tiered HEVC MKV",
|
||||||
Type: "Video",
|
Type: "Video",
|
||||||
Operation:"Transcode",
|
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`,
|
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",
|
Version: "1.01",
|
||||||
Link: "",
|
Link: "",
|
||||||
Tags:"pre-processing,ffmpeg,h265,video only,"
|
Tags: "pre-processing,ffmpeg,h265,video only,",
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
var transcode = 0; //if this var changes to 1 the file will be transcoded
|
var transcode = 0; //if this var changes to 1 the file will be transcoded
|
||||||
|
|
||||||
//default values that will be returned
|
//default values that will be returned
|
||||||
var response = {
|
var response = {
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
container: '.mkv',
|
container: ".mkv",
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: true,
|
FFmpegMode: true,
|
||||||
reQueueAfter: true,
|
reQueueAfter: true,
|
||||||
infoLog: ''
|
infoLog: "",
|
||||||
}
|
};
|
||||||
|
|
||||||
//check if the file is a video, if not the function will be stopped immediately
|
//check if the file is a video, if not the function will be stopped immediately
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
response.processFile = false
|
response.processFile = false;
|
||||||
response.infoLog += "☒File is not a video! \n"
|
response.infoLog += "☒File is not a video! \n";
|
||||||
return response
|
return response;
|
||||||
} else {
|
} else {
|
||||||
response.infoLog += "☑File is a video! \n"
|
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
|
//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') {
|
if (file.ffProbeData.streams[0].codec_name == "hevc") {
|
||||||
response.processFile = false
|
response.processFile = false;
|
||||||
response.infoLog += "☑File is already in hevc! \n"
|
response.infoLog += "☑File is already in hevc! \n";
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
//file will be encoded if the resolution is 480p or 576p
|
//file will be encoded if the resolution is 480p or 576p
|
||||||
//codec will be checked so it can be transcoded correctly
|
//codec will be checked so it can be transcoded correctly
|
||||||
if(file.video_resolution === "480p" || file.video_resolution === "576p" ) {
|
if (file.video_resolution === "480p" || file.video_resolution === "576p") {
|
||||||
if (file.video_codec_name == 'h263') {
|
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'
|
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') {
|
} 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'
|
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') {
|
} 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'
|
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') {
|
} 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'
|
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') {
|
} 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'
|
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') {
|
} 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'
|
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') {
|
} 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'
|
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') {
|
} 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'
|
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') {
|
} 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'
|
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 {
|
} 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'
|
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;
|
transcode = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//file will be encoded if the resolution is 720p
|
//file will be encoded if the resolution is 720p
|
||||||
//codec will be checked so it can be transcoded correctly
|
//codec will be checked so it can be transcoded correctly
|
||||||
if(file.video_resolution === "720p") {
|
if (file.video_resolution === "720p") {
|
||||||
if (file.video_codec_name == 'h263') {
|
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'
|
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') {
|
} 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'
|
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') {
|
} 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'
|
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') {
|
} 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'
|
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') {
|
} 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'
|
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') {
|
} 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'
|
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') {
|
} 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'
|
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') {
|
} 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'
|
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') {
|
} 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'
|
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 {
|
} 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'
|
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;
|
transcode = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//file will be encoded if the resolution is 1080p
|
//file will be encoded if the resolution is 1080p
|
||||||
//codec will be checked so it can be transcoded correctly
|
//codec will be checked so it can be transcoded correctly
|
||||||
if(file.video_resolution === "1080p") {
|
if (file.video_resolution === "1080p") {
|
||||||
if (file.video_codec_name == 'h263') {
|
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'
|
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') {
|
} 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'
|
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') {
|
} 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'
|
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') {
|
} 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'
|
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') {
|
} 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'
|
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') {
|
} 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'
|
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') {
|
} 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'
|
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') {
|
} 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'
|
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') {
|
} 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'
|
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 {
|
} 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'
|
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;
|
transcode = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if the file is eligible for transcoding
|
//check if the file is eligible for transcoding
|
||||||
//if true the neccessary response values will be changed
|
//if true the neccessary response values will be changed
|
||||||
if (transcode == 1) {
|
if (transcode == 1) {
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += `☒File is ${file.video_resolution} but is not hevc!\n`
|
response.infoLog += `☒File is ${file.video_resolution} but is not hevc!\n`;
|
||||||
response.infoLog += `☒File will be transcoded!\n`
|
response.infoLog += `☒File will be transcoded!\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.details = details;
|
module.exports.details = details;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_s710_nick_h265_nvenc_4K",
|
id: "Tdarr_Plugin_s710_nick_h265_nvenc_4K",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
|
|
@ -11,166 +7,144 @@ 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
|
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",
|
Version: "1.00",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_s710_nick_h265_nvenc_4K.js",
|
Link:
|
||||||
Tags:'pre-processing,ffmpeg,nvenc h265',
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_s710_nick_h265_nvenc_4K.js",
|
||||||
}
|
Tags: "pre-processing,ffmpeg,nvenc h265",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
|
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
container: '.mp4',
|
container: ".mp4",
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: false,
|
FFmpegMode: false,
|
||||||
reQueueAfter: false,
|
reQueueAfter: false,
|
||||||
infoLog: '',
|
infoLog: "",
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
response.FFmpegMode = true
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
response.FFmpegMode = true;
|
||||||
|
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
|
console.log("File is not video");
|
||||||
|
|
||||||
|
response.infoLog += "☒File is not video \n";
|
||||||
console.log("File is not video")
|
|
||||||
|
|
||||||
response.infoLog += "☒File is not video \n"
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
var jsonString = JSON.stringify(file);
|
||||||
|
response.container = ".mkv";
|
||||||
|
|
||||||
var jsonString = JSON.stringify(file)
|
if (
|
||||||
response.container = '.mkv'
|
file.ffProbeData.streams[0].codec_name == "hevc" ||
|
||||||
|
file.video_resolution !== "4KUHD"
|
||||||
|
) {
|
||||||
if (file.ffProbeData.streams[0].codec_name == 'hevc' || file.video_resolution !== "4KUHD") {
|
var hasPreferredLangTrack = false;
|
||||||
|
var hasPreferredLangInRequiredCodecs = false;
|
||||||
var hasPreferredLangTrack = false
|
var hasAnyInRequiredCodecs = false;
|
||||||
var hasPreferredLangInRequiredCodecs = false
|
|
||||||
var hasAnyInRequiredCodecs = false
|
|
||||||
|
|
||||||
var audioIdx = -1
|
|
||||||
var engTrackIdx = -1
|
|
||||||
|
|
||||||
var requiredAudioCodecs = "ac3,eac3,dts"
|
|
||||||
var preferredLangTrack = "eng"
|
|
||||||
var preferredCodec = "ac3"
|
|
||||||
|
|
||||||
|
var audioIdx = -1;
|
||||||
|
var engTrackIdx = -1;
|
||||||
|
|
||||||
|
var requiredAudioCodecs = "ac3,eac3,dts";
|
||||||
|
var preferredLangTrack = "eng";
|
||||||
|
var preferredCodec = "ac3";
|
||||||
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
||||||
audioIdx++
|
audioIdx++;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (requiredAudioCodecs.includes(file.ffProbeData.streams[i].codec_name)) {
|
if (
|
||||||
hasAnyInRequiredCodecs = true
|
requiredAudioCodecs.includes(file.ffProbeData.streams[i].codec_name)
|
||||||
|
) {
|
||||||
|
hasAnyInRequiredCodecs = true;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ((requiredAudioCodecs.includes(file.ffProbeData.streams[i].codec_name)) && file.ffProbeData.streams[i].tags.language.toLowerCase().includes(preferredLangTrack)) {
|
if (
|
||||||
hasPreferredLangInRequiredCodecs = true
|
requiredAudioCodecs.includes(
|
||||||
|
file.ffProbeData.streams[i].codec_name
|
||||||
|
) &&
|
||||||
|
file.ffProbeData.streams[i].tags.language
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(preferredLangTrack)
|
||||||
|
) {
|
||||||
|
hasPreferredLangInRequiredCodecs = true;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (file.ffProbeData.streams[i].tags.language.toLowerCase().includes(preferredLangTrack) && file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
if (
|
||||||
hasPreferredLangTrack = true
|
file.ffProbeData.streams[i].tags.language
|
||||||
engTrackIdx = audioIdx
|
.toLowerCase()
|
||||||
|
.includes(preferredLangTrack) &&
|
||||||
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio"
|
||||||
|
) {
|
||||||
|
hasPreferredLangTrack = true;
|
||||||
|
engTrackIdx = audioIdx;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (hasPreferredLangInRequiredCodecs) {
|
if (hasPreferredLangInRequiredCodecs) {
|
||||||
|
response.infoLog += `☑File already has ${preferredLangTrack} language track in ${requiredAudioCodecs}! \n`;
|
||||||
response.infoLog += `☑File already has ${preferredLangTrack} language track in ${requiredAudioCodecs}! \n`
|
|
||||||
|
|
||||||
} else if (hasPreferredLangTrack) {
|
} else if (hasPreferredLangTrack) {
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = `,-map 0:v -map 0:a:${engTrackIdx} -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${preferredCodec} -b:a:0 192k -ac 2`
|
response.preset = `,-map 0:v -map 0:a:${engTrackIdx} -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${preferredCodec} -b:a:0 192k -ac 2`;
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode = false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += `☒File has ${preferredLangTrack} language track but not in ${requiredAudioCodecs}! \n`
|
response.infoLog += `☒File has ${preferredLangTrack} language track but not in ${requiredAudioCodecs}! \n`;
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else if (!hasAnyInRequiredCodecs) {
|
} else if (!hasAnyInRequiredCodecs) {
|
||||||
|
|
||||||
if (audioIdx == -1) {
|
if (audioIdx == -1) {
|
||||||
response.infoLog += `☒File does not have any audio streams. Can't create ${preferredCodec} track. \n`
|
response.infoLog += `☒File does not have any audio streams. Can't create ${preferredCodec} track. \n`;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = `,-map 0:v -map 0:a:0 -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${preferredCodec} -b:a:0 192k -ac 2`
|
response.preset = `,-map 0:v -map 0:a:0 -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${preferredCodec} -b:a:0 192k -ac 2`;
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode = false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += `☒File has no language track in ${requiredAudioCodecs}. No ${preferredLangTrack} track marked so transcoding audio track 1 into ${preferredCodec}! \n`
|
response.infoLog += `☒File has no language track in ${requiredAudioCodecs}. No ${preferredLangTrack} track marked so transcoding audio track 1 into ${preferredCodec}! \n`;
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (file.container != "mkv") {
|
||||||
if (file.container != 'mkv') {
|
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = ', -map 0 -c copy'
|
response.preset = ", -map 0 -c copy";
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode = false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File is not in mkv container! \n"
|
response.infoLog += "☒File is not in mkv container! \n";
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
response.infoLog += "☑File is in mkv container! \n";
|
||||||
response.infoLog += "☑File is in mkv container! \n"
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = '-Z "H.265 MKV 2160p60" --all-audio --all-subtitles'
|
response.preset = '-Z "H.265 MKV 2160p60" --all-audio --all-subtitles';
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode = true
|
response.handBrakeMode = true;
|
||||||
response.FFmpegMode = false
|
response.FFmpegMode = false;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒ 4K file isn't in hevc! \n"
|
response.infoLog += "☒ 4K file isn't in hevc! \n";
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_s7x8_winsome_h265",
|
id: "Tdarr_Plugin_s7x8_winsome_h265",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
|
|
@ -11,166 +7,141 @@ 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
|
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",
|
Version: "1.00",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_s7x8_winsome_h265.js",
|
Link:
|
||||||
Tags:'pre-processing,handbrake,ffmpeg,h265',
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_s7x8_winsome_h265.js",
|
||||||
}
|
Tags: "pre-processing,handbrake,ffmpeg,h265",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
|
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
container: '.mp4',
|
container: ".mp4",
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: false,
|
FFmpegMode: false,
|
||||||
reQueueAfter: false,
|
reQueueAfter: false,
|
||||||
infoLog: '',
|
infoLog: "",
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
response.FFmpegMode = true
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
response.FFmpegMode = true;
|
||||||
|
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
|
console.log("File is not video");
|
||||||
|
|
||||||
|
response.infoLog += "☒File is not video \n";
|
||||||
console.log("File is not video")
|
|
||||||
|
|
||||||
response.infoLog += "☒File is not video \n"
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
var jsonString = JSON.stringify(file);
|
||||||
|
response.container = ".mkv";
|
||||||
|
|
||||||
var jsonString = JSON.stringify(file)
|
if (file.ffProbeData.streams[0].codec_name == "hevc") {
|
||||||
response.container = '.mkv'
|
var hasPreferredLangTrack = false;
|
||||||
|
var hasPreferredLangInRequiredCodecs = false;
|
||||||
|
var hasAnyInRequiredCodecs = false;
|
||||||
if (file.ffProbeData.streams[0].codec_name == 'hevc') {
|
|
||||||
|
|
||||||
var hasPreferredLangTrack = false
|
|
||||||
var hasPreferredLangInRequiredCodecs = false
|
|
||||||
var hasAnyInRequiredCodecs = false
|
|
||||||
|
|
||||||
var audioIdx = -1
|
|
||||||
var engTrackIdx = -1
|
|
||||||
|
|
||||||
var requiredAudioCodecs = "ac3,eac3,dts"
|
|
||||||
var preferredLangTrack = "eng"
|
|
||||||
var preferredCodec = "ac3"
|
|
||||||
|
|
||||||
|
var audioIdx = -1;
|
||||||
|
var engTrackIdx = -1;
|
||||||
|
|
||||||
|
var requiredAudioCodecs = "ac3,eac3,dts";
|
||||||
|
var preferredLangTrack = "eng";
|
||||||
|
var preferredCodec = "ac3";
|
||||||
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
||||||
audioIdx++
|
audioIdx++;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (requiredAudioCodecs.includes(file.ffProbeData.streams[i].codec_name)) {
|
if (
|
||||||
hasAnyInRequiredCodecs = true
|
requiredAudioCodecs.includes(file.ffProbeData.streams[i].codec_name)
|
||||||
|
) {
|
||||||
|
hasAnyInRequiredCodecs = true;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ((requiredAudioCodecs.includes(file.ffProbeData.streams[i].codec_name)) && file.ffProbeData.streams[i].tags.language.toLowerCase().includes(preferredLangTrack)) {
|
if (
|
||||||
hasPreferredLangInRequiredCodecs = true
|
requiredAudioCodecs.includes(
|
||||||
|
file.ffProbeData.streams[i].codec_name
|
||||||
|
) &&
|
||||||
|
file.ffProbeData.streams[i].tags.language
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(preferredLangTrack)
|
||||||
|
) {
|
||||||
|
hasPreferredLangInRequiredCodecs = true;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (file.ffProbeData.streams[i].tags.language.toLowerCase().includes(preferredLangTrack) && file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
if (
|
||||||
hasPreferredLangTrack = true
|
file.ffProbeData.streams[i].tags.language
|
||||||
engTrackIdx = audioIdx
|
.toLowerCase()
|
||||||
|
.includes(preferredLangTrack) &&
|
||||||
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio"
|
||||||
|
) {
|
||||||
|
hasPreferredLangTrack = true;
|
||||||
|
engTrackIdx = audioIdx;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (hasPreferredLangInRequiredCodecs) {
|
if (hasPreferredLangInRequiredCodecs) {
|
||||||
|
response.infoLog += `☑File already has ${preferredLangTrack} language track in ${requiredAudioCodecs}! \n`;
|
||||||
response.infoLog += `☑File already has ${preferredLangTrack} language track in ${requiredAudioCodecs}! \n`
|
|
||||||
|
|
||||||
} else if (hasPreferredLangTrack) {
|
} else if (hasPreferredLangTrack) {
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = `,-map 0:v -map 0:a:${engTrackIdx} -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${preferredCodec} -b:a:0 192k -ac 2`
|
response.preset = `,-map 0:v -map 0:a:${engTrackIdx} -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${preferredCodec} -b:a:0 192k -ac 2`;
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode = false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += `☒File has ${preferredLangTrack} language track but not in ${requiredAudioCodecs}! \n`
|
response.infoLog += `☒File has ${preferredLangTrack} language track but not in ${requiredAudioCodecs}! \n`;
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else if (!hasAnyInRequiredCodecs) {
|
} else if (!hasAnyInRequiredCodecs) {
|
||||||
|
|
||||||
if (audioIdx == -1) {
|
if (audioIdx == -1) {
|
||||||
response.infoLog += `☒File does not have any audio streams. Can't create ${preferredCodec} track. \n`
|
response.infoLog += `☒File does not have any audio streams. Can't create ${preferredCodec} track. \n`;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = `,-map 0:v -map 0:a:0 -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${preferredCodec} -b:a:0 192k -ac 2`
|
response.preset = `,-map 0:v -map 0:a:0 -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${preferredCodec} -b:a:0 192k -ac 2`;
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode = false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += `☒File has no language track in ${requiredAudioCodecs}. No ${preferredLangTrack} track marked so transcoding audio track 1 into ${preferredCodec}! \n`
|
response.infoLog += `☒File has no language track in ${requiredAudioCodecs}. No ${preferredLangTrack} track marked so transcoding audio track 1 into ${preferredCodec}! \n`;
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (file.container != "mkv") {
|
||||||
if (file.container != 'mkv') {
|
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = ', -map 0 -c copy'
|
response.preset = ", -map 0 -c copy";
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode = false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File is not in mkv container! \n"
|
response.infoLog += "☒File is not in mkv container! \n";
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
response.infoLog += "☑File is in mkv container! \n";
|
||||||
response.infoLog += "☑File is in mkv container! \n"
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = '-Z "H.265 MKV 2160p60" --all-audio --all-subtitles'
|
response.preset = '-Z "H.265 MKV 2160p60" --all-audio --all-subtitles';
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode = true
|
response.handBrakeMode = true;
|
||||||
response.FFmpegMode = false
|
response.FFmpegMode = false;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File isn't in hevc! \n"
|
response.infoLog += "☒File isn't in hevc! \n";
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_s7x9_winsome_h265_10bit",
|
id: "Tdarr_Plugin_s7x9_winsome_h265_10bit",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
|
|
@ -11,167 +7,142 @@ 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
|
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",
|
Version: "1.00",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_s7x9_winsome_h265_10bit.js",
|
Link:
|
||||||
Tags:'pre-processing,handbrake,ffmpeg,h265',
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_s7x9_winsome_h265_10bit.js",
|
||||||
}
|
Tags: "pre-processing,handbrake,ffmpeg,h265",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
|
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
container: '.mp4',
|
container: ".mp4",
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: false,
|
FFmpegMode: false,
|
||||||
reQueueAfter: false,
|
reQueueAfter: false,
|
||||||
infoLog: '',
|
infoLog: "",
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
response.FFmpegMode = true
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
response.FFmpegMode = true;
|
||||||
|
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
|
console.log("File is not video");
|
||||||
|
|
||||||
|
response.infoLog += "☒File is not video";
|
||||||
console.log("File is not video")
|
|
||||||
|
|
||||||
response.infoLog += "☒File is not video"
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
var jsonString = JSON.stringify(file);
|
||||||
|
response.container = ".mkv";
|
||||||
|
|
||||||
var jsonString = JSON.stringify(file)
|
if (file.ffProbeData.streams[0].codec_name == "hevc") {
|
||||||
response.container = '.mkv'
|
var hasPreferredLangTrack = false;
|
||||||
|
var hasPreferredLangInRequiredCodecs = false;
|
||||||
|
var hasAnyInRequiredCodecs = false;
|
||||||
if (file.ffProbeData.streams[0].codec_name == 'hevc') {
|
|
||||||
|
|
||||||
|
|
||||||
var hasPreferredLangTrack = false
|
|
||||||
var hasPreferredLangInRequiredCodecs = false
|
|
||||||
var hasAnyInRequiredCodecs = false
|
|
||||||
|
|
||||||
var audioIdx = -1
|
|
||||||
var engTrackIdx = -1
|
|
||||||
|
|
||||||
var requiredAudioCodecs = "ac3,eac3,dts"
|
|
||||||
var preferredLangTrack = "eng"
|
|
||||||
var preferredCodec = "ac3"
|
|
||||||
|
|
||||||
|
var audioIdx = -1;
|
||||||
|
var engTrackIdx = -1;
|
||||||
|
|
||||||
|
var requiredAudioCodecs = "ac3,eac3,dts";
|
||||||
|
var preferredLangTrack = "eng";
|
||||||
|
var preferredCodec = "ac3";
|
||||||
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
||||||
audioIdx++
|
audioIdx++;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (requiredAudioCodecs.includes(file.ffProbeData.streams[i].codec_name)) {
|
if (
|
||||||
hasAnyInRequiredCodecs = true
|
requiredAudioCodecs.includes(file.ffProbeData.streams[i].codec_name)
|
||||||
|
) {
|
||||||
|
hasAnyInRequiredCodecs = true;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ((requiredAudioCodecs.includes(file.ffProbeData.streams[i].codec_name)) && file.ffProbeData.streams[i].tags.language.toLowerCase().includes(preferredLangTrack)) {
|
if (
|
||||||
hasPreferredLangInRequiredCodecs = true
|
requiredAudioCodecs.includes(
|
||||||
|
file.ffProbeData.streams[i].codec_name
|
||||||
|
) &&
|
||||||
|
file.ffProbeData.streams[i].tags.language
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(preferredLangTrack)
|
||||||
|
) {
|
||||||
|
hasPreferredLangInRequiredCodecs = true;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (file.ffProbeData.streams[i].tags.language.toLowerCase().includes(preferredLangTrack) && file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
if (
|
||||||
hasPreferredLangTrack = true
|
file.ffProbeData.streams[i].tags.language
|
||||||
engTrackIdx = audioIdx
|
.toLowerCase()
|
||||||
|
.includes(preferredLangTrack) &&
|
||||||
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio"
|
||||||
|
) {
|
||||||
|
hasPreferredLangTrack = true;
|
||||||
|
engTrackIdx = audioIdx;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (hasPreferredLangInRequiredCodecs) {
|
if (hasPreferredLangInRequiredCodecs) {
|
||||||
|
response.infoLog += `☑File already has ${preferredLangTrack} language track in ${requiredAudioCodecs}! \n`;
|
||||||
response.infoLog += `☑File already has ${preferredLangTrack} language track in ${requiredAudioCodecs}! \n`
|
|
||||||
|
|
||||||
} else if (hasPreferredLangTrack) {
|
} else if (hasPreferredLangTrack) {
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = `,-map 0:v -map 0:a:${engTrackIdx} -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${preferredCodec} -b:a:0 192k -ac 2`
|
response.preset = `,-map 0:v -map 0:a:${engTrackIdx} -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${preferredCodec} -b:a:0 192k -ac 2`;
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode = false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += `☒File has ${preferredLangTrack} language track but not in ${requiredAudioCodecs}! \n`
|
response.infoLog += `☒File has ${preferredLangTrack} language track but not in ${requiredAudioCodecs}! \n`;
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else if (!hasAnyInRequiredCodecs) {
|
} else if (!hasAnyInRequiredCodecs) {
|
||||||
|
|
||||||
if (audioIdx == -1) {
|
if (audioIdx == -1) {
|
||||||
response.infoLog += `☒File does not have any audio streams. Can't create ${preferredCodec} track. \n`
|
response.infoLog += `☒File does not have any audio streams. Can't create ${preferredCodec} track. \n`;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = `,-map 0:v -map 0:a:0 -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${preferredCodec} -b:a:0 192k -ac 2`
|
response.preset = `,-map 0:v -map 0:a:0 -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${preferredCodec} -b:a:0 192k -ac 2`;
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode = false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += `☒File has no language track in ${requiredAudioCodecs}. No ${preferredLangTrack} track marked so transcoding audio track 1 into ${preferredCodec}! \n`
|
response.infoLog += `☒File has no language track in ${requiredAudioCodecs}. No ${preferredLangTrack} track marked so transcoding audio track 1 into ${preferredCodec}! \n`;
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (file.container != "mkv") {
|
||||||
if (file.container != 'mkv') {
|
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = ', -map 0 -c copy'
|
response.preset = ", -map 0 -c copy";
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode = false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File is not in mkv container! \n"
|
response.infoLog += "☒File is not in mkv container! \n";
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
response.infoLog += "☑File is in mkv container! \n";
|
||||||
response.infoLog += "☑File is in mkv container! \n"
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = '-Z "H.265 MKV 2160p60" -e x265_10bit --all-audio --all-subtitles'
|
response.preset =
|
||||||
response.container = '.mkv'
|
'-Z "H.265 MKV 2160p60" -e x265_10bit --all-audio --all-subtitles';
|
||||||
response.handBrakeMode = true
|
response.container = ".mkv";
|
||||||
response.FFmpegMode = false
|
response.handBrakeMode = true;
|
||||||
|
response.FFmpegMode = false;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File isn't in hevc! \n"
|
response.infoLog += "☒File isn't in hevc! \n";
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_s7x9_winsome_h265_nvenc",
|
id: "Tdarr_Plugin_s7x9_winsome_h265_nvenc",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
|
|
@ -11,167 +7,142 @@ 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
|
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",
|
Version: "1.00",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_s7x9_winsome_h265_nvenc.js",
|
Link:
|
||||||
Tags:'pre-processing,handbrake,ffmpeg,nvenc h265',
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_s7x9_winsome_h265_nvenc.js",
|
||||||
}
|
Tags: "pre-processing,handbrake,ffmpeg,nvenc h265",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
|
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
container: '.mp4',
|
container: ".mp4",
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: false,
|
FFmpegMode: false,
|
||||||
reQueueAfter: false,
|
reQueueAfter: false,
|
||||||
infoLog: '',
|
infoLog: "",
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
response.FFmpegMode = true
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
response.FFmpegMode = true;
|
||||||
|
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
|
console.log("File is not video");
|
||||||
|
|
||||||
|
response.infoLog += "☒File is not video \n";
|
||||||
console.log("File is not video")
|
|
||||||
|
|
||||||
response.infoLog += "☒File is not video \n"
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
var jsonString = JSON.stringify(file);
|
||||||
|
response.container = ".mkv";
|
||||||
|
|
||||||
var jsonString = JSON.stringify(file)
|
if (file.ffProbeData.streams[0].codec_name == "hevc") {
|
||||||
response.container = '.mkv'
|
var hasPreferredLangTrack = false;
|
||||||
|
var hasPreferredLangInRequiredCodecs = false;
|
||||||
|
var hasAnyInRequiredCodecs = false;
|
||||||
if (file.ffProbeData.streams[0].codec_name == 'hevc') {
|
|
||||||
|
|
||||||
|
|
||||||
var hasPreferredLangTrack = false
|
|
||||||
var hasPreferredLangInRequiredCodecs = false
|
|
||||||
var hasAnyInRequiredCodecs = false
|
|
||||||
|
|
||||||
var audioIdx = -1
|
|
||||||
var engTrackIdx = -1
|
|
||||||
|
|
||||||
var requiredAudioCodecs = "ac3,eac3,dts"
|
|
||||||
var preferredLangTrack = "eng"
|
|
||||||
var preferredCodec = "ac3"
|
|
||||||
|
|
||||||
|
var audioIdx = -1;
|
||||||
|
var engTrackIdx = -1;
|
||||||
|
|
||||||
|
var requiredAudioCodecs = "ac3,eac3,dts";
|
||||||
|
var preferredLangTrack = "eng";
|
||||||
|
var preferredCodec = "ac3";
|
||||||
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
||||||
audioIdx++
|
audioIdx++;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (requiredAudioCodecs.includes(file.ffProbeData.streams[i].codec_name)) {
|
if (
|
||||||
hasAnyInRequiredCodecs = true
|
requiredAudioCodecs.includes(file.ffProbeData.streams[i].codec_name)
|
||||||
|
) {
|
||||||
|
hasAnyInRequiredCodecs = true;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ((requiredAudioCodecs.includes(file.ffProbeData.streams[i].codec_name)) && file.ffProbeData.streams[i].tags.language.toLowerCase().includes(preferredLangTrack)) {
|
if (
|
||||||
hasPreferredLangInRequiredCodecs = true
|
requiredAudioCodecs.includes(
|
||||||
|
file.ffProbeData.streams[i].codec_name
|
||||||
|
) &&
|
||||||
|
file.ffProbeData.streams[i].tags.language
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(preferredLangTrack)
|
||||||
|
) {
|
||||||
|
hasPreferredLangInRequiredCodecs = true;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (file.ffProbeData.streams[i].tags.language.toLowerCase().includes(preferredLangTrack) && file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
if (
|
||||||
hasPreferredLangTrack = true
|
file.ffProbeData.streams[i].tags.language
|
||||||
engTrackIdx = audioIdx
|
.toLowerCase()
|
||||||
|
.includes(preferredLangTrack) &&
|
||||||
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio"
|
||||||
|
) {
|
||||||
|
hasPreferredLangTrack = true;
|
||||||
|
engTrackIdx = audioIdx;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (hasPreferredLangInRequiredCodecs) {
|
if (hasPreferredLangInRequiredCodecs) {
|
||||||
|
response.infoLog += `☑File already has ${preferredLangTrack} language track in ${requiredAudioCodecs}! \n`;
|
||||||
response.infoLog += `☑File already has ${preferredLangTrack} language track in ${requiredAudioCodecs}! \n`
|
|
||||||
|
|
||||||
} else if (hasPreferredLangTrack) {
|
} else if (hasPreferredLangTrack) {
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = `,-map 0:v -map 0:a:${engTrackIdx} -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${preferredCodec} -b:a:0 192k -ac 2`
|
response.preset = `,-map 0:v -map 0:a:${engTrackIdx} -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${preferredCodec} -b:a:0 192k -ac 2`;
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode = false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += `☒File has ${preferredLangTrack} language track but not in ${requiredAudioCodecs}! \n`
|
response.infoLog += `☒File has ${preferredLangTrack} language track but not in ${requiredAudioCodecs}! \n`;
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else if (!hasAnyInRequiredCodecs) {
|
} else if (!hasAnyInRequiredCodecs) {
|
||||||
|
|
||||||
if (audioIdx == -1) {
|
if (audioIdx == -1) {
|
||||||
response.infoLog += `☒File does not have any audio streams. Can't create ${preferredCodec} track. \n`
|
response.infoLog += `☒File does not have any audio streams. Can't create ${preferredCodec} track. \n`;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = `,-map 0:v -map 0:a:0 -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${preferredCodec} -b:a:0 192k -ac 2`
|
response.preset = `,-map 0:v -map 0:a:0 -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${preferredCodec} -b:a:0 192k -ac 2`;
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode = false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += `☒File has no language track in ${requiredAudioCodecs}. No ${preferredLangTrack} track marked so transcoding audio track 1 into ${preferredCodec}! \n`
|
response.infoLog += `☒File has no language track in ${requiredAudioCodecs}. No ${preferredLangTrack} track marked so transcoding audio track 1 into ${preferredCodec}! \n`;
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (file.container != "mkv") {
|
||||||
if (file.container != 'mkv') {
|
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = ', -map 0 -c copy'
|
response.preset = ", -map 0 -c copy";
|
||||||
response.container = '.mkv'
|
response.container = ".mkv";
|
||||||
response.handBrakeMode = false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File is not in mkv container! \n"
|
response.infoLog += "☒File is not in mkv container! \n";
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
response.infoLog += "☑File is in mkv container! \n";
|
||||||
response.infoLog += "☑File is in mkv container! \n"
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = '-Z "H.265 MKV 2160p60" --all-audio --all-subtitles -e nvenc_h265'
|
response.preset =
|
||||||
response.container = '.mkv'
|
'-Z "H.265 MKV 2160p60" --all-audio --all-subtitles -e nvenc_h265';
|
||||||
response.handBrakeMode = true
|
response.container = ".mkv";
|
||||||
response.FFmpegMode = false
|
response.handBrakeMode = true;
|
||||||
|
response.FFmpegMode = false;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File isn't in hevc! \n"
|
response.infoLog += "☒File isn't in hevc! \n";
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_sdd3_Remove_Commentary_Tracks",
|
id: "Tdarr_Plugin_sdd3_Remove_Commentary_Tracks",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
|
|
@ -11,90 +7,76 @@ function details() {
|
||||||
Operation: "Remux",
|
Operation: "Remux",
|
||||||
Description: `[Contains built-in filter] If commentary tracks are detected, they will be removed. \n\n`,
|
Description: `[Contains built-in filter] If commentary tracks are detected, they will be removed. \n\n`,
|
||||||
Version: "1.00",
|
Version: "1.00",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_sdd3_Remove_Commentary_Tracks.js",
|
Link:
|
||||||
Tags:'pre-processing,ffmpeg,audio only',
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_sdd3_Remove_Commentary_Tracks.js",
|
||||||
}
|
Tags: "pre-processing,ffmpeg,audio only",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
|
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
container: '.mp4',
|
container: ".mp4",
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: false,
|
FFmpegMode: false,
|
||||||
reQueueAfter: false,
|
reQueueAfter: false,
|
||||||
infoLog: '',
|
infoLog: "",
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
response.processFile = false
|
response.processFile = false;
|
||||||
response.infoLog += "☒File is not a video! \n"
|
response.infoLog += "☒File is not a video! \n";
|
||||||
return response
|
return response;
|
||||||
} else {
|
} else {
|
||||||
response.infoLog += "☑File is a video! \n"
|
response.infoLog += "☑File is a video! \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var audioIdx = -1;
|
||||||
|
var hasCommentaryTrack = false;
|
||||||
var audioIdx = -1
|
var ffmpegCommandInsert = "";
|
||||||
var hasCommentaryTrack = false
|
|
||||||
var ffmpegCommandInsert = ""
|
|
||||||
|
|
||||||
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
|
||||||
//keep track of audio streams for when removing commentary track
|
//keep track of audio streams for when removing commentary track
|
||||||
try {
|
try {
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
||||||
audioIdx++
|
audioIdx++;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
|
|
||||||
//check if commentary track and passing audio stream number
|
//check if commentary track and passing audio stream number
|
||||||
try {
|
try {
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" && file.ffProbeData.streams[i].tags.title.toLowerCase().includes("commentary")) {
|
if (
|
||||||
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" &&
|
||||||
|
file.ffProbeData.streams[i].tags.title
|
||||||
ffmpegCommandInsert += ` -map -0:a:${audioIdx}`
|
.toLowerCase()
|
||||||
hasCommentaryTrack = true
|
.includes("commentary")
|
||||||
|
) {
|
||||||
|
ffmpegCommandInsert += ` -map -0:a:${audioIdx}`;
|
||||||
|
hasCommentaryTrack = true;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasCommentaryTrack === true) {
|
if (hasCommentaryTrack === true) {
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = `, -map 0 ${ffmpegCommandInsert} -c copy`
|
response.preset = `, -map 0 ${ffmpegCommandInsert} -c copy`;
|
||||||
response.container = '.' + file.container
|
response.container = "." + file.container;
|
||||||
response.handBrakeMode = false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File contains commentary tracks. Removing! \n"
|
response.infoLog += "☒File contains commentary tracks. Removing! \n";
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
response.infoLog += "☑File doesn't contain commentary tracks! \n";
|
||||||
response.infoLog += "☑File doesn't contain commentary tracks! \n"
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response.processFile = false
|
response.processFile = false;
|
||||||
response.infoLog += "☑File meets conditions! \n"
|
response.infoLog += "☑File meets conditions! \n";
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.details = details;
|
module.exports.details = details;
|
||||||
module.exports.plugin = plugin;
|
module.exports.plugin = plugin;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_sdf5_Thierrrrry_Remove_Non_English_Audio",
|
id: "Tdarr_Plugin_sdf5_Thierrrrry_Remove_Non_English_Audio",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
|
|
@ -11,111 +7,99 @@ 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
|
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",
|
Version: "1.00",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_sdf5_Thierrrrry_Remove_Non_English_Audio.js",
|
Link:
|
||||||
Tags:'pre-processing,ffmpeg,audio only',
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_sdf5_Thierrrrry_Remove_Non_English_Audio.js",
|
||||||
}
|
Tags: "pre-processing,ffmpeg,audio only",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
|
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: '',
|
preset: "",
|
||||||
container: '.mp4',
|
container: ".mp4",
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: false,
|
FFmpegMode: false,
|
||||||
reQueueAfter: false,
|
reQueueAfter: false,
|
||||||
infoLog: '',
|
infoLog: "",
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
response.FFmpegMode = true
|
|
||||||
|
|
||||||
|
response.FFmpegMode = true;
|
||||||
|
|
||||||
//check if files is video
|
//check if files is video
|
||||||
|
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
|
console.log("File is not video");
|
||||||
|
|
||||||
|
response.infoLog += "☒File is not video \n";
|
||||||
console.log("File is not video")
|
|
||||||
|
|
||||||
response.infoLog += "☒File is not video \n"
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ffmpegCommandInsert = "";
|
||||||
|
var audioIdx = -1;
|
||||||
|
var hasNonEngTrack = false;
|
||||||
var ffmpegCommandInsert = ''
|
var audioStreamsRemoved = 0;
|
||||||
var audioIdx = -1
|
|
||||||
var hasNonEngTrack = false
|
|
||||||
var audioStreamsRemoved = 0
|
|
||||||
|
|
||||||
//count number of audio streams
|
//count number of audio streams
|
||||||
var audioStreamCount = file.ffProbeData.streams.filter(row => (row.codec_type.toLowerCase() == "audio")).length;
|
var audioStreamCount = file.ffProbeData.streams.filter(
|
||||||
|
(row) => row.codec_type.toLowerCase() == "audio"
|
||||||
|
).length;
|
||||||
|
|
||||||
console.log("audioStreamCount:" + audioStreamCount)
|
console.log("audioStreamCount:" + audioStreamCount);
|
||||||
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
|
||||||
|
|
||||||
//check if current stream is audio, update audioIdx if so
|
//check if current stream is audio, update audioIdx if so
|
||||||
try {
|
try {
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
||||||
audioIdx++
|
audioIdx++;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" && !(file.ffProbeData.streams[i].tags.language.toLowerCase().includes('eng') || file.ffProbeData.streams[i].tags.language.toLowerCase().includes('und'))) {
|
if (
|
||||||
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" &&
|
||||||
audioStreamsRemoved++
|
!(
|
||||||
|
file.ffProbeData.streams[i].tags.language
|
||||||
|
.toLowerCase()
|
||||||
|
.includes("eng") ||
|
||||||
|
file.ffProbeData.streams[i].tags.language
|
||||||
|
.toLowerCase()
|
||||||
|
.includes("und")
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
audioStreamsRemoved++;
|
||||||
|
|
||||||
if (audioStreamsRemoved == audioStreamCount) {
|
if (audioStreamsRemoved == audioStreamCount) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ffmpegCommandInsert += ` -map -0:a:${audioIdx}`
|
ffmpegCommandInsert += ` -map -0:a:${audioIdx}`;
|
||||||
hasNonEngTrack = true
|
hasNonEngTrack = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (hasNonEngTrack === true) {
|
if (hasNonEngTrack === true) {
|
||||||
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.preset = `, -map 0 ${ffmpegCommandInsert} -c copy`
|
response.preset = `, -map 0 ${ffmpegCommandInsert} -c copy`;
|
||||||
response.container = '.' + file.container
|
response.container = "." + file.container;
|
||||||
response.handBrakeMode = false
|
response.handBrakeMode = false;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.infoLog += "☒File contains tracks which are not english or undefined. Removing! \n"
|
response.infoLog +=
|
||||||
return response
|
"☒File contains tracks which are not english or undefined. Removing! \n";
|
||||||
|
return response;
|
||||||
} else {
|
} else {
|
||||||
|
response.infoLog +=
|
||||||
response.infoLog += "☑File doesn't contain tracks which are not english or undefined! \n"
|
"☑File doesn't contain tracks which are not english or undefined! \n";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.details = details;
|
module.exports.details = details;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_x7ab_Remove_Subs",
|
id: "Tdarr_Plugin_x7ab_Remove_Subs",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
|
|
@ -10,77 +6,60 @@ function details() {
|
||||||
Type: "Video",
|
Type: "Video",
|
||||||
Description: `[Contains built-in filter] This plugin removes subtitles if detected. The output container is the same as the original. \n\n`,
|
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",
|
Version: "1.00",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_x7ab_Remove_Subs.js",
|
Link:
|
||||||
Tags:'pre-processing,ffmpeg,subtitle only',
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_x7ab_Remove_Subs.js",
|
||||||
}
|
Tags: "pre-processing,ffmpeg,subtitle only",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
|
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
processFile: false,
|
||||||
processFile : false,
|
preset: "",
|
||||||
preset : '',
|
container: ".mp4",
|
||||||
container : '.mp4',
|
handBrakeMode: false,
|
||||||
handBrakeMode : false,
|
FFmpegMode: false,
|
||||||
FFmpegMode : false,
|
reQueueAfter: false,
|
||||||
reQueueAfter : false,
|
infoLog: "",
|
||||||
infoLog : '',
|
};
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
|
console.log("File is not video");
|
||||||
|
|
||||||
console.log("File is not video")
|
response.infoLog += "☒File is not video \n";
|
||||||
|
|
||||||
response.infoLog += "☒File is not video \n"
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
response.FFmpegMode = true;
|
||||||
|
response.container = "." + file.container;
|
||||||
|
|
||||||
|
var hasSubs = false;
|
||||||
|
|
||||||
response.FFmpegMode = true
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
response.container = '.' + file.container
|
try {
|
||||||
|
if (
|
||||||
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle"
|
||||||
|
) {
|
||||||
|
hasSubs = true;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
}
|
||||||
|
|
||||||
var hasSubs = false
|
if (hasSubs) {
|
||||||
|
response.infoLog += "☒File has subs \n";
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
response.preset = ",-sn -map 0 -c copy";
|
||||||
|
|
||||||
try {
|
|
||||||
if(file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle"){
|
|
||||||
|
|
||||||
hasSubs = true
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (err) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
if(hasSubs){
|
|
||||||
|
|
||||||
response.infoLog += "☒File has subs \n"
|
|
||||||
response.preset = ',-sn -map 0 -c copy'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
}else{
|
response.infoLog += "☑File has no subs \n";
|
||||||
response.infoLog += "☑File has no subs \n"
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
response.infoLog += "☑File meets conditions! \n"
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
response.infoLog += "☑File meets conditions! \n";
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,86 +1,62 @@
|
||||||
|
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_x7ac_Remove_Closed_Captions",
|
id: "Tdarr_Plugin_x7ac_Remove_Closed_Captions",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
Name: "Remove closed captions",
|
Name: "Remove closed captions",
|
||||||
Type: "Video",
|
Type: "Video",
|
||||||
Operation: "Remux",
|
Operation: "Remux",
|
||||||
Description: "[Contains built-in filter] If detected, closed captions (XDS,608,708) will be removed.",
|
Description:
|
||||||
|
"[Contains built-in filter] If detected, closed captions (XDS,608,708) will be removed.",
|
||||||
Version: "1.00",
|
Version: "1.00",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_x7ac_Remove_Closed_Captions.js",
|
Link:
|
||||||
Tags:'pre-processing,ffmpeg,subtitle only',
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_x7ac_Remove_Closed_Captions.js",
|
||||||
}
|
Tags: "pre-processing,ffmpeg,subtitle only",
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
|
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
processFile: false,
|
||||||
processFile : false,
|
preset: "",
|
||||||
preset : '',
|
container: ".mp4",
|
||||||
container : '.mp4',
|
handBrakeMode: false,
|
||||||
handBrakeMode : false,
|
FFmpegMode: false,
|
||||||
FFmpegMode : false,
|
reQueueAfter: true,
|
||||||
reQueueAfter : true,
|
infoLog: "",
|
||||||
infoLog : '',
|
};
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (file.fileMedium !== "video") {
|
if (file.fileMedium !== "video") {
|
||||||
|
console.log("File is not video");
|
||||||
|
|
||||||
console.log("File is not video")
|
response.infoLog += "☒File is not video \n";
|
||||||
|
|
||||||
response.infoLog += "☒File is not video \n"
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
if (file.hasClosedCaptions === true) {
|
||||||
|
response = {
|
||||||
|
processFile: true,
|
||||||
|
preset: ',-map 0 -codec copy -bsf:v "filter_units=remove_types=6"',
|
||||||
|
container: "." + file.container,
|
||||||
|
handBrakeMode: false,
|
||||||
|
FFmpegMode: true,
|
||||||
|
reQueueAfter: true,
|
||||||
|
infoLog: "☒This file has closed captions \n",
|
||||||
|
};
|
||||||
|
|
||||||
|
return response;
|
||||||
if(file.hasClosedCaptions === true){
|
} else {
|
||||||
|
response.infoLog +=
|
||||||
|
"☑Closed captions have not been detected on this file \n";
|
||||||
response = {
|
|
||||||
|
|
||||||
processFile : true,
|
|
||||||
preset : ',-map 0 -codec copy -bsf:v "filter_units=remove_types=6"',
|
|
||||||
container : '.' + file.container ,
|
|
||||||
handBrakeMode : false,
|
|
||||||
FFmpegMode : true,
|
|
||||||
reQueueAfter : true,
|
|
||||||
infoLog : '☒This file has closed captions \n',
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return response
|
|
||||||
|
|
||||||
}else{
|
|
||||||
|
|
||||||
response.infoLog += "☑Closed captions have not been detected on this file \n"
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.details = details;
|
module.exports.details = details;
|
||||||
|
|
||||||
module.exports.plugin = plugin;
|
module.exports.plugin = plugin;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_z0ab_TheRealShadoh_FFmpeg_Subs_H264_Medium",
|
id: "Tdarr_Plugin_z0ab_TheRealShadoh_FFmpeg_Subs_H264_Medium",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
|
|
@ -11,148 +7,135 @@ function details() {
|
||||||
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
|
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",
|
Version: "1.00",
|
||||||
Link: "https://github.com/TheRealShadoh/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_z0ab_TheRealShadoh_FFmpeg_Subs_H264_Medium.js",
|
Link:
|
||||||
Tags:'pre-processing,ffmpeg,h264',
|
"https://github.com/TheRealShadoh/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_z0ab_TheRealShadoh_FFmpeg_Subs_H264_Medium.js",
|
||||||
}
|
Tags: "pre-processing,ffmpeg,h264",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
|
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
processFile: false,
|
||||||
|
preset: "",
|
||||||
|
container: ".mp4",
|
||||||
|
handBrakeMode: false,
|
||||||
|
FFmpegMode: false,
|
||||||
|
reQueueAfter: false,
|
||||||
|
infoLog: "",
|
||||||
|
};
|
||||||
|
|
||||||
processFile : false,
|
if (file.fileMedium !== "video") {
|
||||||
preset : '',
|
console.log("File is not video");
|
||||||
container : '.mp4',
|
|
||||||
handBrakeMode : false,
|
|
||||||
FFmpegMode : false,
|
|
||||||
reQueueAfter : false,
|
|
||||||
infoLog : '',
|
|
||||||
|
|
||||||
}
|
response.infoLog += "☒File is not video \n";
|
||||||
|
|
||||||
if (file.fileMedium !== "video"){
|
|
||||||
|
|
||||||
|
|
||||||
console.log("File is not video")
|
|
||||||
|
|
||||||
response.infoLog += "☒File is not video \n"
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
var jsonString = JSON.stringify(file);
|
||||||
|
|
||||||
var jsonString = JSON.stringify(file)
|
var hasSubs = false;
|
||||||
|
|
||||||
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
try {
|
||||||
|
let streamData = file.ffProbeData.streams[i];
|
||||||
|
if (
|
||||||
|
streamData.codec_type.toLowerCase() == "subtitle" &&
|
||||||
|
streamData.codec_name != "mov_text"
|
||||||
|
) {
|
||||||
|
hasSubs = true;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
}
|
||||||
|
|
||||||
var hasSubs = false
|
if (file.ffProbeData.streams[0].codec_name != "h264") {
|
||||||
|
response.infoLog += "☒File is not in h264! \n";
|
||||||
|
response.preset =
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
", -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v libx264 -preset medium -c:a aac -c:s mov_text";
|
||||||
|
|
||||||
try {
|
|
||||||
let streamData = file.ffProbeData.streams[i];
|
|
||||||
if(streamData.codec_type.toLowerCase() == "subtitle" && streamData.codec_name != "mov_text"){
|
|
||||||
hasSubs = true
|
|
||||||
}
|
|
||||||
} catch (err) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(file.ffProbeData.streams[0].codec_name != 'h264'){
|
|
||||||
|
|
||||||
response.infoLog += "☒File is not in h264! \n"
|
|
||||||
response.preset = ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v libx264 -preset medium -c:a aac -c:s mov_text'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
|
response.infoLog += "☑File is already in h264! \n";
|
||||||
|
}
|
||||||
|
|
||||||
}else{
|
///
|
||||||
response.infoLog += "☑File is already in h264! \n"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (
|
||||||
///
|
file.meta.Title != undefined &&
|
||||||
|
!jsonString.includes("aac") &&
|
||||||
if((file.meta.Title != undefined) && !jsonString.includes("aac") && hasSubs){
|
hasSubs
|
||||||
|
) {
|
||||||
response.infoLog += "☒File has title metadata and no aac and subs \n"
|
response.infoLog += "☒File has title metadata and no aac and subs \n";
|
||||||
response.preset = ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text'
|
response.preset =
|
||||||
|
", -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text";
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!jsonString.includes("aac") && hasSubs){
|
if (!jsonString.includes("aac") && hasSubs) {
|
||||||
|
response.infoLog += "☒File has no aac track and has subs \n";
|
||||||
response.infoLog += "☒File has no aac track and has subs \n"
|
response.preset =
|
||||||
response.preset = ', -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text'
|
", -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text";
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (file.meta.Title != undefined && hasSubs) {
|
||||||
if(file.meta.Title != undefined && hasSubs){
|
response.infoLog += "☒File has title and has subs \n";
|
||||||
|
response.preset =
|
||||||
response.infoLog += "☒File has title and has subs \n"
|
", -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text";
|
||||||
response.preset = ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
if (file.meta.Title != undefined) {
|
||||||
///
|
response.infoLog += "☒File has title metadata \n";
|
||||||
if(file.meta.Title != undefined ){
|
response.preset =
|
||||||
|
", -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text";
|
||||||
response.infoLog += "☒File has title metadata \n"
|
|
||||||
response.preset = ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
}else{
|
} else {
|
||||||
response.infoLog += "☑File has no title metadata \n"
|
response.infoLog += "☑File has no title metadata \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!jsonString.includes("aac")){
|
if (!jsonString.includes("aac")) {
|
||||||
|
response.infoLog += "☒File has no aac track \n";
|
||||||
response.infoLog += "☒File has no aac track \n"
|
response.preset =
|
||||||
response.preset = ', -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text'
|
", -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text";
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
|
response.infoLog += "☑File has aac track \n";
|
||||||
|
}
|
||||||
|
|
||||||
}else{
|
if (hasSubs) {
|
||||||
response.infoLog += "☑File has aac track \n"
|
response.infoLog += "☒File has incompatible subs \n";
|
||||||
}
|
response.preset =
|
||||||
|
", -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text";
|
||||||
if(hasSubs){
|
|
||||||
|
|
||||||
response.infoLog += "☒File has incompatible subs \n"
|
|
||||||
response.preset = ', -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text'
|
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
}else{
|
response.infoLog += "☑File has no/compatible subs \n";
|
||||||
response.infoLog += "☑File has no/compatible subs \n"
|
}
|
||||||
}
|
|
||||||
|
|
||||||
response.infoLog += "☑File meets conditions! \n"
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
response.infoLog += "☑File meets conditions! \n";
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module.exports.details = function details() {
|
module.exports.details = function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_z18s_rename_files_based_on_codec",
|
id: "Tdarr_Plugin_z18s_rename_files_based_on_codec",
|
||||||
Stage: "Post-processing",
|
Stage: "Post-processing",
|
||||||
|
|
@ -12,61 +8,62 @@ module.exports.details = function details() {
|
||||||
Description: `[TESTING][Contains built-in filter]This plugin renames 264 files to 265 or vice versa depending on codec. \n\n`,
|
Description: `[TESTING][Contains built-in filter]This plugin renames 264 files to 265 or vice versa depending on codec. \n\n`,
|
||||||
Version: "1.00",
|
Version: "1.00",
|
||||||
Link: "",
|
Link: "",
|
||||||
Tags:"post-processing",
|
Tags: "post-processing",
|
||||||
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.plugin = function plugin(file, librarySettings, inputs) {
|
module.exports.plugin = function plugin(file, librarySettings, inputs) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
var fs = require("fs");
|
||||||
var fs = require('fs');
|
var path = require("path");
|
||||||
var path = require('path');
|
if (fs.existsSync(path.join(process.cwd(), "/npm"))) {
|
||||||
if (fs.existsSync(path.join(process.cwd() , '/npm'))) {
|
var rootModules = path.join(process.cwd(), "/npm/node_modules/");
|
||||||
var rootModules = path.join(process.cwd() , '/npm/node_modules/')
|
} else {
|
||||||
} else{
|
var rootModules = "";
|
||||||
var rootModules = ''
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var fsextra = require(rootModules+'fs-extra')
|
var fsextra = require(rootModules + "fs-extra");
|
||||||
|
|
||||||
var fileNameOld = file._id
|
var fileNameOld = file._id;
|
||||||
|
|
||||||
if (file.ffProbeData.streams[0].codec_name == 'hevc' && file._id.includes('264')) {
|
if (
|
||||||
|
file.ffProbeData.streams[0].codec_name == "hevc" &&
|
||||||
|
file._id.includes("264")
|
||||||
|
) {
|
||||||
file._id = file._id.replace("264", "265");
|
file._id = file._id.replace("264", "265");
|
||||||
file.file = file.file.replace("264", "265");
|
file.file = file.file.replace("264", "265");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
file.ffProbeData.streams[0].codec_name == "h264" &&
|
||||||
if (file.ffProbeData.streams[0].codec_name == 'h264' && file._id.includes('265')) {
|
file._id.includes("265")
|
||||||
|
) {
|
||||||
file._id = file._id.replace("265", "264");
|
file._id = file._id.replace("265", "264");
|
||||||
file.file = file.file.replace("265", "264");
|
file.file = file.file.replace("265", "264");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file.ffProbeData.streams[0].codec_name == 'h264' && file._id.includes('hevc')) {
|
if (
|
||||||
|
file.ffProbeData.streams[0].codec_name == "h264" &&
|
||||||
|
file._id.includes("hevc")
|
||||||
|
) {
|
||||||
file._id = file._id.replace("hevc", "264");
|
file._id = file._id.replace("hevc", "264");
|
||||||
file.file = file.file.replace("hevc", "264");
|
file.file = file.file.replace("hevc", "264");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileNameOld != file._id) {
|
if (fileNameOld != file._id) {
|
||||||
|
|
||||||
fsextra.moveSync(fileNameOld, file._id, {
|
fsextra.moveSync(fileNameOld, file._id, {
|
||||||
overwrite: true
|
overwrite: true,
|
||||||
})
|
});
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
file,
|
file,
|
||||||
removeFromDB: false,
|
removeFromDB: false,
|
||||||
updateDB: true,
|
updateDB: true,
|
||||||
}
|
};
|
||||||
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
|
} catch (err) {
|
||||||
} catch (err) { console.log(err) }
|
console.log(err);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_z1ab_TheRealShadoh_FFmpeg_Subs_H264_Fast",
|
id: "Tdarr_Plugin_z1ab_TheRealShadoh_FFmpeg_Subs_H264_Fast",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
|
|
@ -11,148 +7,136 @@ function details() {
|
||||||
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
|
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",
|
Version: "1.00",
|
||||||
Link: "https://github.com/TheRealShadoh/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_z1ab_TheRealShadoh_FFmpeg_Subs_H264_Fast.js",
|
Link:
|
||||||
Tags:'pre-processing,ffmpeg,h264',
|
"https://github.com/TheRealShadoh/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_z1ab_TheRealShadoh_FFmpeg_Subs_H264_Fast.js",
|
||||||
}
|
Tags: "pre-processing,ffmpeg,h264",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
|
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
processFile: false,
|
||||||
|
preset: "",
|
||||||
|
container: ".mp4",
|
||||||
|
handBrakeMode: false,
|
||||||
|
FFmpegMode: false,
|
||||||
|
reQueueAfter: false,
|
||||||
|
infoLog: "",
|
||||||
|
};
|
||||||
|
|
||||||
processFile : false,
|
if (file.fileMedium !== "video") {
|
||||||
preset : '',
|
console.log("File is not video");
|
||||||
container : '.mp4',
|
|
||||||
handBrakeMode : false,
|
|
||||||
FFmpegMode : false,
|
|
||||||
reQueueAfter : false,
|
|
||||||
infoLog : '',
|
|
||||||
|
|
||||||
}
|
response.infoLog += "☒File is not video \n";
|
||||||
|
|
||||||
if (file.fileMedium !== "video"){
|
|
||||||
|
|
||||||
|
|
||||||
console.log("File is not video")
|
|
||||||
|
|
||||||
response.infoLog += "☒File is not video \n"
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
var jsonString = JSON.stringify(file);
|
||||||
|
|
||||||
var jsonString = JSON.stringify(file)
|
var hasSubs = false;
|
||||||
|
|
||||||
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
var hasSubs = false
|
try {
|
||||||
|
|
||||||
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
let streamData = file.ffProbeData.streams[i];
|
let streamData = file.ffProbeData.streams[i];
|
||||||
if(streamData.codec_type.toLowerCase() == "subtitle" && streamData.codec_name != "mov_text"){
|
if (
|
||||||
hasSubs = true
|
streamData.codec_type.toLowerCase() == "subtitle" &&
|
||||||
|
streamData.codec_name != "mov_text"
|
||||||
|
) {
|
||||||
|
hasSubs = true;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (file.ffProbeData.streams[0].codec_name != "h264") {
|
||||||
if(file.ffProbeData.streams[0].codec_name != 'h264'){
|
response.infoLog += "☒File is not in h264! \n";
|
||||||
|
response.preset =
|
||||||
response.infoLog += "☒File is not in h264! \n"
|
", -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v libx264 -preset fast -c:a aac -c:s mov_text";
|
||||||
response.preset = ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v libx264 -preset fast -c:a aac -c:s mov_text'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
|
response.infoLog += "☑File is already in h264! \n";
|
||||||
|
}
|
||||||
|
|
||||||
}else{
|
///
|
||||||
response.infoLog += "☑File is already in h264! \n"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (
|
||||||
///
|
file.meta.Title != undefined &&
|
||||||
|
!jsonString.includes("aac") &&
|
||||||
if((file.meta.Title != undefined) && !jsonString.includes("aac") && hasSubs){
|
hasSubs
|
||||||
|
) {
|
||||||
response.infoLog += "☒File has title metadata and no aac and subs \n"
|
response.infoLog += "☒File has title metadata and no aac and subs \n";
|
||||||
response.preset = ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text'
|
response.preset =
|
||||||
|
", -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text";
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!jsonString.includes("aac") && hasSubs){
|
if (!jsonString.includes("aac") && hasSubs) {
|
||||||
|
response.infoLog += "☒File has no aac track and has subs \n";
|
||||||
response.infoLog += "☒File has no aac track and has subs \n"
|
response.preset =
|
||||||
response.preset = ', -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text'
|
", -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text";
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (file.meta.Title != undefined && hasSubs) {
|
||||||
if(file.meta.Title != undefined && hasSubs){
|
response.infoLog += "☒File has title and has subs \n";
|
||||||
|
response.preset =
|
||||||
response.infoLog += "☒File has title and has subs \n"
|
", -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text";
|
||||||
response.preset = ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
///
|
if (file.meta.Title != undefined) {
|
||||||
if(file.meta.Title != undefined ){
|
response.infoLog += "☒File has title metadata \n";
|
||||||
|
response.preset =
|
||||||
response.infoLog += "☒File has title metadata \n"
|
", -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text";
|
||||||
response.preset = ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
}else{
|
} else {
|
||||||
response.infoLog += "☑File has no title metadata \n"
|
response.infoLog += "☑File has no title metadata \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!jsonString.includes("aac")){
|
if (!jsonString.includes("aac")) {
|
||||||
|
response.infoLog += "☒File has no aac track \n";
|
||||||
response.infoLog += "☒File has no aac track \n"
|
response.preset =
|
||||||
response.preset = ', -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text'
|
", -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text";
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
|
response.infoLog += "☑File has aac track \n";
|
||||||
|
}
|
||||||
|
|
||||||
}else{
|
if (hasSubs) {
|
||||||
response.infoLog += "☑File has aac track \n"
|
response.infoLog += "☒File has incompatible subs \n";
|
||||||
}
|
response.preset =
|
||||||
|
", -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text";
|
||||||
if(hasSubs){
|
|
||||||
|
|
||||||
response.infoLog += "☒File has incompatible subs \n"
|
|
||||||
response.preset = ', -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
}else{
|
response.infoLog += "☑File has no/compatible subs \n";
|
||||||
response.infoLog += "☑File has no/compatible subs \n"
|
}
|
||||||
}
|
|
||||||
|
|
||||||
response.infoLog += "☑File meets conditions! \n"
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
response.infoLog += "☑File meets conditions! \n";
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_z2ab_TheRealShadoh_FFmpeg_Subs_H264_Slow",
|
id: "Tdarr_Plugin_z2ab_TheRealShadoh_FFmpeg_Subs_H264_Slow",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
|
|
@ -11,149 +7,136 @@ function details() {
|
||||||
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
|
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",
|
Version: "1.00",
|
||||||
Link: "https://github.com/TheRealShadoh/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_z2ab_TheRealShadoh_FFmpeg_Subs_H264_Slow.js",
|
Link:
|
||||||
Tags:'pre-processing,ffmpeg,h264',
|
"https://github.com/TheRealShadoh/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_z2ab_TheRealShadoh_FFmpeg_Subs_H264_Slow.js",
|
||||||
}
|
Tags: "pre-processing,ffmpeg,h264",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
|
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
processFile: false,
|
||||||
|
preset: "",
|
||||||
|
container: ".mp4",
|
||||||
|
handBrakeMode: false,
|
||||||
|
FFmpegMode: false,
|
||||||
|
reQueueAfter: false,
|
||||||
|
infoLog: "",
|
||||||
|
};
|
||||||
|
|
||||||
processFile : false,
|
if (file.fileMedium !== "video") {
|
||||||
preset : '',
|
console.log("File is not video");
|
||||||
container : '.mp4',
|
|
||||||
handBrakeMode : false,
|
|
||||||
FFmpegMode : false,
|
|
||||||
reQueueAfter : false,
|
|
||||||
infoLog : '',
|
|
||||||
|
|
||||||
}
|
response.infoLog += "☒File is not video \n";
|
||||||
|
|
||||||
if (file.fileMedium !== "video"){
|
|
||||||
|
|
||||||
|
|
||||||
console.log("File is not video")
|
|
||||||
|
|
||||||
response.infoLog += "☒File is not video \n"
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
var jsonString = JSON.stringify(file);
|
||||||
|
|
||||||
var jsonString = JSON.stringify(file)
|
var hasSubs = false;
|
||||||
|
|
||||||
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
var hasSubs = false
|
try {
|
||||||
|
|
||||||
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
let streamData = file.ffProbeData.streams[i];
|
let streamData = file.ffProbeData.streams[i];
|
||||||
if(streamData.codec_type.toLowerCase() == "subtitle" && streamData.codec_name != "mov_text"){
|
if (
|
||||||
hasSubs = true
|
streamData.codec_type.toLowerCase() == "subtitle" &&
|
||||||
|
streamData.codec_name != "mov_text"
|
||||||
|
) {
|
||||||
|
hasSubs = true;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (file.ffProbeData.streams[0].codec_name != "h264") {
|
||||||
if(file.ffProbeData.streams[0].codec_name != 'h264'){
|
response.infoLog += "☒File is not in h264! \n";
|
||||||
|
response.preset =
|
||||||
response.infoLog += "☒File is not in h264! \n"
|
", -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v libx264 -preset slow -c:a aac -c:s mov_text";
|
||||||
response.preset = ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v libx264 -preset slow -c:a aac -c:s mov_text'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
|
response.infoLog += "☑File is already in h264! \n";
|
||||||
|
}
|
||||||
|
|
||||||
}else{
|
///
|
||||||
response.infoLog += "☑File is already in h264! \n"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (
|
||||||
///
|
file.meta.Title != undefined &&
|
||||||
|
!jsonString.includes("aac") &&
|
||||||
if((file.meta.Title != undefined) && !jsonString.includes("aac") && hasSubs){
|
hasSubs
|
||||||
|
) {
|
||||||
response.infoLog += "☒File has title metadata and no aac and subs \n"
|
response.infoLog += "☒File has title metadata and no aac and subs \n";
|
||||||
response.preset = ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text'
|
response.preset =
|
||||||
|
", -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text";
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!jsonString.includes("aac") && hasSubs){
|
if (!jsonString.includes("aac") && hasSubs) {
|
||||||
|
response.infoLog += "☒File has no aac track and has subs \n";
|
||||||
response.infoLog += "☒File has no aac track and has subs \n"
|
response.preset =
|
||||||
response.preset = ', -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text'
|
", -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text";
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (file.meta.Title != undefined && hasSubs) {
|
||||||
if(file.meta.Title != undefined && hasSubs){
|
response.infoLog += "☒File has title and has subs \n";
|
||||||
|
response.preset =
|
||||||
response.infoLog += "☒File has title and has subs \n"
|
", -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text";
|
||||||
response.preset = ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
if (file.meta.Title != undefined) {
|
||||||
///
|
response.infoLog += "☒File has title metadata \n";
|
||||||
if(file.meta.Title != undefined ){
|
response.preset =
|
||||||
|
", -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text";
|
||||||
response.infoLog += "☒File has title metadata \n"
|
|
||||||
response.preset = ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
}else{
|
} else {
|
||||||
response.infoLog += "☑File has no title metadata \n"
|
response.infoLog += "☑File has no title metadata \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!jsonString.includes("aac")){
|
if (!jsonString.includes("aac")) {
|
||||||
|
response.infoLog += "☒File has no aac track \n";
|
||||||
response.infoLog += "☒File has no aac track \n"
|
response.preset =
|
||||||
response.preset = ', -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text'
|
", -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text";
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
|
response.infoLog += "☑File has aac track \n";
|
||||||
|
}
|
||||||
|
|
||||||
}else{
|
if (hasSubs) {
|
||||||
response.infoLog += "☑File has aac track \n"
|
response.infoLog += "☒File has incompatible subs \n";
|
||||||
}
|
response.preset =
|
||||||
|
", -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text";
|
||||||
if(hasSubs){
|
|
||||||
|
|
||||||
response.infoLog += "☒File has incompatible subs \n"
|
|
||||||
response.preset = ', -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
}else{
|
response.infoLog += "☑File has no/compatible subs \n";
|
||||||
response.infoLog += "☑File has no/compatible subs \n"
|
}
|
||||||
}
|
|
||||||
|
|
||||||
response.infoLog += "☑File meets conditions! \n"
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
response.infoLog += "☑File meets conditions! \n";
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,159 +1,143 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_z3ab_TheRealShadoh_FFmpeg_Subs_H264_VeryFast",
|
id: "Tdarr_Plugin_z3ab_TheRealShadoh_FFmpeg_Subs_H264_VeryFast",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
Name: "TheRealShadoh FFmpeg Subs VeryFast, video MP4, audio AAC, keep subs. ",
|
Name:
|
||||||
|
"TheRealShadoh FFmpeg Subs VeryFast, video MP4, audio AAC, keep subs. ",
|
||||||
Type: "Video",
|
Type: "Video",
|
||||||
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
|
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",
|
Version: "1.00",
|
||||||
Link: "https://github.com/TheRealShadoh/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_z3ab_TheRealShadoh_FFmpeg_Subs_H264_Veryfast.js",
|
Link:
|
||||||
Tags:'pre-processing,ffmpeg,h264',
|
"https://github.com/TheRealShadoh/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_z3ab_TheRealShadoh_FFmpeg_Subs_H264_Veryfast.js",
|
||||||
}
|
Tags: "pre-processing,ffmpeg,h264",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
|
|
||||||
|
|
||||||
//Must return this object
|
//Must return this object
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
processFile: false,
|
||||||
|
preset: "",
|
||||||
|
container: ".mp4",
|
||||||
|
handBrakeMode: false,
|
||||||
|
FFmpegMode: false,
|
||||||
|
reQueueAfter: false,
|
||||||
|
infoLog: "",
|
||||||
|
};
|
||||||
|
|
||||||
processFile : false,
|
if (file.fileMedium !== "video") {
|
||||||
preset : '',
|
console.log("File is not video");
|
||||||
container : '.mp4',
|
|
||||||
handBrakeMode : false,
|
|
||||||
FFmpegMode : false,
|
|
||||||
reQueueAfter : false,
|
|
||||||
infoLog : '',
|
|
||||||
|
|
||||||
}
|
response.infoLog += "☒File is not video \n";
|
||||||
|
|
||||||
if (file.fileMedium !== "video"){
|
|
||||||
|
|
||||||
|
|
||||||
console.log("File is not video")
|
|
||||||
|
|
||||||
response.infoLog += "☒File is not video \n"
|
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
var jsonString = JSON.stringify(file);
|
||||||
|
|
||||||
var jsonString = JSON.stringify(file)
|
var hasSubs = false;
|
||||||
|
|
||||||
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
var hasSubs = false
|
try {
|
||||||
|
|
||||||
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
let streamData = file.ffProbeData.streams[i];
|
let streamData = file.ffProbeData.streams[i];
|
||||||
if(streamData.codec_type.toLowerCase() == "subtitle" && streamData.codec_name != "mov_text"){
|
if (
|
||||||
hasSubs = true
|
streamData.codec_type.toLowerCase() == "subtitle" &&
|
||||||
|
streamData.codec_name != "mov_text"
|
||||||
|
) {
|
||||||
|
hasSubs = true;
|
||||||
}
|
}
|
||||||
} catch (err) { }
|
} catch (err) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (file.ffProbeData.streams[0].codec_name != "h264") {
|
||||||
if(file.ffProbeData.streams[0].codec_name != 'h264'){
|
response.infoLog += "☒File is not in h264! \n";
|
||||||
|
response.preset =
|
||||||
response.infoLog += "☒File is not in h264! \n"
|
", -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v libx264 -preset veryfast -c:a aac -c:s mov_text";
|
||||||
response.preset = ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v libx264 -preset veryfast -c:a aac -c:s mov_text'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
|
response.infoLog += "☑File is already in h264! \n";
|
||||||
|
}
|
||||||
|
|
||||||
}else{
|
///
|
||||||
response.infoLog += "☑File is already in h264! \n"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (
|
||||||
///
|
file.meta.Title != undefined &&
|
||||||
|
!jsonString.includes("aac") &&
|
||||||
if((file.meta.Title != undefined) && !jsonString.includes("aac") && hasSubs){
|
hasSubs
|
||||||
|
) {
|
||||||
response.infoLog += "☒File has title metadata and no aac and subs \n"
|
response.infoLog += "☒File has title metadata and no aac and subs \n";
|
||||||
response.preset = ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text'
|
response.preset =
|
||||||
|
", -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text";
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!jsonString.includes("aac") && hasSubs){
|
if (!jsonString.includes("aac") && hasSubs) {
|
||||||
|
response.infoLog += "☒File has no aac track and has subs \n";
|
||||||
response.infoLog += "☒File has no aac track and has subs \n"
|
response.preset =
|
||||||
response.preset = ', -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text'
|
", -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text";
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (file.meta.Title != undefined && hasSubs) {
|
||||||
if(file.meta.Title != undefined && hasSubs){
|
response.infoLog += "☒File has title and has subs \n";
|
||||||
|
response.preset =
|
||||||
response.infoLog += "☒File has title and has subs \n"
|
", -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text";
|
||||||
response.preset = ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
if (file.meta.Title != undefined) {
|
||||||
///
|
response.infoLog += "☒File has title metadata \n";
|
||||||
if(file.meta.Title != undefined ){
|
response.preset =
|
||||||
|
", -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text";
|
||||||
response.infoLog += "☒File has title metadata \n"
|
|
||||||
response.preset = ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
}else{
|
} else {
|
||||||
response.infoLog += "☑File has no title metadata \n"
|
response.infoLog += "☑File has no title metadata \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!jsonString.includes("aac")){
|
if (!jsonString.includes("aac")) {
|
||||||
|
response.infoLog += "☒File has no aac track \n";
|
||||||
response.infoLog += "☒File has no aac track \n"
|
response.preset =
|
||||||
response.preset = ', -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text'
|
", -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text";
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
|
response.infoLog += "☑File has aac track \n";
|
||||||
|
}
|
||||||
|
|
||||||
}else{
|
if (hasSubs) {
|
||||||
response.infoLog += "☑File has aac track \n"
|
response.infoLog += "☒File has incompatible subs \n";
|
||||||
}
|
response.preset =
|
||||||
|
", -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text";
|
||||||
if(hasSubs){
|
|
||||||
|
|
||||||
response.infoLog += "☒File has incompatible subs \n"
|
|
||||||
response.preset = ', -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text'
|
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
}else{
|
response.infoLog += "☑File has no/compatible subs \n";
|
||||||
response.infoLog += "☑File has no/compatible subs \n"
|
}
|
||||||
}
|
|
||||||
|
|
||||||
response.infoLog += "☑File meets conditions! \n"
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
response.infoLog += "☑File meets conditions! \n";
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
26
README.md
26
README.md
|
|
@ -14,9 +14,9 @@ https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Tdarr_Plugin_aaaa_Pre_P
|
||||||
https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Tdarr_Plugin_zzzz_Post_Proc_Example.js
|
https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Tdarr_Plugin_zzzz_Post_Proc_Example.js
|
||||||
|
|
||||||
2.Determine an id for your plugin. Every id must start with 'Tdarr_Plugin_xxxx' where xxxx is a random mini id containing the following:
|
2.Determine an id for your plugin. Every id must start with 'Tdarr_Plugin_xxxx' where xxxx is a random mini id containing the following:
|
||||||
Numeric digits (0-9)
|
Numeric digits (0-9)
|
||||||
Uppercase letters (A-Z)
|
Uppercase letters (A-Z)
|
||||||
Lowercase letters (a-z)
|
Lowercase letters (a-z)
|
||||||
|
|
||||||
|
|
||||||
The rest of the plugin id can be whatever you like. See the plugins folder for examples:
|
The rest of the plugin id can be whatever you like. See the plugins folder for examples:
|
||||||
|
|
@ -29,7 +29,7 @@ Your plugin id inside the file must be exactly the same as the plugin filename.
|
||||||
IMPORTANT: Think carefully about what you'd like your plugin to do. You cannot change the aim of a community plugin at a later date as others may be using the plugin. After the plugin has been submitted to community plugins, you can only fix bugs, clarify details and improve plugin performance.
|
IMPORTANT: Think carefully about what you'd like your plugin to do. You cannot change the aim of a community plugin at a later date as others may be using the plugin. After the plugin has been submitted to community plugins, you can only fix bugs, clarify details and improve plugin performance.
|
||||||
|
|
||||||
4.(If local plugin then you can skip this)
|
4.(If local plugin then you can skip this)
|
||||||
For the plugin link, I'll add this once you create a PR to community plugins.
|
For the plugin link, I'll add this once you create a PR to community plugins.
|
||||||
|
|
||||||
5. Configure 'function plugin(file)' with logic on whether to transcode the file or not. 'file' is an object with hundreds of file properties extracted using FFprobe and ExifTool. The following response object MUST be returned by your plugin. The values shown are the default values:
|
5. Configure 'function plugin(file)' with logic on whether to transcode the file or not. 'file' is an object with hundreds of file properties extracted using FFprobe and ExifTool. The following response object MUST be returned by your plugin. The values shown are the default values:
|
||||||
|
|
||||||
|
|
@ -56,20 +56,17 @@ For the plugin link, I'll add this once you create a PR to community plugins.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Please see the bottom of this README for the structure of an example file object. To see a specific file's details, search for the file in the search tab and click the 'i' info button.
|
||||||
|
|
||||||
Please see the bottom of this README for the structure of an example file object. To see a specific file's details, search for the file in the search tab and click the 'i' info button.
|
6.Once you have finished configuring your plugin,
|
||||||
|
|
||||||
|
For community plugins:
|
||||||
|
Create a pull request to have your plugin added to:
|
||||||
|
https://github.com/HaveAGitGat/Tdarr_Plugins/tree/master/Community
|
||||||
|
|
||||||
6.Once you have finished configuring your plugin,
|
For local plugins:
|
||||||
|
|
||||||
For community plugins:
|
|
||||||
Create a pull request to have your plugin added to:
|
|
||||||
https://github.com/HaveAGitGat/Tdarr_Plugins/tree/master/Community
|
|
||||||
|
|
||||||
For local plugins:
|
|
||||||
Add them to 'User\Documents\Tdarr\Plugins\Local'. In Tdarr, select 'Local' in the plugin section of the library you're in and add your local plugin id.
|
Add them to 'User\Documents\Tdarr\Plugins\Local'. In Tdarr, select 'Local' in the plugin section of the library you're in and add your local plugin id.
|
||||||
|
|
||||||
|
|
||||||
Example file object:
|
Example file object:
|
||||||
var file = {
|
var file = {
|
||||||
_id: 'C:/Users/H/Desktop/Test Input1/Sample.mp4',
|
_id: 'C:/Users/H/Desktop/Test Input1/Sample.mp4',
|
||||||
|
|
@ -312,6 +309,3 @@ Add them to 'User\Documents\Tdarr\Plugins\Local'. In Tdarr, select 'Local' in th
|
||||||
processingStatus: false,
|
processingStatus: false,
|
||||||
video_codec_name: 'h264',
|
video_codec_name: 'h264',
|
||||||
video_resolution: '720p' }
|
video_resolution: '720p' }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module.exports.details = function details() {
|
module.exports.details = function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_aaaa_Pre_Proc_Example",
|
id: "Tdarr_Plugin_aaaa_Pre_Proc_Example",
|
||||||
Stage: "Pre-processing", //Preprocessing or Post-processing. Determines when the plugin will be executed.
|
Stage: "Pre-processing", //Preprocessing or Post-processing. Determines when the plugin will be executed.
|
||||||
|
|
@ -12,12 +8,13 @@ module.exports.details = function details() {
|
||||||
Description: `This plugin removes metadata (if a title exists). The output container is the same as the original. \n\n`,
|
Description: `This plugin removes metadata (if a title exists). The output container is the same as the original. \n\n`,
|
||||||
Version: "1.00",
|
Version: "1.00",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugin_aaaa_Pre_Proc_Example",
|
Link: "https://github.com/HaveAGitGat/Tdarr_Plugin_aaaa_Pre_Proc_Example",
|
||||||
Tags:"ffmpeg,h265", //Provide tags to categorise your plugin in the plugin browser.Tag options: h265,hevc,h264,nvenc h265,nvenc h264,video only,audio only,subtitle only,handbrake,ffmpeg,radarr,sonarr,pre-processing,post-processing,configurable
|
Tags: "ffmpeg,h265", //Provide tags to categorise your plugin in the plugin browser.Tag options: h265,hevc,h264,nvenc h265,nvenc h264,video only,audio only,subtitle only,handbrake,ffmpeg,radarr,sonarr,pre-processing,post-processing,configurable
|
||||||
|
|
||||||
Inputs: [ //(Optional) Inputs you'd like the user to enter to allow your plugin to be easily configurable from the UI
|
Inputs: [
|
||||||
{
|
//(Optional) Inputs you'd like the user to enter to allow your plugin to be easily configurable from the UI
|
||||||
name: 'language',
|
{
|
||||||
tooltip: `Enter one language tag here for the language of the subtitles you'd like to keep.
|
name: "language",
|
||||||
|
tooltip: `Enter one language tag here for the language of the subtitles you'd like to keep.
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
eng
|
eng
|
||||||
|
|
@ -28,357 +25,345 @@ module.exports.details = function details() {
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
|
|
||||||
de` //Each line following `Example:` will be clearly formatted. \\n used for line breaks
|
de`, //Each line following `Example:` will be clearly formatted. \\n used for line breaks
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'channels',
|
name: "channels",
|
||||||
tooltip: `Desired audio channel number.
|
tooltip: `Desired audio channel number.
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
2`
|
2`,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.plugin = function plugin(file, librarySettings, inputs) {
|
module.exports.plugin = function plugin(file, librarySettings, inputs) {
|
||||||
|
|
||||||
|
|
||||||
//Must return this object at some point in the function else plugin will fail.
|
//Must return this object at some point in the function else plugin will fail.
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
|
|
||||||
processFile: false, //If set to false, the file will be skipped. Set to true to have the file transcoded.
|
processFile: false, //If set to false, the file will be skipped. Set to true to have the file transcoded.
|
||||||
preset: '', //HandBrake/FFmpeg CLI arguments you'd like to use.
|
preset: "", //HandBrake/FFmpeg CLI arguments you'd like to use.
|
||||||
//For FFmpeg, the input arguments come first followed by a comma, followed by the output argument.
|
//For FFmpeg, the input arguments come first followed by a comma, followed by the output argument.
|
||||||
// Examples
|
// Examples
|
||||||
//HandBrake
|
//HandBrake
|
||||||
// '-Z "Very Fast 1080p30"'
|
// '-Z "Very Fast 1080p30"'
|
||||||
//FFmpeg
|
//FFmpeg
|
||||||
// '-sn,-map_metadata -1 -c:v copy -c:a copy'
|
// '-sn,-map_metadata -1 -c:v copy -c:a copy'
|
||||||
container: '.mp4', // The container of the transcoded output file.
|
container: ".mp4", // The container of the transcoded output file.
|
||||||
handBrakeMode: false, //Set whether to use HandBrake or FFmpeg for transcoding
|
handBrakeMode: false, //Set whether to use HandBrake or FFmpeg for transcoding
|
||||||
FFmpegMode: false,
|
FFmpegMode: false,
|
||||||
reQueueAfter: true, //Leave as true. File will be re-qeued afterwards and pass through the plugin filter again to make sure it meets conditions.
|
reQueueAfter: true, //Leave as true. File will be re-qeued afterwards and pass through the plugin filter again to make sure it meets conditions.
|
||||||
infoLog: '', //This will be shown when the user clicks the 'i' (info) button on a file in the output queue if
|
infoLog: "", //This will be shown when the user clicks the 'i' (info) button on a file in the output queue if
|
||||||
//it has been skipped.
|
//it has been skipped.
|
||||||
// Give reasons why it has been skipped ('File has no title metadata, File meets conditions!')
|
// Give reasons why it has been skipped ('File has no title metadata, File meets conditions!')
|
||||||
|
|
||||||
//Optional (include together)
|
//Optional (include together)
|
||||||
file,
|
file,
|
||||||
removeFromDB: false, //Tell Tdarr to remove file from database if true
|
removeFromDB: false, //Tell Tdarr to remove file from database if true
|
||||||
updateDB: false, //Change file object above and update database if true
|
updateDB: false, //Change file object above and update database if true
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
console.log(inputs.language) //eng if user entered 'eng' in input box in Tdarr plugin UI
|
|
||||||
console.log(inputs.channels) //2 if user entered '2' in input box in Tdarr plugin UI
|
|
||||||
|
|
||||||
|
|
||||||
|
console.log(inputs.language); //eng if user entered 'eng' in input box in Tdarr plugin UI
|
||||||
|
console.log(inputs.channels); //2 if user entered '2' in input box in Tdarr plugin UI
|
||||||
|
|
||||||
//Here we specify that we want the output file container to be the same as the current container.
|
//Here we specify that we want the output file container to be the same as the current container.
|
||||||
response.container = '.' + file.container
|
response.container = "." + file.container;
|
||||||
|
|
||||||
//We will use FFmpeg for this procedure.
|
//We will use FFmpeg for this procedure.
|
||||||
response.FFmpegMode = true
|
response.FFmpegMode = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Check if file has title metadata
|
//Check if file has title metadata
|
||||||
if (file.meta.Title != undefined) {
|
if (file.meta.Title != undefined) {
|
||||||
//if so, remove it
|
//if so, remove it
|
||||||
|
|
||||||
response.infoLog += " File has title metadata"
|
response.infoLog += " File has title metadata";
|
||||||
response.preset = ',-map_metadata -1 -c:v copy -c:a copy'
|
response.preset = ",-map_metadata -1 -c:v copy -c:a copy";
|
||||||
response.processFile = true
|
response.processFile = true;
|
||||||
return response
|
return response;
|
||||||
} else {
|
} else {
|
||||||
response.infoLog += " File has no title metadata"
|
response.infoLog += " File has no title metadata";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
response.infoLog += " File meets conditions!";
|
||||||
|
return response;
|
||||||
|
};
|
||||||
|
|
||||||
response.infoLog += " File meets conditions!"
|
module.exports.onTranscodeSuccess = function onTranscodeSuccess(
|
||||||
return response
|
file,
|
||||||
}
|
librarySettings,
|
||||||
|
inputs
|
||||||
|
) {
|
||||||
module.exports.onTranscodeSuccess = function onTranscodeSuccess(file, librarySettings, inputs) {
|
console.log(
|
||||||
|
"Transcode success! Now do some stuff with the newly scanned file."
|
||||||
console.log('Transcode success! Now do some stuff with the newly scanned file.')
|
);
|
||||||
|
|
||||||
|
|
||||||
//Optional response if you need to modify database
|
//Optional response if you need to modify database
|
||||||
var response = {
|
var response = {
|
||||||
file,
|
file,
|
||||||
removeFromDB: false,
|
removeFromDB: false,
|
||||||
updateDB: false,
|
updateDB: false,
|
||||||
}
|
};
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
}
|
};
|
||||||
|
|
||||||
module.exports.onTranscodeError = function onTranscodeError(file, librarySettings, inputs) {
|
|
||||||
|
|
||||||
console.log('Transcode fail! Now do some stuff with the original file.')
|
|
||||||
|
|
||||||
|
module.exports.onTranscodeError = function onTranscodeError(
|
||||||
|
file,
|
||||||
|
librarySettings,
|
||||||
|
inputs
|
||||||
|
) {
|
||||||
|
console.log("Transcode fail! Now do some stuff with the original file.");
|
||||||
|
|
||||||
//Optional response if you need to modify database
|
//Optional response if you need to modify database
|
||||||
var response = {
|
var response = {
|
||||||
file,
|
file,
|
||||||
removeFromDB: false,
|
removeFromDB: false,
|
||||||
updateDB: false,
|
updateDB: false,
|
||||||
}
|
};
|
||||||
|
|
||||||
return response
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return response;
|
||||||
|
};
|
||||||
|
|
||||||
//Example file object:
|
//Example file object:
|
||||||
// {
|
// {
|
||||||
// _id: 'C:/Users/H/Desktop/Test Input1/Sample.mp4',
|
// _id: 'C:/Users/H/Desktop/Test Input1/Sample.mp4',
|
||||||
// DB: 'ZRPDmnmpyuAEQi7nG',
|
// DB: 'ZRPDmnmpyuAEQi7nG',
|
||||||
// HealthCheck: 'Not attempted',
|
// HealthCheck: 'Not attempted',
|
||||||
// TranscodeDecisionMaker: 'Not attempted',
|
// TranscodeDecisionMaker: 'Not attempted',
|
||||||
// bit_rate: 1690430.4,
|
// bit_rate: 1690430.4,
|
||||||
// container: 'mp4',
|
// container: 'mp4',
|
||||||
// createdAt: 2019-09-26T06:46:31.929Z,
|
// createdAt: 2019-09-26T06:46:31.929Z,
|
||||||
// ffProbeData:
|
// ffProbeData:
|
||||||
// { streams:
|
// { streams:
|
||||||
// [ { index: 0,
|
// [ { index: 0,
|
||||||
// codec_name: 'h264',
|
// codec_name: 'h264',
|
||||||
// codec_long_name: 'H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10',
|
// codec_long_name: 'H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10',
|
||||||
// profile: 'Main',
|
// profile: 'Main',
|
||||||
// codec_type: 'video',
|
// codec_type: 'video',
|
||||||
// codec_time_base: '1/50',
|
// codec_time_base: '1/50',
|
||||||
// codec_tag_string: 'avc1',
|
// codec_tag_string: 'avc1',
|
||||||
// codec_tag: '0x31637661',
|
// codec_tag: '0x31637661',
|
||||||
// width: 1280,
|
// width: 1280,
|
||||||
// height: 720,
|
// height: 720,
|
||||||
// coded_width: 1280,
|
// coded_width: 1280,
|
||||||
// coded_height: 720,
|
// coded_height: 720,
|
||||||
// has_b_frames: 0,
|
// has_b_frames: 0,
|
||||||
// sample_aspect_ratio: '1:1',
|
// sample_aspect_ratio: '1:1',
|
||||||
// display_aspect_ratio: '16:9',
|
// display_aspect_ratio: '16:9',
|
||||||
// pix_fmt: 'yuv420p',
|
// pix_fmt: 'yuv420p',
|
||||||
// level: 31,
|
// level: 31,
|
||||||
// chroma_location: 'left',
|
// chroma_location: 'left',
|
||||||
// refs: 1,
|
// refs: 1,
|
||||||
// is_avc: 'true',
|
// is_avc: 'true',
|
||||||
// nal_length_size: '4',
|
// nal_length_size: '4',
|
||||||
// r_frame_rate: '25/1',
|
// r_frame_rate: '25/1',
|
||||||
// avg_frame_rate: '25/1',
|
// avg_frame_rate: '25/1',
|
||||||
// time_base: '1/12800',
|
// time_base: '1/12800',
|
||||||
// start_pts: 0,
|
// start_pts: 0,
|
||||||
// start_time: '0.000000',
|
// start_time: '0.000000',
|
||||||
// duration_ts: 67584,
|
// duration_ts: 67584,
|
||||||
// duration: '5.280000',
|
// duration: '5.280000',
|
||||||
// bit_rate: '1205959',
|
// bit_rate: '1205959',
|
||||||
// bits_per_raw_sample: '8',
|
// bits_per_raw_sample: '8',
|
||||||
// nb_frames: '132',
|
// nb_frames: '132',
|
||||||
// disposition:
|
// disposition:
|
||||||
// { default: 1,
|
// { default: 1,
|
||||||
// dub: 0,
|
// dub: 0,
|
||||||
// original: 0,
|
// original: 0,
|
||||||
// comment: 0,
|
// comment: 0,
|
||||||
// lyrics: 0,
|
// lyrics: 0,
|
||||||
// karaoke: 0,
|
// karaoke: 0,
|
||||||
// forced: 0,
|
// forced: 0,
|
||||||
// hearing_impaired: 0,
|
// hearing_impaired: 0,
|
||||||
// visual_impaired: 0,
|
// visual_impaired: 0,
|
||||||
// clean_effects: 0,
|
// clean_effects: 0,
|
||||||
// attached_pic: 0,
|
// attached_pic: 0,
|
||||||
// timed_thumbnails: 0 },
|
// timed_thumbnails: 0 },
|
||||||
// tags:
|
// tags:
|
||||||
// { creation_time: '1970-01-01T00:00:00.000000Z',
|
// { creation_time: '1970-01-01T00:00:00.000000Z',
|
||||||
// language: 'und',
|
// language: 'und',
|
||||||
// handler_name: 'VideoHandler' } },
|
// handler_name: 'VideoHandler' } },
|
||||||
// { index: 1,
|
// { index: 1,
|
||||||
// codec_name: 'aac',
|
// codec_name: 'aac',
|
||||||
// codec_long_name: 'AAC (Advanced Audio Coding)',
|
// codec_long_name: 'AAC (Advanced Audio Coding)',
|
||||||
// profile: 'LC',
|
// profile: 'LC',
|
||||||
// codec_type: 'audio',
|
// codec_type: 'audio',
|
||||||
// codec_time_base: '1/48000',
|
// codec_time_base: '1/48000',
|
||||||
// codec_tag_string: 'mp4a',
|
// codec_tag_string: 'mp4a',
|
||||||
// codec_tag: '0x6134706d',
|
// codec_tag: '0x6134706d',
|
||||||
// sample_fmt: 'fltp',
|
// sample_fmt: 'fltp',
|
||||||
// sample_rate: '48000',
|
// sample_rate: '48000',
|
||||||
// channels: 6,
|
// channels: 6,
|
||||||
// channel_layout: '5.1',
|
// channel_layout: '5.1',
|
||||||
// bits_per_sample: 0,
|
// bits_per_sample: 0,
|
||||||
// r_frame_rate: '0/0',
|
// r_frame_rate: '0/0',
|
||||||
// avg_frame_rate: '0/0',
|
// avg_frame_rate: '0/0',
|
||||||
// time_base: '1/48000',
|
// time_base: '1/48000',
|
||||||
// start_pts: 0,
|
// start_pts: 0,
|
||||||
// start_time: '0.000000',
|
// start_time: '0.000000',
|
||||||
// duration_ts: 254976,
|
// duration_ts: 254976,
|
||||||
// duration: '5.312000',
|
// duration: '5.312000',
|
||||||
// bit_rate: '384828',
|
// bit_rate: '384828',
|
||||||
// max_bit_rate: '400392',
|
// max_bit_rate: '400392',
|
||||||
// nb_frames: '249',
|
// nb_frames: '249',
|
||||||
// disposition:
|
// disposition:
|
||||||
// { default: 1,
|
// { default: 1,
|
||||||
// dub: 0,
|
// dub: 0,
|
||||||
// original: 0,
|
// original: 0,
|
||||||
// comment: 0,
|
// comment: 0,
|
||||||
// lyrics: 0,
|
// lyrics: 0,
|
||||||
// karaoke: 0,
|
// karaoke: 0,
|
||||||
// forced: 0,
|
// forced: 0,
|
||||||
// hearing_impaired: 0,
|
// hearing_impaired: 0,
|
||||||
// visual_impaired: 0,
|
// visual_impaired: 0,
|
||||||
// clean_effects: 0,
|
// clean_effects: 0,
|
||||||
// attached_pic: 0,
|
// attached_pic: 0,
|
||||||
// timed_thumbnails: 0 },
|
// timed_thumbnails: 0 },
|
||||||
// tags:
|
// tags:
|
||||||
// { creation_time: '1970-01-01T00:00:00.000000Z',
|
// { creation_time: '1970-01-01T00:00:00.000000Z',
|
||||||
// language: 'und',
|
// language: 'und',
|
||||||
// handler_name: 'SoundHandler' } } ] },
|
// handler_name: 'SoundHandler' } } ] },
|
||||||
// ffProbeRead: 'success',
|
// ffProbeRead: 'success',
|
||||||
// file: 'C:/Users/H/Desktop/Test Input1/Sample.mp4',
|
// file: 'C:/Users/H/Desktop/Test Input1/Sample.mp4',
|
||||||
// fileMedium: 'video',
|
// fileMedium: 'video',
|
||||||
// file_size: 1.056519,
|
// file_size: 1.056519,
|
||||||
// meta:
|
// meta:
|
||||||
// { SourceFile: 'C:/Users/H/Desktop/Test Input1/Sample.mp4',
|
// { SourceFile: 'C:/Users/H/Desktop/Test Input1/Sample.mp4',
|
||||||
// errors: [],
|
// errors: [],
|
||||||
// Duration: 5.312,
|
// Duration: 5.312,
|
||||||
// PreviewDuration: 0,
|
// PreviewDuration: 0,
|
||||||
// SelectionDuration: 0,
|
// SelectionDuration: 0,
|
||||||
// TrackDuration: 5.28,
|
// TrackDuration: 5.28,
|
||||||
// MediaDuration: 5.312,
|
// MediaDuration: 5.312,
|
||||||
// ExifToolVersion: 11.65,
|
// ExifToolVersion: 11.65,
|
||||||
// FileName: 'Sample.mp4',
|
// FileName: 'Sample.mp4',
|
||||||
// Directory: 'C:/Users/H/Desktop/Test Input1',
|
// Directory: 'C:/Users/H/Desktop/Test Input1',
|
||||||
// FileSize: '1032 kB',
|
// FileSize: '1032 kB',
|
||||||
// FileModifyDate:
|
// FileModifyDate:
|
||||||
// { year: 2019,
|
// { year: 2019,
|
||||||
// month: 9,
|
// month: 9,
|
||||||
// day: 24,
|
// day: 24,
|
||||||
// hour: 7,
|
// hour: 7,
|
||||||
// minute: 24,
|
// minute: 24,
|
||||||
// second: 22,
|
// second: 22,
|
||||||
// millisecond: 0,
|
// millisecond: 0,
|
||||||
// tzoffsetMinutes: 60,
|
// tzoffsetMinutes: 60,
|
||||||
// rawValue: '2019:09:24 07:24:22+01:00' },
|
// rawValue: '2019:09:24 07:24:22+01:00' },
|
||||||
// FileAccessDate:
|
// FileAccessDate:
|
||||||
// { year: 2019,
|
// { year: 2019,
|
||||||
// month: 9,
|
// month: 9,
|
||||||
// day: 26,
|
// day: 26,
|
||||||
// hour: 7,
|
// hour: 7,
|
||||||
// minute: 44,
|
// minute: 44,
|
||||||
// second: 30,
|
// second: 30,
|
||||||
// millisecond: 0,
|
// millisecond: 0,
|
||||||
// tzoffsetMinutes: 60,
|
// tzoffsetMinutes: 60,
|
||||||
// rawValue: '2019:09:26 07:44:30+01:00' },
|
// rawValue: '2019:09:26 07:44:30+01:00' },
|
||||||
// FileCreateDate:
|
// FileCreateDate:
|
||||||
// { year: 2019,
|
// { year: 2019,
|
||||||
// month: 9,
|
// month: 9,
|
||||||
// day: 26,
|
// day: 26,
|
||||||
// hour: 7,
|
// hour: 7,
|
||||||
// minute: 44,
|
// minute: 44,
|
||||||
// second: 30,
|
// second: 30,
|
||||||
// millisecond: 0,
|
// millisecond: 0,
|
||||||
// tzoffsetMinutes: 60,
|
// tzoffsetMinutes: 60,
|
||||||
// rawValue: '2019:09:26 07:44:30+01:00' },
|
// rawValue: '2019:09:26 07:44:30+01:00' },
|
||||||
// FilePermissions: 'rw-rw-rw-',
|
// FilePermissions: 'rw-rw-rw-',
|
||||||
// FileType: 'MP4',
|
// FileType: 'MP4',
|
||||||
// FileTypeExtension: 'mp4',
|
// FileTypeExtension: 'mp4',
|
||||||
// MIMEType: 'video/mp4',
|
// MIMEType: 'video/mp4',
|
||||||
// MajorBrand: 'MP4 Base Media v1 [IS0 14496-12:2003]',
|
// MajorBrand: 'MP4 Base Media v1 [IS0 14496-12:2003]',
|
||||||
// MinorVersion: '0.2.0',
|
// MinorVersion: '0.2.0',
|
||||||
// CompatibleBrands: [ 'isom', 'iso2', 'avc1', 'mp41' ],
|
// CompatibleBrands: [ 'isom', 'iso2', 'avc1', 'mp41' ],
|
||||||
// MovieDataSize: 0,
|
// MovieDataSize: 0,
|
||||||
// MovieDataOffset: 1051515,
|
// MovieDataOffset: 1051515,
|
||||||
// MovieHeaderVersion: 0,
|
// MovieHeaderVersion: 0,
|
||||||
// CreateDate:
|
// CreateDate:
|
||||||
// { year: 1970,
|
// { year: 1970,
|
||||||
// month: 1,
|
// month: 1,
|
||||||
// day: 8,
|
// day: 8,
|
||||||
// hour: 0,
|
// hour: 0,
|
||||||
// minute: 0,
|
// minute: 0,
|
||||||
// second: 0,
|
// second: 0,
|
||||||
// millisecond: 0,
|
// millisecond: 0,
|
||||||
// rawValue: '1970:01:08 00:00:00' },
|
// rawValue: '1970:01:08 00:00:00' },
|
||||||
// ModifyDate:
|
// ModifyDate:
|
||||||
// { year: 2014,
|
// { year: 2014,
|
||||||
// month: 7,
|
// month: 7,
|
||||||
// day: 19,
|
// day: 19,
|
||||||
// hour: 17,
|
// hour: 17,
|
||||||
// minute: 15,
|
// minute: 15,
|
||||||
// second: 29,
|
// second: 29,
|
||||||
// millisecond: 0,
|
// millisecond: 0,
|
||||||
// rawValue: '2014:07:19 17:15:29' },
|
// rawValue: '2014:07:19 17:15:29' },
|
||||||
// TimeScale: 1000,
|
// TimeScale: 1000,
|
||||||
// PreferredRate: 1,
|
// PreferredRate: 1,
|
||||||
// PreferredVolume: '100.00%',
|
// PreferredVolume: '100.00%',
|
||||||
// PreviewTime: '0 s',
|
// PreviewTime: '0 s',
|
||||||
// PosterTime: '0 s',
|
// PosterTime: '0 s',
|
||||||
// SelectionTime: '0 s',
|
// SelectionTime: '0 s',
|
||||||
// CurrentTime: '0 s',
|
// CurrentTime: '0 s',
|
||||||
// NextTrackID: 3,
|
// NextTrackID: 3,
|
||||||
// TrackHeaderVersion: 0,
|
// TrackHeaderVersion: 0,
|
||||||
// TrackCreateDate: '0000:00:00 00:00:00',
|
// TrackCreateDate: '0000:00:00 00:00:00',
|
||||||
// TrackModifyDate: '0000:00:00 00:00:00',
|
// TrackModifyDate: '0000:00:00 00:00:00',
|
||||||
// TrackID: 1,
|
// TrackID: 1,
|
||||||
// TrackLayer: 0,
|
// TrackLayer: 0,
|
||||||
// TrackVolume: '0.00%',
|
// TrackVolume: '0.00%',
|
||||||
// ImageWidth: 1280,
|
// ImageWidth: 1280,
|
||||||
// ImageHeight: 720,
|
// ImageHeight: 720,
|
||||||
// GraphicsMode: 'srcCopy',
|
// GraphicsMode: 'srcCopy',
|
||||||
// OpColor: '0 0 0',
|
// OpColor: '0 0 0',
|
||||||
// CompressorID: 'avc1',
|
// CompressorID: 'avc1',
|
||||||
// SourceImageWidth: 1280,
|
// SourceImageWidth: 1280,
|
||||||
// SourceImageHeight: 720,
|
// SourceImageHeight: 720,
|
||||||
// XResolution: 72,
|
// XResolution: 72,
|
||||||
// YResolution: 72,
|
// YResolution: 72,
|
||||||
// BitDepth: 24,
|
// BitDepth: 24,
|
||||||
// VideoFrameRate: 25,
|
// VideoFrameRate: 25,
|
||||||
// MatrixStructure: '1 0 0 0 1 0 0 0 1',
|
// MatrixStructure: '1 0 0 0 1 0 0 0 1',
|
||||||
// MediaHeaderVersion: 0,
|
// MediaHeaderVersion: 0,
|
||||||
// MediaCreateDate: '0000:00:00 00:00:00',
|
// MediaCreateDate: '0000:00:00 00:00:00',
|
||||||
// MediaModifyDate: '0000:00:00 00:00:00',
|
// MediaModifyDate: '0000:00:00 00:00:00',
|
||||||
// MediaTimeScale: 48000,
|
// MediaTimeScale: 48000,
|
||||||
// MediaLanguageCode: 'und',
|
// MediaLanguageCode: 'und',
|
||||||
// HandlerDescription: 'SoundHandler',
|
// HandlerDescription: 'SoundHandler',
|
||||||
// Balance: 0,
|
// Balance: 0,
|
||||||
// AudioFormat: 'mp4a',
|
// AudioFormat: 'mp4a',
|
||||||
// AudioChannels: 2,
|
// AudioChannels: 2,
|
||||||
// AudioBitsPerSample: 16,
|
// AudioBitsPerSample: 16,
|
||||||
// AudioSampleRate: 48000,
|
// AudioSampleRate: 48000,
|
||||||
// HandlerType: 'Metadata',
|
// HandlerType: 'Metadata',
|
||||||
// HandlerVendorID: 'Apple',
|
// HandlerVendorID: 'Apple',
|
||||||
// Encoder: 'Lavf53.24.2',
|
// Encoder: 'Lavf53.24.2',
|
||||||
// Title: 'Sample title test',
|
// Title: 'Sample title test',
|
||||||
// Composer: 'th',
|
// Composer: 'th',
|
||||||
// BeatsPerMinute: '',
|
// BeatsPerMinute: '',
|
||||||
// ContentCreateDate: 2018,
|
// ContentCreateDate: 2018,
|
||||||
// Genre: 'this',
|
// Genre: 'this',
|
||||||
// Artist: 'hhj',
|
// Artist: 'hhj',
|
||||||
// Comment: 'hhk',
|
// Comment: 'hhk',
|
||||||
// Subtitle: 'jj',
|
// Subtitle: 'jj',
|
||||||
// Mood: 'lik',
|
// Mood: 'lik',
|
||||||
// ContentDistributor: 'cont',
|
// ContentDistributor: 'cont',
|
||||||
// Conductor: 'jo',
|
// Conductor: 'jo',
|
||||||
// Writer: 'writ',
|
// Writer: 'writ',
|
||||||
// InitialKey: 'ho',
|
// InitialKey: 'ho',
|
||||||
// Producer: 'prod',
|
// Producer: 'prod',
|
||||||
// ParentalRating: 'par',
|
// ParentalRating: 'par',
|
||||||
// Director: 'dir',
|
// Director: 'dir',
|
||||||
// Period: 'pol',
|
// Period: 'pol',
|
||||||
// Publisher: 'pub',
|
// Publisher: 'pub',
|
||||||
// PromotionURL: 'prom',
|
// PromotionURL: 'prom',
|
||||||
// AuthorURL: 'auth',
|
// AuthorURL: 'auth',
|
||||||
// EncodedBy: 'enc',
|
// EncodedBy: 'enc',
|
||||||
// Category: 'h',
|
// Category: 'h',
|
||||||
// ImageSize: '1280x720',
|
// ImageSize: '1280x720',
|
||||||
// Megapixels: 0.922,
|
// Megapixels: 0.922,
|
||||||
// AvgBitrate: '1.58 Mbps',
|
// AvgBitrate: '1.58 Mbps',
|
||||||
// Rotation: 0 },
|
// Rotation: 0 },
|
||||||
// processingStatus: false,
|
// processingStatus: false,
|
||||||
// video_codec_name: 'h264',
|
// video_codec_name: 'h264',
|
||||||
// video_resolution: '720p' }
|
// video_resolution: '720p' }
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module.exports.details = function details() {
|
module.exports.details = function details() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_zzzz_Post_Proc_Example",
|
id: "Tdarr_Plugin_zzzz_Post_Proc_Example",
|
||||||
Stage: "Post-processing", //Preprocessing or Post-processing. Determines when the plugin will be executed. This plugin does some stuff after all plugins have been executed
|
Stage: "Post-processing", //Preprocessing or Post-processing. Determines when the plugin will be executed. This plugin does some stuff after all plugins have been executed
|
||||||
|
|
@ -12,12 +8,13 @@ module.exports.details = function details() {
|
||||||
Description: `This plugin does some stuff after all plugins have been executed. \n\n`,
|
Description: `This plugin does some stuff after all plugins have been executed. \n\n`,
|
||||||
Version: "1.00",
|
Version: "1.00",
|
||||||
Link: "https://github.com/HaveAGitGat/Tdarr_Plugin_aaaa_Post_Proc_Example",
|
Link: "https://github.com/HaveAGitGat/Tdarr_Plugin_aaaa_Post_Proc_Example",
|
||||||
Tags:"ffmpeg,h265", //Provide tags to categorise your plugin in the plugin browser.Tag options: h265,hevc,h264,nvenc h265,nvenc h264,video only,audio only,subtitle only,handbrake,ffmpeg,radarr,sonarr,pre-processing,post-processing,configurable
|
Tags: "ffmpeg,h265", //Provide tags to categorise your plugin in the plugin browser.Tag options: h265,hevc,h264,nvenc h265,nvenc h264,video only,audio only,subtitle only,handbrake,ffmpeg,radarr,sonarr,pre-processing,post-processing,configurable
|
||||||
|
|
||||||
Inputs: [ //(Optional) Inputs you'd like the user to enter to allow your plugin to be easily configurable from the UI
|
Inputs: [
|
||||||
{
|
//(Optional) Inputs you'd like the user to enter to allow your plugin to be easily configurable from the UI
|
||||||
name: 'language',
|
{
|
||||||
tooltip: `Enter one language tag here for the language of the subtitles you'd like to keep.
|
name: "language",
|
||||||
|
tooltip: `Enter one language tag here for the language of the subtitles you'd like to keep.
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
eng
|
eng
|
||||||
|
|
@ -26,277 +23,273 @@ module.exports.details = function details() {
|
||||||
fr
|
fr
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
de` //Each line following `Example:` will be clearly formatted. \\n used for line breaks
|
de`, //Each line following `Example:` will be clearly formatted. \\n used for line breaks
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'channels',
|
name: "channels",
|
||||||
tooltip: `Desired audio channel number.
|
tooltip: `Desired audio channel number.
|
||||||
|
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
2`
|
2`,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.plugin = function plugin(file, librarySettings, inputs) {
|
module.exports.plugin = function plugin(file, librarySettings, inputs) {
|
||||||
|
console.log(
|
||||||
console.log('Transcode success! Now do some stuff with the newly scanned file.')
|
"Transcode success! Now do some stuff with the newly scanned file."
|
||||||
|
);
|
||||||
|
|
||||||
//Optional response if you need to modify database
|
//Optional response if you need to modify database
|
||||||
var response = {
|
var response = {
|
||||||
file,
|
file,
|
||||||
removeFromDB: false,
|
removeFromDB: false,
|
||||||
updateDB: false,
|
updateDB: false,
|
||||||
}
|
};
|
||||||
|
|
||||||
return response
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return response;
|
||||||
|
};
|
||||||
|
|
||||||
//Example file object:
|
//Example file object:
|
||||||
// {
|
// {
|
||||||
// _id: 'C:/Users/H/Desktop/Test Input1/Sample.mp4',
|
// _id: 'C:/Users/H/Desktop/Test Input1/Sample.mp4',
|
||||||
// DB: 'ZRPDmnmpyuAEQi7nG',
|
// DB: 'ZRPDmnmpyuAEQi7nG',
|
||||||
// HealthCheck: 'Not attempted',
|
// HealthCheck: 'Not attempted',
|
||||||
// TranscodeDecisionMaker: 'Not attempted',
|
// TranscodeDecisionMaker: 'Not attempted',
|
||||||
// bit_rate: 1690430.4,
|
// bit_rate: 1690430.4,
|
||||||
// container: 'mp4',
|
// container: 'mp4',
|
||||||
// createdAt: 2019-09-26T06:46:31.929Z,
|
// createdAt: 2019-09-26T06:46:31.929Z,
|
||||||
// ffProbeData:
|
// ffProbeData:
|
||||||
// { streams:
|
// { streams:
|
||||||
// [ { index: 0,
|
// [ { index: 0,
|
||||||
// codec_name: 'h264',
|
// codec_name: 'h264',
|
||||||
// codec_long_name: 'H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10',
|
// codec_long_name: 'H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10',
|
||||||
// profile: 'Main',
|
// profile: 'Main',
|
||||||
// codec_type: 'video',
|
// codec_type: 'video',
|
||||||
// codec_time_base: '1/50',
|
// codec_time_base: '1/50',
|
||||||
// codec_tag_string: 'avc1',
|
// codec_tag_string: 'avc1',
|
||||||
// codec_tag: '0x31637661',
|
// codec_tag: '0x31637661',
|
||||||
// width: 1280,
|
// width: 1280,
|
||||||
// height: 720,
|
// height: 720,
|
||||||
// coded_width: 1280,
|
// coded_width: 1280,
|
||||||
// coded_height: 720,
|
// coded_height: 720,
|
||||||
// has_b_frames: 0,
|
// has_b_frames: 0,
|
||||||
// sample_aspect_ratio: '1:1',
|
// sample_aspect_ratio: '1:1',
|
||||||
// display_aspect_ratio: '16:9',
|
// display_aspect_ratio: '16:9',
|
||||||
// pix_fmt: 'yuv420p',
|
// pix_fmt: 'yuv420p',
|
||||||
// level: 31,
|
// level: 31,
|
||||||
// chroma_location: 'left',
|
// chroma_location: 'left',
|
||||||
// refs: 1,
|
// refs: 1,
|
||||||
// is_avc: 'true',
|
// is_avc: 'true',
|
||||||
// nal_length_size: '4',
|
// nal_length_size: '4',
|
||||||
// r_frame_rate: '25/1',
|
// r_frame_rate: '25/1',
|
||||||
// avg_frame_rate: '25/1',
|
// avg_frame_rate: '25/1',
|
||||||
// time_base: '1/12800',
|
// time_base: '1/12800',
|
||||||
// start_pts: 0,
|
// start_pts: 0,
|
||||||
// start_time: '0.000000',
|
// start_time: '0.000000',
|
||||||
// duration_ts: 67584,
|
// duration_ts: 67584,
|
||||||
// duration: '5.280000',
|
// duration: '5.280000',
|
||||||
// bit_rate: '1205959',
|
// bit_rate: '1205959',
|
||||||
// bits_per_raw_sample: '8',
|
// bits_per_raw_sample: '8',
|
||||||
// nb_frames: '132',
|
// nb_frames: '132',
|
||||||
// disposition:
|
// disposition:
|
||||||
// { default: 1,
|
// { default: 1,
|
||||||
// dub: 0,
|
// dub: 0,
|
||||||
// original: 0,
|
// original: 0,
|
||||||
// comment: 0,
|
// comment: 0,
|
||||||
// lyrics: 0,
|
// lyrics: 0,
|
||||||
// karaoke: 0,
|
// karaoke: 0,
|
||||||
// forced: 0,
|
// forced: 0,
|
||||||
// hearing_impaired: 0,
|
// hearing_impaired: 0,
|
||||||
// visual_impaired: 0,
|
// visual_impaired: 0,
|
||||||
// clean_effects: 0,
|
// clean_effects: 0,
|
||||||
// attached_pic: 0,
|
// attached_pic: 0,
|
||||||
// timed_thumbnails: 0 },
|
// timed_thumbnails: 0 },
|
||||||
// tags:
|
// tags:
|
||||||
// { creation_time: '1970-01-01T00:00:00.000000Z',
|
// { creation_time: '1970-01-01T00:00:00.000000Z',
|
||||||
// language: 'und',
|
// language: 'und',
|
||||||
// handler_name: 'VideoHandler' } },
|
// handler_name: 'VideoHandler' } },
|
||||||
// { index: 1,
|
// { index: 1,
|
||||||
// codec_name: 'aac',
|
// codec_name: 'aac',
|
||||||
// codec_long_name: 'AAC (Advanced Audio Coding)',
|
// codec_long_name: 'AAC (Advanced Audio Coding)',
|
||||||
// profile: 'LC',
|
// profile: 'LC',
|
||||||
// codec_type: 'audio',
|
// codec_type: 'audio',
|
||||||
// codec_time_base: '1/48000',
|
// codec_time_base: '1/48000',
|
||||||
// codec_tag_string: 'mp4a',
|
// codec_tag_string: 'mp4a',
|
||||||
// codec_tag: '0x6134706d',
|
// codec_tag: '0x6134706d',
|
||||||
// sample_fmt: 'fltp',
|
// sample_fmt: 'fltp',
|
||||||
// sample_rate: '48000',
|
// sample_rate: '48000',
|
||||||
// channels: 6,
|
// channels: 6,
|
||||||
// channel_layout: '5.1',
|
// channel_layout: '5.1',
|
||||||
// bits_per_sample: 0,
|
// bits_per_sample: 0,
|
||||||
// r_frame_rate: '0/0',
|
// r_frame_rate: '0/0',
|
||||||
// avg_frame_rate: '0/0',
|
// avg_frame_rate: '0/0',
|
||||||
// time_base: '1/48000',
|
// time_base: '1/48000',
|
||||||
// start_pts: 0,
|
// start_pts: 0,
|
||||||
// start_time: '0.000000',
|
// start_time: '0.000000',
|
||||||
// duration_ts: 254976,
|
// duration_ts: 254976,
|
||||||
// duration: '5.312000',
|
// duration: '5.312000',
|
||||||
// bit_rate: '384828',
|
// bit_rate: '384828',
|
||||||
// max_bit_rate: '400392',
|
// max_bit_rate: '400392',
|
||||||
// nb_frames: '249',
|
// nb_frames: '249',
|
||||||
// disposition:
|
// disposition:
|
||||||
// { default: 1,
|
// { default: 1,
|
||||||
// dub: 0,
|
// dub: 0,
|
||||||
// original: 0,
|
// original: 0,
|
||||||
// comment: 0,
|
// comment: 0,
|
||||||
// lyrics: 0,
|
// lyrics: 0,
|
||||||
// karaoke: 0,
|
// karaoke: 0,
|
||||||
// forced: 0,
|
// forced: 0,
|
||||||
// hearing_impaired: 0,
|
// hearing_impaired: 0,
|
||||||
// visual_impaired: 0,
|
// visual_impaired: 0,
|
||||||
// clean_effects: 0,
|
// clean_effects: 0,
|
||||||
// attached_pic: 0,
|
// attached_pic: 0,
|
||||||
// timed_thumbnails: 0 },
|
// timed_thumbnails: 0 },
|
||||||
// tags:
|
// tags:
|
||||||
// { creation_time: '1970-01-01T00:00:00.000000Z',
|
// { creation_time: '1970-01-01T00:00:00.000000Z',
|
||||||
// language: 'und',
|
// language: 'und',
|
||||||
// handler_name: 'SoundHandler' } } ] },
|
// handler_name: 'SoundHandler' } } ] },
|
||||||
// ffProbeRead: 'success',
|
// ffProbeRead: 'success',
|
||||||
// file: 'C:/Users/H/Desktop/Test Input1/Sample.mp4',
|
// file: 'C:/Users/H/Desktop/Test Input1/Sample.mp4',
|
||||||
// fileMedium: 'video',
|
// fileMedium: 'video',
|
||||||
// file_size: 1.056519,
|
// file_size: 1.056519,
|
||||||
// meta:
|
// meta:
|
||||||
// { SourceFile: 'C:/Users/H/Desktop/Test Input1/Sample.mp4',
|
// { SourceFile: 'C:/Users/H/Desktop/Test Input1/Sample.mp4',
|
||||||
// errors: [],
|
// errors: [],
|
||||||
// Duration: 5.312,
|
// Duration: 5.312,
|
||||||
// PreviewDuration: 0,
|
// PreviewDuration: 0,
|
||||||
// SelectionDuration: 0,
|
// SelectionDuration: 0,
|
||||||
// TrackDuration: 5.28,
|
// TrackDuration: 5.28,
|
||||||
// MediaDuration: 5.312,
|
// MediaDuration: 5.312,
|
||||||
// ExifToolVersion: 11.65,
|
// ExifToolVersion: 11.65,
|
||||||
// FileName: 'Sample.mp4',
|
// FileName: 'Sample.mp4',
|
||||||
// Directory: 'C:/Users/H/Desktop/Test Input1',
|
// Directory: 'C:/Users/H/Desktop/Test Input1',
|
||||||
// FileSize: '1032 kB',
|
// FileSize: '1032 kB',
|
||||||
// FileModifyDate:
|
// FileModifyDate:
|
||||||
// { year: 2019,
|
// { year: 2019,
|
||||||
// month: 9,
|
// month: 9,
|
||||||
// day: 24,
|
// day: 24,
|
||||||
// hour: 7,
|
// hour: 7,
|
||||||
// minute: 24,
|
// minute: 24,
|
||||||
// second: 22,
|
// second: 22,
|
||||||
// millisecond: 0,
|
// millisecond: 0,
|
||||||
// tzoffsetMinutes: 60,
|
// tzoffsetMinutes: 60,
|
||||||
// rawValue: '2019:09:24 07:24:22+01:00' },
|
// rawValue: '2019:09:24 07:24:22+01:00' },
|
||||||
// FileAccessDate:
|
// FileAccessDate:
|
||||||
// { year: 2019,
|
// { year: 2019,
|
||||||
// month: 9,
|
// month: 9,
|
||||||
// day: 26,
|
// day: 26,
|
||||||
// hour: 7,
|
// hour: 7,
|
||||||
// minute: 44,
|
// minute: 44,
|
||||||
// second: 30,
|
// second: 30,
|
||||||
// millisecond: 0,
|
// millisecond: 0,
|
||||||
// tzoffsetMinutes: 60,
|
// tzoffsetMinutes: 60,
|
||||||
// rawValue: '2019:09:26 07:44:30+01:00' },
|
// rawValue: '2019:09:26 07:44:30+01:00' },
|
||||||
// FileCreateDate:
|
// FileCreateDate:
|
||||||
// { year: 2019,
|
// { year: 2019,
|
||||||
// month: 9,
|
// month: 9,
|
||||||
// day: 26,
|
// day: 26,
|
||||||
// hour: 7,
|
// hour: 7,
|
||||||
// minute: 44,
|
// minute: 44,
|
||||||
// second: 30,
|
// second: 30,
|
||||||
// millisecond: 0,
|
// millisecond: 0,
|
||||||
// tzoffsetMinutes: 60,
|
// tzoffsetMinutes: 60,
|
||||||
// rawValue: '2019:09:26 07:44:30+01:00' },
|
// rawValue: '2019:09:26 07:44:30+01:00' },
|
||||||
// FilePermissions: 'rw-rw-rw-',
|
// FilePermissions: 'rw-rw-rw-',
|
||||||
// FileType: 'MP4',
|
// FileType: 'MP4',
|
||||||
// FileTypeExtension: 'mp4',
|
// FileTypeExtension: 'mp4',
|
||||||
// MIMEType: 'video/mp4',
|
// MIMEType: 'video/mp4',
|
||||||
// MajorBrand: 'MP4 Base Media v1 [IS0 14496-12:2003]',
|
// MajorBrand: 'MP4 Base Media v1 [IS0 14496-12:2003]',
|
||||||
// MinorVersion: '0.2.0',
|
// MinorVersion: '0.2.0',
|
||||||
// CompatibleBrands: [ 'isom', 'iso2', 'avc1', 'mp41' ],
|
// CompatibleBrands: [ 'isom', 'iso2', 'avc1', 'mp41' ],
|
||||||
// MovieDataSize: 0,
|
// MovieDataSize: 0,
|
||||||
// MovieDataOffset: 1051515,
|
// MovieDataOffset: 1051515,
|
||||||
// MovieHeaderVersion: 0,
|
// MovieHeaderVersion: 0,
|
||||||
// CreateDate:
|
// CreateDate:
|
||||||
// { year: 1970,
|
// { year: 1970,
|
||||||
// month: 1,
|
// month: 1,
|
||||||
// day: 8,
|
// day: 8,
|
||||||
// hour: 0,
|
// hour: 0,
|
||||||
// minute: 0,
|
// minute: 0,
|
||||||
// second: 0,
|
// second: 0,
|
||||||
// millisecond: 0,
|
// millisecond: 0,
|
||||||
// rawValue: '1970:01:08 00:00:00' },
|
// rawValue: '1970:01:08 00:00:00' },
|
||||||
// ModifyDate:
|
// ModifyDate:
|
||||||
// { year: 2014,
|
// { year: 2014,
|
||||||
// month: 7,
|
// month: 7,
|
||||||
// day: 19,
|
// day: 19,
|
||||||
// hour: 17,
|
// hour: 17,
|
||||||
// minute: 15,
|
// minute: 15,
|
||||||
// second: 29,
|
// second: 29,
|
||||||
// millisecond: 0,
|
// millisecond: 0,
|
||||||
// rawValue: '2014:07:19 17:15:29' },
|
// rawValue: '2014:07:19 17:15:29' },
|
||||||
// TimeScale: 1000,
|
// TimeScale: 1000,
|
||||||
// PreferredRate: 1,
|
// PreferredRate: 1,
|
||||||
// PreferredVolume: '100.00%',
|
// PreferredVolume: '100.00%',
|
||||||
// PreviewTime: '0 s',
|
// PreviewTime: '0 s',
|
||||||
// PosterTime: '0 s',
|
// PosterTime: '0 s',
|
||||||
// SelectionTime: '0 s',
|
// SelectionTime: '0 s',
|
||||||
// CurrentTime: '0 s',
|
// CurrentTime: '0 s',
|
||||||
// NextTrackID: 3,
|
// NextTrackID: 3,
|
||||||
// TrackHeaderVersion: 0,
|
// TrackHeaderVersion: 0,
|
||||||
// TrackCreateDate: '0000:00:00 00:00:00',
|
// TrackCreateDate: '0000:00:00 00:00:00',
|
||||||
// TrackModifyDate: '0000:00:00 00:00:00',
|
// TrackModifyDate: '0000:00:00 00:00:00',
|
||||||
// TrackID: 1,
|
// TrackID: 1,
|
||||||
// TrackLayer: 0,
|
// TrackLayer: 0,
|
||||||
// TrackVolume: '0.00%',
|
// TrackVolume: '0.00%',
|
||||||
// ImageWidth: 1280,
|
// ImageWidth: 1280,
|
||||||
// ImageHeight: 720,
|
// ImageHeight: 720,
|
||||||
// GraphicsMode: 'srcCopy',
|
// GraphicsMode: 'srcCopy',
|
||||||
// OpColor: '0 0 0',
|
// OpColor: '0 0 0',
|
||||||
// CompressorID: 'avc1',
|
// CompressorID: 'avc1',
|
||||||
// SourceImageWidth: 1280,
|
// SourceImageWidth: 1280,
|
||||||
// SourceImageHeight: 720,
|
// SourceImageHeight: 720,
|
||||||
// XResolution: 72,
|
// XResolution: 72,
|
||||||
// YResolution: 72,
|
// YResolution: 72,
|
||||||
// BitDepth: 24,
|
// BitDepth: 24,
|
||||||
// VideoFrameRate: 25,
|
// VideoFrameRate: 25,
|
||||||
// MatrixStructure: '1 0 0 0 1 0 0 0 1',
|
// MatrixStructure: '1 0 0 0 1 0 0 0 1',
|
||||||
// MediaHeaderVersion: 0,
|
// MediaHeaderVersion: 0,
|
||||||
// MediaCreateDate: '0000:00:00 00:00:00',
|
// MediaCreateDate: '0000:00:00 00:00:00',
|
||||||
// MediaModifyDate: '0000:00:00 00:00:00',
|
// MediaModifyDate: '0000:00:00 00:00:00',
|
||||||
// MediaTimeScale: 48000,
|
// MediaTimeScale: 48000,
|
||||||
// MediaLanguageCode: 'und',
|
// MediaLanguageCode: 'und',
|
||||||
// HandlerDescription: 'SoundHandler',
|
// HandlerDescription: 'SoundHandler',
|
||||||
// Balance: 0,
|
// Balance: 0,
|
||||||
// AudioFormat: 'mp4a',
|
// AudioFormat: 'mp4a',
|
||||||
// AudioChannels: 2,
|
// AudioChannels: 2,
|
||||||
// AudioBitsPerSample: 16,
|
// AudioBitsPerSample: 16,
|
||||||
// AudioSampleRate: 48000,
|
// AudioSampleRate: 48000,
|
||||||
// HandlerType: 'Metadata',
|
// HandlerType: 'Metadata',
|
||||||
// HandlerVendorID: 'Apple',
|
// HandlerVendorID: 'Apple',
|
||||||
// Encoder: 'Lavf53.24.2',
|
// Encoder: 'Lavf53.24.2',
|
||||||
// Title: 'Sample title test',
|
// Title: 'Sample title test',
|
||||||
// Composer: 'th',
|
// Composer: 'th',
|
||||||
// BeatsPerMinute: '',
|
// BeatsPerMinute: '',
|
||||||
// ContentCreateDate: 2018,
|
// ContentCreateDate: 2018,
|
||||||
// Genre: 'this',
|
// Genre: 'this',
|
||||||
// Artist: 'hhj',
|
// Artist: 'hhj',
|
||||||
// Comment: 'hhk',
|
// Comment: 'hhk',
|
||||||
// Subtitle: 'jj',
|
// Subtitle: 'jj',
|
||||||
// Mood: 'lik',
|
// Mood: 'lik',
|
||||||
// ContentDistributor: 'cont',
|
// ContentDistributor: 'cont',
|
||||||
// Conductor: 'jo',
|
// Conductor: 'jo',
|
||||||
// Writer: 'writ',
|
// Writer: 'writ',
|
||||||
// InitialKey: 'ho',
|
// InitialKey: 'ho',
|
||||||
// Producer: 'prod',
|
// Producer: 'prod',
|
||||||
// ParentalRating: 'par',
|
// ParentalRating: 'par',
|
||||||
// Director: 'dir',
|
// Director: 'dir',
|
||||||
// Period: 'pol',
|
// Period: 'pol',
|
||||||
// Publisher: 'pub',
|
// Publisher: 'pub',
|
||||||
// PromotionURL: 'prom',
|
// PromotionURL: 'prom',
|
||||||
// AuthorURL: 'auth',
|
// AuthorURL: 'auth',
|
||||||
// EncodedBy: 'enc',
|
// EncodedBy: 'enc',
|
||||||
// Category: 'h',
|
// Category: 'h',
|
||||||
// ImageSize: '1280x720',
|
// ImageSize: '1280x720',
|
||||||
// Megapixels: 0.922,
|
// Megapixels: 0.922,
|
||||||
// AvgBitrate: '1.58 Mbps',
|
// AvgBitrate: '1.58 Mbps',
|
||||||
// Rotation: 0 },
|
// Rotation: 0 },
|
||||||
// processingStatus: false,
|
// processingStatus: false,
|
||||||
// video_codec_name: 'h264',
|
// video_codec_name: 'h264',
|
||||||
// video_resolution: '720p' }
|
// video_resolution: '720p' }
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,21 @@
|
||||||
var fs = require('fs');
|
var fs = require("fs");
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
if (fs.existsSync(path.join(process.cwd() , "/npm"))) {
|
if (fs.existsSync(path.join(process.cwd(), "/npm"))) {
|
||||||
var rootModules = path.join(process.cwd() , '/npm/node_modules/')
|
var rootModules = path.join(process.cwd(), "/npm/node_modules/");
|
||||||
} else{
|
} else {
|
||||||
var rootModules = ''
|
var rootModules = "";
|
||||||
}
|
}
|
||||||
const importFresh = require(rootModules+'import-fresh');
|
const importFresh = require(rootModules + "import-fresh");
|
||||||
|
|
||||||
|
module.exports.remuxContainer = importFresh(
|
||||||
module.exports.remuxContainer = importFresh('./library/actions/remuxContainer.js')
|
"./library/actions/remuxContainer.js"
|
||||||
module.exports.transcodeStandardiseAudioCodecs = importFresh('./library/actions/transcodeStandardiseAudioCodecs.js')
|
);
|
||||||
module.exports.transcodeAddAudioStream = importFresh('./library/actions/transcodeAddAudioStream.js')
|
module.exports.transcodeStandardiseAudioCodecs = importFresh(
|
||||||
module.exports.transcodeKeepOneAudioStream = importFresh('./library/actions/transcodeKeepOneAudioStream.js')
|
"./library/actions/transcodeStandardiseAudioCodecs.js"
|
||||||
|
);
|
||||||
|
module.exports.transcodeAddAudioStream = importFresh(
|
||||||
|
"./library/actions/transcodeAddAudioStream.js"
|
||||||
|
);
|
||||||
|
module.exports.transcodeKeepOneAudioStream = importFresh(
|
||||||
|
"./library/actions/transcodeKeepOneAudioStream.js"
|
||||||
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,20 @@
|
||||||
var fs = require('fs');
|
var fs = require("fs");
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
if (fs.existsSync(path.join(process.cwd() , "/npm"))) {
|
if (fs.existsSync(path.join(process.cwd(), "/npm"))) {
|
||||||
var rootModules = path.join(process.cwd() , '/npm/node_modules/')
|
var rootModules = path.join(process.cwd(), "/npm/node_modules/");
|
||||||
} else{
|
} else {
|
||||||
var rootModules = ''
|
var rootModules = "";
|
||||||
}
|
}
|
||||||
const importFresh = require(rootModules+'import-fresh');
|
const importFresh = require(rootModules + "import-fresh");
|
||||||
|
|
||||||
|
module.exports.filterByAge = importFresh("./library/filters/filterByAge.js");
|
||||||
module.exports.filterByAge = importFresh('./library/filters/filterByAge.js')
|
module.exports.filterByCodec = importFresh(
|
||||||
module.exports.filterByCodec = importFresh('./library/filters/filterByCodec.js')
|
"./library/filters/filterByCodec.js"
|
||||||
module.exports.filterByMedium = importFresh('./library/filters/filterByMedium.js')
|
);
|
||||||
module.exports.filterByResolution = importFresh('./library/filters/filterByResolution.js')
|
module.exports.filterByMedium = importFresh(
|
||||||
module.exports.filterBySize = importFresh('./library/filters/filterBySize.js')
|
"./library/filters/filterByMedium.js"
|
||||||
|
);
|
||||||
|
module.exports.filterByResolution = importFresh(
|
||||||
|
"./library/filters/filterByResolution.js"
|
||||||
|
);
|
||||||
|
module.exports.filterBySize = importFresh("./library/filters/filterBySize.js");
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
var fs = require('fs');
|
var fs = require("fs");
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
if (fs.existsSync(path.join(process.cwd() , "/npm"))) {
|
if (fs.existsSync(path.join(process.cwd(), "/npm"))) {
|
||||||
var rootModules = path.join(process.cwd() , '/npm/node_modules/')
|
var rootModules = path.join(process.cwd(), "/npm/node_modules/");
|
||||||
} else{
|
} else {
|
||||||
var rootModules = ''
|
var rootModules = "";
|
||||||
}
|
}
|
||||||
const importFresh = require(rootModules+'import-fresh');
|
const importFresh = require(rootModules + "import-fresh");
|
||||||
|
|
||||||
module.exports.filters = importFresh('./filters.js')
|
module.exports.filters = importFresh("./filters.js");
|
||||||
module.exports.actions = importFresh('./actions.js')
|
module.exports.actions = importFresh("./actions.js");
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1,25 @@
|
||||||
|
|
||||||
|
|
||||||
function remuxContainer(file, container) {
|
function remuxContainer(file, container) {
|
||||||
|
try {
|
||||||
try {
|
if (file.container != container) {
|
||||||
|
var response = {
|
||||||
|
processFile: true,
|
||||||
if (file.container != container) {
|
note: `File is not in ${container} \n`,
|
||||||
|
};
|
||||||
var response = {
|
return response;
|
||||||
processFile: true,
|
} else {
|
||||||
note:`File is not in ${container} \n`
|
var response = {
|
||||||
}
|
processFile: false,
|
||||||
return response
|
note: `File is already in ${container} \n`,
|
||||||
|
};
|
||||||
} else {
|
return response;
|
||||||
|
|
||||||
var response = {
|
|
||||||
processFile: false,
|
|
||||||
note:`File is already in ${container} \n`
|
|
||||||
}
|
|
||||||
return response
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
var response = {
|
|
||||||
processFile: false,
|
|
||||||
note:`library.actions.remuxContainer error: ${err} \n`
|
|
||||||
}
|
|
||||||
return response
|
|
||||||
}
|
}
|
||||||
|
} catch (err) {
|
||||||
|
var response = {
|
||||||
|
processFile: false,
|
||||||
|
note: `library.actions.remuxContainer error: ${err} \n`,
|
||||||
|
};
|
||||||
|
return response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports = remuxContainer;
|
||||||
module.exports = remuxContainer
|
|
||||||
|
|
|
||||||
|
|
@ -1,313 +1,276 @@
|
||||||
|
module.exports = function transcodeAddAudioStream(
|
||||||
|
file,
|
||||||
|
audioEncoder,
|
||||||
|
langTag,
|
||||||
|
channelCount
|
||||||
|
) {
|
||||||
|
// response.preset = library.actions.transcodeAddAudioStream(file, 'aac', 'en', 1).preset
|
||||||
|
|
||||||
|
//Function required responses
|
||||||
|
// preset
|
||||||
|
// processFile
|
||||||
|
// note
|
||||||
|
|
||||||
module.exports = function transcodeAddAudioStream(file, audioEncoder, langTag, channelCount) {
|
try {
|
||||||
|
var audioCodec = audioEncoder;
|
||||||
|
langTag = langTag.toLowerCase();
|
||||||
|
|
||||||
// response.preset = library.actions.transcodeAddAudioStream(file, 'aac', 'en', 1).preset
|
if (audioEncoder == "dca") {
|
||||||
|
audioCodec = "dts";
|
||||||
|
}
|
||||||
|
|
||||||
//Function required responses
|
if (audioEncoder == "libmp3lame") {
|
||||||
// preset
|
audioCodec = "mp3";
|
||||||
// processFile
|
}
|
||||||
// note
|
|
||||||
|
|
||||||
try {
|
//Step 1: Check if the file already has the required stream codec/langtag/channel count
|
||||||
|
|
||||||
var audioCodec = audioEncoder
|
var hasStreamAlready = file.ffProbeData.streams.filter((stream) => {
|
||||||
langTag = langTag.toLowerCase()
|
try {
|
||||||
|
if (
|
||||||
if (audioEncoder == 'dca') {
|
stream.codec_type == "audio" &&
|
||||||
audioCodec = 'dts'
|
stream.codec_name === audioCodec &&
|
||||||
|
stream.tags.language.toLowerCase().includes(langTag.toLowerCase()) &&
|
||||||
|
stream.channels == channelCount
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
if (audioEncoder == 'libmp3lame') {
|
return false;
|
||||||
audioCodec = 'mp3'
|
});
|
||||||
|
|
||||||
|
if (hasStreamAlready.length > 0) {
|
||||||
|
return {
|
||||||
|
preset: "",
|
||||||
|
processFile: false,
|
||||||
|
note: `File already has ${langTag} stream in ${audioEncoder}, ${channelCount} channels\n`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//Step 2: Check if file has streams with specified lang tag
|
||||||
|
|
||||||
|
var streamsWithLangTag = file.ffProbeData.streams.filter((stream) => {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
stream.codec_type == "audio" &&
|
||||||
|
stream.tags.language.toLowerCase().includes(langTag)
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
//Step 1: Check if the file already has the required stream codec/langtag/channel count
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
var hasStreamAlready = file.ffProbeData.streams.filter(stream => {
|
console.log("streamsWithLangTag:" + streamsWithLangTag);
|
||||||
|
|
||||||
try {
|
if (streamsWithLangTag.length != 0) {
|
||||||
if (stream.codec_type == 'audio' && stream.codec_name === audioCodec && stream.tags.language.toLowerCase().includes(langTag.toLowerCase()) && stream.channels == channelCount) {
|
return attemptMakeStreamLang(langTag);
|
||||||
return true
|
} else {
|
||||||
}
|
return attemptMakeStreamUnd("und");
|
||||||
|
}
|
||||||
|
|
||||||
} catch (err) { }
|
function attemptMakeStreamLang(langTag) {
|
||||||
|
var streamsWithLangTag = file.ffProbeData.streams.filter((stream) => {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
stream.codec_type == "audio" &&
|
||||||
|
stream.tags.language.toLowerCase().includes(langTag)
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
return false
|
return false;
|
||||||
})
|
});
|
||||||
|
|
||||||
|
var highestChannelCount = streamsWithLangTag.reduce(getHighest);
|
||||||
|
|
||||||
|
function getHighest(first, second) {
|
||||||
|
if (first.channels > second.channels && first) {
|
||||||
|
return first;
|
||||||
|
} else {
|
||||||
|
return second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parseInt(highestChannelCount.channels) >= parseInt(channelCount)) {
|
||||||
|
var hasStreamAlready = file.ffProbeData.streams.filter((stream) => {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
stream.codec_type == "audio" &&
|
||||||
|
stream.codec_name === audioCodec &&
|
||||||
|
stream.tags.language
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(langTag.toLowerCase()) &&
|
||||||
|
stream.channels == channelCount
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
if (hasStreamAlready.length > 0) {
|
if (hasStreamAlready.length > 0) {
|
||||||
|
return {
|
||||||
return {
|
preset: "",
|
||||||
preset: '',
|
|
||||||
processFile: false,
|
|
||||||
note: `File already has ${langTag} stream in ${audioEncoder}, ${channelCount} channels\n`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//Step 2: Check if file has streams with specified lang tag
|
|
||||||
|
|
||||||
var streamsWithLangTag = file.ffProbeData.streams.filter(stream => {
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (stream.codec_type == 'audio' && stream.tags.language.toLowerCase().includes(langTag)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
} catch (err) { }
|
|
||||||
|
|
||||||
return false
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
console.log("streamsWithLangTag:" + streamsWithLangTag)
|
|
||||||
|
|
||||||
if (streamsWithLangTag.length != 0) {
|
|
||||||
|
|
||||||
return attemptMakeStreamLang(langTag)
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
return attemptMakeStreamUnd('und')
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function attemptMakeStreamLang(langTag) {
|
|
||||||
|
|
||||||
|
|
||||||
var streamsWithLangTag = file.ffProbeData.streams.filter(stream => {
|
|
||||||
try {
|
|
||||||
if (stream.codec_type == 'audio' && stream.tags.language.toLowerCase().includes(langTag)) {
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) { }
|
|
||||||
|
|
||||||
return false
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
var highestChannelCount = streamsWithLangTag.reduce(getHighest)
|
|
||||||
|
|
||||||
function getHighest(first, second) {
|
|
||||||
if (first.channels > second.channels && first) {
|
|
||||||
return first
|
|
||||||
} else {
|
|
||||||
return second
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (parseInt(highestChannelCount.channels) >= parseInt(channelCount)) {
|
|
||||||
|
|
||||||
var hasStreamAlready = file.ffProbeData.streams.filter(stream => {
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (stream.codec_type == 'audio' && stream.codec_name === audioCodec && stream.tags.language.toLowerCase().includes(langTag.toLowerCase()) && stream.channels == channelCount) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) { }
|
|
||||||
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
if (hasStreamAlready.length > 0) {
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: '',
|
|
||||||
processFile: false,
|
|
||||||
note: `File already has ${langTag} stream in ${audioEncoder}, ${channelCount} channels \n`
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: `,-map 0:v -map 0:${highestChannelCount.index} -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${audioEncoder} -ac ${channelCount}`,
|
|
||||||
processFile: true,
|
|
||||||
note: `The required channel count ${channelCount} is lower than the highest available channel count (${highestChannelCount.channels}). Adding! \n`
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
console.log('here3')
|
|
||||||
|
|
||||||
var hasStreamAlready = file.ffProbeData.streams.filter(stream => {
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (stream.codec_type == 'audio' && stream.codec_name === audioCodec && stream.tags.language.toLowerCase().includes(langTag.toLowerCase()) && stream.channels == highestChannelCount.channels) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) { }
|
|
||||||
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
if (hasStreamAlready.length > 0) {
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: '',
|
|
||||||
processFile: false,
|
|
||||||
note: `File already has ${langTag} stream in ${audioEncoder}, ${highestChannelCount.channels} channels (Highest available) \n`
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: `,-map 0:v -map 0:${highestChannelCount.index} -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${audioEncoder} -ac ${highestChannelCount.channels}`,
|
|
||||||
processFile: true,
|
|
||||||
note: `The required channel count (${channelCount}) is higher than the highest channel available in specified lang tag (${highestChannelCount.channels}). Adding lower channel track. \n`
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function attemptMakeStreamUnd(langTag) {
|
|
||||||
|
|
||||||
console.log('No tracks with specified lang tag exist. Checking undefined tracks.')
|
|
||||||
|
|
||||||
console.log(langTag)
|
|
||||||
|
|
||||||
var streamsWithLangTag = file.ffProbeData.streams.filter(stream => {
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (stream.codec_type == 'audio' && (stream.tags == undefined || stream.tags.language == undefined || stream.tags.language.toLowerCase().includes(langTag))) {
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) { }
|
|
||||||
|
|
||||||
return false
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
if (streamsWithLangTag.length == 0) {
|
|
||||||
return {
|
|
||||||
preset: ``,
|
|
||||||
processFile: false,
|
|
||||||
note: `Unable to add audio stream in ${langTag}/und with ${channelCount} channels \n`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var highestChannelCount = streamsWithLangTag.reduce(getHighest)
|
|
||||||
|
|
||||||
function getHighest(first, second) {
|
|
||||||
if (first.channels > second.channels && first) {
|
|
||||||
return first
|
|
||||||
} else {
|
|
||||||
return second
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (parseInt(highestChannelCount.channels) >= parseInt(channelCount)) {
|
|
||||||
|
|
||||||
var hasStreamAlready = file.ffProbeData.streams.filter(stream => {
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (stream.codec_type == 'audio' && stream.codec_name === audioCodec && (stream.tags == undefined || stream.tags.language == undefined || stream.tags.language.toLowerCase().includes(langTag)) && stream.channels == channelCount) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) { }
|
|
||||||
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
if (hasStreamAlready.length > 0) {
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: '',
|
|
||||||
processFile: false,
|
|
||||||
note: `File already has ${langTag} stream in ${audioEncoder}, ${channelCount} channels \n`
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: `,-map 0:v -map 0:${highestChannelCount.index} -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${audioEncoder} -ac ${channelCount}`,
|
|
||||||
processFile: true,
|
|
||||||
note: `The required channel count ${channelCount} is lower than the highest available channel count (${highestChannelCount.channels}). Adding! \n`
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var hasStreamAlready = file.ffProbeData.streams.filter(stream => {
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (stream.codec_type == 'audio' && stream.codec_name === audioCodec && (stream.tags == undefined || stream.tags.language == undefined || stream.tags.language.toLowerCase().includes(langTag)) && stream.channels == highestChannelCount.channels) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) { }
|
|
||||||
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
if (hasStreamAlready.length > 0) {
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: '',
|
|
||||||
processFile: false,
|
|
||||||
note: `File already has ${langTag} stream in ${audioEncoder}, ${highestChannelCount.channels} channels (Highest available) \n`
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: `,-map 0:v -map 0:${highestChannelCount.index} -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${audioEncoder} -ac ${highestChannelCount.channels}`,
|
|
||||||
processFile: true,
|
|
||||||
note: `The required channel count (${channelCount}) is higher than the highest channel available in specified lang tag (${highestChannelCount.channels}). Adding lower channel track. \n`
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: '',
|
|
||||||
processFile: false,
|
processFile: false,
|
||||||
note: `library.actions.transcodeAddAudioStream error: ${err} \n`
|
note: `File already has ${langTag} stream in ${audioEncoder}, ${channelCount} channels \n`,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
preset: `,-map 0:v -map 0:${highestChannelCount.index} -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${audioEncoder} -ac ${channelCount}`,
|
||||||
|
processFile: true,
|
||||||
|
note: `The required channel count ${channelCount} is lower than the highest available channel count (${highestChannelCount.channels}). Adding! \n`,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
console.log("here3");
|
||||||
|
|
||||||
|
var hasStreamAlready = file.ffProbeData.streams.filter((stream) => {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
stream.codec_type == "audio" &&
|
||||||
|
stream.codec_name === audioCodec &&
|
||||||
|
stream.tags.language
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(langTag.toLowerCase()) &&
|
||||||
|
stream.channels == highestChannelCount.channels
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasStreamAlready.length > 0) {
|
||||||
|
return {
|
||||||
|
preset: "",
|
||||||
|
processFile: false,
|
||||||
|
note: `File already has ${langTag} stream in ${audioEncoder}, ${highestChannelCount.channels} channels (Highest available) \n`,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
preset: `,-map 0:v -map 0:${highestChannelCount.index} -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${audioEncoder} -ac ${highestChannelCount.channels}`,
|
||||||
|
processFile: true,
|
||||||
|
note: `The required channel count (${channelCount}) is higher than the highest channel available in specified lang tag (${highestChannelCount.channels}). Adding lower channel track. \n`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
function attemptMakeStreamUnd(langTag) {
|
||||||
|
console.log(
|
||||||
|
"No tracks with specified lang tag exist. Checking undefined tracks."
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(langTag);
|
||||||
|
|
||||||
|
var streamsWithLangTag = file.ffProbeData.streams.filter((stream) => {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
stream.codec_type == "audio" &&
|
||||||
|
(stream.tags == undefined ||
|
||||||
|
stream.tags.language == undefined ||
|
||||||
|
stream.tags.language.toLowerCase().includes(langTag))
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (streamsWithLangTag.length == 0) {
|
||||||
|
return {
|
||||||
|
preset: ``,
|
||||||
|
processFile: false,
|
||||||
|
note: `Unable to add audio stream in ${langTag}/und with ${channelCount} channels \n`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var highestChannelCount = streamsWithLangTag.reduce(getHighest);
|
||||||
|
|
||||||
|
function getHighest(first, second) {
|
||||||
|
if (first.channels > second.channels && first) {
|
||||||
|
return first;
|
||||||
|
} else {
|
||||||
|
return second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parseInt(highestChannelCount.channels) >= parseInt(channelCount)) {
|
||||||
|
var hasStreamAlready = file.ffProbeData.streams.filter((stream) => {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
stream.codec_type == "audio" &&
|
||||||
|
stream.codec_name === audioCodec &&
|
||||||
|
(stream.tags == undefined ||
|
||||||
|
stream.tags.language == undefined ||
|
||||||
|
stream.tags.language.toLowerCase().includes(langTag)) &&
|
||||||
|
stream.channels == channelCount
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasStreamAlready.length > 0) {
|
||||||
|
return {
|
||||||
|
preset: "",
|
||||||
|
processFile: false,
|
||||||
|
note: `File already has ${langTag} stream in ${audioEncoder}, ${channelCount} channels \n`,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
preset: `,-map 0:v -map 0:${highestChannelCount.index} -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${audioEncoder} -ac ${channelCount}`,
|
||||||
|
processFile: true,
|
||||||
|
note: `The required channel count ${channelCount} is lower than the highest available channel count (${highestChannelCount.channels}). Adding! \n`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var hasStreamAlready = file.ffProbeData.streams.filter((stream) => {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
stream.codec_type == "audio" &&
|
||||||
|
stream.codec_name === audioCodec &&
|
||||||
|
(stream.tags == undefined ||
|
||||||
|
stream.tags.language == undefined ||
|
||||||
|
stream.tags.language.toLowerCase().includes(langTag)) &&
|
||||||
|
stream.channels == highestChannelCount.channels
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasStreamAlready.length > 0) {
|
||||||
|
return {
|
||||||
|
preset: "",
|
||||||
|
processFile: false,
|
||||||
|
note: `File already has ${langTag} stream in ${audioEncoder}, ${highestChannelCount.channels} channels (Highest available) \n`,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
preset: `,-map 0:v -map 0:${highestChannelCount.index} -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ${audioEncoder} -ac ${highestChannelCount.channels}`,
|
||||||
|
processFile: true,
|
||||||
|
note: `The required channel count (${channelCount}) is higher than the highest channel available in specified lang tag (${highestChannelCount.channels}). Adding lower channel track. \n`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
return {
|
||||||
|
preset: "",
|
||||||
|
processFile: false,
|
||||||
|
note: `library.actions.transcodeAddAudioStream error: ${err} \n`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,365 +1,325 @@
|
||||||
|
module.exports = function transcodeKeepOneAudioStream(
|
||||||
|
file,
|
||||||
|
audioEncoder,
|
||||||
|
langTag,
|
||||||
|
channelCount
|
||||||
|
) {
|
||||||
|
// response.preset = library.actions.transcodeKeepOneAudioStream(file, 'aac', 'en', 1).preset
|
||||||
|
|
||||||
|
//Function required responses
|
||||||
|
// preset
|
||||||
|
// processFile
|
||||||
|
// note
|
||||||
|
|
||||||
module.exports = function transcodeKeepOneAudioStream(file, audioEncoder, langTag, channelCount) {
|
try {
|
||||||
|
var audioCodec = audioEncoder;
|
||||||
|
langTag = langTag.toLowerCase();
|
||||||
|
|
||||||
// response.preset = library.actions.transcodeKeepOneAudioStream(file, 'aac', 'en', 1).preset
|
if (audioEncoder == "dca") {
|
||||||
|
audioCodec = "dts";
|
||||||
|
}
|
||||||
|
|
||||||
//Function required responses
|
if (audioEncoder == "libmp3lame") {
|
||||||
// preset
|
audioCodec = "mp3";
|
||||||
// processFile
|
}
|
||||||
// note
|
|
||||||
|
|
||||||
try {
|
var reqLang = langTag;
|
||||||
|
|
||||||
var audioCodec = audioEncoder
|
var numberOfAudioStreams = file.ffProbeData.streams.filter(
|
||||||
langTag = langTag.toLowerCase()
|
(stream) => stream.codec_type == "audio"
|
||||||
|
).length;
|
||||||
|
|
||||||
if (audioEncoder == 'dca') {
|
//Step 1: Check if the file already has the required stream codec/langtag/channel count
|
||||||
audioCodec = 'dts'
|
|
||||||
|
var hasStreamAlready = file.ffProbeData.streams.filter((stream) => {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
stream.codec_type == "audio" &&
|
||||||
|
stream.codec_name === audioCodec &&
|
||||||
|
stream.tags.language.toLowerCase().includes(langTag.toLowerCase()) &&
|
||||||
|
stream.channels == channelCount
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
if (audioEncoder == 'libmp3lame') {
|
return false;
|
||||||
audioCodec = 'mp3'
|
});
|
||||||
|
|
||||||
|
if (numberOfAudioStreams == 1 && hasStreamAlready.length == 1) {
|
||||||
|
return {
|
||||||
|
preset: "",
|
||||||
|
processFile: false,
|
||||||
|
note: `File already has ${langTag} stream in ${audioEncoder}, ${channelCount} channels. It is the only track! \n`,
|
||||||
|
};
|
||||||
|
} else if (hasStreamAlready.length >= 1) {
|
||||||
|
var audioStreamToKeep = hasStreamAlready[0].index;
|
||||||
|
var ffmpegCommandInsert = "";
|
||||||
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" &&
|
||||||
|
i !== audioStreamToKeep
|
||||||
|
) {
|
||||||
|
ffmpegCommandInsert += ` -map -0:${i}`;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
preset: `, -map 0 ${ffmpegCommandInsert} -c copy`,
|
||||||
|
processFile: true,
|
||||||
|
note: `File already has ${langTag} stream in ${audioEncoder}, ${channelCount} channels. It is not the only track, removing others. \n`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//Step 2: Check if file has streams with specified lang tag
|
||||||
|
|
||||||
|
var streamsWithLangTag = file.ffProbeData.streams.filter((stream) => {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
stream.codec_type == "audio" &&
|
||||||
|
stream.tags.language.toLowerCase().includes(langTag)
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
var reqLang = langTag
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
var numberOfAudioStreams = file.ffProbeData.streams.filter(stream => stream.codec_type == 'audio').length
|
console.log("streamsWithLangTag:" + streamsWithLangTag);
|
||||||
|
|
||||||
|
if (streamsWithLangTag.length != 0) {
|
||||||
|
return attemptMakeStreamLang(langTag);
|
||||||
|
} else {
|
||||||
|
return attemptMakeStreamUnd("und");
|
||||||
|
}
|
||||||
|
|
||||||
//Step 1: Check if the file already has the required stream codec/langtag/channel count
|
function attemptMakeStreamLang(langTag) {
|
||||||
|
var streamsWithLangTag = file.ffProbeData.streams.filter((stream) => {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
stream.codec_type == "audio" &&
|
||||||
|
stream.tags.language.toLowerCase().includes(langTag)
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
var hasStreamAlready = file.ffProbeData.streams.filter(stream => {
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
var highestChannelCount = streamsWithLangTag.reduce(getHighest);
|
||||||
if (stream.codec_type == 'audio' && stream.codec_name === audioCodec && stream.tags.language.toLowerCase().includes(langTag.toLowerCase()) && stream.channels == channelCount) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) { }
|
function getHighest(first, second) {
|
||||||
|
if (first.channels > second.channels && first) {
|
||||||
|
return first;
|
||||||
|
} else {
|
||||||
|
return second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false
|
if (parseInt(highestChannelCount.channels) >= parseInt(channelCount)) {
|
||||||
})
|
var hasStreamAlready = file.ffProbeData.streams.filter((stream) => {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
stream.codec_type == "audio" &&
|
||||||
|
stream.codec_name === audioCodec &&
|
||||||
|
stream.tags.language
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(langTag.toLowerCase()) &&
|
||||||
|
stream.channels == channelCount
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
if (numberOfAudioStreams == 1 && hasStreamAlready.length == 1) {
|
if (numberOfAudioStreams == 1 && hasStreamAlready.length == 1) {
|
||||||
|
return {
|
||||||
|
preset: "",
|
||||||
|
|
||||||
return {
|
|
||||||
preset: '',
|
|
||||||
processFile: false,
|
|
||||||
note: `File already has ${langTag} stream in ${audioEncoder}, ${channelCount} channels. It is the only track! \n`
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} else if (hasStreamAlready.length >= 1) {
|
|
||||||
|
|
||||||
var audioStreamToKeep = hasStreamAlready[0].index
|
|
||||||
var ffmpegCommandInsert = ''
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" && i !== audioStreamToKeep) {
|
|
||||||
ffmpegCommandInsert += ` -map -0:${i}`
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (err) { }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: `, -map 0 ${ffmpegCommandInsert} -c copy`,
|
|
||||||
processFile: true,
|
|
||||||
note: `File already has ${langTag} stream in ${audioEncoder}, ${channelCount} channels. It is not the only track, removing others. \n`
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//Step 2: Check if file has streams with specified lang tag
|
|
||||||
|
|
||||||
var streamsWithLangTag = file.ffProbeData.streams.filter(stream => {
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (stream.codec_type == 'audio' && stream.tags.language.toLowerCase().includes(langTag)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
} catch (err) { }
|
|
||||||
|
|
||||||
return false
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
console.log("streamsWithLangTag:" + streamsWithLangTag)
|
|
||||||
|
|
||||||
if (streamsWithLangTag.length != 0) {
|
|
||||||
|
|
||||||
return attemptMakeStreamLang(langTag)
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
return attemptMakeStreamUnd('und')
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function attemptMakeStreamLang(langTag) {
|
|
||||||
|
|
||||||
|
|
||||||
var streamsWithLangTag = file.ffProbeData.streams.filter(stream => {
|
|
||||||
try {
|
|
||||||
if (stream.codec_type == 'audio' && stream.tags.language.toLowerCase().includes(langTag)) {
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) { }
|
|
||||||
|
|
||||||
return false
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
var highestChannelCount = streamsWithLangTag.reduce(getHighest)
|
|
||||||
|
|
||||||
function getHighest(first, second) {
|
|
||||||
if (first.channels > second.channels && first) {
|
|
||||||
return first
|
|
||||||
} else {
|
|
||||||
return second
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (parseInt(highestChannelCount.channels) >= parseInt(channelCount)) {
|
|
||||||
|
|
||||||
var hasStreamAlready = file.ffProbeData.streams.filter(stream => {
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (stream.codec_type == 'audio' && stream.codec_name === audioCodec && stream.tags.language.toLowerCase().includes(langTag.toLowerCase()) && stream.channels == channelCount) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) { }
|
|
||||||
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
if (numberOfAudioStreams == 1 && hasStreamAlready.length == 1) {
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: '',
|
|
||||||
processFile: false,
|
|
||||||
note: `The required stream already exists. It is the only audio stream. \n`
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (hasStreamAlready.length >= 1) {
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: `,-map 0:v -map 0:${hasStreamAlready[0].index} -map 0:s? -map 0:d? -c copy`,
|
|
||||||
processFile: true,
|
|
||||||
note: `The required stream already exists. Removing others. \n`
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: `,-map 0:v -map 0:${highestChannelCount.index} -map 0:s? -map 0:d? -c copy -c:a:0 ${audioEncoder} -ac ${channelCount}`,
|
|
||||||
processFile: true,
|
|
||||||
note: `The required channel count ${channelCount} is lower than the highest available channel count (${highestChannelCount.channels}). Adding it and removing others! \n`
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
console.log('here3')
|
|
||||||
|
|
||||||
var hasStreamAlready = file.ffProbeData.streams.filter(stream => {
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (stream.codec_type == 'audio' && stream.codec_name === audioCodec && stream.tags.language.toLowerCase().includes(langTag.toLowerCase()) && stream.channels == highestChannelCount.channels) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) { }
|
|
||||||
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
if (numberOfAudioStreams == 1 && hasStreamAlready.length == 1) {
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: '',
|
|
||||||
processFile: false,
|
|
||||||
note: `The best ${reqLang} stream already exists. It is the only audio stream. \n`
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (hasStreamAlready.length >= 1) {
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: `,-map 0:v -map 0:${hasStreamAlready[0].index} -map 0:s? -map 0:d? -c copy`,
|
|
||||||
processFile: true,
|
|
||||||
note: `The best ${reqLang} stream already exists. Removing others. \n`
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: `,-map 0:v -map 0:${highestChannelCount.index} -map 0:s? -map 0:d? -c copy -c:a:0 ${audioEncoder} -ac ${highestChannelCount.channels}`,
|
|
||||||
processFile: true,
|
|
||||||
note: `The required channel count (${channelCount}) is higher than the highest channel available in specified lang tag (${highestChannelCount.channels}). Adding lower channel track, removing others. \n`
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function attemptMakeStreamUnd(langTag) {
|
|
||||||
|
|
||||||
console.log('No tracks with specified lang tag exist. Checking undefined tracks.')
|
|
||||||
|
|
||||||
console.log(langTag)
|
|
||||||
|
|
||||||
var streamsWithLangTag = file.ffProbeData.streams.filter(stream => {
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (stream.codec_type == 'audio' && (stream.tags == undefined || stream.tags.language == undefined || stream.tags.language.toLowerCase().includes(langTag))) {
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) { }
|
|
||||||
|
|
||||||
return false
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
if (streamsWithLangTag.length == 0) {
|
|
||||||
return {
|
|
||||||
preset: ``,
|
|
||||||
processFile: false,
|
|
||||||
note: `Unable to add audio stream in ${langTag}/und with ${channelCount} channels \n`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var highestChannelCount = streamsWithLangTag.reduce(getHighest)
|
|
||||||
|
|
||||||
function getHighest(first, second) {
|
|
||||||
if (first.channels > second.channels && first) {
|
|
||||||
return first
|
|
||||||
} else {
|
|
||||||
return second
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (parseInt(highestChannelCount.channels) >= parseInt(channelCount)) {
|
|
||||||
|
|
||||||
var hasStreamAlready = file.ffProbeData.streams.filter(stream => {
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (stream.codec_type == 'audio' && stream.codec_name === audioCodec && (stream.tags == undefined || stream.tags.language == undefined || stream.tags.language.toLowerCase().includes(langTag)) && stream.channels == channelCount) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) { }
|
|
||||||
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
if (numberOfAudioStreams == 1 && hasStreamAlready.length == 1) {
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: '',
|
|
||||||
processFile: false,
|
|
||||||
note: `No ${reqLang} streams. The required und stream already exists. It is the only audio stream. \n`
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} else if (hasStreamAlready.length >= 1) {
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: `,-map 0:v -map 0:${hasStreamAlready[0].index} -map 0:s? -map 0:d? -c copy`,
|
|
||||||
processFile: true,
|
|
||||||
note: `No ${reqLang} streams. The required und stream already exists. Removing others. \n`
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: `,-map 0:v -map 0:${highestChannelCount.index} -map 0:s? -map 0:d? -c copy -c:a:0 ${audioEncoder} -ac ${channelCount}`,
|
|
||||||
processFile: true,
|
|
||||||
note: `No ${reqLang} streams. The required channel count ${channelCount} is lower than the highest available channel count (${highestChannelCount.channels}).Adding it and removing others! \n`
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var hasStreamAlready = file.ffProbeData.streams.filter(stream => {
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (stream.codec_type == 'audio' && stream.codec_name === audioCodec && (stream.tags == undefined || stream.tags.language == undefined || stream.tags.language.toLowerCase().includes(langTag)) && stream.channels == highestChannelCount.channels) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) { }
|
|
||||||
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
if (numberOfAudioStreams == 1 && hasStreamAlready.length == 1) {
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: '',
|
|
||||||
processFile: false,
|
|
||||||
note: `No ${reqLang} streams. The best und stream already exists. It is the only audio stream. \n`
|
|
||||||
}
|
|
||||||
} else if (hasStreamAlready.length >= 1) {
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: `,-map 0:v -map 0:${hasStreamAlready[0].index} -map 0:s? -map 0:d? -c copy`,
|
|
||||||
processFile: true,
|
|
||||||
note: `No ${reqLang} streams. The best stream already exists. Removing others. \n`
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: `,-map 0:v -map 0:${highestChannelCount.index} -map 0:s? -map 0:d? -c copy -c:a:0 ${audioEncoder} -ac ${highestChannelCount.channels}`,
|
|
||||||
processFile: true,
|
|
||||||
note: `No ${reqLang} streams. The required channel count (${channelCount}) is higher than the highest channel available in specified lang tag (${highestChannelCount.channels}). Adding lower channel track, removing others. \n`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: '',
|
|
||||||
processFile: false,
|
processFile: false,
|
||||||
note: `library.actions.transcodeKeepOneAudioStream error: ${err} \n`
|
note: `The required stream already exists. It is the only audio stream. \n`,
|
||||||
|
};
|
||||||
|
} else if (hasStreamAlready.length >= 1) {
|
||||||
|
return {
|
||||||
|
preset: `,-map 0:v -map 0:${hasStreamAlready[0].index} -map 0:s? -map 0:d? -c copy`,
|
||||||
|
processFile: true,
|
||||||
|
note: `The required stream already exists. Removing others. \n`,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
preset: `,-map 0:v -map 0:${highestChannelCount.index} -map 0:s? -map 0:d? -c copy -c:a:0 ${audioEncoder} -ac ${channelCount}`,
|
||||||
|
processFile: true,
|
||||||
|
note: `The required channel count ${channelCount} is lower than the highest available channel count (${highestChannelCount.channels}). Adding it and removing others! \n`,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
console.log("here3");
|
||||||
|
|
||||||
|
var hasStreamAlready = file.ffProbeData.streams.filter((stream) => {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
stream.codec_type == "audio" &&
|
||||||
|
stream.codec_name === audioCodec &&
|
||||||
|
stream.tags.language
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(langTag.toLowerCase()) &&
|
||||||
|
stream.channels == highestChannelCount.channels
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (numberOfAudioStreams == 1 && hasStreamAlready.length == 1) {
|
||||||
|
return {
|
||||||
|
preset: "",
|
||||||
|
processFile: false,
|
||||||
|
note: `The best ${reqLang} stream already exists. It is the only audio stream. \n`,
|
||||||
|
};
|
||||||
|
} else if (hasStreamAlready.length >= 1) {
|
||||||
|
return {
|
||||||
|
preset: `,-map 0:v -map 0:${hasStreamAlready[0].index} -map 0:s? -map 0:d? -c copy`,
|
||||||
|
processFile: true,
|
||||||
|
note: `The best ${reqLang} stream already exists. Removing others. \n`,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
preset: `,-map 0:v -map 0:${highestChannelCount.index} -map 0:s? -map 0:d? -c copy -c:a:0 ${audioEncoder} -ac ${highestChannelCount.channels}`,
|
||||||
|
processFile: true,
|
||||||
|
note: `The required channel count (${channelCount}) is higher than the highest channel available in specified lang tag (${highestChannelCount.channels}). Adding lower channel track, removing others. \n`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
function attemptMakeStreamUnd(langTag) {
|
||||||
|
console.log(
|
||||||
|
"No tracks with specified lang tag exist. Checking undefined tracks."
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(langTag);
|
||||||
|
|
||||||
|
var streamsWithLangTag = file.ffProbeData.streams.filter((stream) => {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
stream.codec_type == "audio" &&
|
||||||
|
(stream.tags == undefined ||
|
||||||
|
stream.tags.language == undefined ||
|
||||||
|
stream.tags.language.toLowerCase().includes(langTag))
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (streamsWithLangTag.length == 0) {
|
||||||
|
return {
|
||||||
|
preset: ``,
|
||||||
|
processFile: false,
|
||||||
|
note: `Unable to add audio stream in ${langTag}/und with ${channelCount} channels \n`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var highestChannelCount = streamsWithLangTag.reduce(getHighest);
|
||||||
|
|
||||||
|
function getHighest(first, second) {
|
||||||
|
if (first.channels > second.channels && first) {
|
||||||
|
return first;
|
||||||
|
} else {
|
||||||
|
return second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parseInt(highestChannelCount.channels) >= parseInt(channelCount)) {
|
||||||
|
var hasStreamAlready = file.ffProbeData.streams.filter((stream) => {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
stream.codec_type == "audio" &&
|
||||||
|
stream.codec_name === audioCodec &&
|
||||||
|
(stream.tags == undefined ||
|
||||||
|
stream.tags.language == undefined ||
|
||||||
|
stream.tags.language.toLowerCase().includes(langTag)) &&
|
||||||
|
stream.channels == channelCount
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (numberOfAudioStreams == 1 && hasStreamAlready.length == 1) {
|
||||||
|
return {
|
||||||
|
preset: "",
|
||||||
|
processFile: false,
|
||||||
|
note: `No ${reqLang} streams. The required und stream already exists. It is the only audio stream. \n`,
|
||||||
|
};
|
||||||
|
} else if (hasStreamAlready.length >= 1) {
|
||||||
|
return {
|
||||||
|
preset: `,-map 0:v -map 0:${hasStreamAlready[0].index} -map 0:s? -map 0:d? -c copy`,
|
||||||
|
processFile: true,
|
||||||
|
note: `No ${reqLang} streams. The required und stream already exists. Removing others. \n`,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
preset: `,-map 0:v -map 0:${highestChannelCount.index} -map 0:s? -map 0:d? -c copy -c:a:0 ${audioEncoder} -ac ${channelCount}`,
|
||||||
|
processFile: true,
|
||||||
|
note: `No ${reqLang} streams. The required channel count ${channelCount} is lower than the highest available channel count (${highestChannelCount.channels}).Adding it and removing others! \n`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var hasStreamAlready = file.ffProbeData.streams.filter((stream) => {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
stream.codec_type == "audio" &&
|
||||||
|
stream.codec_name === audioCodec &&
|
||||||
|
(stream.tags == undefined ||
|
||||||
|
stream.tags.language == undefined ||
|
||||||
|
stream.tags.language.toLowerCase().includes(langTag)) &&
|
||||||
|
stream.channels == highestChannelCount.channels
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (numberOfAudioStreams == 1 && hasStreamAlready.length == 1) {
|
||||||
|
return {
|
||||||
|
preset: "",
|
||||||
|
processFile: false,
|
||||||
|
note: `No ${reqLang} streams. The best und stream already exists. It is the only audio stream. \n`,
|
||||||
|
};
|
||||||
|
} else if (hasStreamAlready.length >= 1) {
|
||||||
|
return {
|
||||||
|
preset: `,-map 0:v -map 0:${hasStreamAlready[0].index} -map 0:s? -map 0:d? -c copy`,
|
||||||
|
processFile: true,
|
||||||
|
note: `No ${reqLang} streams. The best stream already exists. Removing others. \n`,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
preset: `,-map 0:v -map 0:${highestChannelCount.index} -map 0:s? -map 0:d? -c copy -c:a:0 ${audioEncoder} -ac ${highestChannelCount.channels}`,
|
||||||
|
processFile: true,
|
||||||
|
note: `No ${reqLang} streams. The required channel count (${channelCount}) is higher than the highest channel available in specified lang tag (${highestChannelCount.channels}). Adding lower channel track, removing others. \n`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
return {
|
||||||
|
preset: "",
|
||||||
|
processFile: false,
|
||||||
|
note: `library.actions.transcodeKeepOneAudioStream error: ${err} \n`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,77 +1,59 @@
|
||||||
|
|
||||||
|
|
||||||
module.exports = function transcodeStandardiseAudioCodecs(file, audioEncoder) {
|
module.exports = function transcodeStandardiseAudioCodecs(file, audioEncoder) {
|
||||||
|
//Function required responses
|
||||||
|
// preset
|
||||||
|
// processFile
|
||||||
|
// note
|
||||||
|
|
||||||
|
try {
|
||||||
|
var audioIdx = -1;
|
||||||
|
var hasNonSpecifiedAudioCodecStream = false;
|
||||||
|
var ffmpegCommandInsert = "";
|
||||||
|
var audioCodec = audioEncoder;
|
||||||
|
|
||||||
//Function required responses
|
if (audioEncoder == "dca") {
|
||||||
// preset
|
audioCodec = "dts";
|
||||||
// processFile
|
|
||||||
// note
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
var audioIdx = -1
|
|
||||||
var hasNonSpecifiedAudioCodecStream = false
|
|
||||||
var ffmpegCommandInsert = ''
|
|
||||||
var audioCodec = audioEncoder
|
|
||||||
|
|
||||||
if (audioEncoder == 'dca') {
|
|
||||||
audioCodec = 'dts'
|
|
||||||
}
|
|
||||||
|
|
||||||
if (audioEncoder == 'libmp3lame') {
|
|
||||||
audioCodec = 'mp3'
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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" && file.ffProbeData.streams[i].codec_name != audioCodec) {
|
|
||||||
|
|
||||||
ffmpegCommandInsert += ` -c:a:${audioIdx} ${audioEncoder}`
|
|
||||||
hasNonSpecifiedAudioCodecStream = true
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (err) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (hasNonSpecifiedAudioCodecStream === true) {
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: `,-map 0:v -map 0:a -map 0:s? -map 0:d? -c copy ${ffmpegCommandInsert}`,
|
|
||||||
processFile: true,
|
|
||||||
note: `File has audio streams which aren't in ${audioCodec} \n`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: '',
|
|
||||||
processFile: false,
|
|
||||||
note: `File does not have any audio streams which aren't in ${audioCodec} \n`
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
|
|
||||||
return {
|
|
||||||
preset: '',
|
|
||||||
processFile: false,
|
|
||||||
note: `library.actions.transcodeStandardiseAudioCodecs error: ${err} \n`
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if (audioEncoder == "libmp3lame") {
|
||||||
|
audioCodec = "mp3";
|
||||||
|
}
|
||||||
|
|
||||||
|
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" &&
|
||||||
|
file.ffProbeData.streams[i].codec_name != audioCodec
|
||||||
|
) {
|
||||||
|
ffmpegCommandInsert += ` -c:a:${audioIdx} ${audioEncoder}`;
|
||||||
|
hasNonSpecifiedAudioCodecStream = true;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasNonSpecifiedAudioCodecStream === true) {
|
||||||
|
return {
|
||||||
|
preset: `,-map 0:v -map 0:a -map 0:s? -map 0:d? -c copy ${ffmpegCommandInsert}`,
|
||||||
|
processFile: true,
|
||||||
|
note: `File has audio streams which aren't in ${audioCodec} \n`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
preset: "",
|
||||||
|
processFile: false,
|
||||||
|
note: `File does not have any audio streams which aren't in ${audioCodec} \n`,
|
||||||
|
};
|
||||||
|
} catch (err) {
|
||||||
|
return {
|
||||||
|
preset: "",
|
||||||
|
processFile: false,
|
||||||
|
note: `library.actions.transcodeStandardiseAudioCodecs error: ${err} \n`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,29 @@
|
||||||
|
|
||||||
|
|
||||||
function filterByAge(file, ageCutOff_Seconds) {
|
function filterByAge(file, ageCutOff_Seconds) {
|
||||||
|
try {
|
||||||
|
var timeNow = new Date();
|
||||||
|
var dateCreated = new Date(file.statSync.birthtime);
|
||||||
|
var fileAge = Math.round((timeNow - dateCreated) / 1000);
|
||||||
|
|
||||||
try {
|
if (fileAge > ageCutOff_Seconds) {
|
||||||
|
var response = {
|
||||||
var timeNow = new Date()
|
outcome: false,
|
||||||
var dateCreated = new Date(file.statSync.birthtime)
|
note: `☒File creation date is older than specified requirement. \n`,
|
||||||
var fileAge = Math.round((timeNow - dateCreated) / 1000)
|
};
|
||||||
|
return response;
|
||||||
|
} else {
|
||||||
if (fileAge > ageCutOff_Seconds) {
|
var response = {
|
||||||
|
outcome: true,
|
||||||
var response = {
|
note: `☑File creation date is within specified requirement. \n`,
|
||||||
outcome: false,
|
};
|
||||||
note: `☒File creation date is older than specified requirement. \n`
|
return response;
|
||||||
}
|
|
||||||
return response
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
var response = {
|
|
||||||
outcome: true,
|
|
||||||
note: `☑File creation date is within specified requirement. \n`
|
|
||||||
}
|
|
||||||
return response
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
var response = {
|
|
||||||
outcome: false,
|
|
||||||
note: `library.filters.filterByAge error: ${err} \n`
|
|
||||||
}
|
|
||||||
return response
|
|
||||||
}
|
}
|
||||||
|
} catch (err) {
|
||||||
|
var response = {
|
||||||
|
outcome: false,
|
||||||
|
note: `library.filters.filterByAge error: ${err} \n`,
|
||||||
|
};
|
||||||
|
return response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports = filterByAge;
|
||||||
module.exports = filterByAge
|
|
||||||
|
|
|
||||||
|
|
@ -1,82 +1,60 @@
|
||||||
|
|
||||||
|
|
||||||
function filterByCodec(file, mode, codecs) {
|
function filterByCodec(file, mode, codecs) {
|
||||||
|
try {
|
||||||
|
// console.log(file,mode,codecs)
|
||||||
|
|
||||||
|
var allCodecs = file.ffProbeData.streams.map((row) => row.codec_name);
|
||||||
|
|
||||||
try {
|
var included = false;
|
||||||
|
|
||||||
// console.log(file,mode,codecs)
|
for (var i = 0; i < allCodecs.length; i++) {
|
||||||
|
if (codecs.toLowerCase().includes(allCodecs[i])) {
|
||||||
var allCodecs = file.ffProbeData.streams.map(row => row.codec_name)
|
included = true;
|
||||||
|
}
|
||||||
var included = false
|
|
||||||
|
|
||||||
for (var i = 0; i < allCodecs.length; i++) {
|
|
||||||
|
|
||||||
if (codecs.toLowerCase().includes(allCodecs[i])) {
|
|
||||||
included = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode === 'include') {
|
|
||||||
|
|
||||||
if (included) {
|
|
||||||
|
|
||||||
var response = {
|
|
||||||
outcome: true,
|
|
||||||
note: `☑Codec included \n`
|
|
||||||
}
|
|
||||||
return response
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
var response = {
|
|
||||||
outcome: false,
|
|
||||||
note: `☒Codec excluded \n`
|
|
||||||
}
|
|
||||||
return response
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (mode === 'exclude') {
|
|
||||||
|
|
||||||
if (included) {
|
|
||||||
|
|
||||||
var response = {
|
|
||||||
outcome: false,
|
|
||||||
note: `☒Codec excluded \n`
|
|
||||||
}
|
|
||||||
return response
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
var response = {
|
|
||||||
outcome: true,
|
|
||||||
note: `☑Codec not excluded \n`
|
|
||||||
}
|
|
||||||
return response
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var response = {
|
|
||||||
outcome: false,
|
|
||||||
note: `library.filters.filterByCodec error: ${err} \n`
|
|
||||||
}
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
|
|
||||||
console.log(err)
|
|
||||||
var response = {
|
|
||||||
outcome: false,
|
|
||||||
note: `Filter error hello! ${err}\n`
|
|
||||||
}
|
|
||||||
return response
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mode === "include") {
|
||||||
|
if (included) {
|
||||||
|
var response = {
|
||||||
|
outcome: true,
|
||||||
|
note: `☑Codec included \n`,
|
||||||
|
};
|
||||||
|
return response;
|
||||||
|
} else {
|
||||||
|
var response = {
|
||||||
|
outcome: false,
|
||||||
|
note: `☒Codec excluded \n`,
|
||||||
|
};
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
} else if (mode === "exclude") {
|
||||||
|
if (included) {
|
||||||
|
var response = {
|
||||||
|
outcome: false,
|
||||||
|
note: `☒Codec excluded \n`,
|
||||||
|
};
|
||||||
|
return response;
|
||||||
|
} else {
|
||||||
|
var response = {
|
||||||
|
outcome: true,
|
||||||
|
note: `☑Codec not excluded \n`,
|
||||||
|
};
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var response = {
|
||||||
|
outcome: false,
|
||||||
|
note: `library.filters.filterByCodec error: ${err} \n`,
|
||||||
|
};
|
||||||
|
return response;
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
var response = {
|
||||||
|
outcome: false,
|
||||||
|
note: `Filter error hello! ${err}\n`,
|
||||||
|
};
|
||||||
|
return response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports = filterByCodec;
|
||||||
module.exports = filterByCodec
|
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,25 @@
|
||||||
|
|
||||||
|
|
||||||
function filterByMedium(file, medium) {
|
function filterByMedium(file, medium) {
|
||||||
|
try {
|
||||||
try {
|
if (file.fileMedium !== medium) {
|
||||||
|
var response = {
|
||||||
if (file.fileMedium !== medium) {
|
outcome: false,
|
||||||
|
note: `☒File is not ${medium} \n`,
|
||||||
var response = {
|
};
|
||||||
outcome: false,
|
return response;
|
||||||
note: `☒File is not ${medium} \n`
|
} else {
|
||||||
}
|
var response = {
|
||||||
return response
|
outcome: true,
|
||||||
|
note: `☑File is ${medium} \n`,
|
||||||
} else {
|
};
|
||||||
|
return response;
|
||||||
var response = {
|
|
||||||
outcome: true,
|
|
||||||
note: `☑File is ${medium} \n`
|
|
||||||
}
|
|
||||||
return response
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
var response = {
|
|
||||||
outcome: false,
|
|
||||||
note: `library.filters.filterByMedium error: ${err} \n`
|
|
||||||
}
|
|
||||||
return response
|
|
||||||
}
|
}
|
||||||
|
} catch (err) {
|
||||||
|
var response = {
|
||||||
|
outcome: false,
|
||||||
|
note: `library.filters.filterByMedium error: ${err} \n`,
|
||||||
|
};
|
||||||
|
return response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports = filterByMedium;
|
||||||
module.exports = filterByMedium
|
|
||||||
|
|
|
||||||
|
|
@ -1,58 +1,45 @@
|
||||||
|
|
||||||
|
|
||||||
function filterByResolution(file, mode, resolution) {
|
function filterByResolution(file, mode, resolution) {
|
||||||
|
try {
|
||||||
try {
|
if (mode === "exclude") {
|
||||||
|
if (
|
||||||
if (mode === 'exclude') {
|
resolution.toLowerCase().includes(file.video_resolution.toLowerCase())
|
||||||
|
) {
|
||||||
if (resolution.toLowerCase().includes(file.video_resolution.toLowerCase())) {
|
|
||||||
|
|
||||||
var response = {
|
|
||||||
outcome: false,
|
|
||||||
note: `☒File is in excluded resolution. \n`
|
|
||||||
}
|
|
||||||
return response
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
var response = {
|
|
||||||
outcome: true,
|
|
||||||
note: `☑File is not in excluded resolution. \n`
|
|
||||||
}
|
|
||||||
return response
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (mode === 'include') {
|
|
||||||
|
|
||||||
if (resolution.toLowerCase().includes(file.video_resolution.toLowerCase())) {
|
|
||||||
|
|
||||||
var response = {
|
|
||||||
outcome: true,
|
|
||||||
note: `☑File is in included resolution. \n`
|
|
||||||
}
|
|
||||||
return response
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
var response = {
|
|
||||||
outcome: false,
|
|
||||||
note: `☒File is not in included resolution. \n`
|
|
||||||
}
|
|
||||||
return response
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
var response = {
|
var response = {
|
||||||
outcome: false,
|
outcome: false,
|
||||||
note: `library.filters.filterByResolution error: ${err} \n`
|
note: `☒File is in excluded resolution. \n`,
|
||||||
}
|
};
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
|
var response = {
|
||||||
|
outcome: true,
|
||||||
|
note: `☑File is not in excluded resolution. \n`,
|
||||||
|
};
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
} else if (mode === "include") {
|
||||||
|
if (
|
||||||
|
resolution.toLowerCase().includes(file.video_resolution.toLowerCase())
|
||||||
|
) {
|
||||||
|
var response = {
|
||||||
|
outcome: true,
|
||||||
|
note: `☑File is in included resolution. \n`,
|
||||||
|
};
|
||||||
|
return response;
|
||||||
|
} else {
|
||||||
|
var response = {
|
||||||
|
outcome: false,
|
||||||
|
note: `☒File is not in included resolution. \n`,
|
||||||
|
};
|
||||||
|
return response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (err) {
|
||||||
|
var response = {
|
||||||
|
outcome: false,
|
||||||
|
note: `library.filters.filterByResolution error: ${err} \n`,
|
||||||
|
};
|
||||||
|
return response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports = filterByResolution;
|
||||||
module.exports = filterByResolution
|
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,28 @@
|
||||||
|
|
||||||
|
|
||||||
function filterBySize(file, lowerBound, upperBound) {
|
function filterBySize(file, lowerBound, upperBound) {
|
||||||
|
try {
|
||||||
try {
|
if (
|
||||||
|
file.file_size / 1000 >= lowerBound &&
|
||||||
if (file.file_size / 1000 >= lowerBound && file.file_size / 1000 <= upperBound) {
|
file.file_size / 1000 <= upperBound
|
||||||
|
) {
|
||||||
var response = {
|
var response = {
|
||||||
outcome: true,
|
outcome: true,
|
||||||
note: `☑File size is within filter limits. \n`
|
note: `☑File size is within filter limits. \n`,
|
||||||
}
|
};
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
} else {
|
var response = {
|
||||||
|
outcome: false,
|
||||||
var response = {
|
note: `☒File size is not within filter limits. \n`,
|
||||||
outcome: false,
|
};
|
||||||
note: `☒File size is not within filter limits. \n`
|
return response;
|
||||||
}
|
|
||||||
return response
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
var response = {
|
|
||||||
outcome: false,
|
|
||||||
note: `library.filters.filterBySize error: ${err} \n`
|
|
||||||
}
|
|
||||||
return response
|
|
||||||
}
|
}
|
||||||
|
} catch (err) {
|
||||||
|
var response = {
|
||||||
|
outcome: false,
|
||||||
|
note: `library.filters.filterBySize error: ${err} \n`,
|
||||||
|
};
|
||||||
|
return response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = filterBySize
|
module.exports = filterBySize;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue