parent
d28272f6d4
commit
9c8ac98728
@ -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.
|
|
||||||
if (inputs.container == "") {
|
// Check if 10bit variable is true.
|
||||||
response.infoLog += "☒Container has not been configured within plugin settings, please configure required options. Skipping this plugin. \n"
|
if (inputs.enable_10bit == "true") {
|
||||||
response.processFile = false
|
// If set to true then add 10bit argument
|
||||||
return response
|
extraArguments += `-pix_fmt p010le `;
|
||||||
} else {
|
}
|
||||||
response.container = '.' + inputs.container
|
|
||||||
}
|
// Go through each stream in the file.
|
||||||
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
// Check if file is MKV, if so then add extra argument to drop data. MKV does not support data streams.
|
// Check if stream is a video.
|
||||||
if (inputs.container == "mkv") {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "video") {
|
||||||
extraArguments += "-map -0:d "
|
// 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 a video. If it isn't then exit plugin.
|
|
||||||
if (file.fileMedium !== "video") {
|
// Set bitrateSettings variable using bitrate information calulcated earlier.
|
||||||
response.processFile = false
|
bitrateSettings = `-b:v ${targetBitrate}k -minrate ${minimumBitrate}k -maxrate ${maximumBitrate}k -bufsize ${currentBitrate}k`;
|
||||||
response.infoLog += "☒File is not a video. \n"
|
// Print to infoLog information around file & bitrate settings.
|
||||||
return response
|
response.infoLog += `Container for output selected as ${
|
||||||
}
|
inputs.container
|
||||||
|
}. \n Current bitrate = ${~~(
|
||||||
// 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.
|
file.file_size /
|
||||||
if (typeof file.meta.Duration != 'undefined') {
|
(duration * 0.0075)
|
||||||
var duration = (file.meta.Duration * 0.0166667)
|
)} \n Bitrate settings: \nTarget = ${targetBitrate} \nMinimum = ${minimumBitrate} \nMaximum = ${maximumBitrate} \n`;
|
||||||
} else {
|
|
||||||
var duration = (file.ffProbeData.streams[0].duration * 0.0166667)
|
// Codec will be checked so it can be transcoded correctly
|
||||||
}
|
if (file.video_codec_name == "h263") {
|
||||||
|
response.preset = `-c:v h263_cuvid`;
|
||||||
// Set up required variables.
|
} else if (file.video_codec_name == "h264") {
|
||||||
var videoIdx = 0
|
if (file.ffProbeData.streams[0].profile != "High 10") {
|
||||||
var extraArguments = ""
|
//if a h264 coded video is not HDR
|
||||||
var bitrateSettings = ""
|
response.preset = `-c:v h264_cuvid`;
|
||||||
// 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
|
|
||||||
}
|
}
|
||||||
|
} else if (file.video_codec_name == "mjpeg") {
|
||||||
// Check if inputs.bitrate cutoff has something entered (Entered means user actually wants something to happen, empty would disable this).
|
response.preset = `c:v mjpeg_cuvid`;
|
||||||
if (inputs.bitrate_cutoff != "") {
|
} else if (file.video_codec_name == "mpeg1") {
|
||||||
// Checks if currentBitrate is below inputs.bitrate_cutoff, if so then cancel plugin without touching original files.
|
response.preset = `-c:v mpeg1_cuvid`;
|
||||||
if (currentBitrate <= inputs.bitrate_cutoff) {
|
} else if (file.video_codec_name == "mpeg2") {
|
||||||
response.processFile = false
|
response.preset = `-c:v mpeg2_cuvid`;
|
||||||
response.infoLog += `☑Current bitrate is below configured bitrate cutoff of ${inputs.bitrate_cutoff}. Nothing to do, cancelling plugin. \n`
|
} else if (file.video_codec_name == "vc1") {
|
||||||
return response
|
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") {
|
||||||
// Check if 10bit variable is true.
|
response.preset = `-c:v vp9_cuvid`;
|
||||||
if (inputs.enable_10bit == "true") {
|
}
|
||||||
// If set to true then add 10bit argument
|
|
||||||
extraArguments += `-pix_fmt p010le `
|
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`;
|
||||||
// Go through each stream in the file.
|
return response;
|
||||||
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.
|
// Check if inputs.container has been configured. If it hasn't then exit plugin.
|
||||||
if (inputs.container == "") {
|
if (inputs.container == "") {
|
||||||
response.infoLog += "☒Container has not been configured within plugin settings, please configure required options. Skipping this plugin. \n"
|
response.infoLog +=
|
||||||
response.processFile = false
|
"☒Container has not been configured within plugin settings, please configure required options. Skipping this plugin. \n";
|
||||||
return response
|
response.processFile = false;
|
||||||
} else {
|
return response;
|
||||||
response.container = '.' + inputs.container
|
} 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") {
|
// Check if file is MKV, if so then add extra argument to drop data. MKV does not support data streams.
|
||||||
extraArguments += "-map -0:d "
|
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") {
|
// Check if file is a video. If it isn't then exit plugin.
|
||||||
response.processFile = false
|
if (file.fileMedium !== "video") {
|
||||||
response.infoLog += "☒File is not a video. \n"
|
response.processFile = false;
|
||||||
return response
|
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 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') {
|
// Check if 10bit variable is true.
|
||||||
var duration = (file.meta.Duration * 0.0166667)
|
if (inputs.enable_10bit == "true") {
|
||||||
} else {
|
// If set to true then add 10bit argument
|
||||||
var duration = (file.ffProbeData.streams[0].duration * 0.0166667)
|
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 up required variables.
|
|
||||||
var videoIdx = -1
|
// Set bitrateSettings variable using bitrate information calulcated earlier.
|
||||||
var extraArguments = ""
|
bitrateSettings = `-b:v ${targetBitrate}k -minrate ${minimumBitrate}k -maxrate ${maximumBitrate}k -bufsize ${currentBitrate}k`;
|
||||||
var bitrateSettings = ""
|
// Print to infoLog information around file & bitrate settings.
|
||||||
// Work out currentBitrate using "Bitrate = file size / (number of minutes * .0075)" - Used from here https://blog.frame.io/2017/03/06/calculate-video-bitrates/
|
response.infoLog += `Container for output selected as ${
|
||||||
var currentBitrate = ~~(file.file_size / (duration * 0.0075))
|
inputs.container
|
||||||
// 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.
|
}. \n Current bitrate = ${~~(
|
||||||
var targetBitrate = ~~((file.file_size / (duration * 0.0075)) / 2)
|
file.file_size /
|
||||||
// Allow some leeway under and over the targetBitrate.
|
(duration * 0.0075)
|
||||||
var minimumBitrate = ~~(targetBitrate * 0.7)
|
)} \n Bitrate settings: \nTarget = ${targetBitrate} \nMinimum = ${minimumBitrate} \nMaximum = ${maximumBitrate} \n`;
|
||||||
var maximumBitrate = ~~(targetBitrate * 1.3)
|
|
||||||
|
response.preset += `,-map 0 -c:v libx265 ${bitrateSettings} -c:a copy -c:s copy -max_muxing_queue_size 4096 ${extraArguments}`;
|
||||||
// If targetBitrate comes out as 0 then something has gone wrong and bitrates could not be calculcated. Cancel plugin completely.
|
response.processFile = true;
|
||||||
if (targetBitrate == "0") {
|
response.infoLog += `☒File is not hevc. Transcoding. \n`;
|
||||||
response.processFile = false
|
return response;
|
||||||
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,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.
|
|
||||||
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.processFile = false
|
|
||||||
return response
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if file is a video. If it isn't then exit plugin.
|
|
||||||
if (file.fileMedium !== "video") {
|
|
||||||
console.log("File is not video")
|
|
||||||
response.infoLog += "☒File is not video. \n"
|
|
||||||
response.processFile = false;
|
|
||||||
return response
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up required variables.
|
// Check if both inputs.aac_stereo AND inputs.downmix have been left empty. If they have then exit plugin.
|
||||||
var ffmpegCommandInsert = ''
|
if (inputs && inputs.aac_stereo == "" && inputs.downmix == "") {
|
||||||
var audioIdx = 0
|
response.infoLog +=
|
||||||
var has2Channel = false
|
"☒Neither aac_stereo or downmix options have been configured within plugin settings, please configure required options. Skipping this plugin. \n";
|
||||||
var has6Channel = false
|
response.processFile = false;
|
||||||
var has8Channel = false
|
return response;
|
||||||
var convert = false
|
}
|
||||||
|
|
||||||
// Go through each stream in the file.
|
// Check if file is a video. If it isn't then exit plugin.
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
if (file.fileMedium !== "video") {
|
||||||
try {
|
console.log("File is not video");
|
||||||
// Go through all audio streams and check if 2,6 & 8 channel tracks exist or not.
|
response.infoLog += "☒File is not video. \n";
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
response.processFile = false;
|
||||||
if (file.ffProbeData.streams[i].channels == "2") {
|
return response;
|
||||||
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.
|
// Set up required variables.
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
var ffmpegCommandInsert = "";
|
||||||
// Check if stream is audio.
|
var audioIdx = 0;
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
var has2Channel = false;
|
||||||
// Catch error here incase user left inputs.downmix empty.
|
var has6Channel = false;
|
||||||
try {
|
var has8Channel = false;
|
||||||
// Check if inputs.downmix is set to true.
|
var convert = false;
|
||||||
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.
|
// Go through each stream in the file.
|
||||||
try {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
// Check if inputs.aac_stereo is set to true.
|
try {
|
||||||
if (inputs.aac_stereo.toLowerCase() == "true") {
|
// Go through all audio streams and check if 2,6 & 8 channel tracks exist or not.
|
||||||
// Check if codec_name for stream is NOT aac AND check if channel ammount is 2.
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
||||||
if (file.ffProbeData.streams[i].codec_name != "aac" && file.ffProbeData.streams[i].channels == "2") {
|
if (file.ffProbeData.streams[i].channels == "2") {
|
||||||
ffmpegCommandInsert += `-c:a:${audioIdx} aac `
|
has2Channel = true;
|
||||||
response.infoLog += "☒Audio track is 2 channel but is not AAC. Converting. \n"
|
}
|
||||||
convert = true
|
if (file.ffProbeData.streams[i].channels == "6") {
|
||||||
}
|
has6Channel = true;
|
||||||
}
|
}
|
||||||
} catch (err) {}
|
if (file.ffProbeData.streams[i].channels == "8") {
|
||||||
audioIdx++
|
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) {}
|
||||||
|
|
||||||
// Convert file if convert variable is set to true.
|
// Catch error here incase user left inputs.downmix empty.
|
||||||
if (convert == true) {
|
try {
|
||||||
response.processFile = true;
|
// Check if inputs.aac_stereo is set to true.
|
||||||
response.preset = `, -map 0 -c:v copy -c:a copy ${ffmpegCommandInsert} -strict -2 -c:s copy -max_muxing_queue_size 4096 `
|
if (inputs.aac_stereo.toLowerCase() == "true") {
|
||||||
} else {
|
// Check if codec_name for stream is NOT aac AND check if channel ammount is 2.
|
||||||
response.infoLog += "☑File contains all required audio formats. \n"
|
if (
|
||||||
response.processFile = false;
|
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++;
|
||||||
}
|
}
|
||||||
return response
|
}
|
||||||
|
|
||||||
|
// Convert file if convert variable is set to true.
|
||||||
|
if (convert == true) {
|
||||||
|
response.processFile = true;
|
||||||
|
response.preset = `, -map 0 -c:v copy -c:a copy ${ffmpegCommandInsert} -strict -2 -c:s copy -max_muxing_queue_size 4096 `;
|
||||||
|
} else {
|
||||||
|
response.infoLog += "☑File contains all required audio formats. \n";
|
||||||
|
response.processFile = false;
|
||||||
|
}
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
module.exports.details = details;
|
module.exports.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.
|
|
||||||
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.
|
|
||||||
if (audio6Idx != "0" || audio8Idx != "0") {
|
|
||||||
convert = true
|
|
||||||
response.infoLog += "☒ Audio 2ch not first. \n"
|
|
||||||
}
|
|
||||||
// Increment audio2Idx.
|
|
||||||
audio2Idx++
|
|
||||||
}
|
|
||||||
// Check if audio track is 6 channel.
|
|
||||||
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.
|
|
||||||
if (audio8Idx != "0") {
|
|
||||||
convert = true
|
|
||||||
response.infoLog += "☒ Audio 6ch not second. \n"
|
|
||||||
}
|
|
||||||
// Increment audio6Idx.
|
|
||||||
audio6Idx++
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if audio track is 8 channel.
|
|
||||||
if (file.ffProbeData.streams[i].channels == "8") {
|
|
||||||
// Increment audio8Idx.
|
|
||||||
audio8Idx++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if stream is subtitle.
|
// Check if audio track is 2 channel.
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle") {
|
if (file.ffProbeData.streams[i].channels == "2") {
|
||||||
// Increment subtitleIdx
|
// 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.
|
||||||
subtitleIdx++
|
if (audio6Idx != "0" || audio8Idx != "0") {
|
||||||
}
|
convert = true;
|
||||||
} catch (err) {}
|
response.infoLog += "☒ Audio 2ch not first. \n";
|
||||||
}
|
}
|
||||||
|
// Increment audio2Idx.
|
||||||
|
audio2Idx++;
|
||||||
|
}
|
||||||
|
// Check if audio track is 6 channel.
|
||||||
|
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.
|
||||||
|
if (audio8Idx != "0") {
|
||||||
|
convert = true;
|
||||||
|
response.infoLog += "☒ Audio 6ch not second. \n";
|
||||||
|
}
|
||||||
|
// Increment audio6Idx.
|
||||||
|
audio6Idx++;
|
||||||
|
}
|
||||||
|
|
||||||
// Go through each stream in the file.
|
// Check if audio track is 8 channel.
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
if (file.ffProbeData.streams[i].channels == "8") {
|
||||||
try {
|
// Increment audio8Idx.
|
||||||
// Check if stream is video AND is not a mjpeg.
|
audio8Idx++;
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "video" && file.ffProbeData.streams[i].codec_name.toLowerCase() != "mjpeg") {
|
}
|
||||||
ffmpegCommandInsert += `-map 0:${i} `
|
}
|
||||||
}
|
|
||||||
} catch (err) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go through each stream in the file.
|
// Check if stream is subtitle.
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle") {
|
||||||
try {
|
// Increment subtitleIdx
|
||||||
// Check if stream is audio AND 2 channel.
|
subtitleIdx++;
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" && file.ffProbeData.streams[i].channels == "2") {
|
}
|
||||||
ffmpegCommandInsert += `-map 0:${i} `
|
} 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 audio AND 6 channel.
|
// Check if stream is video AND is not a mjpeg.
|
||||||
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() == "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 8 channel.
|
// Check if stream is audio AND 2 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 == "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 not 2, 6 or 8 channel.
|
// Check if stream is audio AND 6 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 == "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 subtitle.
|
// Check if stream is audio AND 8 channel.
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle") {
|
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) {}
|
||||||
|
}
|
||||||
|
|
||||||
// Convert file if convert variable is set to true.
|
// Go through each stream in the file.
|
||||||
if (convert == true) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
response.processFile = true;
|
try {
|
||||||
response.preset = `,${ffmpegCommandInsert} -c copy -max_muxing_queue_size 4096`
|
// Check if stream is audio AND not 2, 6 or 8 channel.
|
||||||
response.reQueueAfter = true;
|
if (
|
||||||
response.infoLog += "☒ Streams are out of order, reorganizing streams. Video, Audio, Subtitles. \n"
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" &&
|
||||||
} else {
|
file.ffProbeData.streams[i].channels != "2" &&
|
||||||
response.infoLog += "☑ Streams are in expected order. \n "
|
file.ffProbeData.streams[i].channels != "6" &&
|
||||||
response.processFile = false;
|
file.ffProbeData.streams[i].channels != "8"
|
||||||
}
|
) {
|
||||||
return response
|
ffmpegCommandInsert += `-map 0:${i} `;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go through each stream in the file.
|
||||||
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
try {
|
||||||
|
// Check if stream is subtitle.
|
||||||
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle") {
|
||||||
|
ffmpegCommandInsert += `-map 0:${i} `;
|
||||||
|
}
|
||||||
|
} 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;
|
||||||
}
|
}
|
||||||
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.
|
||||||
// Check if all inputs have been configured. If they haven't then exit plugin.
|
if (
|
||||||
if (inputs && inputs.autoscan_address == "" && inputs.autoscan_port == "" && inputs.autoscan_passkey == "") {
|
inputs &&
|
||||||
response.infoLog += "☒Autoscan options have not been configured, please configure all options. Skipping this plugin. \n"
|
inputs.autoscan_address == "" &&
|
||||||
response.processFile = false;
|
inputs.autoscan_port == "" &&
|
||||||
return response
|
inputs.autoscan_passkey == ""
|
||||||
}
|
) {
|
||||||
|
response.infoLog +=
|
||||||
// Take variable inputs and turn them into read only variable
|
"☒Autoscan options have not been configured, please configure all options. Skipping this plugin. \n";
|
||||||
const request = require('request')
|
response.processFile = false;
|
||||||
const ADDRESS = inputs.autoscan_address
|
return response;
|
||||||
const PORT = inputs.autoscan_port
|
}
|
||||||
const PASSKEY = inputs.autoscan_passkey
|
|
||||||
|
|
||||||
// Set up required variables.
|
// Take variable inputs and turn them into read only variable
|
||||||
var response = ""
|
const request = require("request");
|
||||||
filepath = `${file.file}`
|
const ADDRESS = inputs.autoscan_address;
|
||||||
|
const PORT = inputs.autoscan_port;
|
||||||
|
const PASSKEY = inputs.autoscan_passkey;
|
||||||
|
|
||||||
// Set content of request/post.
|
// Set up required variables.
|
||||||
request.post({
|
var response = "";
|
||||||
headers: {
|
filepath = `${file.file}`;
|
||||||
'content-type': 'application/json'
|
|
||||||
},
|
// Set content of request/post.
|
||||||
url: `${ADDRESS}:${PORT}/${PASSKEY}`,
|
request.post(
|
||||||
form: {
|
{
|
||||||
"eventType": "Manual",
|
headers: {
|
||||||
"filepath": `${filepath}`
|
"content-type": "application/json",
|
||||||
}
|
},
|
||||||
}, (error, res, body) => {
|
url: `${ADDRESS}:${PORT}/${PASSKEY}`,
|
||||||
if (error) {
|
form: {
|
||||||
console.error(error)
|
eventType: "Manual",
|
||||||
}
|
filepath: `${filepath}`,
|
||||||
console.log(`statusCode: ${res.statusCode}`)
|
},
|
||||||
console.log(body)
|
},
|
||||||
})
|
(error, res, body) => {
|
||||||
|
if (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
console.log(`statusCode: ${res.statusCode}`);
|
||||||
|
console.log(body);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
console.log("request next")
|
console.log("request next");
|
||||||
console.log(request.post)
|
console.log(request.post);
|
||||||
}
|
};
|
||||||
|
|||||||
@ -1,138 +1,138 @@
|
|||||||
function details() {
|
function details() {
|
||||||
return {
|
return {
|
||||||
id: "Tdarr_Plugin_a8hc_HaveAGitGat_HandBrake_H264_VeryFast1080p30",
|
id: "Tdarr_Plugin_a8hc_HaveAGitGat_HandBrake_H264_VeryFast1080p30",
|
||||||
Stage: "Pre-processing",
|
Stage: "Pre-processing",
|
||||||
Name:
|
Name:
|
||||||
"HaveAGitGat HandBrake VeryFast1080p30, No title meta, no subs, 192Kb AAC stereo,MP4 ",
|
"HaveAGitGat HandBrake VeryFast1080p30, No title meta, no subs, 192Kb AAC stereo,MP4 ",
|
||||||
Type: "Video",
|
Type: "Video",
|
||||||
Description: `[Contains built-in filter] This plugin transcodes into H264 using HandBrake's 'Very Fast 1080p30' preset if the file is not in H264 already. It removes subs, metadata (if a title exists) and adds a stereo 192kbit AAC track if an AAC track (any) doesn't exist. The output container is MP4. \n\n
|
Description: `[Contains built-in filter] This plugin transcodes into H264 using HandBrake's 'Very Fast 1080p30' preset if the file is not in H264 already. It removes subs, metadata (if a title exists) and adds a stereo 192kbit AAC track if an AAC track (any) doesn't exist. The output container is MP4. \n\n
|
||||||
`,
|
`,
|
||||||
Version: "1.00",
|
Version: "1.00",
|
||||||
Link:
|
Link:
|
||||||
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_a8hc_HaveAGitGat_HandBrake_H264_VeryFast1080p30.js",
|
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_a8hc_HaveAGitGat_HandBrake_H264_VeryFast1080p30.js",
|
||||||
Tags: "pre-processing,handbrake,ffmpeg,h264",
|
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,
|
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 {
|
||||||
var jsonString = JSON.stringify(file);
|
var jsonString = JSON.stringify(file);
|
||||||
|
|
||||||
var hasSubs = false;
|
var hasSubs = false;
|
||||||
|
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
try {
|
try {
|
||||||
if (
|
if (
|
||||||
file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle"
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "subtitle"
|
||||||
) {
|
) {
|
||||||
hasSubs = true;
|
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.infoLog += "☒File is not in h264! \n";
|
||||||
response.preset = '-Z "Very Fast 1080p30"';
|
response.preset = '-Z "Very Fast 1080p30"';
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
response.handBrakeMode = true;
|
response.handBrakeMode = true;
|
||||||
return response;
|
return response;
|
||||||
} else {
|
} else {
|
||||||
response.infoLog += "☑File is already in h264! \n";
|
response.infoLog += "☑File is already in h264! \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;
|
||||||
response.FFmpegMode = true;
|
response.FFmpegMode = true;
|
||||||
return response;
|
return response;
|
||||||
} else {
|
} else {
|
||||||
response.infoLog += "☑File has no subs \n";
|
response.infoLog += "☑File has no subs \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
file.meta.Title != "undefined" &&
|
file.meta.Title != "undefined" &&
|
||||||
!jsonString.includes("aac") &&
|
!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 -c copy";
|
response.preset = ",-map_metadata -1 -map 0 -c copy";
|
||||||
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 =
|
||||||
",-sn -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";
|
",-sn -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;
|
||||||
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.infoLog += "☒File has title and has subs \n";
|
||||||
response.preset = ",-sn -map_metadata -1 -map 0 -c copy";
|
response.preset = ",-sn -map_metadata -1 -map 0 -c copy";
|
||||||
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.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;
|
||||||
response.FFmpegMode = true;
|
response.FFmpegMode = true;
|
||||||
return response;
|
return response;
|
||||||
} else {
|
} else {
|
||||||
response.infoLog += "☑File has no title metadata";
|
response.infoLog += "☑File has no title metadata";
|
||||||
}
|
}
|
||||||
|
|
||||||
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: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;
|
||||||
response.FFmpegMode = true;
|
response.FFmpegMode = 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";
|
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,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,
|
||||||
|
preset: "",
|
||||||
|
container: ".mp4",
|
||||||
|
handBrakeMode: false,
|
||||||
|
FFmpegMode: false,
|
||||||
|
reQueueAfter: true,
|
||||||
|
infoLog: "",
|
||||||
|
};
|
||||||
|
|
||||||
processFile : false,
|
|
||||||
preset : '',
|
|
||||||
container : '.mp4',
|
|
||||||
handBrakeMode : false,
|
|
||||||
FFmpegMode : false,
|
|
||||||
reQueueAfter : true,
|
|
||||||
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
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
|
|
||||||
if(file.hasClosedCaptions === true){
|
|
||||||
|
|
||||||
|
return response;
|
||||||
response = {
|
} else {
|
||||||
|
if (file.hasClosedCaptions === true) {
|
||||||
processFile : true,
|
response = {
|
||||||
preset : ',-map 0 -codec copy -bsf:v "filter_units=remove_types=6"',
|
processFile: true,
|
||||||
container : '.' + file.container ,
|
preset: ',-map 0 -codec copy -bsf:v "filter_units=remove_types=6"',
|
||||||
handBrakeMode : false,
|
container: "." + file.container,
|
||||||
FFmpegMode : true,
|
handBrakeMode: false,
|
||||||
reQueueAfter : true,
|
FFmpegMode: true,
|
||||||
infoLog : '☒This file has closed captions \n',
|
reQueueAfter: true,
|
||||||
|
infoLog: "☒This file has closed captions \n",
|
||||||
}
|
};
|
||||||
|
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
}else{
|
response.infoLog +=
|
||||||
|
"☑Closed captions have not been detected on this file \n";
|
||||||
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,72 +1,69 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
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",
|
||||||
Name: "Rename based on codec",
|
Name: "Rename based on codec",
|
||||||
Type: "Video",
|
Type: "Video",
|
||||||
Operation: "",
|
Operation: "",
|
||||||
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,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
|
||||||
|
|
||||||
|
try {
|
||||||
|
var audioCodec = audioEncoder;
|
||||||
|
langTag = langTag.toLowerCase();
|
||||||
|
|
||||||
|
if (audioEncoder == "dca") {
|
||||||
|
audioCodec = "dts";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (audioEncoder == "libmp3lame") {
|
||||||
|
audioCodec = "mp3";
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = function transcodeAddAudioStream(file, audioEncoder, langTag, channelCount) {
|
//Step 1: Check if the file already has the required stream codec/langtag/channel count
|
||||||
|
|
||||||
// response.preset = library.actions.transcodeAddAudioStream(file, 'aac', 'en', 1).preset
|
var hasStreamAlready = file.ffProbeData.streams.filter((stream) => {
|
||||||
|
try {
|
||||||
//Function required responses
|
if (
|
||||||
// preset
|
stream.codec_type == "audio" &&
|
||||||
// processFile
|
stream.codec_name === audioCodec &&
|
||||||
// note
|
stream.tags.language.toLowerCase().includes(langTag.toLowerCase()) &&
|
||||||
|
stream.channels == channelCount
|
||||||
try {
|
) {
|
||||||
|
return true;
|
||||||
var audioCodec = audioEncoder
|
|
||||||
langTag = langTag.toLowerCase()
|
|
||||||
|
|
||||||
if (audioEncoder == 'dca') {
|
|
||||||
audioCodec = 'dts'
|
|
||||||
}
|
|
||||||
|
|
||||||
if (audioEncoder == 'libmp3lame') {
|
|
||||||
audioCodec = 'mp3'
|
|
||||||
}
|
}
|
||||||
|
} 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 => {
|
if (hasStreamAlready.length > 0) {
|
||||||
|
return {
|
||||||
try {
|
preset: "",
|
||||||
if (stream.codec_type == 'audio' && stream.codec_name === audioCodec && stream.tags.language.toLowerCase().includes(langTag.toLowerCase()) && stream.channels == channelCount) {
|
processFile: false,
|
||||||
return true
|
note: `File already has ${langTag} stream in ${audioEncoder}, ${channelCount} channels\n`,
|
||||||
}
|
};
|
||||||
|
}
|
||||||
} catch (err) { }
|
|
||||||
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
if (hasStreamAlready.length > 0) {
|
//Step 2: Check if file has streams with specified lang tag
|
||||||
|
|
||||||
return {
|
var streamsWithLangTag = file.ffProbeData.streams.filter((stream) => {
|
||||||
preset: '',
|
try {
|
||||||
processFile: false,
|
if (
|
||||||
note: `File already has ${langTag} stream in ${audioEncoder}, ${channelCount} channels\n`
|
stream.codec_type == "audio" &&
|
||||||
}
|
stream.tags.language.toLowerCase().includes(langTag)
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
//Step 2: Check if file has streams with specified lang tag
|
console.log("streamsWithLangTag:" + streamsWithLangTag);
|
||||||
|
|
||||||
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
|
if (streamsWithLangTag.length != 0) {
|
||||||
|
return attemptMakeStreamLang(langTag);
|
||||||
})
|
} else {
|
||||||
|
return attemptMakeStreamUnd("und");
|
||||||
console.log("streamsWithLangTag:" + streamsWithLangTag)
|
}
|
||||||
|
|
||||||
if (streamsWithLangTag.length != 0) {
|
|
||||||
|
|
||||||
return attemptMakeStreamLang(langTag)
|
|
||||||
|
|
||||||
|
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 {
|
} else {
|
||||||
|
return second;
|
||||||
return attemptMakeStreamUnd('und')
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function attemptMakeStreamLang(langTag) {
|
if (parseInt(highestChannelCount.channels) >= parseInt(channelCount)) {
|
||||||
|
var hasStreamAlready = file.ffProbeData.streams.filter((stream) => {
|
||||||
|
try {
|
||||||
var streamsWithLangTag = file.ffProbeData.streams.filter(stream => {
|
if (
|
||||||
try {
|
stream.codec_type == "audio" &&
|
||||||
if (stream.codec_type == 'audio' && stream.tags.language.toLowerCase().includes(langTag)) {
|
stream.codec_name === audioCodec &&
|
||||||
|
stream.tags.language
|
||||||
return true
|
.toLowerCase()
|
||||||
}
|
.includes(langTag.toLowerCase()) &&
|
||||||
|
stream.channels == channelCount
|
||||||
} catch (err) { }
|
) {
|
||||||
|
return true;
|
||||||
return false
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
var highestChannelCount = streamsWithLangTag.reduce(getHighest)
|
|
||||||
|
|
||||||
function getHighest(first, second) {
|
|
||||||
if (first.channels > second.channels && first) {
|
|
||||||
return first
|
|
||||||
} else {
|
|
||||||
return second
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasStreamAlready.length > 0) {
|
||||||
if (parseInt(highestChannelCount.channels) >= parseInt(channelCount)) {
|
return {
|
||||||
|
preset: "",
|
||||||
var hasStreamAlready = file.ffProbeData.streams.filter(stream => {
|
processFile: false,
|
||||||
|
note: `File already has ${langTag} stream in ${audioEncoder}, ${channelCount} channels \n`,
|
||||||
try {
|
};
|
||||||
if (stream.codec_type == 'audio' && stream.codec_name === audioCodec && stream.tags.language.toLowerCase().includes(langTag.toLowerCase()) && stream.channels == channelCount) {
|
} else {
|
||||||
return true
|
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,
|
||||||
} catch (err) { }
|
note: `The required channel count ${channelCount} is lower than the highest available channel count (${highestChannelCount.channels}). Adding! \n`,
|
||||||
|
};
|
||||||
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`
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
console.log("here3");
|
||||||
function attemptMakeStreamUnd(langTag) {
|
|
||||||
|
var hasStreamAlready = file.ffProbeData.streams.filter((stream) => {
|
||||||
console.log('No tracks with specified lang tag exist. Checking undefined tracks.')
|
try {
|
||||||
|
if (
|
||||||
console.log(langTag)
|
stream.codec_type == "audio" &&
|
||||||
|
stream.codec_name === audioCodec &&
|
||||||
var streamsWithLangTag = file.ffProbeData.streams.filter(stream => {
|
stream.tags.language
|
||||||
|
.toLowerCase()
|
||||||
try {
|
.includes(langTag.toLowerCase()) &&
|
||||||
if (stream.codec_type == 'audio' && (stream.tags == undefined || stream.tags.language == undefined || stream.tags.language.toLowerCase().includes(langTag))) {
|
stream.channels == highestChannelCount.channels
|
||||||
|
) {
|
||||||
return true
|
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`
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
var highestChannelCount = streamsWithLangTag.reduce(getHighest)
|
return false;
|
||||||
|
});
|
||||||
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`
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
if (hasStreamAlready.length > 0) {
|
||||||
|
return {
|
||||||
} else {
|
preset: "",
|
||||||
|
processFile: false,
|
||||||
|
note: `File already has ${langTag} stream in ${audioEncoder}, ${highestChannelCount.channels} channels (Highest available) \n`,
|
||||||
|
};
|
||||||
var hasStreamAlready = file.ffProbeData.streams.filter(stream => {
|
} else {
|
||||||
|
return {
|
||||||
try {
|
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}`,
|
||||||
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) {
|
processFile: true,
|
||||||
return 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 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;
|
||||||
|
});
|
||||||
|
|
||||||
} catch (err) {
|
if (hasStreamAlready.length > 0) {
|
||||||
|
return {
|
||||||
return {
|
preset: "",
|
||||||
preset: '',
|
|
||||||
processFile: false,
|
processFile: false,
|
||||||
note: `library.actions.transcodeAddAudioStream error: ${err} \n`
|
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
|
||||||
|
|
||||||
|
try {
|
||||||
|
var audioCodec = audioEncoder;
|
||||||
|
langTag = langTag.toLowerCase();
|
||||||
|
|
||||||
|
if (audioEncoder == "dca") {
|
||||||
|
audioCodec = "dts";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (audioEncoder == "libmp3lame") {
|
||||||
|
audioCodec = "mp3";
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = function transcodeKeepOneAudioStream(file, audioEncoder, langTag, channelCount) {
|
var reqLang = langTag;
|
||||||
|
|
||||||
// response.preset = library.actions.transcodeKeepOneAudioStream(file, 'aac', 'en', 1).preset
|
|
||||||
|
|
||||||
//Function required responses
|
|
||||||
// preset
|
|
||||||
// processFile
|
|
||||||
// note
|
|
||||||
|
|
||||||
try {
|
var numberOfAudioStreams = file.ffProbeData.streams.filter(
|
||||||
|
(stream) => stream.codec_type == "audio"
|
||||||
|
).length;
|
||||||
|
|
||||||
var audioCodec = audioEncoder
|
//Step 1: Check if the file already has the required stream codec/langtag/channel count
|
||||||
langTag = langTag.toLowerCase()
|
|
||||||
|
|
||||||
if (audioEncoder == 'dca') {
|
var hasStreamAlready = file.ffProbeData.streams.filter((stream) => {
|
||||||
audioCodec = 'dts'
|
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: `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`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (audioEncoder == 'libmp3lame') {
|
//Step 2: Check if file has streams with specified lang tag
|
||||||
audioCodec = 'mp3'
|
|
||||||
}
|
|
||||||
|
|
||||||
var reqLang = langTag
|
|
||||||
|
|
||||||
var numberOfAudioStreams = file.ffProbeData.streams.filter(stream => stream.codec_type == 'audio').length
|
|
||||||
|
|
||||||
|
|
||||||
//Step 1: Check if the file already has the required stream codec/langtag/channel count
|
|
||||||
|
|
||||||
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) { }
|
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;
|
||||||
})
|
});
|
||||||
|
|
||||||
if (numberOfAudioStreams == 1 && hasStreamAlready.length == 1) {
|
|
||||||
|
|
||||||
|
console.log("streamsWithLangTag:" + streamsWithLangTag);
|
||||||
|
|
||||||
|
if (streamsWithLangTag.length != 0) {
|
||||||
|
return attemptMakeStreamLang(langTag);
|
||||||
|
} else {
|
||||||
|
return attemptMakeStreamUnd("und");
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
function attemptMakeStreamLang(langTag) {
|
||||||
preset: '',
|
var streamsWithLangTag = file.ffProbeData.streams.filter((stream) => {
|
||||||
processFile: false,
|
try {
|
||||||
note: `File already has ${langTag} stream in ${audioEncoder}, ${channelCount} channels. It is the only track! \n`
|
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) {
|
} else if (hasStreamAlready.length >= 1) {
|
||||||
|
return {
|
||||||
var audioStreamToKeep = hasStreamAlready[0].index
|
preset: `,-map 0:v -map 0:${hasStreamAlready[0].index} -map 0:s? -map 0:d? -c copy`,
|
||||||
var ffmpegCommandInsert = ''
|
processFile: true,
|
||||||
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
note: `The required stream already exists. Removing others. \n`,
|
||||||
|
};
|
||||||
try {
|
} else {
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" && i !== audioStreamToKeep) {
|
return {
|
||||||
ffmpegCommandInsert += ` -map -0:${i}`
|
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`,
|
||||||
} catch (err) { }
|
};
|
||||||
|
}
|
||||||
|
} 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 {
|
return false;
|
||||||
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`
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
//Step 2: Check if file has streams with specified lang tag
|
var highestChannelCount = streamsWithLangTag.reduce(getHighest);
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
function getHighest(first, second) {
|
||||||
|
if (first.channels > second.channels && first) {
|
||||||
|
return first;
|
||||||
} else {
|
} else {
|
||||||
|
return second;
|
||||||
return attemptMakeStreamUnd('und')
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function attemptMakeStreamLang(langTag) {
|
if (parseInt(highestChannelCount.channels) >= parseInt(channelCount)) {
|
||||||
|
var hasStreamAlready = file.ffProbeData.streams.filter((stream) => {
|
||||||
|
try {
|
||||||
var streamsWithLangTag = file.ffProbeData.streams.filter(stream => {
|
if (
|
||||||
try {
|
stream.codec_type == "audio" &&
|
||||||
if (stream.codec_type == 'audio' && stream.tags.language.toLowerCase().includes(langTag)) {
|
stream.codec_name === audioCodec &&
|
||||||
|
(stream.tags == undefined ||
|
||||||
return true
|
stream.tags.language == undefined ||
|
||||||
}
|
stream.tags.language.toLowerCase().includes(langTag)) &&
|
||||||
|
stream.channels == channelCount
|
||||||
} catch (err) { }
|
) {
|
||||||
|
return true;
|
||||||
return false
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
var highestChannelCount = streamsWithLangTag.reduce(getHighest)
|
|
||||||
|
|
||||||
function getHighest(first, second) {
|
|
||||||
if (first.channels > second.channels && first) {
|
|
||||||
return first
|
|
||||||
} else {
|
|
||||||
return second
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (numberOfAudioStreams == 1 && hasStreamAlready.length == 1) {
|
||||||
if (parseInt(highestChannelCount.channels) >= parseInt(channelCount)) {
|
return {
|
||||||
|
preset: "",
|
||||||
var hasStreamAlready = file.ffProbeData.streams.filter(stream => {
|
processFile: false,
|
||||||
|
note: `No ${reqLang} streams. The required und stream already exists. It is the only audio stream. \n`,
|
||||||
try {
|
};
|
||||||
if (stream.codec_type == 'audio' && stream.codec_name === audioCodec && stream.tags.language.toLowerCase().includes(langTag.toLowerCase()) && stream.channels == channelCount) {
|
} else if (hasStreamAlready.length >= 1) {
|
||||||
return true
|
return {
|
||||||
}
|
preset: `,-map 0:v -map 0:${hasStreamAlready[0].index} -map 0:s? -map 0:d? -c copy`,
|
||||||
|
processFile: true,
|
||||||
} catch (err) { }
|
note: `No ${reqLang} streams. The required und stream already exists. Removing others. \n`,
|
||||||
|
};
|
||||||
return false
|
} else {
|
||||||
})
|
return {
|
||||||
|
preset: `,-map 0:v -map 0:${highestChannelCount.index} -map 0:s? -map 0:d? -c copy -c:a:0 ${audioEncoder} -ac ${channelCount}`,
|
||||||
if (numberOfAudioStreams == 1 && hasStreamAlready.length == 1) {
|
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`,
|
||||||
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`
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
var hasStreamAlready = file.ffProbeData.streams.filter((stream) => {
|
||||||
function attemptMakeStreamUnd(langTag) {
|
try {
|
||||||
|
if (
|
||||||
console.log('No tracks with specified lang tag exist. Checking undefined tracks.')
|
stream.codec_type == "audio" &&
|
||||||
|
stream.codec_name === audioCodec &&
|
||||||
console.log(langTag)
|
(stream.tags == undefined ||
|
||||||
|
stream.tags.language == undefined ||
|
||||||
var streamsWithLangTag = file.ffProbeData.streams.filter(stream => {
|
stream.tags.language.toLowerCase().includes(langTag)) &&
|
||||||
|
stream.channels == highestChannelCount.channels
|
||||||
try {
|
) {
|
||||||
if (stream.codec_type == 'audio' && (stream.tags == undefined || stream.tags.language == undefined || stream.tags.language.toLowerCase().includes(langTag))) {
|
return true;
|
||||||
|
|
||||||
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 false;
|
||||||
|
});
|
||||||
|
|
||||||
} catch (err) {
|
if (numberOfAudioStreams == 1 && hasStreamAlready.length == 1) {
|
||||||
|
return {
|
||||||
return {
|
preset: "",
|
||||||
preset: '',
|
|
||||||
processFile: false,
|
processFile: false,
|
||||||
note: `library.actions.transcodeKeepOneAudioStream error: ${err} \n`
|
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;
|
||||||
|
|
||||||
|
if (audioEncoder == "dca") {
|
||||||
|
audioCodec = "dts";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (audioEncoder == "libmp3lame") {
|
||||||
|
audioCodec = "mp3";
|
||||||
|
}
|
||||||
|
|
||||||
//Function required responses
|
for (var i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
// preset
|
try {
|
||||||
// processFile
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio") {
|
||||||
// note
|
audioIdx++;
|
||||||
|
|
||||||
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) {}
|
||||||
|
|
||||||
|
try {
|
||||||
} catch (err) {
|
if (
|
||||||
|
file.ffProbeData.streams[i].codec_type.toLowerCase() == "audio" &&
|
||||||
return {
|
file.ffProbeData.streams[i].codec_name != audioCodec
|
||||||
preset: '',
|
) {
|
||||||
processFile: false,
|
ffmpegCommandInsert += ` -c:a:${audioIdx} ${audioEncoder}`;
|
||||||
note: `library.actions.transcodeStandardiseAudioCodecs error: ${err} \n`
|
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 {
|
||||||
try {
|
var timeNow = new Date();
|
||||||
|
var dateCreated = new Date(file.statSync.birthtime);
|
||||||
var timeNow = new Date()
|
var fileAge = Math.round((timeNow - dateCreated) / 1000);
|
||||||
var dateCreated = new Date(file.statSync.birthtime)
|
|
||||||
var fileAge = Math.round((timeNow - dateCreated) / 1000)
|
if (fileAge > ageCutOff_Seconds) {
|
||||||
|
var response = {
|
||||||
|
outcome: false,
|
||||||
if (fileAge > ageCutOff_Seconds) {
|
note: `☒File creation date is older than specified requirement. \n`,
|
||||||
|
};
|
||||||
var response = {
|
return response;
|
||||||
outcome: false,
|
} else {
|
||||||
note: `☒File creation date is older than specified requirement. \n`
|
var response = {
|
||||||
}
|
outcome: true,
|
||||||
return response
|
note: `☑File creation date is within specified requirement. \n`,
|
||||||
|
};
|
||||||
} else {
|
return response;
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
var allCodecs = file.ffProbeData.streams.map(row => row.codec_name)
|
|
||||||
|
|
||||||
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') {
|
for (var i = 0; i < allCodecs.length; i++) {
|
||||||
|
if (codecs.toLowerCase().includes(allCodecs[i])) {
|
||||||
if (included) {
|
included = true;
|
||||||
|
}
|
||||||
var response = {
|
}
|
||||||
outcome: false,
|
|
||||||
note: `☒Codec excluded \n`
|
|
||||||
}
|
|
||||||
return response
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
var response = {
|
|
||||||
outcome: true,
|
|
||||||
note: `☑Codec not excluded \n`
|
|
||||||
}
|
|
||||||
return response
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (mode === "include") {
|
||||||
|
if (included) {
|
||||||
var response = {
|
var response = {
|
||||||
outcome: false,
|
outcome: true,
|
||||||
note: `library.filters.filterByCodec error: ${err} \n`
|
note: `☑Codec included \n`,
|
||||||
}
|
};
|
||||||
return response
|
return response;
|
||||||
|
} else {
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
|
|
||||||
console.log(err)
|
|
||||||
var response = {
|
var response = {
|
||||||
outcome: false,
|
outcome: false,
|
||||||
note: `Filter error hello! ${err}\n`
|
note: `☒Codec excluded \n`,
|
||||||
}
|
};
|
||||||
return response
|
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,
|
||||||
var response = {
|
note: `☒File is in excluded resolution. \n`,
|
||||||
outcome: false,
|
};
|
||||||
note: `☒File is in excluded resolution. \n`
|
return response;
|
||||||
}
|
} else {
|
||||||
return response
|
var response = {
|
||||||
|
outcome: true,
|
||||||
} else {
|
note: `☑File is not in excluded resolution. \n`,
|
||||||
|
};
|
||||||
var response = {
|
return response;
|
||||||
outcome: true,
|
}
|
||||||
note: `☑File is not in excluded resolution. \n`
|
} else if (mode === "include") {
|
||||||
}
|
if (
|
||||||
return response
|
resolution.toLowerCase().includes(file.video_resolution.toLowerCase())
|
||||||
|
) {
|
||||||
}
|
|
||||||
|
|
||||||
} 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: true,
|
||||||
note: `library.filters.filterByResolution error: ${err} \n`
|
note: `☑File is in included resolution. \n`,
|
||||||
}
|
};
|
||||||
return response
|
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…
Reference in new issue