diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index 042233b..0000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Node.js CI - -on: - pull_request: - branches: ['**'] - -jobs: - build: - - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [16.x] - - steps: - - uses: actions/checkout@v2 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - - run: npm i - - run: npm run checkPlugins && npm run lint && npm run test diff --git a/.github/workflows/lint_and_test.yml b/.github/workflows/lint_and_test.yml new file mode 100644 index 0000000..c85eb73 --- /dev/null +++ b/.github/workflows/lint_and_test.yml @@ -0,0 +1,34 @@ +name: Node.js CI + +on: + pull_request: + branches: ['**'] + +jobs: + build: + strategy: + matrix: + node-version: [16.x] + os: + [ + ["ubuntu-20.04"], + ["windows-2019"], + ["macos-11.0"], + ] + runs-on: ${{ matrix.os }} + + steps: + - name: Set git to use LF + run: | + git config --global core.autocrlf false + git config --global core.eol lf + + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - run: npm i + - run: npm run checkPlugins + - run: npm run lint + - run: npm run test diff --git a/Community/Tdarr_Plugin_SV6x_Smoove1FFMPEG_NVENC_H264.js b/Community/Tdarr_Plugin_SV6x_Smoove1FFMPEG_NVENC_H264.js index b91e1a9..eef3529 100644 --- a/Community/Tdarr_Plugin_SV6x_Smoove1FFMPEG_NVENC_H264.js +++ b/Community/Tdarr_Plugin_SV6x_Smoove1FFMPEG_NVENC_H264.js @@ -3,7 +3,6 @@ // https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_MC93_Migz1FFMPEG.js // Seriously, all I did was make it work for converting things to h264 instead of hevc -// tdarrSkipTest const details = () => ({ id: 'Tdarr_Plugin_SV6x_Smoove1FFMPEG_NVENC_H264', Stage: 'Pre-processing', // Preprocessing or Post-processing. Determines when the plugin will be executed. diff --git a/Community/Tdarr_Plugin_VP92_VP9_Match_Bitrate_One_Pass.js b/Community/Tdarr_Plugin_VP92_VP9_Match_Bitrate_One_Pass.js index e5bf1af..1412281 100644 --- a/Community/Tdarr_Plugin_VP92_VP9_Match_Bitrate_One_Pass.js +++ b/Community/Tdarr_Plugin_VP92_VP9_Match_Bitrate_One_Pass.js @@ -1,5 +1,4 @@ /* eslint max-classes-per-file: ["error", 2] */ -// tdarrSkipTest const details = () => ({ id: 'Tdarr_Plugin_VP92_VP9_Match_Bitrate_One_Pass', Stage: 'Pre-processing', diff --git a/Community/Tdarr_Plugin_a9hf_New_file_duration_check.js b/Community/Tdarr_Plugin_a9hf_New_file_duration_check.js index 6f1fcc5..4cda5ca 100644 --- a/Community/Tdarr_Plugin_a9hf_New_file_duration_check.js +++ b/Community/Tdarr_Plugin_a9hf_New_file_duration_check.js @@ -1,6 +1,5 @@ // eslint-disable-next-line import/no-unresolved -// tdarrSkipTest const details = () => ({ id: 'Tdarr_Plugin_a9hf_New_file_duration_check', Stage: 'Pre-processing', diff --git a/Community/Tdarr_Plugin_s710_nick_h265_nvenc_4K.js b/Community/Tdarr_Plugin_s710_nick_h265_nvenc_4K.js index 6c559b0..689d403 100644 --- a/Community/Tdarr_Plugin_s710_nick_h265_nvenc_4K.js +++ b/Community/Tdarr_Plugin_s710_nick_h265_nvenc_4K.js @@ -1,5 +1,4 @@ /* eslint-disable */ -// tdarrSkipTest const details = () => { return { id: "Tdarr_Plugin_s710_nick_h265_nvenc_4K", diff --git a/Community/Tdarr_Plugin_s7x9_winsome_h265_10bit.js b/Community/Tdarr_Plugin_s7x9_winsome_h265_10bit.js index acf22fb..d5d23f6 100644 --- a/Community/Tdarr_Plugin_s7x9_winsome_h265_10bit.js +++ b/Community/Tdarr_Plugin_s7x9_winsome_h265_10bit.js @@ -1,5 +1,4 @@ /* eslint-disable */ -// tdarrSkipTest const details = () => { return { id: "Tdarr_Plugin_s7x9_winsome_h265_10bit", diff --git a/Community/Tdarr_Plugin_s7x9_winsome_h265_nvenc.js b/Community/Tdarr_Plugin_s7x9_winsome_h265_nvenc.js index 447044d..f336a5e 100644 --- a/Community/Tdarr_Plugin_s7x9_winsome_h265_nvenc.js +++ b/Community/Tdarr_Plugin_s7x9_winsome_h265_nvenc.js @@ -1,5 +1,4 @@ /* eslint-disable */ -// tdarrSkipTest const details = () => { return { id: "Tdarr_Plugin_s7x9_winsome_h265_nvenc", diff --git a/Community/Tdarr_Plugin_sdd3_Remove_Commentary_Tracks.js b/Community/Tdarr_Plugin_sdd3_Remove_Commentary_Tracks.js index 8c8b8e2..00df33b 100644 --- a/Community/Tdarr_Plugin_sdd3_Remove_Commentary_Tracks.js +++ b/Community/Tdarr_Plugin_sdd3_Remove_Commentary_Tracks.js @@ -1,5 +1,4 @@ /* eslint-disable */ -// tdarrSkipTest const details = () => { return { id: "Tdarr_Plugin_sdd3_Remove_Commentary_Tracks", diff --git a/Community/Tdarr_Plugin_sdf5_Thierrrrry_Remove_Non_English_Audio.js b/Community/Tdarr_Plugin_sdf5_Thierrrrry_Remove_Non_English_Audio.js index 71708c3..9be9ed1 100644 --- a/Community/Tdarr_Plugin_sdf5_Thierrrrry_Remove_Non_English_Audio.js +++ b/Community/Tdarr_Plugin_sdf5_Thierrrrry_Remove_Non_English_Audio.js @@ -1,5 +1,4 @@ /* eslint-disable */ -// tdarrSkipTest const details = () => { return { id: "Tdarr_Plugin_sdf5_Thierrrrry_Remove_Non_English_Audio", diff --git a/Community/Tdarr_Plugin_vdka_Remove_DataStreams.js b/Community/Tdarr_Plugin_vdka_Remove_DataStreams.js index 64e71ef..634c9d3 100644 --- a/Community/Tdarr_Plugin_vdka_Remove_DataStreams.js +++ b/Community/Tdarr_Plugin_vdka_Remove_DataStreams.js @@ -1,5 +1,4 @@ /* eslint-disable */ -// tdarrSkipTest const details = () => { return { id: "Tdarr_Plugin_vdka_Remove_DataStreams", diff --git a/Community/Tdarr_Plugin_vdka_Tiered_CPU_CRF_Based_Configurable.js b/Community/Tdarr_Plugin_vdka_Tiered_CPU_CRF_Based_Configurable.js index f5614f8..e1d5aee 100644 --- a/Community/Tdarr_Plugin_vdka_Tiered_CPU_CRF_Based_Configurable.js +++ b/Community/Tdarr_Plugin_vdka_Tiered_CPU_CRF_Based_Configurable.js @@ -1,4 +1,3 @@ -// tdarrSkipTest const details = () => ({ id: 'Tdarr_Plugin_vdka_Tiered_CPU_CRF_Based_Configurable', Stage: 'Pre-processing', diff --git a/Community/Tdarr_Plugin_vdka_Tiered_NVENC_CQV_BASED_CONFIGURABLE.js b/Community/Tdarr_Plugin_vdka_Tiered_NVENC_CQV_BASED_CONFIGURABLE.js index e0ca948..4afd5f3 100644 --- a/Community/Tdarr_Plugin_vdka_Tiered_NVENC_CQV_BASED_CONFIGURABLE.js +++ b/Community/Tdarr_Plugin_vdka_Tiered_NVENC_CQV_BASED_CONFIGURABLE.js @@ -1,5 +1,4 @@ /* eslint-disable */ -// tdarrSkipTest const details = () => { return { id: 'Tdarr_Plugin_vdka_Tiered_NVENC_CQV_BASED_CONFIGURABLE', diff --git a/Community/Tdarr_Plugin_x7ab_Remove_Subs.js b/Community/Tdarr_Plugin_x7ab_Remove_Subs.js index 3bf03de..7bd12ff 100644 --- a/Community/Tdarr_Plugin_x7ab_Remove_Subs.js +++ b/Community/Tdarr_Plugin_x7ab_Remove_Subs.js @@ -1,5 +1,4 @@ /* eslint-disable */ -// tdarrSkipTest const details = () => { return { id: "Tdarr_Plugin_x7ab_Remove_Subs", diff --git a/Community/Tdarr_Plugin_x7ac_Remove_Closed_Captions.js b/Community/Tdarr_Plugin_x7ac_Remove_Closed_Captions.js index 26afd05..f5fe57a 100644 --- a/Community/Tdarr_Plugin_x7ac_Remove_Closed_Captions.js +++ b/Community/Tdarr_Plugin_x7ac_Remove_Closed_Captions.js @@ -1,4 +1,3 @@ -// tdarrSkipTest const details = () => ({ id: 'Tdarr_Plugin_x7ac_Remove_Closed_Captions', Stage: 'Pre-processing', diff --git a/Community/Tdarr_Plugin_z0ab_TheRealShadoh_FFmpeg_Subs_H264_Medium.js b/Community/Tdarr_Plugin_z0ab_TheRealShadoh_FFmpeg_Subs_H264_Medium.js index 716e730..88fc14e 100644 --- a/Community/Tdarr_Plugin_z0ab_TheRealShadoh_FFmpeg_Subs_H264_Medium.js +++ b/Community/Tdarr_Plugin_z0ab_TheRealShadoh_FFmpeg_Subs_H264_Medium.js @@ -1,4 +1,3 @@ -// tdarrSkipTest const details = () => ({ id: 'Tdarr_Plugin_z0ab_TheRealShadoh_FFmpeg_Subs_H264_Medium', Stage: 'Pre-processing', diff --git a/Community/Tdarr_Plugin_z1ab_TheRealShadoh_FFmpeg_Subs_H264_Fast.js b/Community/Tdarr_Plugin_z1ab_TheRealShadoh_FFmpeg_Subs_H264_Fast.js index ad301d8..fbc9de3 100644 --- a/Community/Tdarr_Plugin_z1ab_TheRealShadoh_FFmpeg_Subs_H264_Fast.js +++ b/Community/Tdarr_Plugin_z1ab_TheRealShadoh_FFmpeg_Subs_H264_Fast.js @@ -1,4 +1,3 @@ -// tdarrSkipTest const details = () => ({ id: 'Tdarr_Plugin_z1ab_TheRealShadoh_FFmpeg_Subs_H264_Fast', Stage: 'Pre-processing', diff --git a/Community/Tdarr_Plugin_z2ab_TheRealShadoh_FFmpeg_Subs_H264_Slow.js b/Community/Tdarr_Plugin_z2ab_TheRealShadoh_FFmpeg_Subs_H264_Slow.js index dc863a4..28ee579 100644 --- a/Community/Tdarr_Plugin_z2ab_TheRealShadoh_FFmpeg_Subs_H264_Slow.js +++ b/Community/Tdarr_Plugin_z2ab_TheRealShadoh_FFmpeg_Subs_H264_Slow.js @@ -1,4 +1,3 @@ -// tdarrSkipTest const details = () => ({ id: 'Tdarr_Plugin_z2ab_TheRealShadoh_FFmpeg_Subs_H264_Slow', Stage: 'Pre-processing', diff --git a/Community/Tdarr_Plugin_z3ab_TheRealShadoh_FFmpeg_Subs_H264_VeryFast.js b/Community/Tdarr_Plugin_z3ab_TheRealShadoh_FFmpeg_Subs_H264_VeryFast.js index be10d89..597003f 100644 --- a/Community/Tdarr_Plugin_z3ab_TheRealShadoh_FFmpeg_Subs_H264_VeryFast.js +++ b/Community/Tdarr_Plugin_z3ab_TheRealShadoh_FFmpeg_Subs_H264_VeryFast.js @@ -1,4 +1,3 @@ -// tdarrSkipTest const details = () => ({ id: 'Tdarr_Plugin_z3ab_TheRealShadoh_FFmpeg_Subs_H264_VeryFast', Stage: 'Pre-processing', diff --git a/tests/Community/Tdarr_Plugin_ER01_Transcode audio and video with HW (PC and Mac).js b/tests/Community/Tdarr_Plugin_ER01_Transcode audio and video with HW (PC and Mac).js index c725079..93e847c 100644 --- a/tests/Community/Tdarr_Plugin_ER01_Transcode audio and video with HW (PC and Mac).js +++ b/tests/Community/Tdarr_Plugin_ER01_Transcode audio and video with HW (PC and Mac).js @@ -11,17 +11,33 @@ const tests = [ otherArguments: {}, }, output: { - container: '.mkv', - processFile: true, - preset: ', -sn -map 0:v -c:v copy -b:v 758k -minrate 530k -maxrate 985k -bufsize 1517k -map 0:a -c:a copy ', - handBrakeMode: false, - FFmpegMode: true, - reQueueAfter: true, - infoLog: 'Converting video, NOT resizing. 720p, h264 --> 720p, hevc. bitrate = 1517 --> 758, multiplier 0.5. \n' - + 'Not converting audio. \n' - + '2 channels - \n' - + '6 channels - und aac \n' - + '8 channels - ', + win32: { + container: '.mkv', + processFile: true, + preset: ', -sn -map 0:v -c:v hevc_qsv -load_plugin hevc_hw -b:v 758k -minrate 530k -maxrate 985k -bufsize 1517k -map 0:a -c:a copy ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'Converting video, NOT resizing. 720p, h264 --> 720p, hevc. bitrate = 1517 --> 758, multiplier 0.5. \n' + + 'Not converting audio. \n' + + '2 channels - \n' + + '6 channels - und aac \n' + + '8 channels - ', + }, + linux: false, + darwin: { + container: '.mkv', + processFile: true, + preset: ', -sn -map 0:v -c:v hevc_videotoolbox -profile main -b:v 758k -minrate 530k -maxrate 985k -bufsize 1517k -map 0:a -c:a copy ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'Converting video, NOT resizing. 720p, h264 --> 720p, hevc. bitrate = 1517 --> 758, multiplier 0.5. \n' + + 'Not converting audio. \n' + + '2 channels - \n' + + '6 channels - und aac \n' + + '8 channels - ', + }, }, }, { @@ -70,17 +86,33 @@ const tests = [ otherArguments: {}, }, output: { - container: '.mkv', - processFile: true, - preset: ', -sn -map 0:v -c:v copy -b:v 3933k -minrate 2753k -maxrate 5112k -bufsize 7866k -map 0:a -c:a copy ', - handBrakeMode: false, - FFmpegMode: true, - reQueueAfter: true, - infoLog: 'Converting video, NOT resizing. 1080p, h264 --> 1080p, hevc. bitrate = 7866 --> 3933, multiplier 0.5. \n' - + 'Not converting audio. \n' - + '2 channels - eng flac \n' - + '6 channels - \n' - + '8 channels - ', + win32: { + container: '.mkv', + processFile: true, + preset: ', -sn -map 0:v -c:v hevc_qsv -load_plugin hevc_hw -b:v 3933k -minrate 2753k -maxrate 5112k -bufsize 7866k -map 0:a -c:a copy ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'Converting video, NOT resizing. 1080p, h264 --> 1080p, hevc. bitrate = 7866 --> 3933, multiplier 0.5. \n' + + 'Not converting audio. \n' + + '2 channels - eng flac \n' + + '6 channels - \n' + + '8 channels - ', + }, + linux: false, + darwin: { + container: '.mkv', + processFile: true, + preset: ', -sn -map 0:v -c:v hevc_videotoolbox -profile main -b:v 3933k -minrate 2753k -maxrate 5112k -bufsize 7866k -map 0:a -c:a copy ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'Converting video, NOT resizing. 1080p, h264 --> 1080p, hevc. bitrate = 7866 --> 3933, multiplier 0.5. \n' + + 'Not converting audio. \n' + + '2 channels - eng flac \n' + + '6 channels - \n' + + '8 channels - ', + }, }, }, { diff --git a/tests/Community/Tdarr_Plugin_SV6x_Smoove1FFMPEG_NVENC_H264.js b/tests/Community/Tdarr_Plugin_SV6x_Smoove1FFMPEG_NVENC_H264.js new file mode 100644 index 0000000..d1fbf71 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_SV6x_Smoove1FFMPEG_NVENC_H264.js @@ -0,0 +1,106 @@ +/* eslint max-len: 0 */ +const _ = require('lodash'); +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + infoLog: 'File is already H264 but file is not in mkv. Remuxing \n', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + container: '.mkv', + preset: ', -map 0 -c copy ', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.container = 'mkv'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + infoLog: 'File is already H264 and in mkv \n', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + container: '.mkv', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + infoLog: 'Target bitrate could not be calculated. Skipping this plugin. \n', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + container: '.mkv', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.ffProbeData.streams[0].codec_name = 'hevc'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + infoLog: 'Container for output selected as mkv. \n' + + 'Current bitrate = 1526 \n' + + 'Bitrate settings: \n' + + 'Target = 1526 \n' + + 'Minimum = 1068 \n' + + 'Maximum = 1983 \n' + + 'File is not h264. Transcoding. \n', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + container: '.mkv', + preset: 'undefined,-map 0 -c:v h264_nvenc -preset fast -crf 23 -tune film -b:v 1526k -minrate 1068k -maxrate 1983k -bufsize 1526k -c:a copy -c:s copy -max_muxing_queue_size 9999 -pix_fmt yuv420p ', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: { + container: 'mp4', + }, + otherArguments: {}, + }, + output: { + processFile: false, + infoLog: 'File is already H264 and in mp4 \n', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + container: '.mp4', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_VP92_VP9_Match_Bitrate_One_Pass.js b/tests/Community/Tdarr_Plugin_VP92_VP9_Match_Bitrate_One_Pass.js new file mode 100644 index 0000000..228ff5c --- /dev/null +++ b/tests/Community/Tdarr_Plugin_VP92_VP9_Match_Bitrate_One_Pass.js @@ -0,0 +1,505 @@ +/* eslint max-len: 0 */ +const _ = require('lodash'); +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + container: '.webm', + FFmpegMode: true, + handBrakeMode: false, + infoLog: '☒ Audio is not in proper codec, will format\n' + + '☒ Transcoding file to VP9\n' + + '☑ No subtitle processing necessary', + processFile: true, + preset: ',-map 0 -map -0:d -pix_fmt yuv420p10le -c:v libvpx-vp9 -b:v 0 -crf 27 -threads 64 -speed 2 \n' + + ' -quality good -static-thresh 0 -tile-columns 2 -tile-rows 0 -frame-parallel 0 -row-mt 1 \n' + + ' -aq-mode 0 -g 240 \n' + + ' -c:a libopus -c:s copy', + reQueueAfter: true, + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + container: '.webm', + FFmpegMode: true, + handBrakeMode: false, + infoLog: '☒ Audio is not in proper codec, will format\n' + + '☒ Transcoding file to VP9\n' + + '☑ No subtitle processing necessary', + processFile: true, + preset: ',-map 0 -map -0:d -pix_fmt yuv420p10le -c:v libvpx-vp9 -b:v 0 -crf 26 -threads 64 -speed 2 \n' + + ' -quality good -static-thresh 0 -tile-columns 2 -tile-rows 0 -frame-parallel 0 -row-mt 1 \n' + + ' -aq-mode 0 -g 240 \n' + + ' -c:a libopus -c:s copy', + reQueueAfter: true, + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.container = 'webm'; + file.ffProbeData.streams[0].codec_name = 'vp9'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + container: '.webm', + FFmpegMode: true, + handBrakeMode: false, + infoLog: '☒ Audio is not in proper codec, will format\n' + + '☑ File is in proper video format\n' + + '☑ No video processing necessary\n' + + '☑ No subtitle processing necessary', + processFile: true, + preset: ',-map 0 -map -0:d -c:v copy \n -c:a libopus -c:s copy', + reQueueAfter: true, + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.container = 'webm'; + file.ffProbeData.streams[0].codec_name = 'vp9'; + file.ffProbeData.streams[1].codec_name = 'opus'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + container: '.webm', + FFmpegMode: true, + handBrakeMode: false, + infoLog: '☑ No audio processing necessary\n' + + '☑ File is in proper video format\n' + + '☑ No video processing necessary\n' + + '☑ No subtitle processing necessary\n' + + '☑ No need to process file', + processFile: false, + preset: ',-map 0 -map -0:d -c:v copy \n -c:a copy -c:s copy', + reQueueAfter: true, + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: { + CQ_240p: '33', + CQ_360p: '32', + CQ_480p: '29', + CQ_720p: '28', + CQ_1080p: '27', + CQ_4KUHD: '16', + CQ_8KUHD: '16', + audio_language: 'eng,und,fre', + audio_commentary: 'true', + subtitle_language: 'eng', + subtitle_commentary: 'true', + remove_mjpeg: 'true', + }, + otherArguments: {}, + }, + output: { + container: '.webm', + FFmpegMode: true, + handBrakeMode: false, + infoLog: '☒ Audio is not in proper codec, will format\n' + + '☒ Transcoding file to VP9\n' + + '☑ No subtitle processing necessary', + processFile: true, + preset: ',-map 0 -map -0:d -pix_fmt yuv420p10le -c:v libvpx-vp9 -b:v 0 -crf 28 -threads 64 -speed 2 \n' + + ' -quality good -static-thresh 0 -tile-columns 2 -tile-rows 0 -frame-parallel 0 -row-mt 1 \n' + + ' -aq-mode 0 -g 240 \n' + + ' -c:a libopus -c:s copy', + reQueueAfter: true, + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.video_resolution = '240p'; + return file; + })(), + librarySettings: {}, + inputs: { + CQ_240p: '33', + CQ_360p: '32', + CQ_480p: '29', + CQ_720p: '28', + CQ_1080p: '27', + CQ_4KUHD: '16', + CQ_8KUHD: '16', + audio_language: 'eng,und,fre', + audio_commentary: 'true', + subtitle_language: 'eng', + subtitle_commentary: 'true', + remove_mjpeg: 'true', + }, + otherArguments: {}, + }, + output: { + container: '.webm', + FFmpegMode: true, + handBrakeMode: false, + infoLog: '☒ Audio is not in proper codec, will format\n' + + '☒ Transcoding file to VP9\n' + + '☑ No subtitle processing necessary', + processFile: true, + preset: ',-map 0 -map -0:d -pix_fmt yuv420p10le -c:v libvpx-vp9 -b:v 0 -crf 33 -threads 64 -speed 1 \n' + + ' -quality good -static-thresh 0 -tile-columns 0 -tile-rows 0 -frame-parallel 0 -row-mt 1 \n' + + ' -aq-mode 0 -g 240 \n' + + ' -c:a libopus -c:s copy', + reQueueAfter: true, + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.video_resolution = '360p'; + return file; + })(), + librarySettings: {}, + inputs: { + CQ_240p: '33', + CQ_360p: '32', + CQ_480p: '29', + CQ_720p: '28', + CQ_1080p: '27', + CQ_4KUHD: '16', + CQ_8KUHD: '16', + audio_language: 'eng,und,fre', + audio_commentary: 'true', + subtitle_language: 'eng', + subtitle_commentary: 'true', + remove_mjpeg: 'true', + }, + otherArguments: {}, + }, + output: { + container: '.webm', + FFmpegMode: true, + handBrakeMode: false, + infoLog: '☒ Audio is not in proper codec, will format\n' + + '☒ Transcoding file to VP9\n' + + '☑ No subtitle processing necessary', + processFile: true, + preset: ',-map 0 -map -0:d -pix_fmt yuv420p10le -c:v libvpx-vp9 -b:v 0 -crf 32 -threads 64 -speed 1 \n' + + ' -quality good -static-thresh 0 -tile-columns 1 -tile-rows 0 -frame-parallel 0 -row-mt 1 \n' + + ' -aq-mode 0 -g 240 \n' + + ' -c:a libopus -c:s copy', + reQueueAfter: true, + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.video_resolution = '480p'; + return file; + })(), + librarySettings: {}, + inputs: { + CQ_240p: '33', + CQ_360p: '32', + CQ_480p: '29', + CQ_720p: '28', + CQ_1080p: '27', + CQ_4KUHD: '16', + CQ_8KUHD: '16', + audio_language: 'eng,und,fre', + audio_commentary: 'true', + subtitle_language: 'eng', + subtitle_commentary: 'true', + remove_mjpeg: 'true', + }, + otherArguments: {}, + }, + output: { + container: '.webm', + FFmpegMode: true, + handBrakeMode: false, + infoLog: '☒ Audio is not in proper codec, will format\n' + + '☒ Transcoding file to VP9\n' + + '☑ No subtitle processing necessary', + processFile: true, + preset: ',-map 0 -map -0:d -pix_fmt yuv420p10le -c:v libvpx-vp9 -b:v 0 -crf 29 -threads 64 -speed 1 \n' + + ' -quality good -static-thresh 0 -tile-columns 1 -tile-rows 0 -frame-parallel 0 -row-mt 1 \n' + + ' -aq-mode 0 -g 240 \n' + + ' -c:a libopus -c:s copy', + reQueueAfter: true, + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.video_resolution = '1080p'; + return file; + })(), + librarySettings: {}, + inputs: { + CQ_240p: '33', + CQ_360p: '32', + CQ_480p: '29', + CQ_720p: '28', + CQ_1080p: '27', + CQ_4KUHD: '16', + CQ_8KUHD: '16', + audio_language: 'eng,und,fre', + audio_commentary: 'true', + subtitle_language: 'eng', + subtitle_commentary: 'true', + remove_mjpeg: 'true', + }, + otherArguments: {}, + }, + output: { + container: '.webm', + FFmpegMode: true, + handBrakeMode: false, + infoLog: '☒ Audio is not in proper codec, will format\n' + + '☒ Transcoding file to VP9\n' + + '☑ No subtitle processing necessary', + processFile: true, + preset: ',-map 0 -map -0:d -pix_fmt yuv420p10le -c:v libvpx-vp9 -b:v 0 -crf 27 -threads 64 -speed 2 \n' + + ' -quality good -static-thresh 0 -tile-columns 2 -tile-rows 0 -frame-parallel 0 -row-mt 1 \n' + + ' -aq-mode 0 -g 240 \n' + + ' -c:a libopus -c:s copy', + reQueueAfter: true, + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.video_resolution = '4KUHD'; + return file; + })(), + librarySettings: {}, + inputs: { + CQ_240p: '33', + CQ_360p: '32', + CQ_480p: '29', + CQ_720p: '28', + CQ_1080p: '27', + CQ_4KUHD: '16', + CQ_8KUHD: '17', + audio_language: 'eng,und,fre', + audio_commentary: 'true', + subtitle_language: 'eng', + subtitle_commentary: 'true', + remove_mjpeg: 'true', + }, + otherArguments: {}, + }, + output: { + container: '.webm', + FFmpegMode: true, + handBrakeMode: false, + infoLog: '☒ Audio is not in proper codec, will format\n' + + '☒ Transcoding file to VP9\n' + + '☑ No subtitle processing necessary', + processFile: true, + preset: ',-map 0 -map -0:d -pix_fmt yuv420p10le -c:v libvpx-vp9 -b:v 0 -crf 16 -threads 64 -speed 2 \n' + + ' -quality good -static-thresh 0 -tile-columns 3 -tile-rows 0 -frame-parallel 0 -row-mt 1 \n' + + ' -aq-mode 0 -g 240 \n' + + ' -c:a libopus -c:s copy', + reQueueAfter: true, + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.video_resolution = '8KUHD'; + return file; + })(), + librarySettings: {}, + inputs: { + CQ_240p: '33', + CQ_360p: '32', + CQ_480p: '29', + CQ_720p: '28', + CQ_1080p: '27', + CQ_4KUHD: '16', + CQ_8KUHD: '17', + audio_language: 'eng,und,fre', + audio_commentary: 'true', + subtitle_language: 'eng', + subtitle_commentary: 'true', + remove_mjpeg: 'true', + }, + otherArguments: {}, + }, + output: { + container: '.webm', + FFmpegMode: true, + handBrakeMode: false, + infoLog: '☒ Audio is not in proper codec, will format\n' + + '☒ Transcoding file to VP9\n' + + '☑ No subtitle processing necessary', + processFile: true, + preset: ',-map 0 -map -0:d -pix_fmt yuv420p10le -c:v libvpx-vp9 -b:v 0 -crf 17 -threads 64 -speed 2 \n' + + ' -quality good -static-thresh 0 -tile-columns 3 -tile-rows 0 -frame-parallel 0 -row-mt 1 \n' + + ' -aq-mode 0 -g 240 \n' + + ' -c:a libopus -c:s copy', + reQueueAfter: true, + }, + }, + + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.container = 'webm'; + file.ffProbeData.streams[0].codec_name = 'vp9'; + file.ffProbeData.streams[1].codec_name = 'opus'; + file.ffProbeData.streams[1].tags.language = 'eng'; + + file.ffProbeData.streams[2] = _.cloneDeep(file.ffProbeData.streams[1]); + file.ffProbeData.streams[2].codec_type = 'subtitle'; + file.ffProbeData.streams[2].tags.title = 'commentary'; + return file; + })(), + librarySettings: {}, + inputs: { + CQ_240p: '33', + CQ_360p: '32', + CQ_480p: '29', + CQ_720p: '28', + CQ_1080p: '27', + CQ_4KUHD: '16', + CQ_8KUHD: '17', + audio_language: 'eng,und,fre', + audio_commentary: 'true', + subtitle_language: 'eng,und', + subtitle_commentary: 'true', + remove_mjpeg: 'true', + }, + otherArguments: {}, + }, + output: { + container: '.webm', + FFmpegMode: true, + handBrakeMode: false, + infoLog: '☑ No audio processing necessary\n' + + '☑ File is in proper video format\n' + + '☑ No video processing necessary\n' + + '☒ Removing Commentary or Description subtitle: commentary', + processFile: true, + preset: ',-map 0 -map -0:d -c:v copy \n -c:a copy -c:s copy -map -0:s:0', + reQueueAfter: true, + }, + }, + + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.container = 'webm'; + file.ffProbeData.streams[0].codec_name = 'vp9'; + file.ffProbeData.streams[1].codec_name = 'opus'; + file.ffProbeData.streams[1].tags.language = 'eng'; + + file.ffProbeData.streams[2] = _.cloneDeep(file.ffProbeData.streams[0]); + file.ffProbeData.streams[2].codec_name = 'mjpeg'; + return file; + })(), + librarySettings: {}, + inputs: { + CQ_240p: '33', + CQ_360p: '32', + CQ_480p: '29', + CQ_720p: '28', + CQ_1080p: '27', + CQ_4KUHD: '16', + CQ_8KUHD: '17', + audio_language: 'eng,und,fre', + audio_commentary: 'true', + subtitle_language: 'eng,und', + subtitle_commentary: 'true', + remove_mjpeg: 'true', + }, + otherArguments: {}, + }, + output: { + container: '.webm', + FFmpegMode: true, + handBrakeMode: false, + infoLog: '☑ No audio processing necessary\n' + + '☑ File is in proper video format\n' + + '☒ Removing mjpeg\n' + + '☑ No subtitle processing necessary', + processFile: true, + preset: ',-map 0 -map -0:d -c:v copy -map -0:v:1 \n -c:a copy -c:s copy', + reQueueAfter: true, + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.container = 'webm'; + file.ffProbeData.streams[0].codec_name = 'vp9'; + file.ffProbeData.streams[1].codec_name = 'opus'; + file.ffProbeData.streams[1].tags.language = 'eng'; + + file.ffProbeData.streams[2] = _.cloneDeep(file.ffProbeData.streams[1]); + file.ffProbeData.streams[2].tags.language = 'fre'; + return file; + })(), + librarySettings: {}, + inputs: { + CQ_240p: '33', + CQ_360p: '32', + CQ_480p: '29', + CQ_720p: '28', + CQ_1080p: '27', + CQ_4KUHD: '16', + CQ_8KUHD: '17', + audio_language: 'eng,und', + audio_commentary: 'true', + subtitle_language: 'eng,und', + subtitle_commentary: 'true', + remove_mjpeg: 'true', + }, + otherArguments: {}, + }, + output: { + container: '.webm', + FFmpegMode: true, + handBrakeMode: false, + infoLog: '☒ Removing audio track in language fre\n' + + '☑ File is in proper video format\n' + + '☑ No video processing necessary\n' + + '☑ No subtitle processing necessary', + processFile: true, + preset: ',-map 0 -map -0:d -c:v copy \n -c:a copy -map -0:a:1 -c:s copy', + reQueueAfter: true, + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_a9he_New_file_size_check.js b/tests/Community/Tdarr_Plugin_a9he_New_file_size_check.js index 7e1de0d..e990b36 100644 --- a/tests/Community/Tdarr_Plugin_a9he_New_file_size_check.js +++ b/tests/Community/Tdarr_Plugin_a9he_New_file_size_check.js @@ -5,11 +5,11 @@ const run = require('../helpers/run'); const tests = [ { input: { - file: require('../sampleData/media/sampleH264_1.json'), + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), librarySettings: {}, inputs: {}, otherArguments: { - originalLibraryFile: require('../sampleData/media/sampleH264_1.json'), + originalLibraryFile: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), }, }, output: { @@ -23,7 +23,7 @@ const tests = [ }, { input: { - file: require('../sampleData/media/sampleH264_1.json'), + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), librarySettings: {}, inputs: { upperBound: '110', @@ -44,7 +44,7 @@ const tests = [ }, { input: { - file: require('../sampleData/media/sampleH264_1.json'), + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), librarySettings: {}, inputs: { upperBound: '120', diff --git a/tests/Community/Tdarr_Plugin_a9hf_New_file_duration_check.js b/tests/Community/Tdarr_Plugin_a9hf_New_file_duration_check.js new file mode 100644 index 0000000..9497714 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_a9hf_New_file_duration_check.js @@ -0,0 +1,68 @@ +/* eslint max-len: 0 */ +const _ = require('lodash'); +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: { + originalLibraryFile: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + }, + }, + output: { + processFile: false, + preset: '', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'New file has duration 5.312 s which is 100.000% of original file duration: 5.312 s', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: { + upperBound: '110', + lowerBound: '35', + }, + otherArguments: { + originalLibraryFile: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.mediaInfo.track.filter((row) => row['@type'] === 'General')[0].Duration = 20; + return file; + })(), + }, + }, + output: 'New file duration not within limits. New file has duration 5.312 s which is 26.560% of original file duration: 20 s. lowerBound is 35%', + error: { + shouldThrow: true, + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: { + upperBound: '110', + lowerBound: '35', + }, + otherArguments: { + originalLibraryFile: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.mediaInfo.track.filter((row) => row['@type'] === 'General')[0].Duration = 1; + return file; + })(), + }, + }, + output: 'New file duration not within limits. New file has duration 5.312 s which is 531.200% of original file duration: 1 s. upperBound is 110%', + error: { + shouldThrow: true, + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js b/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js index 336f2f0..6d0dd96 100644 --- a/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js +++ b/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js @@ -11,21 +11,57 @@ const tests = [ otherArguments: {}, }, output: { - processFile: true, - preset: '-fflags +genpts -hwaccel qsv -c:v h264_qsv -map 0 -c:v hevc_qsv -b:v 759k -minrate 569k -maxrate 949k -bufsize 1517k -preset slow \n' - + ' -c:a copy -c:s copy -max_muxing_queue_size 9999 ', - handBrakeMode: false, - FFmpegMode: true, - reQueueAfter: true, - infoLog: '☑ It looks like the current bitrate is 1517k. \n' - + '\n' - + 'Container for output selected as mkv. \n' - + 'Encode variable bitrate settings: \n' - + 'Target = 759k \n' - + 'Minimum = 569k \n' - + 'Maximum = 949k \n' - + 'File Transcoding... \n', - container: '.mkv', + linux: { + processFile: true, + preset: '-fflags +genpts -hwaccel qsv -c:v h264_qsv -map 0 -c:v hevc_qsv -b:v 759k -minrate 569k -maxrate 949k -bufsize 1517k -preset slow \n' + + ' -c:a copy -c:s copy -max_muxing_queue_size 9999 ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑ It looks like the current bitrate is 1517k. \n' + + '\n' + + 'Container for output selected as mkv. \n' + + 'Encode variable bitrate settings: \n' + + 'Target = 759k \n' + + 'Minimum = 569k \n' + + 'Maximum = 949k \n' + + 'File Transcoding... \n', + container: '.mkv', + }, + win32: { + processFile: true, + preset: '-fflags +genpts -hwaccel qsv -c:v h264_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -b:v 759k -minrate 569k -maxrate 949k -bufsize 1517k -preset slow \n' + + ' -c:a copy -c:s copy -max_muxing_queue_size 9999 ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑ It looks like the current bitrate is 1517k. \n' + + '\n' + + 'Container for output selected as mkv. \n' + + 'Encode variable bitrate settings: \n' + + 'Target = 759k \n' + + 'Minimum = 569k \n' + + 'Maximum = 949k \n' + + 'File Transcoding... \n', + container: '.mkv', + }, + darwin: { + processFile: true, + preset: '-fflags +genpts -hwaccel qsv -c:v h264_qsv -map 0 -c:v hevc_videotoolbox -b:v 759k -minrate 569k -maxrate 949k -bufsize 1517k -preset slow \n' + + ' -c:a copy -c:s copy -max_muxing_queue_size 9999 ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑ It looks like the current bitrate is 1517k. \n' + + '\n' + + 'Container for output selected as mkv. \n' + + 'Encode variable bitrate settings: \n' + + 'Target = 759k \n' + + 'Minimum = 569k \n' + + 'Maximum = 949k \n' + + 'File Transcoding... \n', + container: '.mkv', + }, }, }, { @@ -40,22 +76,60 @@ const tests = [ otherArguments: {}, }, output: { - processFile: true, - preset: '-fflags +genpts -hwaccel qsv -map 0 -c:v hevc_qsv -b:v 759k -minrate 569k -maxrate 949k -bufsize 1517k -preset fast \n' - + ' -c:a copy -c:s copy -max_muxing_queue_size 9999 -profile:v main10 -pix_fmt p010le ', - handBrakeMode: false, - FFmpegMode: true, - reQueueAfter: true, - infoLog: '☑ It looks like the current bitrate is 1517k. \n' - + '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format \n' - + '\n' - + 'Container for output selected as mp4. \n' - + 'Encode variable bitrate settings: \n' - + 'Target = 759k \n' - + 'Minimum = 569k \n' - + 'Maximum = 949k \n' - + 'File Transcoding... \n', - container: '.mp4', + linux: { + processFile: true, + preset: '-fflags +genpts -hwaccel qsv -map 0 -c:v hevc_qsv -b:v 759k -minrate 569k -maxrate 949k -bufsize 1517k -preset fast \n' + + ' -c:a copy -c:s copy -max_muxing_queue_size 9999 -profile:v main10 -pix_fmt p010le ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑ It looks like the current bitrate is 1517k. \n' + + '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format \n' + + '\n' + + 'Container for output selected as mp4. \n' + + 'Encode variable bitrate settings: \n' + + 'Target = 759k \n' + + 'Minimum = 569k \n' + + 'Maximum = 949k \n' + + 'File Transcoding... \n', + container: '.mp4', + }, + win32: { + processFile: true, + preset: '-fflags +genpts -hwaccel qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -b:v 759k -minrate 569k -maxrate 949k -bufsize 1517k -preset fast \n' + + ' -c:a copy -c:s copy -max_muxing_queue_size 9999 -profile:v main10 -pix_fmt p010le ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑ It looks like the current bitrate is 1517k. \n' + + '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format \n' + + '\n' + + 'Container for output selected as mp4. \n' + + 'Encode variable bitrate settings: \n' + + 'Target = 759k \n' + + 'Minimum = 569k \n' + + 'Maximum = 949k \n' + + 'File Transcoding... \n', + container: '.mp4', + }, + darwin: { + processFile: true, + preset: '-fflags +genpts -hwaccel qsv -map 0 -c:v hevc_videotoolbox -b:v 759k -minrate 569k -maxrate 949k -bufsize 1517k -preset fast \n' + + ' -c:a copy -c:s copy -max_muxing_queue_size 9999 -profile:v main10 -pix_fmt p010le ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑ It looks like the current bitrate is 1517k. \n' + + '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format \n' + + '\n' + + 'Container for output selected as mp4. \n' + + 'Encode variable bitrate settings: \n' + + 'Target = 759k \n' + + 'Minimum = 569k \n' + + 'Maximum = 949k \n' + + 'File Transcoding... \n', + container: '.mp4', + }, }, }, { diff --git a/tests/Community/Tdarr_Plugin_s710_nick_h265_nvenc_4K.js b/tests/Community/Tdarr_Plugin_s710_nick_h265_nvenc_4K.js new file mode 100644 index 0000000..a6aa2ff --- /dev/null +++ b/tests/Community/Tdarr_Plugin_s710_nick_h265_nvenc_4K.js @@ -0,0 +1,84 @@ +/* eslint max-len: 0 */ +const _ = require('lodash'); +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0:v -map 0:a:0 -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ac3 -b:a:0 192k -ac 2', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒File has no language track in ac3,eac3,dts. No eng track marked so transcoding audio track 1 into ac3! \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0:v -map 0:a:0 -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ac3 -b:a:0 192k -ac 2', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒File has no language track in ac3,eac3,dts. No eng track marked so transcoding audio track 1 into ac3! \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH265_1.json')); + file.ffProbeData.streams[1].codec_name = 'ac3'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: false, + infoLog: '☑File is in mkv container! \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.video_resolution = '4KUHD'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-Z "H.265 MKV 2160p60" --all-audio --all-subtitles', + container: '.mkv', + handBrakeMode: true, + FFmpegMode: false, + reQueueAfter: true, + infoLog: "☒ 4K file isn't in hevc! \n", + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_s7x9_winsome_h265_10bit.js b/tests/Community/Tdarr_Plugin_s7x9_winsome_h265_10bit.js new file mode 100644 index 0000000..6fad6fc --- /dev/null +++ b/tests/Community/Tdarr_Plugin_s7x9_winsome_h265_10bit.js @@ -0,0 +1,63 @@ +/* eslint max-len: 0 */ +const _ = require('lodash'); +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-Z "H.265 MKV 2160p60" -e x265_10bit --all-audio --all-subtitles', + container: '.mkv', + handBrakeMode: true, + FFmpegMode: false, + reQueueAfter: true, + infoLog: "☒File isn't in hevc! \n", + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0:v -map 0:a:0 -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ac3 -b:a:0 192k -ac 2', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒File has no language track in ac3,eac3,dts. No eng track marked so transcoding audio track 1 into ac3! \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH265_1.json')); + file.ffProbeData.streams[1].codec_name = 'ac3'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: false, + infoLog: '☑File is in mkv container! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_s7x9_winsome_h265_nvenc.js b/tests/Community/Tdarr_Plugin_s7x9_winsome_h265_nvenc.js new file mode 100644 index 0000000..e81f664 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_s7x9_winsome_h265_nvenc.js @@ -0,0 +1,63 @@ +/* eslint max-len: 0 */ +const _ = require('lodash'); +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-Z "H.265 MKV 2160p60" --all-audio --all-subtitles -e nvenc_h265', + container: '.mkv', + handBrakeMode: true, + FFmpegMode: false, + reQueueAfter: true, + infoLog: "☒File isn't in hevc! \n", + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0:v -map 0:a:0 -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 ac3 -b:a:0 192k -ac 2', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒File has no language track in ac3,eac3,dts. No eng track marked so transcoding audio track 1 into ac3! \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH265_1.json')); + file.ffProbeData.streams[1].codec_name = 'ac3'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: false, + infoLog: '☑File is in mkv container! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_sdd3_Remove_Commentary_Tracks.js b/tests/Community/Tdarr_Plugin_sdd3_Remove_Commentary_Tracks.js new file mode 100644 index 0000000..0cbc716 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_sdd3_Remove_Commentary_Tracks.js @@ -0,0 +1,48 @@ +/* eslint max-len: 0 */ +const _ = require('lodash'); +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: '☑File is a video! \n' + + "☑File doesn't contain commentary tracks! \n" + + '☑File meets conditions! \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.ffProbeData.streams[1].tags.title = 'commentary'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map 0 -map -0:a:0 -c copy', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is a video! \n☒File contains commentary tracks. Removing! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_sdf5_Thierrrrry_Remove_Non_English_Audio.js b/tests/Community/Tdarr_Plugin_sdf5_Thierrrrry_Remove_Non_English_Audio.js new file mode 100644 index 0000000..10424ec --- /dev/null +++ b/tests/Community/Tdarr_Plugin_sdf5_Thierrrrry_Remove_Non_English_Audio.js @@ -0,0 +1,63 @@ +/* eslint max-len: 0 */ +const _ = require('lodash'); +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: false, + infoLog: "☑File doesn't contain tracks which are not english or undefined! \n", + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.ffProbeData.streams[1].tags.language = 'fre'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: false, + infoLog: "☑File doesn't contain tracks which are not english or undefined! \n", + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_2.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map 0 -map -0:a:3 -c copy', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒File contains tracks which are not english or undefined. Removing! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_vdka_Remove_DataStreams.js b/tests/Community/Tdarr_Plugin_vdka_Remove_DataStreams.js new file mode 100644 index 0000000..74a9319 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_vdka_Remove_DataStreams.js @@ -0,0 +1,46 @@ +/* eslint max-len: 0 */ +const _ = require('lodash'); +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: false, + infoLog: '☑File has no data streams! \n☑File meets conditions! \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.ffProbeData.streams[1].codec_type = 'data'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0 -c copy -dn -map_chapters -1', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒File has data streams \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_vdka_Tiered_CPU_CRF_Based_Configurable.js b/tests/Community/Tdarr_Plugin_vdka_Tiered_CPU_CRF_Based_Configurable.js new file mode 100644 index 0000000..a916de0 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_vdka_Tiered_CPU_CRF_Based_Configurable.js @@ -0,0 +1,244 @@ +/* eslint max-len: 0 */ +const _ = require('lodash'); +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ' -map 0 -dn -c:v libx265 -preset slow -x265-params crf=22:bframes=8:rc-lookahead=32:ref=6:b-intra=1:aq-mode=3 -a53cc 0 -c:a copy -c:s copy -max_muxing_queue_size 9999', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is a video! \n' + + '☒File is not hevc!\n' + + '☑Preset set as slow\n' + + '☑File is 720p, using CRF value of 22!\n' + + 'File is being transcoded!\n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is a video! \n☑File is already in hevc! \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: { + sdCRF: '21', + hdCRF: '23', + fullhdCRF: '24', + uhdCRF: '29', + bframe: '10', + ffmpegPreset: 'medium', + sdDisabled: 'false', + uhdDisabled: 'false', + force10bit: 'force10bit', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ' -map 0 -dn -c:v libx265 -preset medium -x265-params crf=23:bframes=10:rc-lookahead=32:ref=6:b-intra=1:aq-mode=3 -a53cc 0 -c:a copy -c:s copy -max_muxing_queue_size 9999', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is a video! \n' + + '☒File is not hevc!\n' + + '☑Preset set as medium\n' + + '☑File is 720p, using CRF value of 23!\n' + + 'File is being transcoded!\n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.video_resolution = '480p'; + return file; + })(), + librarySettings: {}, + inputs: { + sdCRF: '21', + hdCRF: '23', + fullhdCRF: '24', + uhdCRF: '29', + bframe: '10', + ffmpegPreset: 'medium', + sdDisabled: 'false', + uhdDisabled: 'false', + force10bit: 'force10bit', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ' -map 0 -dn -c:v libx265 -preset medium -x265-params crf=21:bframes=10:rc-lookahead=32:ref=6:b-intra=1:aq-mode=3 -a53cc 0 -c:a copy -c:s copy -max_muxing_queue_size 9999', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is a video! \n' + + '☒File is not hevc!\n' + + '☑Preset set as medium\n' + + '☑File is 480p, using CRF value of 21!\n' + + 'File is being transcoded!\n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.video_resolution = '480p'; + return file; + })(), + librarySettings: {}, + inputs: { + sdCRF: '21', + hdCRF: '23', + fullhdCRF: '24', + uhdCRF: '29', + bframe: '10', + ffmpegPreset: 'medium', + sdDisabled: 'true', + uhdDisabled: 'false', + force10bit: 'force10bit', + }, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is a video! \n☒File is SD and disabled, not processing\n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.video_resolution = '4KUHD'; + return file; + })(), + librarySettings: {}, + inputs: { + sdCRF: '21', + hdCRF: '23', + fullhdCRF: '24', + uhdCRF: '29', + bframe: '10', + ffmpegPreset: 'medium', + sdDisabled: 'false', + uhdDisabled: 'false', + force10bit: 'force10bit', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ' -map 0 -dn -c:v libx265 -preset medium -x265-params crf=29:bframes=10:rc-lookahead=32:ref=6:b-intra=1:aq-mode=3 -a53cc 0 -c:a copy -c:s copy -max_muxing_queue_size 9999', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is a video! \n' + + '☒File is not hevc!\n' + + '☑Preset set as medium\n' + + '☑File is 4KUHD, using CRF value of 29!\n' + + 'File is being transcoded!\n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.video_resolution = '4KUHD'; + return file; + })(), + librarySettings: {}, + inputs: { + sdCRF: '21', + hdCRF: '23', + fullhdCRF: '24', + uhdCRF: '29', + bframe: '10', + ffmpegPreset: 'medium', + sdDisabled: 'false', + uhdDisabled: 'true', + force10bit: 'force10bit', + }, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is a video! \n☒File is 4k/UHD and disabled, not processing\n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.video_resolution = '1080p'; + return file; + })(), + librarySettings: {}, + inputs: { + sdCRF: '21', + hdCRF: '23', + fullhdCRF: '24', + uhdCRF: '29', + bframe: '10', + ffmpegPreset: 'medium', + sdDisabled: 'false', + uhdDisabled: 'false', + force10bit: 'force10bit', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ' -map 0 -dn -c:v libx265 -preset medium -x265-params crf=24:bframes=10:rc-lookahead=32:ref=6:b-intra=1:aq-mode=3 -a53cc 0 -c:a copy -c:s copy -max_muxing_queue_size 9999', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is a video! \n' + + '☒File is not hevc!\n' + + '☑Preset set as medium\n' + + '☑File is 1080p, using CRF value of 24!\n' + + 'File is being transcoded!\n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_vdka_Tiered_NVENC_CQV_BASED_CONFIGURABLE.js b/tests/Community/Tdarr_Plugin_vdka_Tiered_NVENC_CQV_BASED_CONFIGURABLE.js new file mode 100644 index 0000000..fa423cf --- /dev/null +++ b/tests/Community/Tdarr_Plugin_vdka_Tiered_NVENC_CQV_BASED_CONFIGURABLE.js @@ -0,0 +1,170 @@ +/* eslint max-len: 0 */ +const _ = require('lodash'); +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-c:v h264_cuvid,-map 0 -dn -c:v hevc_nvenc -b:v 0 -preset slow -cq 23 -rc-lookahead 32 -bf 0 -a53cc 0 -c:a copy -c:s copy', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is a video! \n' + + '☑Preset set as slow\n' + + '☑File is 720p, using CQ:V value of 23!\n' + + '☒File is not hevc!\n' + + 'File is being transcoded!\n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: true, + infoLog: '☑File is a video! \n☑File is already in hevc! \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: { + sdCQV: '22', + hdCQV: '24', + fullhdCQV: '26', + uhdCQV: '29', + bframe: '5', + ffmpeg_preset: 'medium', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-c:v h264_cuvid,-map 0 -dn -c:v hevc_nvenc -b:v 0 -preset medium -cq 24 -rc-lookahead 32 -bf 5 -a53cc 0 -c:a copy -c:s copy', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is a video! \n' + + '☑Preset set as medium\n' + + '☑File is 720p, using CQ:V value of 24!\n' + + '☒File is not hevc!\n' + + 'File is being transcoded!\n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.video_resolution = '480p'; + return file; + })(), + librarySettings: {}, + inputs: { + sdCQV: '22', + hdCQV: '24', + fullhdCQV: '26', + uhdCQV: '29', + bframe: '5', + ffmpeg_preset: 'medium', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-c:v h264_cuvid,-map 0 -dn -c:v hevc_nvenc -b:v 0 -preset medium -cq 22 -rc-lookahead 32 -bf 5 -a53cc 0 -c:a copy -c:s copy', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is a video! \n' + + '☑Preset set as medium\n' + + '☑File is 480p, using CQ:V value of 22!\n' + + '☒File is not hevc!\n' + + 'File is being transcoded!\n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.video_resolution = '1080p'; + return file; + })(), + librarySettings: {}, + inputs: { + sdCQV: '22', + hdCQV: '24', + fullhdCQV: '26', + uhdCQV: '29', + bframe: '5', + ffmpeg_preset: 'medium', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-c:v h264_cuvid,-map 0 -dn -c:v hevc_nvenc -b:v 0 -preset medium -cq 26 -rc-lookahead 32 -bf 5 -a53cc 0 -c:a copy -c:s copy', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is a video! \n' + + '☑Preset set as medium\n' + + '☑File is 1080p, using CQ:V value of 26!\n' + + '☒File is not hevc!\n' + + 'File is being transcoded!\n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.video_resolution = '4KUHD'; + return file; + })(), + librarySettings: {}, + inputs: { + sdCQV: '22', + hdCQV: '24', + fullhdCQV: '26', + uhdCQV: '29', + bframe: '5', + ffmpeg_preset: 'medium', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-c:v h264_cuvid,-map 0 -dn -c:v hevc_nvenc -b:v 0 -preset medium -cq 29 -rc-lookahead 32 -bf 5 -a53cc 0 -c:a copy -c:s copy', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is a video! \n' + + '☑Preset set as medium\n' + + '☑File is 4KUHD, using CQ:V value of 29!\n' + + '☒File is not hevc!\n' + + 'File is being transcoded!\n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_x7ab_Remove_Subs.js b/tests/Community/Tdarr_Plugin_x7ab_Remove_Subs.js new file mode 100644 index 0000000..9eca971 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_x7ab_Remove_Subs.js @@ -0,0 +1,42 @@ +/* eslint max-len: 0 */ +const _ = require('lodash'); +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: false, + infoLog: '☑File has no subs \n☑File meets conditions! \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_2.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-sn -map 0 -c copy', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒File has subs \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_x7ac_Remove_Closed_Captions.js b/tests/Community/Tdarr_Plugin_x7ac_Remove_Closed_Captions.js new file mode 100644 index 0000000..01df48b --- /dev/null +++ b/tests/Community/Tdarr_Plugin_x7ac_Remove_Closed_Captions.js @@ -0,0 +1,67 @@ +/* eslint max-len: 0 */ +const _ = require('lodash'); +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: ',-map 0 -codec copy -bsf:v "filter_units=remove_types=6"', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑Closed captions have not been detected on this file \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.hasClosedCaptions = true; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0 -codec copy -bsf:v "filter_units=remove_types=6"', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒This file has closed captions \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.ffProbeData.streams[0].closed_captions = 1; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0 -codec copy -bsf:v "filter_units=remove_types=6"', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒This file has burnt closed captions \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_z0ab_TheRealShadoh_FFmpeg_Subs_H264_Medium.js b/tests/Community/Tdarr_Plugin_z0ab_TheRealShadoh_FFmpeg_Subs_H264_Medium.js new file mode 100644 index 0000000..7f04b00 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_z0ab_TheRealShadoh_FFmpeg_Subs_H264_Medium.js @@ -0,0 +1,111 @@ +/* eslint max-len: 0 */ +const _ = require('lodash'); +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is already in h264! \n☒File has title metadata \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v libx264 -preset medium -c:a aac -c:s mov_text', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒File is not in h264! \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.meta.Title = undefined; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: '☑File is already in h264! \n' + + '☑File has no title metadata \n' + + '☑File has aac track \n' + + '☑File has no/compatible subs \n' + + '☑File meets conditions! \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.meta.Title = undefined; + file.ffProbeData.streams[1].codec_name = 'ac3'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is already in h264! \n' + + '☑File has no title metadata \n' + + '☒File has no aac track \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_2.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: false, + infoLog: '☑File is already in h264! \n' + + '☑File has no title metadata \n' + + '☑File has aac track \n' + + '☒File has incompatible subs \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_z1ab_TheRealShadoh_FFmpeg_Subs_H264_Fast.js b/tests/Community/Tdarr_Plugin_z1ab_TheRealShadoh_FFmpeg_Subs_H264_Fast.js new file mode 100644 index 0000000..56e03e7 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_z1ab_TheRealShadoh_FFmpeg_Subs_H264_Fast.js @@ -0,0 +1,111 @@ +/* eslint max-len: 0 */ +const _ = require('lodash'); +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is already in h264! \n☒File has title metadata \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v libx264 -preset fast -c:a aac -c:s mov_text', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒File is not in h264! \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.meta.Title = undefined; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: '☑File is already in h264! \n' + + '☑File has no title metadata \n' + + '☑File has aac track \n' + + '☑File has no/compatible subs \n' + + '☑File meets conditions! \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.meta.Title = undefined; + file.ffProbeData.streams[1].codec_name = 'ac3'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is already in h264! \n' + + '☑File has no title metadata \n' + + '☒File has no aac track \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_2.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is already in h264! \n' + + '☑File has no title metadata \n' + + '☑File has aac track \n' + + '☒File has incompatible subs \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_z2ab_TheRealShadoh_FFmpeg_Subs_H264_Slow.js b/tests/Community/Tdarr_Plugin_z2ab_TheRealShadoh_FFmpeg_Subs_H264_Slow.js new file mode 100644 index 0000000..3d37593 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_z2ab_TheRealShadoh_FFmpeg_Subs_H264_Slow.js @@ -0,0 +1,111 @@ +/* eslint max-len: 0 */ +const _ = require('lodash'); +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is already in h264! \n☒File has title metadata \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v libx264 -preset slow -c:a aac -c:s mov_text', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒File is not in h264! \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.meta.Title = undefined; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: '☑File is already in h264! \n' + + '☑File has no title metadata \n' + + '☑File has aac track \n' + + '☑File has no/compatible subs \n' + + '☑File meets conditions! \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.meta.Title = undefined; + file.ffProbeData.streams[1].codec_name = 'ac3'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is already in h264! \n' + + '☑File has no title metadata \n' + + '☒File has no aac track \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_2.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is already in h264! \n' + + '☑File has no title metadata \n' + + '☑File has aac track \n' + + '☒File has incompatible subs \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_z3ab_TheRealShadoh_FFmpeg_Subs_H264_VeryFast.js b/tests/Community/Tdarr_Plugin_z3ab_TheRealShadoh_FFmpeg_Subs_H264_VeryFast.js new file mode 100644 index 0000000..8216fb3 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_z3ab_TheRealShadoh_FFmpeg_Subs_H264_VeryFast.js @@ -0,0 +1,111 @@ +/* eslint max-len: 0 */ +const _ = require('lodash'); +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is already in h264! \n☒File has title metadata \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map_metadata -1 -map 0:v -map 0:s? -map 0:a -c:v libx264 -preset veryfast -c:a aac -c:s mov_text', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒File is not in h264! \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.meta.Title = undefined; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: '☑File is already in h264! \n' + + '☑File has no title metadata \n' + + '☑File has aac track \n' + + '☑File has no/compatible subs \n' + + '☑File meets conditions! \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.meta.Title = undefined; + file.ffProbeData.streams[1].codec_name = 'ac3'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map 0:v -map 0:s? -map 0:a -c:v copy -c:a aac -c:s mov_text', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is already in h264! \n' + + '☑File has no title metadata \n' + + '☒File has no aac track \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_2.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map 0:v -map 0:s? -map 0:a -c:v copy -c:a copy -c:s mov_text', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is already in h264! \n' + + '☑File has no title metadata \n' + + '☑File has aac track \n' + + '☒File has incompatible subs \n', + }, + }, +]; + +run(tests); diff --git a/tests/helpers/run.js b/tests/helpers/run.js index 58b6e05..ff1dabf 100644 --- a/tests/helpers/run.js +++ b/tests/helpers/run.js @@ -2,6 +2,7 @@ const path = require('path'); const chai = require('chai'); const _ = require('lodash'); const importFresh = require('import-fresh'); +const os = require('os'); const scriptName = path.basename(process.mainModule.filename); @@ -9,40 +10,53 @@ const run = async (tests) => { try { for (let i = 0; i < tests.length; i += 1) { // eslint-disable-next-line no-console - console.log(`${scriptName}: test ${i}`); + console.log(`[${os.platform()}] ${scriptName}: test ${i}`); const test = tests[i]; - let testOutput; - let errorEncountered = false; - // eslint-disable-next-line import/no-dynamic-require - const { plugin } = importFresh(`../../Community/${scriptName}`); - - try { - // eslint-disable-next-line no-await-in-loop - testOutput = await plugin( - _.cloneDeep(test.input.file), - _.cloneDeep(test.input.librarySettings), - _.cloneDeep(test.input.inputs), - _.cloneDeep(test.input.otherArguments), - ); - } catch (err1) { - errorEncountered = err1; - } - - if (test.outputModify) { - testOutput = test.outputModify(test.output); - } - - if (test.error && test.error.shouldThrow) { - if (errorEncountered !== false) { - // eslint-disable-next-line no-console - console.log(errorEncountered); - chai.assert.deepEqual(errorEncountered.message, test.output); - } else { - throw new Error('Expected plugin error but none was thrown!'); - } + let expectedOutput; + if (test.output[os.platform()] !== undefined) { + expectedOutput = test.output[os.platform()]; } else { - chai.assert.deepEqual(testOutput, test.output); + expectedOutput = test.output; + } + + if (expectedOutput === false) { + // skip test due to OS + // eslint-disable-next-line no-console + console.log(`Test not meant to run on ${os.platform()}, skipping`); + } else { + let testOutput; + let errorEncountered = false; + // eslint-disable-next-line import/no-dynamic-require + const { plugin } = importFresh(`../../Community/${scriptName}`); + + try { + // eslint-disable-next-line no-await-in-loop + testOutput = await plugin( + _.cloneDeep(test.input.file), + _.cloneDeep(test.input.librarySettings), + _.cloneDeep(test.input.inputs), + _.cloneDeep(test.input.otherArguments), + ); + } catch (err1) { + errorEncountered = err1; + } + + if (test.outputModify) { + testOutput = test.outputModify(testOutput); + } + + if (test.error && test.error.shouldThrow) { + if (errorEncountered !== false) { + // eslint-disable-next-line no-console + console.log(errorEncountered); + chai.assert.deepEqual(errorEncountered.message, expectedOutput); + } else { + throw new Error('Expected plugin error but none was thrown!'); + } + } else { + chai.assert.deepEqual(testOutput, expectedOutput); + } } } } catch (err) { diff --git a/tests/runTests.js b/tests/runTests.js index d5d7285..c96915d 100644 --- a/tests/runTests.js +++ b/tests/runTests.js @@ -6,45 +6,71 @@ const childProcess = require('child_process'); const filenames = fs.readdirSync(`${process.cwd()}/Community`).reverse(); +const errorsEncountered = []; const run = async () => { + const pluginsToRun = []; for (let i = 0; i < filenames.length; i += 1) { - const pluginPath = `${process.cwd()}/Community/${filenames[i]}`; + const filename = filenames[i]; + const pluginPath = `${process.cwd()}/Community/${filename}`; const text = fs.readFileSync(pluginPath); - const pluginTestpath = `${__dirname}/Community/${filenames[i]}`; + const pluginTestpath = `${__dirname}/Community/${filename}`; - let shouldRunTest = true; if (!text.includes('// tdarrSkipTest') && !fs.existsSync(pluginTestpath)) { - console.log(chalk.red(`${filenames[i]} does not have a test but should do.`)); + console.log(chalk.red(`${filename} does not have a test but should do.`)); process.exit(1); } else if (!text.includes('// tdarrSkipTest') && fs.existsSync(pluginTestpath)) { - console.log(chalk.white(`${filenames[i]} running test`)); + pluginsToRun.push({ + filename, + pluginTestpath, + }); } else if (text.includes('// tdarrSkipTest') && fs.existsSync(pluginTestpath)) { - console.log(chalk.red(`${filenames[i]} should have // tdarrSkipTest removed`)); + console.log(chalk.red(`${filename} should have // tdarrSkipTest removed`)); process.exit(1); } else if (text.includes('// tdarrSkipTest') && !fs.existsSync(pluginTestpath)) { - console.log(chalk.yellow(`${filenames[i]} skipping tests`)); - shouldRunTest = false; + console.log(chalk.yellow(`${filename} skipping tests`)); } + } - if (shouldRunTest) { - // eslint-disable-next-line no-await-in-loop - await new Promise((resolve) => { - childProcess.exec(`node "${pluginTestpath}"`, (err, stdout, stderr) => { - if (err) { - console.log(err); - } - console.log(stdout); - console.log(chalk.red(stderr)); - }).on('exit', async (code) => { - if (code !== 0) { - await new Promise((resolve2) => setTimeout(resolve2, 1000)); - process.exit(1); - } else { - resolve(); - } + let pluginsFinished = 0; + for (let i = 0; i < pluginsToRun.length; i += 1) { + const { filename } = pluginsToRun[i]; + const { pluginTestpath } = pluginsToRun[i]; + console.log(chalk.white(`${filename} running test`)); + + const output = {}; + childProcess.exec(`node "${pluginTestpath}"`, (err, stdout, stderr) => { + if (err) { + output.err = err; + } + output.stdout = stdout; + output.stderr = stderr; + // eslint-disable-next-line no-loop-func + }).on('exit', async (code) => { + if (code !== 0) { + await new Promise((resolve2) => setTimeout(resolve2, 1000)); + errorsEncountered.push({ + id: filenames[i], + ...output, }); - }); - } + } + + pluginsFinished += 1; + + if (pluginsFinished === pluginsToRun.length) { + if (errorsEncountered.length > 0) { + errorsEncountered.forEach((plugin) => { + console.log(plugin.id); + console.log(chalk.red(plugin.err)); + console.log(plugin.stdout); + console.log(chalk.red(plugin.stderr)); + }); + process.exit(1); + } else { + console.log(chalk.green('No errors encountered!')); + process.exit(0); + } + } + }); } };