mirror of
https://github.com/gabehf/Tdarr_Plugins.git
synced 2026-03-14 09:45:55 -07:00
Merge branch 'master' into patch-1
This commit is contained in:
commit
67e4f71b43
12 changed files with 358 additions and 281 deletions
|
|
@ -1,5 +1,10 @@
|
||||||
/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */
|
/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
/* eslint max-len: 0 */
|
||||||
|
/* eslint no-bitwise: 0 */
|
||||||
|
/* eslint no-mixed-operators: 0 */
|
||||||
|
|
||||||
|
const os = require('os');
|
||||||
function details() {
|
function details() {
|
||||||
return {
|
return {
|
||||||
id: 'Tdarr_Plugin_ER01_Transcode audio and video with HW (PC and Mac)',
|
id: 'Tdarr_Plugin_ER01_Transcode audio and video with HW (PC and Mac)',
|
||||||
|
|
@ -8,10 +13,10 @@ function details() {
|
||||||
Type: 'Video',
|
Type: 'Video',
|
||||||
Operation: 'Transcode',
|
Operation: 'Transcode',
|
||||||
Description: `Files not in H265 will be transcoded into H265 using hw with ffmpeg, assuming mkv container. Plugin uses QS if the node runs on a PC, or Videotoolbox if run on a Mac.
|
Description: `Files not in H265 will be transcoded into H265 using hw with ffmpeg, assuming mkv container. Plugin uses QS if the node runs on a PC, or Videotoolbox if run on a Mac.
|
||||||
Much thanks to Migz for bulk of the important code.
|
Much thanks to Migz for bulk of the important code.
|
||||||
Quality is controlled via bitrate adjustments - H264 to H265 assumes 0.5x bitrate. Resolution change from 1080p to 720p assumes 0.7x bitrate.
|
Quality is controlled via bitrate adjustments - H264 to H265 assumes 0.5x bitrate. Resolution change from 1080p to 720p assumes 0.7x bitrate.
|
||||||
Audio conversion is either 2 channel ac3 or 6 channel ac3, for maximal compatibility and small file size. All subtitles removed.
|
Audio conversion is either 2 channel ac3 or 6 channel ac3, for maximal compatibility and small file size. All subtitles removed.
|
||||||
The idea is to homogenize your collection to 1080p or higher movies with 5.1 audio, or 720p TV shows with 2.0 audio.`,
|
The idea is to homogenize your collection to 1080p or higher movies with 5.1 audio, or 720p TV shows with 2.0 audio.`,
|
||||||
|
|
||||||
Tags: 'pre-processing,ffmpeg,video only,configurable,h265',
|
Tags: 'pre-processing,ffmpeg,video only,configurable,h265',
|
||||||
Inputs: [{
|
Inputs: [{
|
||||||
|
|
@ -33,7 +38,7 @@ function details() {
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
no`,
|
no`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'bitrate_cutoff',
|
name: 'bitrate_cutoff',
|
||||||
tooltip: `Specify bitrate cutoff, files with a current bitrate lower then this will not be transcoded.
|
tooltip: `Specify bitrate cutoff, files with a current bitrate lower then this will not be transcoded.
|
||||||
\\n Rate is in kbps.
|
\\n Rate is in kbps.
|
||||||
|
|
@ -80,23 +85,20 @@ function plugin(file, librarySettings, inputs) {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
const os = require('os');
|
// VIDEO SECTION
|
||||||
|
|
||||||
|
let bitRateMultiplier = 1.00;
|
||||||
|
let videoIdx = -1;
|
||||||
|
let willBeResized = false;
|
||||||
|
let videoOptions = '-map 0:v -c:v copy ';
|
||||||
|
|
||||||
// VIDEO SECTION
|
// video options
|
||||||
|
// hevc, 1080, false - do nothing
|
||||||
let bitRateMultiplier = 1.00;
|
// hevc, not 1080 - do nothing
|
||||||
let videoIdx = -1;
|
// hevc, 1080, true - resize, mult 0.5
|
||||||
let willBeResized = false;
|
// not hevc, 1080, true - resize, mult 0.25
|
||||||
let videoOptions = `-map 0:v -c:v copy `;
|
// not hevc, 1080, false - no resize, mult 0.5
|
||||||
|
// not hevc, not 1080 - no resize, mult 0.5
|
||||||
// video options
|
|
||||||
// hevc, 1080, false - do nothing
|
|
||||||
// hevc, not 1080 - do nothing
|
|
||||||
// hevc, 1080, true - resize, mult 0.5
|
|
||||||
// not hevc, 1080, true - resize, mult 0.25
|
|
||||||
// not hevc, 1080, false - no resize, mult 0.5
|
|
||||||
// not hevc, not 1080 - no resize, mult 0.5
|
|
||||||
|
|
||||||
// Go through each stream in the file.
|
// Go through each stream in the file.
|
||||||
for (let i = 0; i < file.ffProbeData.streams.length; i++) {
|
for (let i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
|
|
@ -104,44 +106,50 @@ let videoOptions = `-map 0:v -c:v copy `;
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() === 'video') {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() === 'video') {
|
||||||
// Check if codec of stream is mjpeg/png. If so then remove this "video" stream.
|
// Check if codec of stream is mjpeg/png. If so then remove this "video" stream.
|
||||||
// mjpeg/png are usually embedded pictures that can cause havoc with plugins.
|
// mjpeg/png are usually embedded pictures that can cause havoc with plugins.
|
||||||
if (file.ffProbeData.streams[i].codec_name === 'mjpeg' || file.ffProbeData.streams[i].codec_name === 'png' ) {
|
if (file.ffProbeData.streams[i].codec_name === 'mjpeg' || file.ffProbeData.streams[i].codec_name === 'png') {
|
||||||
extraArguments += `-map -v:${videoIdx} `;
|
extraArguments += `-map -v:${videoIdx} `;
|
||||||
convertVideo = true; }
|
convertVideo = true;
|
||||||
/* // no video conversion if: hevc, 1080, false OR hevc, not 1080
|
}
|
||||||
|
/* // no video conversion if: hevc, 1080, false OR hevc, not 1080
|
||||||
if (file.ffProbeData.streams[i].codec_name === 'hevc'
|
if (file.ffProbeData.streams[i].codec_name === 'hevc'
|
||||||
&& ((file.video_resolution === '1080p' && inputs.resize === 'no' ) || (file.video_resolution !== '1080p' ))) {
|
&& ((file.video_resolution === '1080p' && inputs.resize === 'no' ) || (file.video_resolution !== '1080p' ))) {
|
||||||
convertVideo = false; } */
|
convertVideo = false; } */
|
||||||
// no video conversion if: hevc, 1080, false
|
// no video conversion if: hevc, 1080, false
|
||||||
if (file.ffProbeData.streams[i].codec_name === 'hevc' && file.ffProbeData.streams[i].width > 1800 && file.ffProbeData.streams[i].width < 2000 && inputs.resize === 'no' ) {
|
if (file.ffProbeData.streams[i].codec_name === 'hevc' && file.ffProbeData.streams[i].width > 1800 && file.ffProbeData.streams[i].width < 2000 && inputs.resize === 'no') {
|
||||||
convertVideo = false; }
|
convertVideo = false;
|
||||||
|
}
|
||||||
// no video conversion if: hevc, not 1080
|
// no video conversion if: hevc, not 1080
|
||||||
if (file.ffProbeData.streams[i].codec_name === 'hevc' && (file.ffProbeData.streams[i].width < 1800 || file.ffProbeData.streams[i].width > 2000)) {
|
if (file.ffProbeData.streams[i].codec_name === 'hevc' && (file.ffProbeData.streams[i].width < 1800 || file.ffProbeData.streams[i].width > 2000)) {
|
||||||
convertVideo = false; }
|
convertVideo = false;
|
||||||
// resize video if: hevc, 1080, true
|
}
|
||||||
if (file.ffProbeData.streams[i].codec_name === 'hevc' && file.ffProbeData.streams[i].width > 1800 && file.ffProbeData.streams[i].width < 2000 && inputs.resize === 'yes' ) {
|
// resize video if: hevc, 1080, true
|
||||||
convertVideo = true;
|
if (file.ffProbeData.streams[i].codec_name === 'hevc' && file.ffProbeData.streams[i].width > 1800 && file.ffProbeData.streams[i].width < 2000 && inputs.resize === 'yes') {
|
||||||
willBeResized = true;
|
convertVideo = true;
|
||||||
bitRateMultiplier = 0.7; }
|
willBeResized = true;
|
||||||
// resize video if: not hevc, 1080, true
|
bitRateMultiplier = 0.7;
|
||||||
if (file.ffProbeData.streams[i].codec_name !== 'hevc' && file.ffProbeData.streams[i].width > 1800 && file.ffProbeData.streams[i].width < 2000 && inputs.resize === 'yes' ) {
|
}
|
||||||
convertVideo = true;
|
// resize video if: not hevc, 1080, true
|
||||||
willBeResized = true;
|
if (file.ffProbeData.streams[i].codec_name !== 'hevc' && file.ffProbeData.streams[i].width > 1800 && file.ffProbeData.streams[i].width < 2000 && inputs.resize === 'yes') {
|
||||||
bitRateMultiplier = 0.4; }
|
convertVideo = true;
|
||||||
// no resize video if: not hevc, 1080, false
|
willBeResized = true;
|
||||||
if (file.ffProbeData.streams[i].codec_name !== 'hevc' && file.ffProbeData.streams[i].width > 1800 && file.ffProbeData.streams[i].width < 2000 && inputs.resize === 'no' ) {
|
bitRateMultiplier = 0.4;
|
||||||
convertVideo = true;
|
}
|
||||||
bitRateMultiplier = 0.5; }
|
// no resize video if: not hevc, 1080, false
|
||||||
// no resize video if: not hevc, not 1080
|
if (file.ffProbeData.streams[i].codec_name !== 'hevc' && file.ffProbeData.streams[i].width > 1800 && file.ffProbeData.streams[i].width < 2000 && inputs.resize === 'no') {
|
||||||
if (file.ffProbeData.streams[i].codec_name !== 'hevc' && file.ffProbeData.streams[i].width < 1800 ) {
|
convertVideo = true;
|
||||||
convertVideo = true;
|
bitRateMultiplier = 0.5;
|
||||||
bitRateMultiplier = 0.5; }
|
}
|
||||||
|
// no resize video if: not hevc, not 1080
|
||||||
|
if (file.ffProbeData.streams[i].codec_name !== 'hevc' && file.ffProbeData.streams[i].width < 1800) {
|
||||||
|
convertVideo = true;
|
||||||
|
bitRateMultiplier = 0.5;
|
||||||
}
|
}
|
||||||
// Increment videoIdx.
|
|
||||||
videoIdx += 1;
|
|
||||||
}
|
}
|
||||||
|
// Increment videoIdx.
|
||||||
|
videoIdx += 1;
|
||||||
|
}
|
||||||
|
|
||||||
// figure out final bitrate
|
// figure out final bitrate
|
||||||
// Check if duration info is filled, if so times it by 0.0166667 to get time in minutes.
|
// 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 not filled then get duration of stream 0 and do the same.
|
||||||
if (typeof file.meta.Duration !== 'undefined') {
|
if (typeof file.meta.Duration !== 'undefined') {
|
||||||
|
|
@ -170,20 +178,20 @@ let videoOptions = `-map 0:v -c:v copy `;
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if inputs.bitrate cutoff has something entered.
|
// Check if inputs.bitrate cutoff has something entered.
|
||||||
// (Entered means user actually wants something to happen, empty would disable this).
|
// (Entered means user actually wants something to happen, empty would disable this).
|
||||||
if (inputs.bitrate_cutoff !== '') {
|
if (inputs.bitrate_cutoff !== '') {
|
||||||
// Checks if currentBitrate is below inputs.bitrate_cutoff
|
// Checks if currentBitrate is below inputs.bitrate_cutoff
|
||||||
// If so then don't convert video.
|
// If so then don't convert video.
|
||||||
if (currentBitrate <= inputs.bitrate_cutoff) {
|
if (currentBitrate <= inputs.bitrate_cutoff) {
|
||||||
convertVideo = false; }
|
convertVideo = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AUDIO SECTION
|
||||||
|
|
||||||
// AUDIO SECTION
|
// Set up required variables.
|
||||||
|
let audioOptions = '-map 0:a -c:a copy ';
|
||||||
// Set up required variables.
|
|
||||||
let audioOptions = `-map 0:a -c:a copy `;
|
|
||||||
let audioIdx = 0;
|
let audioIdx = 0;
|
||||||
let numberofAudioChannels = 0;
|
let numberofAudioChannels = 0;
|
||||||
let has2Channels = false;
|
let has2Channels = false;
|
||||||
|
|
@ -197,7 +205,7 @@ let videoOptions = `-map 0:v -c:v copy `;
|
||||||
let type8Channels = '';
|
let type8Channels = '';
|
||||||
|
|
||||||
let keepAudioIdx = -1;
|
let keepAudioIdx = -1;
|
||||||
let keepIGuessAudioIdx = -1;
|
// const keepIGuessAudioIdx = -1;
|
||||||
let encodeAudioIdx = -1;
|
let encodeAudioIdx = -1;
|
||||||
let keepAudioStream = -1;
|
let keepAudioStream = -1;
|
||||||
let encodeAudioStream = -1;
|
let encodeAudioStream = -1;
|
||||||
|
|
@ -209,20 +217,20 @@ let videoOptions = `-map 0:v -c:v copy `;
|
||||||
// Go through all audio streams and check if 2,6 & 8 channel tracks exist or not.
|
// Go through all audio streams and check if 2,6 & 8 channel tracks exist or not.
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() === 'audio') {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() === 'audio') {
|
||||||
numberofAudioChannels += 1;
|
numberofAudioChannels += 1;
|
||||||
if (file.ffProbeData.streams[i].channels === 2 && has2Channels === false) {
|
if (file.ffProbeData.streams[i].channels === 2 && has2Channels === false) {
|
||||||
has2Channels = true;
|
has2Channels = true;
|
||||||
lang2Channels = file.ffProbeData.streams[i].tags.language.toLowerCase();
|
lang2Channels = file.ffProbeData.streams[i].tags.language.toLowerCase();
|
||||||
type2Channels = file.ffProbeData.streams[i].codec_name.toLowerCase();
|
type2Channels = file.ffProbeData.streams[i].codec_name.toLowerCase();
|
||||||
}
|
}
|
||||||
if (file.ffProbeData.streams[i].channels === 6 && has6Channels === false) {
|
if (file.ffProbeData.streams[i].channels === 6 && has6Channels === false) {
|
||||||
has6Channels = true;
|
has6Channels = true;
|
||||||
lang6Channels = file.ffProbeData.streams[i].tags.language.toLowerCase();
|
lang6Channels = file.ffProbeData.streams[i].tags.language.toLowerCase();
|
||||||
type6Channels = file.ffProbeData.streams[i].codec_name.toLowerCase();
|
type6Channels = file.ffProbeData.streams[i].codec_name.toLowerCase();
|
||||||
}
|
}
|
||||||
if (file.ffProbeData.streams[i].channels === 8 && has8Channels === false) {
|
if (file.ffProbeData.streams[i].channels === 8 && has8Channels === false) {
|
||||||
has8Channels = true;
|
has8Channels = true;
|
||||||
lang8Channels = file.ffProbeData.streams[i].tags.language.toLowerCase();
|
lang8Channels = file.ffProbeData.streams[i].tags.language.toLowerCase();
|
||||||
type8Channels = file.ffProbeData.streams[i].codec_name.toLowerCase();
|
type8Channels = file.ffProbeData.streams[i].codec_name.toLowerCase();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
@ -230,159 +238,156 @@ let videoOptions = `-map 0:v -c:v copy `;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Are we processing for 6 channels?
|
||||||
// Are we processing for 6 channels?
|
if (inputs.audio_channels === 6) {
|
||||||
if (inputs.audio_channels == 6) {
|
audioIdx = -1;
|
||||||
audioIdx = -1;
|
for (let i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
for (let i = 0; i < file.ffProbeData.streams.length; i++) {
|
try {
|
||||||
try {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() === 'audio') {
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() === 'audio') {
|
audioIdx += 1;
|
||||||
audioIdx += 1;
|
if (file.ffProbeData.streams[i].tags.language.toLowerCase() === 'eng' || file.ffProbeData.streams[i].tags.language.toLowerCase() === 'und') {
|
||||||
if (file.ffProbeData.streams[i].tags.language.toLowerCase() === 'eng' || file.ffProbeData.streams[i].tags.language.toLowerCase() === 'und') {
|
if (file.ffProbeData.streams[i].channels === 6) {
|
||||||
if (file.ffProbeData.streams[i].channels == 6 ) {
|
if (file.ffProbeData.streams[i].codec_name.toLowerCase() === 'ac3') {
|
||||||
if (file.ffProbeData.streams[i].codec_name.toLowerCase() === 'ac3') {
|
// response.infoLog += `Found 6 channel audio in proper language and codec, audio stream ${audioIdx}\n`;
|
||||||
//response.infoLog += `Found 6 channel audio in proper language and codec, audio stream ${audioIdx}\n`;
|
if (keepAudioIdx === -1) {
|
||||||
if (keepAudioIdx === -1) {
|
keepAudioIdx = audioIdx;
|
||||||
keepAudioIdx = audioIdx;
|
keepAudioStream = i;
|
||||||
keepAudioStream = i;}
|
}
|
||||||
} else {
|
} else if (encodeAudioIdx === -1) {
|
||||||
//response.infoLog += `Found 6 channel audio in proper language, need to re-encode, audio stream ${audioIdx}\n`;
|
// response.infoLog += `Found 6 channel audio in proper language, need to re-encode, audio stream ${audioIdx}\n`;
|
||||||
if (encodeAudioIdx === -1) {
|
encodeAudioIdx = audioIdx;
|
||||||
encodeAudioIdx = audioIdx;
|
encodeAudioStream = i;
|
||||||
encodeAudioStream = i;}
|
}
|
||||||
}}
|
}
|
||||||
if (file.ffProbeData.streams[i].channels > 6 ) {
|
if (file.ffProbeData.streams[i].channels > 6) {
|
||||||
//response.infoLog += `Found existing multi-channel audio in proper language, need to re-encode, audio stream ${audioIdx}\n`;
|
// response.infoLog += `Found existing multi-channel audio in proper language, need to re-encode, audio stream ${audioIdx}\n`;
|
||||||
if (encodeAudioIdx === -1) {
|
if (encodeAudioIdx === -1) {
|
||||||
encodeAudioIdx = audioIdx;
|
encodeAudioIdx = audioIdx;
|
||||||
encodeAudioStream = i;}
|
encodeAudioStream = i;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Error
|
// Error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (keepAudioIdx === -1 && encodeAudioIdx === -1) { // didn't find any 5.1 or better audio streams in proper language, defaulting to using 2 channels
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
inputs.audio_channels = '2';
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (keepAudioIdx === -1 && encodeAudioIdx === -1) { // didn't find any 5.1 or better audio streams in proper language, defaulting to using 2 channels
|
|
||||||
inputs.audio_channels = '2';}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Are we processing for 2 channels?
|
||||||
// Are we processing for 2 channels?
|
if (inputs.audio_channels === 2) {
|
||||||
if (inputs.audio_channels == 2) {
|
audioIdx = -1;
|
||||||
audioIdx = -1;
|
for (let i = 0; i < file.ffProbeData.streams.length; i++) {
|
||||||
for (let i = 0; i < file.ffProbeData.streams.length; i++) {
|
try {
|
||||||
try {
|
if (file.ffProbeData.streams[i].codec_type.toLowerCase() === 'audio') {
|
||||||
if (file.ffProbeData.streams[i].codec_type.toLowerCase() === 'audio') {
|
audioIdx += 1;
|
||||||
audioIdx += 1;
|
if (file.ffProbeData.streams[i].tags.language.toLowerCase() === 'eng' || file.ffProbeData.streams[i].tags.language.toLowerCase() === 'und') {
|
||||||
if (file.ffProbeData.streams[i].tags.language.toLowerCase() === 'eng' || file.ffProbeData.streams[i].tags.language.toLowerCase() === 'und') {
|
if (file.ffProbeData.streams[i].channels === 2) {
|
||||||
if (file.ffProbeData.streams[i].channels == 2 ) {
|
if (file.ffProbeData.streams[i].codec_name.toLowerCase() === 'aac' || file.ffProbeData.streams[i].codec_name.toLowerCase() === 'ac3') {
|
||||||
if (file.ffProbeData.streams[i].codec_name.toLowerCase() === 'aac' || file.ffProbeData.streams[i].codec_name.toLowerCase() === 'ac3') {
|
// response.infoLog += `Found 2 channel audio in proper language and codec, audio stream ${audioIdx}\n`;
|
||||||
//response.infoLog += `Found 2 channel audio in proper language and codec, audio stream ${audioIdx}\n`;
|
if (keepAudioIdx === -1) {
|
||||||
if (keepAudioIdx === -1) {
|
keepAudioIdx = audioIdx;
|
||||||
keepAudioIdx = audioIdx;
|
keepAudioStream = i;
|
||||||
keepAudioStream = i;}
|
}
|
||||||
} else {
|
} else if (encodeAudioIdx === -1) {
|
||||||
//response.infoLog += `Found 2 channel audio in proper language, need to re-encode, audio stream ${audioIdx}\n`;
|
// response.infoLog += `Found 2 channel audio in proper language, need to re-encode, audio stream ${audioIdx}\n`;
|
||||||
if (encodeAudioIdx === -1) {
|
encodeAudioIdx = audioIdx;
|
||||||
encodeAudioIdx = audioIdx;
|
encodeAudioStream = i;
|
||||||
encodeAudioStream = i;}
|
}
|
||||||
}
|
} else if (encodeAudioIdx === -1) {
|
||||||
} else {
|
// response.infoLog += `Found existing multi-channel audio in proper language, need to re-encode, audio stream ${audioIdx}\n`;
|
||||||
//response.infoLog += `Found existing multi-channel audio in proper language, need to re-encode, audio stream ${audioIdx}\n`;
|
encodeAudioIdx = audioIdx;
|
||||||
if (encodeAudioIdx === -1) {
|
encodeAudioStream = i;
|
||||||
encodeAudioIdx = audioIdx;
|
}
|
||||||
encodeAudioStream = i;}
|
}
|
||||||
}
|
// response.infoLog += `a ${audioIdx}. k ${keepAudioIdx}. e ${encodeAudioIdx}\n `;
|
||||||
}
|
}
|
||||||
// response.infoLog += `a ${audioIdx}. k ${keepAudioIdx}. e ${encodeAudioIdx}\n `;
|
} catch (err) {
|
||||||
}
|
// Error
|
||||||
} catch (err) {
|
}
|
||||||
// Error
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let audioMessage = '';
|
let audioMessage = '';
|
||||||
|
|
||||||
// selecting channels to keep, only if 2 or 6 channels processed
|
// selecting channels to keep, only if 2 or 6 channels processed
|
||||||
|
|
||||||
if (keepAudioIdx !== -1) {
|
if (keepAudioIdx !== -1) {
|
||||||
//keep audio, exclude everything else
|
// keep audio, exclude everything else
|
||||||
if (numberofAudioChannels !== 1) {
|
if (numberofAudioChannels !== 1) {
|
||||||
convertAudio = true;
|
convertAudio = true;
|
||||||
audioMessage += `keeping audio stream ${keepAudioIdx}.`;
|
audioMessage += `keeping audio stream ${keepAudioIdx}.`;
|
||||||
audioOptions = `-map 0:a:${keepAudioIdx} -c:a copy `;
|
audioOptions = `-map 0:a:${keepAudioIdx} -c:a copy `;
|
||||||
originalAudio += `${file.ffProbeData.streams[keepAudioStream].channels} channel ${file.ffProbeData.streams[keepAudioStream].codec_name} --> ${inputs.audio_channels} channel ac3`;}
|
originalAudio += `${file.ffProbeData.streams[keepAudioStream].channels} channel ${file.ffProbeData.streams[keepAudioStream].codec_name} --> ${inputs.audio_channels} channel ac3`;
|
||||||
|
}
|
||||||
|
} else if (encodeAudioIdx !== -1) {
|
||||||
|
// encode this audio
|
||||||
|
convertAudio = true;
|
||||||
|
audioMessage += `encoding audio stream ${encodeAudioIdx}. `;
|
||||||
|
audioOptions = `-map 0:a:${encodeAudioIdx} -c:a ac3 -ac ${inputs.audio_channels} `; // 2 or 6 channels encoding
|
||||||
|
originalAudio += `${file.ffProbeData.streams[encodeAudioStream].channels} channel ${file.ffProbeData.streams[encodeAudioStream].codec_name} --> ${inputs.audio_channels} channel ac3`;
|
||||||
} else {
|
} else {
|
||||||
if (encodeAudioIdx !== -1) {
|
// do not encode audio
|
||||||
// encode this audio
|
convertAudio = false;
|
||||||
convertAudio = true;
|
audioMessage += 'no audio to encode.';
|
||||||
audioMessage += `encoding audio stream ${encodeAudioIdx}. `;
|
|
||||||
audioOptions = `-map 0:a:${encodeAudioIdx} -c:a ac3 -ac ${inputs.audio_channels} `; // 2 or 6 channels encoding
|
|
||||||
originalAudio += `${file.ffProbeData.streams[encodeAudioStream].channels} channel ${file.ffProbeData.streams[encodeAudioStream].codec_name} --> ${inputs.audio_channels} channel ac3`;
|
|
||||||
} else {
|
|
||||||
// do not encode audio
|
|
||||||
convertAudio = false;
|
|
||||||
audioMessage += `no audio to encode.`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test for whether the file needs to be processed - separate for video and audio convertAudio, convertVideo
|
||||||
|
|
||||||
|
|
||||||
// test for whether the file needs to be processed - separate for video and audio convertAudio, convertVideo
|
|
||||||
|
|
||||||
if (convertAudio === false && convertVideo === false) { // if nothing to do, exit
|
if (convertAudio === false && convertVideo === false) { // if nothing to do, exit
|
||||||
response.infoLog += `File is processed already, nothing to do`;
|
response.infoLog += 'File is processed already, nothing to do';
|
||||||
response.processFile = false;
|
response.processFile = false;
|
||||||
return response; }
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
// Generate ffmpeg command line arguments in total
|
// Generate ffmpeg command line arguments in total
|
||||||
|
|
||||||
// few defaults
|
// few defaults
|
||||||
|
|
||||||
response.preset = `, -sn `;
|
response.preset = ', -sn ';
|
||||||
|
|
||||||
|
|
||||||
if (convertVideo === true) {
|
if (convertVideo === true) {
|
||||||
// Set bitrateSettings variable using bitrate information calculated earlier.
|
// Set bitrateSettings variable using bitrate information calculated earlier.
|
||||||
bitrateSettings = `-b:v ${targetBitrate}k -minrate ${minimumBitrate}k `
|
bitrateSettings = `-b:v ${targetBitrate}k -minrate ${minimumBitrate}k `
|
||||||
+ `-maxrate ${maximumBitrate}k -bufsize ${currentBitrate}k`;
|
+ `-maxrate ${maximumBitrate}k -bufsize ${currentBitrate}k`;
|
||||||
|
|
||||||
if (willBeResized === true) {
|
if (willBeResized === true) {
|
||||||
extraArguments += `-filter:v scale=1280:-1 `; }
|
extraArguments += '-filter:v scale=1280:-1 ';
|
||||||
|
}
|
||||||
|
|
||||||
if (os.platform() === 'darwin') {
|
if (os.platform() === 'darwin') {
|
||||||
videoOptions = `-map 0:v -c:v hevc_videotoolbox -profile main `;
|
videoOptions = '-map 0:v -c:v hevc_videotoolbox -profile main ';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (os.platform() === 'win32') {
|
if (os.platform() === 'win32') {
|
||||||
videoOptions = `-map 0:v -c:v hevc_qsv -load_plugin hevc_hw `;
|
videoOptions = '-map 0:v -c:v hevc_qsv -load_plugin hevc_hw ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
response.preset += `${videoOptions} ${bitrateSettings} ${extraArguments} ${audioOptions} `;
|
response.preset += `${videoOptions} ${bitrateSettings} ${extraArguments} ${audioOptions} `;
|
||||||
|
|
||||||
|
|
||||||
let outputResolution = file.video_resolution;
|
let outputResolution = file.video_resolution;
|
||||||
if (willBeResized === true) {
|
if (willBeResized === true) {
|
||||||
outputResolution = '720p';}
|
outputResolution = '720p';
|
||||||
|
}
|
||||||
|
|
||||||
if (convertVideo === false) {
|
if (convertVideo === false) {
|
||||||
response.infoLog += `NOT converting video ${file.video_resolution}, ${file.video_codec_name}, bitrate = ${currentBitrate} \n`;
|
response.infoLog += `NOT converting video ${file.video_resolution}, ${file.video_codec_name}, bitrate = ${currentBitrate} \n`;
|
||||||
} else {
|
} else {
|
||||||
response.infoLog += `Converting video, `;
|
response.infoLog += 'Converting video, ';
|
||||||
if (willBeResized === false ) { response.infoLog += `NOT `; }
|
if (willBeResized === false) { response.infoLog += 'NOT '; }
|
||||||
response.infoLog += `resizing. ${file.video_resolution}, ${file.video_codec_name} --> ${outputResolution}, hevc. bitrate = ${currentBitrate} --> ${targetBitrate}, multiplier ${bitRateMultiplier}. \n`;
|
response.infoLog += `resizing. ${file.video_resolution}, ${file.video_codec_name} --> ${outputResolution}, hevc. bitrate = ${currentBitrate} --> ${targetBitrate}, multiplier ${bitRateMultiplier}. \n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (convertAudio === true) {
|
if (convertAudio === true) {
|
||||||
response.infoLog += `Converting audio, ${audioMessage} ${originalAudio}. \n`;
|
response.infoLog += `Converting audio, ${audioMessage} ${originalAudio}. \n`;
|
||||||
} else {
|
} else {
|
||||||
response.infoLog += `Not converting audio. \n`;}
|
response.infoLog += 'Not converting audio. \n';
|
||||||
|
}
|
||||||
|
|
||||||
response.infoLog += `2 channels - ${lang2Channels} ${type2Channels} \n`;
|
response.infoLog += `2 channels - ${lang2Channels} ${type2Channels} \n`;
|
||||||
response.infoLog += `6 channels - ${lang6Channels} ${type6Channels} \n`;
|
response.infoLog += `6 channels - ${lang6Channels} ${type6Channels} \n`;
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
// If the source video is less than this rate the script will either:
|
// If the source video is less than this rate the script will either:
|
||||||
// Copy the existing stream, if the codec is hevc
|
// Copy the existing stream, if the codec is hevc
|
||||||
// Transcode the stream to hevc using 80% of the original streams bitrate
|
// Transcode the stream to hevc using 80% of the original streams bitrate
|
||||||
// It could probably be less but if the source is of low bitrate we don’t want to compromise too much on the transcode
|
// It could probably be less but if the source is of low bitrate we don<EFBFBD>t want to compromise too much on the transcode
|
||||||
//
|
//
|
||||||
// If the source media bitrate is close, within 10%, of the target bitrate and the codec is hevc, it will copy instead of transcode to preserve quality
|
// If the source media bitrate is close, within 10%, of the target bitrate and the codec is hevc, it will copy instead of transcode to preserve quality
|
||||||
//
|
//
|
||||||
|
|
@ -53,7 +53,7 @@
|
||||||
// If the source audio is less than this rate the script will either:
|
// If the source audio is less than this rate the script will either:
|
||||||
// Copy the existing stream, if the codec is aac
|
// Copy the existing stream, if the codec is aac
|
||||||
// Transcode the stream to aac using 100% of the original streams bitrate
|
// Transcode the stream to aac using 100% of the original streams bitrate
|
||||||
// It could probably be less but if the source is of low bitrate but, we don’t want to compromise too much on the transcode
|
// It could probably be less but if the source is of low bitrate but, we don<EFBFBD>t want to compromise too much on the transcode
|
||||||
//
|
//
|
||||||
// Subtitles:
|
// Subtitles:
|
||||||
// All are removed?? (TODO: ensure this is correct and mention the flag to keep them if desired)
|
// All are removed?? (TODO: ensure this is correct and mention the flag to keep them if desired)
|
||||||
|
|
@ -761,7 +761,7 @@ function findMediaInfoItem(file, index) {
|
||||||
currMIOrder = file.mediaInfo.track[i].ID - 1;
|
currMIOrder = file.mediaInfo.track[i].ID - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currMIOrder == index || currMIOrder == "0-" + index) {
|
if (currMIOrder == index|| currMIOrder == "0-" + index) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ function plugin(file, librarySettings, inputs) {
|
||||||
response.preset =
|
response.preset =
|
||||||
", -map_metadata -1 -map 0:V " +
|
", -map_metadata -1 -map 0:V " +
|
||||||
subMap +
|
subMap +
|
||||||
" -map 0:a -c:v libx264 -preset medium -c:a aac -strict -2 " +
|
" -map 0:a -c:v libx264 -preset " + preset + " -c:a aac -strict -2 " +
|
||||||
subType;
|
subType;
|
||||||
response.reQueueAfter = true;
|
response.reQueueAfter = true;
|
||||||
response.processFile = true;
|
response.processFile = true;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ const details = () => ({
|
||||||
(requires TMDB api key) and English.
|
(requires TMDB api key) and English.
|
||||||
'Native' languages are the ones that are listed on imdb. It does an API call to
|
'Native' languages are the ones that are listed on imdb. It does an API call to
|
||||||
Radarr, Sonarr to check if the movie/series exists and grabs the IMDB id. As a last resort it
|
Radarr, Sonarr to check if the movie/series exists and grabs the IMDB id. As a last resort it
|
||||||
falls back to '[imdb-ttDIGITS] in the filename.`,
|
falls back to the IMDB id in the filename.`,
|
||||||
Version: '1.00',
|
Version: '1.00',
|
||||||
Link: 'https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/'
|
Link: 'https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/'
|
||||||
+ 'Tdarr_Plugin_henk_Keep_Native_Lang_Plus_Eng.js',
|
+ 'Tdarr_Plugin_henk_Keep_Native_Lang_Plus_Eng.js',
|
||||||
|
|
@ -32,7 +32,7 @@ const details = () => ({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'api_key',
|
name: 'api_key',
|
||||||
tooltip: 'Input your TMDB api key here. (https://www.themoviedb.org/)',
|
tooltip: 'Input your TMDB api (v3) key here. (https://www.themoviedb.org/)',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'radarr_api_key',
|
name: 'radarr_api_key',
|
||||||
|
|
@ -139,7 +139,7 @@ const tmdbApi = async (filename, api_key, axios) => {
|
||||||
if (filename.substr(0, 2) === 'tt') {
|
if (filename.substr(0, 2) === 'tt') {
|
||||||
fileName = filename;
|
fileName = filename;
|
||||||
} else {
|
} else {
|
||||||
const idRegex = /\[imdb-(tt\d*)]/;
|
const idRegex = /(tt\d{7,8})/;
|
||||||
const fileMatch = filename.match(idRegex);
|
const fileMatch = filename.match(idRegex);
|
||||||
// eslint-disable-next-line prefer-destructuring
|
// eslint-disable-next-line prefer-destructuring
|
||||||
if (fileMatch) fileName = fileMatch[1];
|
if (fileMatch) fileName = fileMatch[1];
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,20 @@ function details() {
|
||||||
\\nExample:\\n
|
\\nExample:\\n
|
||||||
veryfast`,
|
veryfast`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'sdDisabled',
|
||||||
|
tooltip: `Input "true" if you want to skip SD (480p and 576p) files
|
||||||
|
|
||||||
|
\\nExample:\\n
|
||||||
|
true`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'uhdDisabled',
|
||||||
|
tooltip: `Input "true" if you want to skip 4k (UHD) files
|
||||||
|
|
||||||
|
\\nExample:\\n
|
||||||
|
true`,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -97,6 +111,22 @@ function plugin(file, librarySettings, inputs) {
|
||||||
}
|
}
|
||||||
response.infoLog += '☑File is a video! \n';
|
response.infoLog += '☑File is a video! \n';
|
||||||
|
|
||||||
|
// check if the file is SD and sdDisable is enabled
|
||||||
|
// skip this plugin if so
|
||||||
|
if (['480p', '576p'].includes(file.video_resolution) && inputs.sdDisabled) {
|
||||||
|
response.processFile = false;
|
||||||
|
response.infoLog += '☒File is SD, not processing\n';
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the file is 4k and 4kDisable is enabled
|
||||||
|
// skip this plugin if so
|
||||||
|
if (file.video_resolution === '4KUHD' && inputs.uhdDisabled) {
|
||||||
|
response.processFile = false;
|
||||||
|
response.infoLog += '☒File is 4k/UHD, not processing\n';
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
// check if the file is already hevc
|
// check if the file is already hevc
|
||||||
// it will not be transcoded if true and the plugin will be stopped immediately
|
// it will not be transcoded if true and the plugin will be stopped immediately
|
||||||
for (let i = 0; i < file.ffProbeData.streams.length; i += 1) {
|
for (let i = 0; i < file.ffProbeData.streams.length; i += 1) {
|
||||||
|
|
|
||||||
|
|
@ -1,62 +1,51 @@
|
||||||
/* eslint-disable */
|
|
||||||
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 burned closed captions',
|
||||||
Type: "Video",
|
Type: 'Video',
|
||||||
Operation: "Remux",
|
Operation: 'Remux',
|
||||||
Description:
|
Description:
|
||||||
"[Contains built-in filter] If detected, closed captions (XDS,608,708) will be removed.",
|
'[Contains built-in filter] If detected, closed captions (XDS,608,708) will be removed from streams.',
|
||||||
Version: "1.00",
|
Version: '1.01',
|
||||||
Link:
|
Link:
|
||||||
"https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_x7ac_Remove_Closed_Captions.js",
|
'https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_x7ac_Remove_Closed_Captions.js',
|
||||||
Tags: "pre-processing,ffmpeg,subtitle only",
|
Tags: 'pre-processing,ffmpeg,subtitle only',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function plugin(file) {
|
function plugin(file) {
|
||||||
//Must return this object
|
const response = {
|
||||||
|
|
||||||
var response = {
|
|
||||||
processFile: false,
|
processFile: false,
|
||||||
preset: "",
|
// eslint-disable-next-line no-useless-escape
|
||||||
container: ".mp4",
|
preset: ',-map 0 -codec copy -bsf:v \"filter_units=remove_types=6\"',
|
||||||
|
container: `.${file.container}`,
|
||||||
handBrakeMode: false,
|
handBrakeMode: false,
|
||||||
FFmpegMode: false,
|
FFmpegMode: true,
|
||||||
reQueueAfter: true,
|
reQueueAfter: true,
|
||||||
infoLog: "",
|
infoLog: '',
|
||||||
};
|
};
|
||||||
|
if (file.fileMedium !== 'video') {
|
||||||
if (file.fileMedium !== "video") {
|
response.infoLog += '☒File is not video \n';
|
||||||
console.log("File is not video");
|
|
||||||
|
|
||||||
response.infoLog += "☒File is not video \n";
|
|
||||||
response.processFile = false;
|
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
} else {
|
|
||||||
if (file.hasClosedCaptions === true) {
|
|
||||||
response = {
|
|
||||||
processFile: true,
|
|
||||||
preset: ',-map 0 -codec copy -bsf:v "filter_units=remove_types=6"',
|
|
||||||
container: "." + file.container,
|
|
||||||
handBrakeMode: false,
|
|
||||||
FFmpegMode: true,
|
|
||||||
reQueueAfter: true,
|
|
||||||
infoLog: "☒This file has closed captions \n",
|
|
||||||
};
|
|
||||||
|
|
||||||
return response;
|
|
||||||
} else {
|
|
||||||
response.infoLog +=
|
|
||||||
"☑Closed captions have not been detected on this file \n";
|
|
||||||
response.processFile = false;
|
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
// Check if Closed Captions are set at file level
|
||||||
|
if (file.hasClosedCaptions) {
|
||||||
|
response.processFile = true;
|
||||||
|
response.infoLog += '☒This file has closed captions \n';
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
// If not, check for Closed Captions in the streams
|
||||||
|
const { streams } = file.ffProbeData;
|
||||||
|
streams.forEach((stream) => {
|
||||||
|
if (stream.closed_captions) {
|
||||||
|
response.processFile = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
response.infoLog += response.processFile ? '☒This file has burnt closed captions \n'
|
||||||
|
: '☑Closed captions have not been detected on this file \n';
|
||||||
|
return response;
|
||||||
|
}
|
||||||
module.exports.details = details;
|
module.exports.details = details;
|
||||||
module.exports.plugin = plugin;
|
module.exports.plugin = plugin;
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,5 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
|
||||||
module.exports.dependencies = [
|
|
||||||
'fs-extra',
|
|
||||||
];
|
|
||||||
|
|
||||||
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",
|
||||||
|
|
@ -11,7 +7,7 @@ module.exports.details = function details() {
|
||||||
Name: "Rename based on codec",
|
Name: "Rename based on codec",
|
||||||
Type: "Video",
|
Type: "Video",
|
||||||
Operation: "",
|
Operation: "",
|
||||||
Description: `[Contains built-in filter]This plugin renames 264 files to 265 or vice versa depending on codec. \n\n`,
|
Description: `[Contains built-in filter] If the filename contains '264' or '265', 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",
|
||||||
|
|
@ -21,15 +17,6 @@ module.exports.details = function details() {
|
||||||
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");
|
|
||||||
if (fs.existsSync(path.join(process.cwd(), "/npm"))) {
|
|
||||||
var rootModules = path.join(process.cwd(), "/npm/node_modules/");
|
|
||||||
} else {
|
|
||||||
var rootModules = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
var fsextra = require(rootModules + "fs-extra");
|
|
||||||
|
|
||||||
var fileNameOld = file._id;
|
var fileNameOld = file._id;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|
@ -40,6 +27,15 @@ module.exports.plugin = function plugin(file, librarySettings, inputs) {
|
||||||
file.file = file.file.replace("264", "265");
|
file.file = file.file.replace("264", "265");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//added handling for files with AVC in the name instead of h264/x264
|
||||||
|
if (
|
||||||
|
file.ffProbeData.streams[0].codec_name == "hevc" &&
|
||||||
|
file._id.includes("AVC")
|
||||||
|
) {
|
||||||
|
file._id = file._id.replace("AVC", "HEVC");
|
||||||
|
file.file = file.file.replace("AVC", "HEVC");
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
file.ffProbeData.streams[0].codec_name == "h264" &&
|
file.ffProbeData.streams[0].codec_name == "h264" &&
|
||||||
file._id.includes("265")
|
file._id.includes("265")
|
||||||
|
|
@ -57,7 +53,7 @@ module.exports.plugin = function plugin(file, librarySettings, inputs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileNameOld != file._id) {
|
if (fileNameOld != file._id) {
|
||||||
fsextra.moveSync(fileNameOld, file._id, {
|
fs.renameSync(fileNameOld, file._id, {
|
||||||
overwrite: true,
|
overwrite: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,3 @@
|
||||||
module.exports.dependencies = [
|
|
||||||
'fs-extra',
|
|
||||||
];
|
|
||||||
|
|
||||||
module.exports.details = function details() {
|
module.exports.details = function details() {
|
||||||
return {
|
return {
|
||||||
id: 'Tdarr_Plugin_z18t_rename_files_based_on_codec_and_resolution',
|
id: 'Tdarr_Plugin_z18t_rename_files_based_on_codec_and_resolution',
|
||||||
|
|
@ -20,17 +16,6 @@ module.exports.plugin = function plugin(file) {
|
||||||
try {
|
try {
|
||||||
// eslint-disable-next-line global-require
|
// eslint-disable-next-line global-require
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
// eslint-disable-next-line global-require
|
|
||||||
const path = require('path');
|
|
||||||
let rootModules;
|
|
||||||
if (fs.existsSync(path.join(process.cwd(), '/npm'))) {
|
|
||||||
rootModules = path.join(process.cwd(), '/npm/node_modules/');
|
|
||||||
} else {
|
|
||||||
rootModules = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line global-require,import/no-dynamic-require
|
|
||||||
const fsextra = require(`${rootModules}fs-extra`);
|
|
||||||
const fileNameOld = file._id;
|
const fileNameOld = file._id;
|
||||||
|
|
||||||
const resolutions = {
|
const resolutions = {
|
||||||
|
|
@ -133,7 +118,7 @@ module.exports.plugin = function plugin(file) {
|
||||||
file.file = fileName;
|
file.file = fileName;
|
||||||
|
|
||||||
if (fileNameOld !== file._id) {
|
if (fileNameOld !== file._id) {
|
||||||
fsextra.moveSync(fileNameOld, file._id, {
|
fs.renameSync(fileNameOld, file._id, {
|
||||||
overwrite: true,
|
overwrite: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ module.exports.dependencies = [
|
||||||
module.exports.details = function details() {
|
module.exports.details = function details() {
|
||||||
return {
|
return {
|
||||||
id: 'Tdarr_Plugin_aaaa_Pre_Proc_Example',
|
id: 'Tdarr_Plugin_aaaa_Pre_Proc_Example',
|
||||||
Stage: 'Pre-processing', // Preprocessing or Post-processing. Determines when the plugin will be executed.
|
Stage: 'Pre-processing', // Pre-processing or Post-processing. Determines when the plugin will be executed.
|
||||||
Name: 'No title meta data ',
|
Name: 'No title meta data ',
|
||||||
Type: 'Video',
|
Type: 'Video',
|
||||||
Operation: 'Transcode',
|
Operation: 'Transcode',
|
||||||
|
|
|
||||||
37
examples/Tdarr_Plugin_a9he_New_file_size_check.js
Normal file
37
examples/Tdarr_Plugin_a9he_New_file_size_check.js
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
module.exports.details = function details() {
|
||||||
|
return {
|
||||||
|
id: 'Tdarr_Plugin_a9he_New_file_size_check',
|
||||||
|
Stage: 'Pre-processing',
|
||||||
|
Name: 'New file size check',
|
||||||
|
Type: 'Video',
|
||||||
|
Operation: 'Transcode',
|
||||||
|
Description: 'Give an error if new file is larger than the original \n\n',
|
||||||
|
Version: '1.00',
|
||||||
|
Link: '',
|
||||||
|
Tags: '',
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.plugin = function plugin(file, librarySettings, inputs, otherArguments) {
|
||||||
|
// Must return this object at some point in the function else plugin will fail.
|
||||||
|
const response = {
|
||||||
|
processFile: false,
|
||||||
|
preset: '',
|
||||||
|
handBrakeMode: false,
|
||||||
|
FFmpegMode: true,
|
||||||
|
reQueueAfter: true,
|
||||||
|
infoLog: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
const newSize = file.file_size;
|
||||||
|
const oldSize = otherArguments.originalLibraryFile.file_size;
|
||||||
|
if (newSize > oldSize) {
|
||||||
|
// Item will be errored in UI
|
||||||
|
throw new Error(`Error! New file has size ${newSize} which is larger than original file ${oldSize}`);
|
||||||
|
} else if (newSize < oldSize) {
|
||||||
|
response.infoLog += `New file has size ${newSize} which is smaller than original file ${oldSize}`;
|
||||||
|
}
|
||||||
|
// if file sizes are exactly the same then file has not been transcoded yet
|
||||||
|
|
||||||
|
return response;
|
||||||
|
};
|
||||||
35
examples/filters/Tdarr_Plugin_bbbc_Filter_Example.js
Normal file
35
examples/filters/Tdarr_Plugin_bbbc_Filter_Example.js
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
module.exports.details = function details() {
|
||||||
|
return {
|
||||||
|
id: 'Tdarr_Plugin_bbbc_Filter_Example',
|
||||||
|
Stage: 'Pre-processing',
|
||||||
|
Name: 'Filter resolutions',
|
||||||
|
Type: 'Video',
|
||||||
|
Operation: 'Filter',
|
||||||
|
Description: 'This plugin prevents processing files with specified resolutions \n\n',
|
||||||
|
Version: '1.00',
|
||||||
|
Link: '',
|
||||||
|
Tags: '',
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.plugin = function plugin(file) {
|
||||||
|
const response = {
|
||||||
|
processFile: true,
|
||||||
|
infoLog: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
const resolutionsToSkip = [
|
||||||
|
'1080p',
|
||||||
|
'4KUHD',
|
||||||
|
];
|
||||||
|
|
||||||
|
for (let i = 0; i < resolutionsToSkip.length; i += 1) {
|
||||||
|
if (file.video_resolution === resolutionsToSkip[i]) {
|
||||||
|
response.processFile = false;
|
||||||
|
response.infoLog += `Filter preventing processing. File has resolution ${resolutionsToSkip[i]}`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
};
|
||||||
|
|
@ -12,8 +12,8 @@
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
"lint": "eslint Community methods --ext js",
|
"lint": "eslint Community methods examples --ext js",
|
||||||
"lint:fix": "eslint Community methods --ext js --fix"
|
"lint:fix": "eslint Community methods examples --ext js --fix"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue