diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 9c76f0f..042233b 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -20,4 +20,4 @@ jobs: with: node-version: ${{ matrix.node-version }} - run: npm i - - run: npm run checkPlugins && npm run lint + - run: npm run checkPlugins && npm run lint && npm run test diff --git a/Community/Tdarr_Plugin_00td_action_handbrake_ffmpeg_custom.js b/Community/Tdarr_Plugin_00td_action_handbrake_ffmpeg_custom.js index 3c3871d..995603e 100644 --- a/Community/Tdarr_Plugin_00td_action_handbrake_ffmpeg_custom.js +++ b/Community/Tdarr_Plugin_00td_action_handbrake_ffmpeg_custom.js @@ -84,8 +84,8 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { processFile: false, preset: '', container: '', - handBrakeMode: false, - FFmpegMode: false, + handbrakeMode: false, + ffmpegMode: false, reQueueAfter: false, infoLog: '', }; diff --git a/Community/Tdarr_Plugin_00td_action_re_order_all_streams_v2.js b/Community/Tdarr_Plugin_00td_action_re_order_all_streams_v2.js index 691b173..4f162b2 100644 --- a/Community/Tdarr_Plugin_00td_action_re_order_all_streams_v2.js +++ b/Community/Tdarr_Plugin_00td_action_re_order_all_streams_v2.js @@ -117,7 +117,7 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { for (let i = 0; i < items.length; i += 1) { const matchedStreams = []; for (let j = 0; j < streams.length; j += 1) { - if (String(sortType.getValue(streams[j])).includes(String(items[i]))) { + if (String(sortType.getValue(streams[j])) === String(items[i])) { if ( streams[j].codec_long_name && ( diff --git a/Community/Tdarr_Plugin_078d_Output_embedded_subs_to_SRT_and_remove.js b/Community/Tdarr_Plugin_078d_Output_embedded_subs_to_SRT_and_remove.js index 5198704..5a868a5 100644 --- a/Community/Tdarr_Plugin_078d_Output_embedded_subs_to_SRT_and_remove.js +++ b/Community/Tdarr_Plugin_078d_Output_embedded_subs_to_SRT_and_remove.js @@ -1,4 +1,5 @@ /* eslint-disable */ +// tdarrSkipTest const details = () => { return { id: "Tdarr_Plugin_078d_Output_embedded_subs_to_SRT_and_remove", diff --git a/Community/Tdarr_Plugin_43az_add_to_radarr.js b/Community/Tdarr_Plugin_43az_add_to_radarr.js index eff190d..8129e09 100644 --- a/Community/Tdarr_Plugin_43az_add_to_radarr.js +++ b/Community/Tdarr_Plugin_43az_add_to_radarr.js @@ -1,4 +1,5 @@ /* eslint-disable */ +// tdarrSkipTest const details = () => { return { id: 'Tdarr_Plugin_43az_add_to_radarr', diff --git a/Community/Tdarr_Plugin_ER01_Transcode audio and video with HW (PC and Mac).js b/Community/Tdarr_Plugin_ER01_Transcode audio and video with HW (PC and Mac).js index d7cd530..e52695c 100644 --- a/Community/Tdarr_Plugin_ER01_Transcode audio and video with HW (PC and Mac).js +++ b/Community/Tdarr_Plugin_ER01_Transcode audio and video with HW (PC and Mac).js @@ -203,6 +203,7 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { if (inputs.bitrate_cutoff !== '') { // Checks if currentBitrate is below inputs.bitrate_cutoff // If so then don't convert video. + console.log(currentBitrate) if (currentBitrate <= inputs.bitrate_cutoff) { convertVideo = false; } diff --git a/Community/Tdarr_Plugin_JB69_JBHEVCQSV_MinimalFile.js b/Community/Tdarr_Plugin_JB69_JBHEVCQSV_MinimalFile.js index afa0182..2b685a3 100644 --- a/Community/Tdarr_Plugin_JB69_JBHEVCQSV_MinimalFile.js +++ b/Community/Tdarr_Plugin_JB69_JBHEVCQSV_MinimalFile.js @@ -86,6 +86,7 @@ Audio: (Only one audio stream is used!!) /// /////////////////////////////////////////////////////////////////////////////////////////////////// */ +// tdarrSkipTest const details = () => ({ id: 'Tdarr_Plugin_JB69_JBHEVCQSV_MinimalFile', Stage: 'Pre-processing', diff --git a/Community/Tdarr_Plugin_JB69_JBHEVCQSZ_PostFix.js b/Community/Tdarr_Plugin_JB69_JBHEVCQSZ_PostFix.js index 7459154..50277de 100644 --- a/Community/Tdarr_Plugin_JB69_JBHEVCQSZ_PostFix.js +++ b/Community/Tdarr_Plugin_JB69_JBHEVCQSZ_PostFix.js @@ -148,6 +148,7 @@ // ////////////////////////////////////////////////////////////////////////////////////////////////////// +// tdarrSkipTest const details = () => { return { id: "Tdarr_Plugin_JB69_JBHEVCQSZ_PostFix", diff --git a/Community/Tdarr_Plugin_MC93_MigzPlex_Autoscan.js b/Community/Tdarr_Plugin_MC93_MigzPlex_Autoscan.js index fb77764..f29ce6f 100644 --- a/Community/Tdarr_Plugin_MC93_MigzPlex_Autoscan.js +++ b/Community/Tdarr_Plugin_MC93_MigzPlex_Autoscan.js @@ -3,6 +3,7 @@ module.exports.dependencies = [ ]; /* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +// tdarrSkipTest const details = () => ({ id: 'Tdarr_Plugin_MC93_MigzPlex_Autoscan', Stage: 'Post-processing', diff --git a/Community/Tdarr_Plugin_NIfPZuCLU_2_Pass_Loudnorm_Audio_Normalisation.js b/Community/Tdarr_Plugin_NIfPZuCLU_2_Pass_Loudnorm_Audio_Normalisation.js index 1cbe2bf..dac17b6 100644 --- a/Community/Tdarr_Plugin_NIfPZuCLU_2_Pass_Loudnorm_Audio_Normalisation.js +++ b/Community/Tdarr_Plugin_NIfPZuCLU_2_Pass_Loudnorm_Audio_Normalisation.js @@ -14,6 +14,7 @@ var secondPass = false; var logOutFile = ''; +// tdarrSkipTest const details = () => { return { id: "Tdarr_Plugin_NIfPZuCLU_2_Pass_Loudnorm_Audio_Normalisation", diff --git a/Community/Tdarr_Plugin_O8O0dCTlb_Set_File_Permissions_For_UnRaid.js b/Community/Tdarr_Plugin_O8O0dCTlb_Set_File_Permissions_For_UnRaid.js index d79f302..d083a33 100644 --- a/Community/Tdarr_Plugin_O8O0dCTlb_Set_File_Permissions_For_UnRaid.js +++ b/Community/Tdarr_Plugin_O8O0dCTlb_Set_File_Permissions_For_UnRaid.js @@ -1,6 +1,7 @@ /* eslint-disable */ +// tdarrSkipTest const details = () => { return { id: "Tdarr_Plugin_O8O0dCTlb_Set_File_Permissions_For_UnRaid", diff --git a/Community/Tdarr_Plugin_SV6x_Smoove1FFMPEG_NVENC_H264.js b/Community/Tdarr_Plugin_SV6x_Smoove1FFMPEG_NVENC_H264.js index eef3529..b91e1a9 100644 --- a/Community/Tdarr_Plugin_SV6x_Smoove1FFMPEG_NVENC_H264.js +++ b/Community/Tdarr_Plugin_SV6x_Smoove1FFMPEG_NVENC_H264.js @@ -3,6 +3,7 @@ // 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_TD01_TOAD_Autoscan.js b/Community/Tdarr_Plugin_TD01_TOAD_Autoscan.js index 63d5ec6..86c6dea 100644 --- a/Community/Tdarr_Plugin_TD01_TOAD_Autoscan.js +++ b/Community/Tdarr_Plugin_TD01_TOAD_Autoscan.js @@ -4,6 +4,7 @@ module.exports.dependencies = [ ]; /* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +// tdarrSkipTest const details = () => ({ id: 'Tdarr_Plugin_TD01_TOAD_Autoscan', Stage: 'Post-processing', 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 1412281..e5bf1af 100644 --- a/Community/Tdarr_Plugin_VP92_VP9_Match_Bitrate_One_Pass.js +++ b/Community/Tdarr_Plugin_VP92_VP9_Match_Bitrate_One_Pass.js @@ -1,4 +1,5 @@ /* 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 4cda5ca..6f1fcc5 100644 --- a/Community/Tdarr_Plugin_a9hf_New_file_duration_check.js +++ b/Community/Tdarr_Plugin_a9hf_New_file_duration_check.js @@ -1,5 +1,6 @@ // 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_da11_Dallas_FFmpeg_Presets_H264_MP4.js b/Community/Tdarr_Plugin_da11_Dallas_FFmpeg_Presets_H264_MP4.js index c1ebc6a..2dc1a31 100644 --- a/Community/Tdarr_Plugin_da11_Dallas_FFmpeg_Presets_H264_MP4.js +++ b/Community/Tdarr_Plugin_da11_Dallas_FFmpeg_Presets_H264_MP4.js @@ -62,6 +62,7 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { const lib = require('../methods/lib')(); // eslint-disable-next-line no-unused-vars,no-param-reassign inputs = lib.loadDefaultValues(inputs, details); + var response = { processFile: false, preset: "", @@ -70,15 +71,17 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { FFmpegMode: false, reQueueAfter: false, infoLog: "", - addInfo(status, info) { - this.infoLog += (status ? "☑" : "☒") + " " + info + "\n"; - }, + }; + const addInfo = (status, info) => { + response.infoLog += (status ? "☑" : "☒") + " " + info + "\n"; + } + // Check the file is a video if (file.fileMedium !== "video") { console.log("File is not video"); - response.addInfo(BAD, `File is not video`); + addInfo(BAD, `File is not video`); response.processFile = false; return response; } @@ -87,7 +90,7 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { let preset = getPreset(inputs.FFmpeg_preset); if (preset === null) { - response.addInfo( + addInfo( BAD, `Invalid Preset, \"${inputs.FFmpeg_preset}\" please select from (slow,medium,fast,veryfast)` ); @@ -125,10 +128,10 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { } if (hasBadSubs) - response.addInfo(BAD, "File contains unsupported sub(s), dropping these!"); + addInfo(BAD, "File contains unsupported sub(s), dropping these!"); if (file.ffProbeData.streams[0].codec_name != "h264") { - response.addInfo(BAD, "File is not in h264!"); + addInfo(BAD, "File is not in h264!"); response.preset = ", -map_metadata -1 -map 0:V " + subMap + @@ -139,11 +142,11 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { response.FFmpegMode = true; return response; } else { - response.addInfo(GOOD, "File is already in h264!"); + addInfo(GOOD, "File is already in h264!"); } if (file.meta.Title != undefined && !jsonString.includes("aac") && hasSubs) { - response.addInfo(BAD, "File has title metadata and no aac and subs"); + addInfo(BAD, "File has title metadata and no aac and subs"); response.preset = ", -map_metadata -1 -map 0:v " + subMap + @@ -156,7 +159,7 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { } if (!jsonString.includes("aac") && hasSubs) { - response.addInfo(BAD, "File has no aac track and has subs"); + addInfo(BAD, "File has no aac track and has subs"); response.preset = ", -map 0:v " + subMap + @@ -169,7 +172,7 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { } if (file.meta.Title != undefined && hasSubs) { - response.addInfo(BAD, "File has title and has subs"); + addInfo(BAD, "File has title and has subs"); response.preset = ", -map_metadata -1 -map 0:v " + subMap + @@ -182,7 +185,7 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { } if (file.meta.Title != undefined) { - response.addInfo(BAD, "File has title metadata"); + addInfo(BAD, "File has title metadata"); response.preset = ", -map_metadata -1 -map 0:v " + subMap + @@ -193,11 +196,11 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { response.FFmpegMode = true; return response; } else { - response.addInfo(GOOD, "File has no title metadata"); + addInfo(GOOD, "File has no title metadata"); } if (!jsonString.includes("aac")) { - response.addInfo(BAD, "File has no aac track"); + addInfo(BAD, "File has no aac track"); response.preset = ", -map 0:v " + subMap + @@ -208,14 +211,14 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { response.FFmpegMode = true; return response; } else { - response.addInfo(GOOD, "File has aac track"); + addInfo(GOOD, "File has aac track"); } if (hasSubs) { if (hasBadSubs) { - response.addInfo(BAD, "File has incompatible subs, dropping these..."); + addInfo(BAD, "File has incompatible subs, dropping these..."); } else { - response.addInfo(BAD, "File has compatible subs, copying..."); + addInfo(BAD, "File has compatible subs, copying..."); } response.preset = ", -map 0:v " + subMap + " -map 0:a -c:v copy -c:a copy " + subType; @@ -223,10 +226,10 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { response.FFmpegMode = true; return response; } else { - response.addInfo(GOOD, "File has no/compatible subs"); + addInfo(GOOD, "File has no/compatible subs"); } - response.addInfo(GOOD, "File meets conditions!"); + addInfo(GOOD, "File meets conditions!"); return response; } diff --git a/Community/Tdarr_Plugin_drdd_standardise_all_in_one.js b/Community/Tdarr_Plugin_drdd_standardise_all_in_one.js index 9fdd9f8..608b0f5 100644 --- a/Community/Tdarr_Plugin_drdd_standardise_all_in_one.js +++ b/Community/Tdarr_Plugin_drdd_standardise_all_in_one.js @@ -4,14 +4,14 @@ const details = () => { return { id: "Tdarr_Plugin_drdd_standardise_all_in_one", Stage: "Pre-processing", - Name: "DrDD H265 MKV AC3 audio subtitles [QSV & NVENC]", + Name: "DrDD H265 MKV AC3 audio subtitles [VAAPI & NVENC]", Stage: "Pre-processing", Type: "Video", Operation: "Transcode", Description: "In a single pass ensures all files are in MKV containers and where possible encoded in h265 (settings dependant on file bitrate), converts all multi channel audio to AC3, removes audio commentary and removes subtitles that are not in the configured language or marked as commentary. This plugin is opinionated based on how I like my library to be configured and based on the work done by Migz with his plugins (Thanks!).", Version: "1.0", - Tags: "pre-processing,ffmpeg,qsv h265, nvenc h265", + Tags: "pre-processing,ffmpeg,vaapi,h265, nvenc h265", Inputs: [ { name: "nvenc", @@ -346,7 +346,7 @@ function buildVideoConfiguration(inputs, file, logger) { configuration.RemoveOutputSetting("-c:v copy"); configuration.AddOutputSetting(`-c:v hevc_vaapi ${bitrateSettings}`); - logger.AddError("Transcoding to HEVC using QSV"); + logger.AddError("Transcoding to HEVC using VAAPI"); } /** diff --git a/Community/Tdarr_Plugin_e5c3_CnT_Add_Subtitles.js b/Community/Tdarr_Plugin_e5c3_CnT_Add_Subtitles.js index 967339c..7b56fdf 100644 --- a/Community/Tdarr_Plugin_e5c3_CnT_Add_Subtitles.js +++ b/Community/Tdarr_Plugin_e5c3_CnT_Add_Subtitles.js @@ -1,5 +1,6 @@ /* eslint-disable */ +// tdarrSkipTest const details = () => { return { id: "Tdarr_Plugin_e5c3_CnT_Add_Subtitles", diff --git a/Community/Tdarr_Plugin_e5c3_CnT_Remove_Letterbox.js b/Community/Tdarr_Plugin_e5c3_CnT_Remove_Letterbox.js index 6b0b0ea..d4b8266 100644 --- a/Community/Tdarr_Plugin_e5c3_CnT_Remove_Letterbox.js +++ b/Community/Tdarr_Plugin_e5c3_CnT_Remove_Letterbox.js @@ -1,5 +1,6 @@ /* eslint-disable */ +// tdarrSkipTest const details = () => { return { id: "Tdarr_Plugin_e5c3_CnT_Remove_Letterbox", diff --git a/Community/Tdarr_Plugin_goof1_URL_Plex_Refresh.js b/Community/Tdarr_Plugin_goof1_URL_Plex_Refresh.js index 7644d98..9afa86a 100644 --- a/Community/Tdarr_Plugin_goof1_URL_Plex_Refresh.js +++ b/Community/Tdarr_Plugin_goof1_URL_Plex_Refresh.js @@ -1,3 +1,4 @@ +// tdarrSkipTest const details = () => ({ id: 'Tdarr_Plugin_goof1_URL_Plex_Refresh', Stage: 'Post-processing', diff --git a/Community/Tdarr_Plugin_henk_Keep_Native_Lang_Plus_Eng.js b/Community/Tdarr_Plugin_henk_Keep_Native_Lang_Plus_Eng.js index 4aa06ae..243b675 100644 --- a/Community/Tdarr_Plugin_henk_Keep_Native_Lang_Plus_Eng.js +++ b/Community/Tdarr_Plugin_henk_Keep_Native_Lang_Plus_Eng.js @@ -1,5 +1,6 @@ /* eslint-disable no-await-in-loop */ module.exports.dependencies = ['axios', '@cospired/i18n-iso-languages']; +// tdarrSkipTest const details = () => ({ id: 'Tdarr_Plugin_henk_Keep_Native_Lang_Plus_Eng', Stage: 'Pre-processing', diff --git a/Community/Tdarr_Plugin_jeons001_Downmix_to_stereo_and_apply_DRC.js b/Community/Tdarr_Plugin_jeons001_Downmix_to_stereo_and_apply_DRC.js index 95d04ec..8baf72e 100644 --- a/Community/Tdarr_Plugin_jeons001_Downmix_to_stereo_and_apply_DRC.js +++ b/Community/Tdarr_Plugin_jeons001_Downmix_to_stereo_and_apply_DRC.js @@ -23,9 +23,6 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { FFmpegMode: true, reQueueAfter: true, infoLog: '', - file, - removeFromDB: false, - updateDB: false, container: `.${file.container}`, }; diff --git a/Community/Tdarr_Plugin_rr01_drpeppershaker_extract_subs_to_SRT.js b/Community/Tdarr_Plugin_rr01_drpeppershaker_extract_subs_to_SRT.js index 4dcd6ee..75d5e77 100644 --- a/Community/Tdarr_Plugin_rr01_drpeppershaker_extract_subs_to_SRT.js +++ b/Community/Tdarr_Plugin_rr01_drpeppershaker_extract_subs_to_SRT.js @@ -1,3 +1,4 @@ +// tdarrSkipTest const details = () => ({ id: 'Tdarr_Plugin_rr01_drpeppershaker_extract_subs_to_SRT', 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 689d403..6c559b0 100644 --- a/Community/Tdarr_Plugin_s710_nick_h265_nvenc_4K.js +++ b/Community/Tdarr_Plugin_s710_nick_h265_nvenc_4K.js @@ -1,4 +1,5 @@ /* 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 d5d23f6..acf22fb 100644 --- a/Community/Tdarr_Plugin_s7x9_winsome_h265_10bit.js +++ b/Community/Tdarr_Plugin_s7x9_winsome_h265_10bit.js @@ -1,4 +1,5 @@ /* 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 f336a5e..447044d 100644 --- a/Community/Tdarr_Plugin_s7x9_winsome_h265_nvenc.js +++ b/Community/Tdarr_Plugin_s7x9_winsome_h265_nvenc.js @@ -1,4 +1,5 @@ /* 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 00df33b..8c8b8e2 100644 --- a/Community/Tdarr_Plugin_sdd3_Remove_Commentary_Tracks.js +++ b/Community/Tdarr_Plugin_sdd3_Remove_Commentary_Tracks.js @@ -1,4 +1,5 @@ /* 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 9be9ed1..71708c3 100644 --- a/Community/Tdarr_Plugin_sdf5_Thierrrrry_Remove_Non_English_Audio.js +++ b/Community/Tdarr_Plugin_sdf5_Thierrrrry_Remove_Non_English_Audio.js @@ -1,4 +1,5 @@ /* 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 634c9d3..64e71ef 100644 --- a/Community/Tdarr_Plugin_vdka_Remove_DataStreams.js +++ b/Community/Tdarr_Plugin_vdka_Remove_DataStreams.js @@ -1,4 +1,5 @@ /* 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 e1d5aee..f5614f8 100644 --- a/Community/Tdarr_Plugin_vdka_Tiered_CPU_CRF_Based_Configurable.js +++ b/Community/Tdarr_Plugin_vdka_Tiered_CPU_CRF_Based_Configurable.js @@ -1,3 +1,4 @@ +// 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 4afd5f3..e0ca948 100644 --- a/Community/Tdarr_Plugin_vdka_Tiered_NVENC_CQV_BASED_CONFIGURABLE.js +++ b/Community/Tdarr_Plugin_vdka_Tiered_NVENC_CQV_BASED_CONFIGURABLE.js @@ -1,4 +1,5 @@ /* 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 7bd12ff..3bf03de 100644 --- a/Community/Tdarr_Plugin_x7ab_Remove_Subs.js +++ b/Community/Tdarr_Plugin_x7ab_Remove_Subs.js @@ -1,4 +1,5 @@ /* 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 f5fe57a..26afd05 100644 --- a/Community/Tdarr_Plugin_x7ac_Remove_Closed_Captions.js +++ b/Community/Tdarr_Plugin_x7ac_Remove_Closed_Captions.js @@ -1,3 +1,4 @@ +// 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 88fc14e..716e730 100644 --- a/Community/Tdarr_Plugin_z0ab_TheRealShadoh_FFmpeg_Subs_H264_Medium.js +++ b/Community/Tdarr_Plugin_z0ab_TheRealShadoh_FFmpeg_Subs_H264_Medium.js @@ -1,3 +1,4 @@ +// tdarrSkipTest const details = () => ({ id: 'Tdarr_Plugin_z0ab_TheRealShadoh_FFmpeg_Subs_H264_Medium', Stage: 'Pre-processing', diff --git a/Community/Tdarr_Plugin_z18s_rename_files_based_on_codec.js b/Community/Tdarr_Plugin_z18s_rename_files_based_on_codec.js index db917e8..7cff564 100644 --- a/Community/Tdarr_Plugin_z18s_rename_files_based_on_codec.js +++ b/Community/Tdarr_Plugin_z18s_rename_files_based_on_codec.js @@ -1,5 +1,6 @@ /* eslint-disable */ +// tdarrSkipTest const details = () => { return { id: "Tdarr_Plugin_z18s_rename_files_based_on_codec", diff --git a/Community/Tdarr_Plugin_z18t_rename_files_based_on_codec_and_resolution.js b/Community/Tdarr_Plugin_z18t_rename_files_based_on_codec_and_resolution.js index d6adedd..1a2f75d 100644 --- a/Community/Tdarr_Plugin_z18t_rename_files_based_on_codec_and_resolution.js +++ b/Community/Tdarr_Plugin_z18t_rename_files_based_on_codec_and_resolution.js @@ -1,3 +1,4 @@ +// tdarrSkipTest const details = () => ({ id: 'Tdarr_Plugin_z18t_rename_files_based_on_codec_and_resolution', Stage: 'Post-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 fbc9de3..ad301d8 100644 --- a/Community/Tdarr_Plugin_z1ab_TheRealShadoh_FFmpeg_Subs_H264_Fast.js +++ b/Community/Tdarr_Plugin_z1ab_TheRealShadoh_FFmpeg_Subs_H264_Fast.js @@ -1,3 +1,4 @@ +// 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 28ee579..dc863a4 100644 --- a/Community/Tdarr_Plugin_z2ab_TheRealShadoh_FFmpeg_Subs_H264_Slow.js +++ b/Community/Tdarr_Plugin_z2ab_TheRealShadoh_FFmpeg_Subs_H264_Slow.js @@ -1,3 +1,4 @@ +// 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 597003f..be10d89 100644 --- a/Community/Tdarr_Plugin_z3ab_TheRealShadoh_FFmpeg_Subs_H264_VeryFast.js +++ b/Community/Tdarr_Plugin_z3ab_TheRealShadoh_FFmpeg_Subs_H264_VeryFast.js @@ -1,3 +1,4 @@ +// tdarrSkipTest const details = () => ({ id: 'Tdarr_Plugin_z3ab_TheRealShadoh_FFmpeg_Subs_H264_VeryFast', Stage: 'Pre-processing', diff --git a/Community/Tdarr_Plugin_z80t_keep_original_date.js b/Community/Tdarr_Plugin_z80t_keep_original_date.js index d7f6715..9364705 100644 --- a/Community/Tdarr_Plugin_z80t_keep_original_date.js +++ b/Community/Tdarr_Plugin_z80t_keep_original_date.js @@ -4,6 +4,7 @@ module.exports.dependencies = [ 'touch', ]; +// tdarrSkipTest const details = () => ({ id: 'Tdarr_Plugin_z80t_keep_original_date', Stage: 'Post-processing', diff --git a/package-lock.json b/package-lock.json index 5a261a7..136bce7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -174,6 +174,12 @@ "es-abstract": "^1.18.0-next.1" } }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, "ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", @@ -227,14 +233,27 @@ "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + }, + "chai": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + } }, "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -244,7 +263,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -253,7 +271,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "requires": { "color-name": "~1.1.4" } @@ -261,26 +278,29 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "requires": { "has-flag": "^4.0.0" } } } }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "dev": true + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -346,6 +366,15 @@ "ms": "2.1.2" } }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", @@ -474,6 +503,57 @@ "table": "^5.2.3", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "eslint-config-airbnb-base": { @@ -790,6 +870,12 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, "get-intrinsic": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.1.tgz", @@ -873,10 +959,9 @@ "dev": true }, "import-fresh": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz", - "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==", - "dev": true, + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -1091,8 +1176,16 @@ "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "loupe": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", + "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "dev": true, + "requires": { + "get-func-name": "^2.0.0" + } }, "lru-cache": { "version": "6.0.0", @@ -1249,7 +1342,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "requires": { "callsites": "^3.0.0" } @@ -1296,6 +1388,12 @@ "pify": "^2.0.0" } }, + "pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true + }, "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", @@ -1375,8 +1473,7 @@ "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" }, "rimraf": { "version": "3.0.2", @@ -1577,6 +1674,12 @@ "prelude-ls": "^1.2.1" } }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", diff --git a/package.json b/package.json index a1436a8..7897352 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,22 @@ { "name": "tdarr_plugins", "version": "1.0.0", - "description": "There are two types of plugin:", - "main": "Tdarr_Plugin_aaaa_Pre_Proc_Example.js", - "dependencies": {}, + "description": "Tdar Plugins Repo", + "main": "", + "dependencies": { + "chalk": "^4.1.2", + "import-fresh": "^3.3.0", + "lodash": "^4.17.21" + }, "devDependencies": { + "chai": "^4.3.6", "eslint": "^7.14.0", "eslint-config-airbnb-base": "^14.2.1", "eslint-plugin-import": "^2.22.1", "eslint-plugin-jsx-a11y": "^6.4.1" }, "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", + "test": "node ./tests/runTests.js", "lint": "eslint Community methods examples tests --ext js", "lint:fix": "eslint Community methods examples tests --ext js --fix", "checkPlugins": "node ./tests/checkPlugins.js" diff --git a/tests/Community/Tdarr_Plugin_00td_action_add_audio_stream_codec.js b/tests/Community/Tdarr_Plugin_00td_action_add_audio_stream_codec.js new file mode 100644 index 0000000..3862352 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_00td_action_add_audio_stream_codec.js @@ -0,0 +1,92 @@ +/* eslint max-len: 0 */ +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0:v -map 0:1 -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 aac -ac 2', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: true, + infoLog: 'The required channel count 2 is lower than the highest available channel count (6). Adding! \n', + handbrakeMode: false, + ffmpegMode: true, + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + audioCodec: 'eac3', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0:v -map 0:1 -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 eac3 -ac 2', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: true, + infoLog: 'The required channel count 2 is lower than the highest available channel count (6). Adding! \n', + handbrakeMode: false, + ffmpegMode: true, + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + audioCodec: 'eac3', + channels: 6, + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0:v -map 0:1 -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 eac3 -ac 6', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: true, + infoLog: 'The required channel count 6 is lower than the highest available channel count (6). Adding! \n', + handbrakeMode: false, + ffmpegMode: true, + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + audioCodec: 'eac3', + channels: 8, + language: 'fr', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0:v -map 0:1 -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 eac3 -ac 6', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: true, + infoLog: 'The required channel count (8) is higher than the highest channel available in specified lang tag (6). Adding lower channel track. \n', + handbrakeMode: false, + ffmpegMode: true, + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_00td_action_handbrake_basic_options.js b/tests/Community/Tdarr_Plugin_00td_action_handbrake_basic_options.js new file mode 100644 index 0000000..5777e28 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_00td_action_handbrake_basic_options.js @@ -0,0 +1,74 @@ +/* eslint max-len: 0 */ +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-Z "Very Fast 1080p30" -e x265 --all-subtitles', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: true, + infoLog: 'File is being transcoded using HandBrake \n', + handbrakeMode: true, + ffmpegMode: false, + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + handbrakePreset: 'Fast 576p25', + videoEncoder: 'nvenc_h265', + keepSubtitles: 'true', + container: 'mp4', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-Z "Fast 576p25" -e nvenc_h265 --all-subtitles', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: true, + infoLog: 'File is being transcoded using HandBrake \n', + handbrakeMode: true, + ffmpegMode: false, + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + handbrakePreset: 'Fast 576p25', + videoEncoder: 'nvenc_h265', + keepSubtitles: 'false', + container: 'mov', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-Z "Fast 576p25" -e nvenc_h265 ', + container: '.mov', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: true, + infoLog: 'File is being transcoded using HandBrake \n', + handbrakeMode: true, + ffmpegMode: false, + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_00td_action_handbrake_ffmpeg_custom.js b/tests/Community/Tdarr_Plugin_00td_action_handbrake_ffmpeg_custom.js new file mode 100644 index 0000000..6be2efd --- /dev/null +++ b/tests/Community/Tdarr_Plugin_00td_action_handbrake_ffmpeg_custom.js @@ -0,0 +1,66 @@ +/* eslint max-len: 0 */ +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ' -map 0 -c copy', + container: '.mkv', + handbrakeMode: false, + ffmpegMode: true, + reQueueAfter: true, + infoLog: 'File is being transcoded using custom arguments \n', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + cli: 'handbrake', + arguments: '-Z "Very Fast 1080p30" --all-subtitles --all-audio', + container: 'mp4', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-Z "Very Fast 1080p30" --all-subtitles --all-audio', + container: '.mp4', + handbrakeMode: true, + ffmpegMode: false, + reQueueAfter: true, + infoLog: 'File is being transcoded using custom arguments \n', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + cli: 'ffmpeg', + arguments: '-c:v libx265 -crf 23 -ac 6 -c:a aac -preset veryfast', + container: 'mov', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-c:v libx265 -crf 23 -ac 6 -c:a aac -preset veryfast', + container: '.mov', + handbrakeMode: false, + ffmpegMode: true, + reQueueAfter: true, + infoLog: 'File is being transcoded using custom arguments \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_00td_action_keep_one_audio_stream.js b/tests/Community/Tdarr_Plugin_00td_action_keep_one_audio_stream.js new file mode 100644 index 0000000..26d68f4 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_00td_action_keep_one_audio_stream.js @@ -0,0 +1,89 @@ +/* eslint max-len: 0 */ +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0:v -map 0:1 -map 0:s? -map 0:d? -c copy -c:a:0 aac -ac 2', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'No en streams. The required channel count 2 is lower than the highest available channel count (6).Adding it and removing others! \n', + handbrakeMode: false, + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + audioCodec: 'eac3', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0:v -map 0:1 -map 0:s? -map 0:d? -c copy -c:a:0 eac3 -ac 2', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'No en streams. The required channel count 2 is lower than the highest available channel count (6).Adding it and removing others! \n', + handbrakeMode: false, + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + audioCodec: 'eac3', + language: 'fr', + channels: '6', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0:v -map 0:1 -map 0:s? -map 0:d? -c copy -c:a:0 eac3 -ac 6', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'No fr streams. The required channel count 6 is lower than the highest available channel count (6).Adding it and removing others! \n', + handbrakeMode: false, + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + audioCodec: 'aac', + language: 'und', + channels: '8', + }, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'The best und stream already exists. It is the only audio stream. \n', + handbrakeMode: false, + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_00td_action_re_order_all_streams_v2.js b/tests/Community/Tdarr_Plugin_00td_action_re_order_all_streams_v2.js new file mode 100644 index 0000000..2567bac --- /dev/null +++ b/tests/Community/Tdarr_Plugin_00td_action_re_order_all_streams_v2.js @@ -0,0 +1,72 @@ +/* eslint max-len: 0 */ +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + infoLog: 'Streams are in the correct order!', + }, + }, + { + // orig + // 0 vid h264 + // 1 flac eng + // 2 ac3 eng + // 3 eac3 eng + // 4 aac fre + // 5 aac eng + // 6 sub fre + + // expect + // 4 aac fre + // 2 ac3 eng + // 1 flac eng + // 3 eac3 eng + // 5 aac eng + // 6 sub fre + // 0 vid h264 + + // console.log(streams.map(stream => { + // return { + // "index": stream.index, + // codec_name: stream.codec_name, + // codec_type: stream.codec_type, + // language: stream.tags.language, + // } + // })) + + input: { + file: require('../sampleData/media/sampleH264_2.json'), + librarySettings: {}, + inputs: { + processOrder: 'codecs,channels,languages,streamTypes', + languages: 'fre,eng', + streamTypes: 'audio,subtitle,video', + codecs: 'ac3,flac,eac3,aac', + channels: '7.1,5.1,2,1', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ' -c copy -map 0:4 -map 0:2 -map 0:1 -map 0:3 -map 0:5 -map 0:6 -map 0:0', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + infoLog: 'Streams are not in the correct order!', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_00td_action_remux_container.js b/tests/Community/Tdarr_Plugin_00td_action_remux_container.js new file mode 100644 index 0000000..985688b --- /dev/null +++ b/tests/Community/Tdarr_Plugin_00td_action_remux_container.js @@ -0,0 +1,65 @@ +/* eslint max-len: 0 */ +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map 0 -c copy', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'File is not in mkv \n', + handbrakeMode: false, + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + container: 'mkv', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map 0 -c copy', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'File is not in mkv \n', + handbrakeMode: false, + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + container: 'mp4', + }, + otherArguments: {}, + }, + output: { + processFile: false, + preset: ', -map 0 -c copy', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'File is already in mp4 \n', + handbrakeMode: false, + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_00td_action_standardise_audio_stream_codecs.js b/tests/Community/Tdarr_Plugin_00td_action_standardise_audio_stream_codecs.js new file mode 100644 index 0000000..63e1505 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_00td_action_standardise_audio_stream_codecs.js @@ -0,0 +1,66 @@ +/* eslint max-len: 0 */ +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: true, + infoLog: "File does not have any audio streams which aren't in aac \n", + handbrakeMode: false, + ffmpegMode: true, + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_2.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0:v -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 aac -c:a:1 aac -c:a:2 aac', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: true, + infoLog: "File has audio streams which aren't in aac \n", + handbrakeMode: false, + ffmpegMode: true, + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_2.json'), + librarySettings: {}, + inputs: { + audioCodec: 'eac3', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0:v -map 0:a -map 0:s? -map 0:d? -c copy -c:a:0 eac3 -c:a:1 eac3 -c:a:3 eac3 -c:a:4 eac3', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: true, + infoLog: "File has audio streams which aren't in eac3 \n", + handbrakeMode: false, + ffmpegMode: true, + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_00td_filter_by_bitrate.js b/tests/Community/Tdarr_Plugin_00td_filter_by_bitrate.js new file mode 100644 index 0000000..4c22116 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_00td_filter_by_bitrate.js @@ -0,0 +1,64 @@ +/* eslint max-len: 0 */ +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: require('../sampleData/media/sampleH264_2.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + infoLog: '☑File bitrate is within filter limits. Moving to next plugin.', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + upperBound: 500, + lowerBound: 0, + }, + otherArguments: {}, + }, + output: { + processFile: false, + infoLog: '☒File bitrate is not within filter limits. Breaking out of plugin stack.\n', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + upperBound: 10000, + lowerBound: 0, + }, + otherArguments: {}, + }, + output: { + processFile: true, + infoLog: '☑File bitrate is within filter limits. Moving to next plugin.', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + upperBound: 10000, + lowerBound: 9000, + }, + otherArguments: {}, + }, + output: { + processFile: false, + infoLog: '☒File bitrate is not within filter limits. Breaking out of plugin stack.\n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_00td_filter_by_codec.js b/tests/Community/Tdarr_Plugin_00td_filter_by_codec.js new file mode 100644 index 0000000..e8e6cd3 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_00td_filter_by_codec.js @@ -0,0 +1,59 @@ +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { processFile: false, infoLog: '' }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + codecsToProcess: 'h264', + }, + otherArguments: {}, + }, + output: { processFile: true, infoLog: 'File is in codecsToProcess. Moving to next plugin.' }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + codecsToProcess: 'h265', + }, + otherArguments: {}, + }, + output: { processFile: false, infoLog: 'File is not in codecsToProcess. Breaking out of plugin stack.' }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + codecsToNotProcess: 'h264', + }, + otherArguments: {}, + }, + output: { processFile: false, infoLog: 'File is in codecsToNotProcess. Breaking out of plugin stack.' }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + codecsToNotProcess: 'h265', + }, + otherArguments: {}, + }, + output: { processFile: true, infoLog: 'File is not in codecsToNotProcess. Moving to next plugin.' }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_00td_filter_by_codec_tag_string.js b/tests/Community/Tdarr_Plugin_00td_filter_by_codec_tag_string.js new file mode 100644 index 0000000..4616650 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_00td_filter_by_codec_tag_string.js @@ -0,0 +1,59 @@ +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { processFile: false, infoLog: '' }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + codecTagStringsToProcess: 'avc1,rand', + }, + otherArguments: {}, + }, + output: { processFile: true, infoLog: 'File is in codecTagStringsToProcess. Moving to next plugin.' }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + codecTagStringsToNotProcess: 'avc1,rand', + }, + otherArguments: {}, + }, + output: { processFile: false, infoLog: 'File is in codecTagStringsToNotProcess. Breaking out of plugin stack.' }, + }, + { + input: { + file: require('../sampleData/media/sampleH265_1.json'), + librarySettings: {}, + inputs: { + codecTagStringsToProcess: 'avc1,rand', + }, + otherArguments: {}, + }, + output: { processFile: false, infoLog: 'File is not in codecTagStringsToProcess. Breaking out of plugin stack.' }, + }, + { + input: { + file: require('../sampleData/media/sampleH265_1.json'), + librarySettings: {}, + inputs: { + codecTagStringsToNotProcess: 'avc1,rand', + }, + otherArguments: {}, + }, + output: { processFile: true, infoLog: 'File is not in codecTagStringsToNotProcess. Moving to next plugin.' }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_00td_filter_by_resolution.js b/tests/Community/Tdarr_Plugin_00td_filter_by_resolution.js new file mode 100644 index 0000000..91cc03f --- /dev/null +++ b/tests/Community/Tdarr_Plugin_00td_filter_by_resolution.js @@ -0,0 +1,74 @@ +/* eslint max-len: 0 */ +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, infoLog: '', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + resolutionsToProcess: '480p,720p', + }, + otherArguments: {}, + }, + output: { + processFile: true, + infoLog: 'File is in resolutionsToProcess. Moving to next plugin.', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + resolutionsToProcess: '480p,1080p', + }, + otherArguments: {}, + }, + output: { + processFile: false, + infoLog: 'File is not in resolutionsToProcess. Breaking out of plugin stack.', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + resolutionsToNotProcess: '480p,720p', + }, + otherArguments: {}, + }, + output: { + processFile: false, + infoLog: 'File is in resolutionsToNotProcess. Breaking out of plugin stack.', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + resolutionsToNotProcess: '480p,1080p', + }, + otherArguments: {}, + }, + output: { + processFile: true, + infoLog: 'File is not in resolutionsToNotProcess. Moving to next plugin.', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_00td_filter_by_size.js b/tests/Community/Tdarr_Plugin_00td_filter_by_size.js new file mode 100644 index 0000000..a869c4c --- /dev/null +++ b/tests/Community/Tdarr_Plugin_00td_filter_by_size.js @@ -0,0 +1,64 @@ +/* eslint max-len: 0 */ +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + infoLog: 'File is within lower and upper bound size limits. Moving to next plugin.', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + upperBound: 0.5, + lowerBound: 0, + }, + otherArguments: {}, + }, + output: { + processFile: false, + infoLog: 'File is not within lower and upper bound size limits. Breaking out of plugin stack.', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + upperBound: 2, + lowerBound: 0, + }, + otherArguments: {}, + }, + output: { + processFile: true, + infoLog: 'File is within lower and upper bound size limits. Moving to next plugin.', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + upperBound: 4, + lowerBound: 2, + }, + otherArguments: {}, + }, + output: { + processFile: false, + infoLog: 'File is not within lower and upper bound size limits. Breaking out of plugin stack.', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_075a_FFMPEG_HEVC_Generic.js b/tests/Community/Tdarr_Plugin_075a_FFMPEG_HEVC_Generic.js new file mode 100644 index 0000000..9365ddf --- /dev/null +++ b/tests/Community/Tdarr_Plugin_075a_FFMPEG_HEVC_Generic.js @@ -0,0 +1,41 @@ +/* eslint max-len: 0 */ +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0:v -map 0:a -map 0:s? -map 0:d? -c copy -c:v:0 libx265 -max_muxing_queue_size 9999', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is a video! \n☒File is not hevc! \n', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH265_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: '☑File is a video! \n☑File is already in hevc! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_075a_Transcode_Customisable.js b/tests/Community/Tdarr_Plugin_075a_Transcode_Customisable.js new file mode 100644 index 0000000..c6627a6 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_075a_Transcode_Customisable.js @@ -0,0 +1,81 @@ +/* eslint max-len: 0 */ +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-Z "Very Fast 1080p30" --all-subtitles --all-audio', + container: '.mkv', + handBrakeMode: true, + FFmpegMode: false, + reQueueAfter: true, + infoLog: '☒File is not in desired codec! \n', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH265_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: '☑File is already in hevc! \n', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + codecs_to_exclude: 'h264', + }, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: '☑File is already in h264! \n', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + codecs_to_exclude: 'hevc', + cli: 'handbrake', + transcode_arguments: '-Z "Very Fast 480p30"', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-Z "Very Fast 480p30"', + container: '.mkv', + handBrakeMode: true, + FFmpegMode: false, + reQueueAfter: true, + infoLog: '☒File is not in desired codec! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_075b_FFMPEG_HEVC_Generic_Video_Audio_Only.js b/tests/Community/Tdarr_Plugin_075b_FFMPEG_HEVC_Generic_Video_Audio_Only.js new file mode 100644 index 0000000..d6dc22c --- /dev/null +++ b/tests/Community/Tdarr_Plugin_075b_FFMPEG_HEVC_Generic_Video_Audio_Only.js @@ -0,0 +1,41 @@ +/* eslint max-len: 0 */ +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0:v -map 0:a -c copy -c:v:0 libx265 -max_muxing_queue_size 9999', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is a video! \n☒File is not hevc! \n', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH265_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: '☑File is a video! \n☑File is already in hevc! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_075c_FFMPEG_HEVC_Generic_Video_Audio_Only_CRF20.js b/tests/Community/Tdarr_Plugin_075c_FFMPEG_HEVC_Generic_Video_Audio_Only_CRF20.js new file mode 100644 index 0000000..88633af --- /dev/null +++ b/tests/Community/Tdarr_Plugin_075c_FFMPEG_HEVC_Generic_Video_Audio_Only_CRF20.js @@ -0,0 +1,41 @@ +/* eslint max-len: 0 */ +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0:v -map 0:a -c copy -c:v:0 libx265 -crf 20', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is a video! \n☒File is not hevc! \n', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH265_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: '☑File is a video! \n☑File is already in hevc! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_075d_FFMPEG_HEVC_GPU_Generic_Video_Audio_Only_CRF20.js b/tests/Community/Tdarr_Plugin_075d_FFMPEG_HEVC_GPU_Generic_Video_Audio_Only_CRF20.js new file mode 100644 index 0000000..0d7ee54 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_075d_FFMPEG_HEVC_GPU_Generic_Video_Audio_Only_CRF20.js @@ -0,0 +1,41 @@ +/* eslint max-len: 0 */ +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0:v -map 0:a -c copy -c:v:0 hevc_nvenc -crf 20', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is a video! \n☒File is not hevc! \n', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH265_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: '☑File is a video! \n☑File is already in hevc! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_076a_re_order_audio_streams.js b/tests/Community/Tdarr_Plugin_076a_re_order_audio_streams.js new file mode 100644 index 0000000..95a1b47 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_076a_re_order_audio_streams.js @@ -0,0 +1,43 @@ +/* eslint max-len: 0 */ +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: require('../sampleData/media/sampleH264_2.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: '☑ Preferred language is already first audio track! \n', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_2.json'), + librarySettings: {}, + inputs: { + preferred_language: 'fre', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -c copy -map 0:v -map 0:a:3 -disposition:a:0 default -map 0:a:0 -map 0:a:1 -disposition:a:1 0 -map 0:a:2 -disposition:a:2 0 -disposition:a:3 0 -map 0:a:4 -disposition:a:4 0 -map 0:s? -map 0:d? ', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒ Desired audio lang is not first audio stream, moving! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_076b_re_order_subtitle_streams.js b/tests/Community/Tdarr_Plugin_076b_re_order_subtitle_streams.js new file mode 100644 index 0000000..cc9ef73 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_076b_re_order_subtitle_streams.js @@ -0,0 +1,62 @@ +/* eslint max-len: 0 */ +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: require('../sampleData/media/sampleH264_2.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: '☒ No subtitle tracks in desired language! \n', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_2.json'), + librarySettings: {}, + inputs: { + preferred_language: 'fre', + }, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: '☑ Preferred language is already first subtitle track! \n', + }, + + }, { + input: { + file: require('../sampleData/media/sampleH264_3.json'), + librarySettings: {}, + inputs: { + preferred_language: 'fre', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -c copy -map 0:v -map 0:a -map 0:s:1 -disposition:s:0 default -map 0:s:0 -disposition:s:1 0 -map 0:d? ', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒ Desired subtitle lang is not first subtitle stream, moving! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_077b_HandBrake_NVENC_264_Configurable.js b/tests/Community/Tdarr_Plugin_077b_HandBrake_NVENC_264_Configurable.js new file mode 100644 index 0000000..9a3053c --- /dev/null +++ b/tests/Community/Tdarr_Plugin_077b_HandBrake_NVENC_264_Configurable.js @@ -0,0 +1,44 @@ +/* eslint max-len: 0 */ +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: '☑ File is already in h264, no need to transcode! \n', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH265_1.json'), + librarySettings: {}, + inputs: { + handbrake_preset: 'Very Fast 1080p30', + output_container: '.mp4', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-Z "Very Fast 1080p30" -e nvenc_h264 --all-audio --all-subtitles', + container: '.mp4', + handBrakeMode: true, + FFmpegMode: false, + reQueueAfter: true, + infoLog: '☒ File is not in h264, transcoding! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_A47j_FFMPEG_NVENC_HEVC_Video_Only.js b/tests/Community/Tdarr_Plugin_A47j_FFMPEG_NVENC_HEVC_Video_Only.js new file mode 100644 index 0000000..780bf5d --- /dev/null +++ b/tests/Community/Tdarr_Plugin_A47j_FFMPEG_NVENC_HEVC_Video_Only.js @@ -0,0 +1,112 @@ +/* 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: '-vsync 0 -hwaccel cuda -hwaccel_output_format cuda -c:v h264_cuvid ,-map 0:v -map 0:a -map 0:s? -map -:d? -c copy -c:v:0 hevc_nvenc -preset medium -profile:v main10 -rc-lookahead 32 -spatial_aq:v 1 -aq-strength:v 8 -max_muxing_queue_size 4096 -b:v 967680 -maxrate 1257984 -minrate 677376 -bufsize 1205959 -map_metadata:g -1', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'No valid resolution selected, defaulting to 8KUHD.\n' + + 'Video details: h264-720p \n' + + ' 1280x720x25@8 bits.\n' + + 'Video bitrate is 1206Kbps, overall is 1591Kbps. Calculated target is 1613Kbps.\n' + + '☒H264 Resolution is 720p, bitrate was 1206Kbps. HEVC target bitrate will be 968Kbps.\n' + + '☒Transcoding to HEVC.', + }, + }, { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: { + ffmpegPreset: 'veryslow', + container: 'mkv', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-vsync 0 -hwaccel cuda -hwaccel_output_format cuda -c:v hevc_cuvid ,-map 0:v -map 0:a -map 0:s? -map -:d? -c copy -c:v:0 hevc_nvenc -preset veryslow -profile:v main10 -rc-lookahead 32 -spatial_aq:v 1 -aq-strength:v 8 -max_muxing_queue_size 4096 -b:v 3207442 -maxrate 4717440 -minrate 2540160 -bufsize 3628800 -map_metadata:g -1', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'No valid resolution selected, defaulting to 8KUHD.\n' + + 'Video details: hevc-1080p \n' + + ' 1920x1080x25@8 bits.\n' + + 'Video bitrate is NaNKbps, overall is 3207Kbps. Calculated target is 3629Kbps.\n' + + '☒HEVC Bitrate for 1080p could not be determined, \n' + + ' using sensible default of 3207Kbps.\n' + + '☒Transcoding to HEVC.', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: { + maxResolution: '720p', + ffmpegPreset: 'veryslow', + container: 'mkv', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-vsync 0 -hwaccel cuda -hwaccel_output_format cuda -c:v hevc_cuvid -resize 1280x720 ,-map 0:v -map 0:a -map 0:s? -map -:d? -c copy -c:v:0 hevc_nvenc -preset veryslow -profile:v main10 -rc-lookahead 32 -spatial_aq:v 1 -aq-strength:v 8 -max_muxing_queue_size 4096 -b:v 1612800 -maxrate 2096640 -minrate 1128960 -bufsize 1612800 -map_metadata:g -1', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'Resizing to 1280x720.\n' + + 'Video details: hevc-1080p \n' + + ' 1920x1080x25@8 bits.\n' + + 'Video bitrate is NaNKbps, overall is 3207Kbps. Calculated target is 1613Kbps.\n' + + '☒HEVC Bitrate for 1080p could not be determined, \n' + + ' using sensible default of 1613Kbps.\n' + + '☒Transcoding to HEVC.', + }, + }, + { + input: { + file: (() => { + // modify so no processing needed + const file = _.cloneDeep(require('../sampleData/media/sampleH264_2.json')); + file.ffProbeData.streams[0].codec_name = 'hevc'; + return file; + })(), + librarySettings: {}, + inputs: { + maxResolution: '1080p', + ffmpegPreset: 'veryslow', + container: 'mkv', + compressionFactor: '1', + }, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '-vsync 0 -hwaccel cuda -hwaccel_output_format cuda -c:v hevc_cuvid ,-map 0:v -map 0:a -map 0:s? -map -:d? -c copy -c:v:0 hevc_nvenc -preset veryslow -profile:v main10 -rc-lookahead 32 -spatial_aq:v 1 -aq-strength:v 8 -max_muxing_queue_size 4096 ', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'Video details: hevc-1080p \n' + + ' 1918x1080x25@8 bits.\n' + + 'Video bitrate is 6454Kbps, overall is 8249Kbps. Calculated target is 51786Kbps.\n' + + '☑HEVC Bitrate is within limits.\n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_DOOM_NVENC_Tiered_MKV_CleanAll.js b/tests/Community/Tdarr_Plugin_DOOM_NVENC_Tiered_MKV_CleanAll.js new file mode 100644 index 0000000..6557f17 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_DOOM_NVENC_Tiered_MKV_CleanAll.js @@ -0,0 +1,75 @@ +/* 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: '.mkv', + FFmpegMode: true, + handBrakeMode: false, + infoLog: '☒ Removing audio track in language und\n' + + '☒ *** All audio tracks would have been removed. Defaulting to keeping all tracks for this file.\n' + + '☒ Transcoding to HEVC using NVidia NVENC\n' + + '☑ No subtitle processing necessary', + processFile: true, + preset: ' -c:v h264_cuvid,-map 0 -map -0:d -c:v hevc_nvenc -qmin 0 -cq:v 30 -b:v 602k -maxrate:v 2602k -preset medium -rc-lookahead 32 -spatial_aq:v 1 -aq-strength:v 8 -c:a copy -c:s copy -max_muxing_queue_size 9999 -bf 5 -analyzeduration 2147483647 -probesize 2147483647', + reQueueAfter: true, + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + container: '.mkv', + FFmpegMode: true, + handBrakeMode: false, + infoLog: '☑ File is in HEVC codec and in MKV\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 -c:a copy -c:s copy -max_muxing_queue_size 9999 -bf 5 -analyzeduration 2147483647 -probesize 2147483647', + reQueueAfter: true, + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.ffProbeData.streams[0].bit_rate = undefined; + return file; + })(), + librarySettings: {}, + inputs: { + target_bitrate_720p: '1500000', + }, + otherArguments: {}, + }, + output: { + container: '.mkv', + FFmpegMode: true, + handBrakeMode: false, + infoLog: '☒ Removing audio track in language und\n' + + '☒ *** All audio tracks would have been removed. Defaulting to keeping all tracks for this file.\n' + + '☒ Transcoding to HEVC using NVidia NVENC\n' + + '☑ No subtitle processing necessary', + processFile: true, + preset: ' -c:v h264_cuvid,-map 0 -map -0:d -c:v hevc_nvenc -qmin 0 -cq:v 30 -b:v 1500k -maxrate:v 3500k -preset medium -rc-lookahead 32 -spatial_aq:v 1 -aq-strength:v 8 -c:a copy -c:s copy -max_muxing_queue_size 9999 -bf 5 -analyzeduration 2147483647 -probesize 2147483647', + reQueueAfter: true, + }, + }, + +]; + +run(tests); 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 new file mode 100644 index 0000000..c725079 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_ER01_Transcode audio and video with HW (PC and Mac).js @@ -0,0 +1,107 @@ +/* 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: '.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 - ', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + container: '.mkv', + processFile: false, + preset: '', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'File is processed already, nothing to do', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_2.json')), + librarySettings: {}, + inputs: { + resize: 'true', + }, + otherArguments: {}, + }, + output: { + container: '.mkv', + processFile: false, + preset: '', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'File is processed already, nothing to do', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_2.json')), + librarySettings: {}, + inputs: { + bitrate_cutoff: '6000', + }, + 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 - ', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_2.json')), + librarySettings: {}, + inputs: { + bitrate_cutoff: '8000', + }, + otherArguments: {}, + }, + output: { + container: '.mkv', + processFile: false, + preset: '', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'File is processed already, nothing to do', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_Greg_MP3_FFMPEG_CPU.js b/tests/Community/Tdarr_Plugin_Greg_MP3_FFMPEG_CPU.js new file mode 100644 index 0000000..ef5221c --- /dev/null +++ b/tests/Community/Tdarr_Plugin_Greg_MP3_FFMPEG_CPU.js @@ -0,0 +1,59 @@ +/* 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: { + preset: ', -map_metadata 0 -id3v2_version 3 -b:a 320k', + container: '.mp3', + handbrakeMode: false, + ffmpegMode: true, + processFile: false, + reQueueAfter: true, + infoLog: 'undefined☒Codec excluded \n ☑Codec not excluded \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleAAC_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + preset: ', -map_metadata 0 -id3v2_version 3 -b:a 320k', + container: '.mp3', + handbrakeMode: false, + ffmpegMode: true, + processFile: false, + reQueueAfter: true, + infoLog: 'undefined☒Codec excluded \n ☑Codec not excluded \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleMP3_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + preset: ', -map_metadata 0 -id3v2_version 3 -b:a 320k', + container: '.mp3', + handbrakeMode: false, + ffmpegMode: true, + processFile: false, + reQueueAfter: true, + infoLog: 'undefined☒Codec excluded \n ☒Codec excluded \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_MC93_Migz1FFMPEG.js b/tests/Community/Tdarr_Plugin_MC93_Migz1FFMPEG.js new file mode 100644 index 0000000..a329f18 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_MC93_Migz1FFMPEG.js @@ -0,0 +1,145 @@ +/* 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 -c:v hevc_nvenc -cq:v 19 -b:v 758k -minrate 530k -maxrate 985k -bufsize 1517k -spatial_aq:v 1 -rc-lookahead:v 32 -c:a copy -c:s copy -max_muxing_queue_size 9999 ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'Container for output selected as mkv. \n' + + 'Current bitrate = 1517 \n' + + 'Bitrate settings: \n' + + 'Target = 758 \n' + + 'Minimum = 530 \n' + + 'Maximum = 985 \n' + + 'File is not hevc or vp9. Transcoding. \n', + container: '.mkv', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'File is already hevc or vp9 & in mkv. \n', + container: '.mkv', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: { + container: 'mp4', + enable_10bit: 'true', + force_conform: 'true', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-c:v h264_cuvid, -map 0 -c:v hevc_nvenc -cq:v 19 -b:v 758k -minrate 530k -maxrate 985k -bufsize 1517k -spatial_aq:v 1 -rc-lookahead:v 32 -c:a copy -c:s copy -max_muxing_queue_size 9999 -pix_fmt p010le ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'Container for output selected as mp4. \n' + + 'Current bitrate = 1517 \n' + + 'Bitrate settings: \n' + + 'Target = 758 \n' + + 'Minimum = 530 \n' + + 'Maximum = 985 \n' + + 'File is not hevc or vp9. Transcoding. \n', + container: '.mp4', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: { + container: 'mp4', + enable_10bit: 'true', + force_conform: 'true', + bitrate_cutoff: '10000', + }, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'Current bitrate is below set cutoff of 10000. Cancelling plugin. \n', + container: '.mp4', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: { + container: 'mp4', + enable_10bit: 'true', + force_conform: 'true', + bitrate_cutoff: '1000', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-c:v h264_cuvid, -map 0 -c:v hevc_nvenc -cq:v 19 -b:v 758k -minrate 530k -maxrate 985k -bufsize 1517k -spatial_aq:v 1 -rc-lookahead:v 32 -c:a copy -c:s copy -max_muxing_queue_size 9999 -pix_fmt p010le ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'Container for output selected as mp4. \n' + + 'Current bitrate = 1517 \n' + + 'Bitrate settings: \n' + + 'Target = 758 \n' + + 'Minimum = 530 \n' + + 'Maximum = 985 \n' + + 'File is not hevc or vp9. Transcoding. \n', + container: '.mp4', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: { + container: 'mp4', + force_conform: 'false', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map 0 -c copy ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'File is hevc or vp9 but is not in mp4 container. Remuxing. \n', + container: '.mp4', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_MC93_Migz1FFMPEG_CPU.js b/tests/Community/Tdarr_Plugin_MC93_Migz1FFMPEG_CPU.js new file mode 100644 index 0000000..6e1afa3 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_MC93_Migz1FFMPEG_CPU.js @@ -0,0 +1,145 @@ +/* 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 -c:v libx265 -b:v 758k -minrate 530k -maxrate 985k -bufsize 1517k -c:a copy -c:s copy -max_muxing_queue_size 9999 ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'Container for output selected as mkv. \n' + + 'Current bitrate = 1517 \n' + + 'Bitrate settings: \n' + + 'Target = 758 \n' + + 'Minimum = 530 \n' + + 'Maximum = 985 \n' + + 'File is not hevc or vp9. Transcoding. \n', + container: '.mkv', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'File is already hevc or vp9 & in mkv. \n', + container: '.mkv', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: { + container: 'mp4', + enable_10bit: 'true', + force_conform: 'true', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0 -c:v libx265 -b:v 758k -minrate 530k -maxrate 985k -bufsize 1517k -c:a copy -c:s copy -max_muxing_queue_size 9999 -pix_fmt p010le ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'Container for output selected as mp4. \n' + + 'Current bitrate = 1517 \n' + + 'Bitrate settings: \n' + + 'Target = 758 \n' + + 'Minimum = 530 \n' + + 'Maximum = 985 \n' + + 'File is not hevc or vp9. Transcoding. \n', + container: '.mp4', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: { + container: 'mp4', + enable_10bit: 'true', + force_conform: 'true', + bitrate_cutoff: '10000', + }, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'Current bitrate is below set bitrate cutoff of 10000. Nothing to do, cancelling plugin. \n', + container: '.mp4', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: { + container: 'mp4', + enable_10bit: 'true', + force_conform: 'true', + bitrate_cutoff: '1000', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0 -c:v libx265 -b:v 758k -minrate 530k -maxrate 985k -bufsize 1517k -c:a copy -c:s copy -max_muxing_queue_size 9999 -pix_fmt p010le ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'Container for output selected as mp4. \n' + + 'Current bitrate = 1517 \n' + + 'Bitrate settings: \n' + + 'Target = 758 \n' + + 'Minimum = 530 \n' + + 'Maximum = 985 \n' + + 'File is not hevc or vp9. Transcoding. \n', + container: '.mp4', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: { + container: 'mp4', + force_conform: 'false', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map 0 -c copy ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'File is hevc or vp9 but is not in mp4 container. Remuxing. \n', + container: '.mp4', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_MC93_Migz1Remux.js b/tests/Community/Tdarr_Plugin_MC93_Migz1Remux.js new file mode 100644 index 0000000..16051f0 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_MC93_Migz1Remux.js @@ -0,0 +1,45 @@ +/* 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 -c copy -max_muxing_queue_size 9999 ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒File is mp4 but requested to be mkv container. Remuxing. \n', + container: '.mkv', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: { + container: 'mp4', + force_conform: 'true', + }, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is already in mp4 container. \n', + container: '.mp4', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_MC93_Migz2CleanTitle.js b/tests/Community/Tdarr_Plugin_MC93_Migz2CleanTitle.js new file mode 100644 index 0000000..5208106 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_MC93_Migz2CleanTitle.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: true, + preset: ', -metadata title= -c copy -map 0 -max_muxing_queue_size 9999', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒File has title metadata. Removing \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: true, + reQueueAfter: false, + infoLog: '☑File has no title metadata \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_MC93_Migz3CleanAudio.js b/tests/Community/Tdarr_Plugin_MC93_Migz3CleanAudio.js new file mode 100644 index 0000000..11bd864 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_MC93_Migz3CleanAudio.js @@ -0,0 +1,98 @@ +/* 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 audio tracks which are unwanted or that require tagging.\n", + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_2.json')), + librarySettings: {}, + inputs: { + language: 'eng', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map 0 -map -0:a:3 -c copy -max_muxing_queue_size 9999', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒Audio stream 0:a:3 has unwanted language tag fre, removing. \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_2.json')); + file.ffProbeData.streams[3].tags.title = 'description'; + return file; + })(), + librarySettings: {}, + inputs: { + language: 'eng', + commentary: 'true', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map 0 -map -0:a:2 -map -0:a:3 -c copy -max_muxing_queue_size 9999', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒Audio stream 0:a:2 detected as being descriptive, removing. \n' + + '☒Audio stream 0:a:3 has unwanted language tag fre, removing. \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_2.json')); + file.ffProbeData.streams[2].tags.title = 'description'; + file.ffProbeData.streams[3].tags.language = 'und'; + return file; + })(), + librarySettings: {}, + inputs: { + language: 'eng', + commentary: 'true', + tag_language: 'eng', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map 0 -map -0:a:1 -map -0:a:2 -metadata:s:a:2 language=eng -map -0:a:3 -c copy -max_muxing_queue_size 9999', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒Audio stream 0:a:1 detected as being descriptive, removing. \n' + + '☒Audio stream 0:a:2 has unwanted language tag und, removing. \n' + + '☒Audio stream 0:a:2 detected as having no language, tagging as eng. \n' + + '☒Audio stream 0:a:3 has unwanted language tag fre, removing. \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_MC93_Migz4CleanSubs.js b/tests/Community/Tdarr_Plugin_MC93_Migz4CleanSubs.js new file mode 100644 index 0000000..fa10ac5 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_MC93_Migz4CleanSubs.js @@ -0,0 +1,72 @@ +/* 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 subtitle tracks which are unwanted or that require tagging.\n", + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_2.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map 0 -map -0:s:0 -c copy -max_muxing_queue_size 9999', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒Subtitle stream 0:s:0 has unwanted language tag fre, removing. \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_2.json')); + + file.ffProbeData.streams[7] = _.cloneDeep(file.ffProbeData.streams[6]); + file.ffProbeData.streams[6].tags.title = 'description'; + file.ffProbeData.streams[7].tags.language = 'und'; + return file; + })(), + librarySettings: {}, + inputs: { + language: 'eng,und', + commentary: 'true', + tag_language: 'eng', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map 0 -map -0:s:0 -map -0:s:0 -metadata:s:s:1 language=eng -c copy -max_muxing_queue_size 9999', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒Subtitle stream 0:s:0 has unwanted language tag fre, removing. \n' + + '☒Subtitle stream 0:s:0 detected as being descriptive, removing. \n' + + '☒Subtitle stream 0:s:1 has no language, tagging as eng. \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_MC93_Migz5ConvertAudio.js b/tests/Community/Tdarr_Plugin_MC93_Migz5ConvertAudio.js new file mode 100644 index 0000000..9d9497c --- /dev/null +++ b/tests/Community/Tdarr_Plugin_MC93_Migz5ConvertAudio.js @@ -0,0 +1,90 @@ +/* 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, + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒Plugin has not been configured, please configure required options. Skipping this plugin. \n', + }, + }, + + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: { + aac_stereo: 'true', + }, + otherArguments: {}, + }, + output: { + processFile: false, + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File contains all required audio formats. \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_2.json')), + librarySettings: {}, + inputs: { + aac_stereo: 'true', + }, + otherArguments: {}, + }, + output: { + processFile: true, + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒Audio track is 2 channel but is not AAC. Converting. \n' + + '☒Audio track is 2 channel but is not AAC. Converting. \n' + + '☒Audio track is 2 channel but is not AAC. Converting. \n', + preset: ', -map 0 -c:v copy -c:a copy -c:a:0 aac -c:a:1 aac -c:a:2 aac -strict -2 -c:s copy -max_muxing_queue_size 9999 ', + }, + }, + + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_2.json')); + file.ffProbeData.streams[1].channels = 8; + return file; + })(), + librarySettings: {}, + inputs: { + aac_stereo: 'false', + downmix: 'true', + }, + otherArguments: {}, + }, + output: { + processFile: true, + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒Audio track is 8 channel, no 6 channel exists. Creating 6 channel from 8 channel. \n', + preset: ', -map 0 -c:v copy -c:a copy -map 0:1 -c:a:0 ac3 -ac 6 -metadata:s:a:0 title="5.1" -strict -2 -c:s copy -max_muxing_queue_size 9999 ', + }, + }, + +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_MC93_Migz6OrderStreams.js b/tests/Community/Tdarr_Plugin_MC93_Migz6OrderStreams.js new file mode 100644 index 0000000..d4a111a --- /dev/null +++ b/tests/Community/Tdarr_Plugin_MC93_Migz6OrderStreams.js @@ -0,0 +1,103 @@ +/* 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, + infoLog: '☑ Streams are in expected order. \n ', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_2.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + infoLog: '☑ Streams are in expected order. \n ', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_2.json')); + file.ffProbeData.streams[1].channels = 8; + file.ffProbeData.streams[2].channels = 6; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0:0 -map 0:3 -map 0:4 -map 0:5 -map 0:2 -map 0:1 -map 0:6 -c copy -max_muxing_queue_size 9999', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + infoLog: '☒ Audio 6ch not second. \n' + + '☒ Audio 2ch not first. \n' + + '☒ Audio 2ch not first. \n' + + '☒ Audio 2ch not first. \n' + + '☒ Streams are out of order, reorganizing streams. Video, Audio, Subtitles. \n', + reQueueAfter: true, + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_2.json')); + file.ffProbeData.streams[1].channels = 8; + file.ffProbeData.streams[2].channels = 6; + const video = file.ffProbeData.streams.splice(0, 1)[0]; + file.ffProbeData.streams.push(video); + const subs = file.ffProbeData.streams.splice(5, 1)[0]; + file.ffProbeData.streams.unshift(subs); + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0:6 -map 0:3 -map 0:4 -map 0:5 -map 0:2 -map 0:1 -map 0:0 -c copy -max_muxing_queue_size 9999', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + infoLog: '☒ Audio not second. \n' + + '☒ Audio not second. \n' + + '☒ Audio 6ch not second. \n' + + '☒ Audio not second. \n' + + '☒ Audio 2ch not first. \n' + + '☒ Audio not second. \n' + + '☒ Audio 2ch not first. \n' + + '☒ Audio not second. \n' + + '☒ Audio 2ch not first. \n' + + '☒ Video not first. \n' + + '☒ Streams are out of order, reorganizing streams. Video, Audio, Subtitles. \n', + reQueueAfter: true, + }, + }, + +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_MC93_MigzImageRemoval.js b/tests/Community/Tdarr_Plugin_MC93_MigzImageRemoval.js new file mode 100644 index 0000000..bdb0c02 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_MC93_MigzImageRemoval.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: '', + handBrakeMode: false, + container: '.mp4', + FFmpegMode: true, + reQueueAfter: true, + infoLog: "☑File doesn't contain any unwanted image format streams.\n", + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_2.json')); + file.ffProbeData.streams[0].codec_name = 'mjpeg'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0 -c copy -max_muxing_queue_size 9999 -map -v:0 ', + handBrakeMode: false, + container: '.mkv', + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒File has image format stream, removing. \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_MP01_MichPasCleanSubsAndAudioCodecs.js b/tests/Community/Tdarr_Plugin_MP01_MichPasCleanSubsAndAudioCodecs.js new file mode 100644 index 0000000..40adead --- /dev/null +++ b/tests/Community/Tdarr_Plugin_MP01_MichPasCleanSubsAndAudioCodecs.js @@ -0,0 +1,47 @@ +/* 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 subtitle or audio codecs which were unwanted or that require tagging.\n", + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_2.json')), + librarySettings: {}, + inputs: { + tag_subtitle_codecs: 'subrip', + tag_audio_codecs: 'aac', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map 0 -map -0:a:3 -map -0:a:4 -map -0:s:0 -c copy -max_muxing_queue_size 4096', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒audio stream detected as unwanted. removing audio stream 0:a:3 - Français E-AC3 2.0 - aac \n' + + '☒audio stream detected as unwanted. removing audio stream 0:a:4 - Anglais E-AC3 2.0 - aac \n' + + '☒Subtitle stream detected as unwanted. removing subtitle stream 0:s:0 - Français - subrip. \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_Mthr_VaapiHEVCTranscode.js b/tests/Community/Tdarr_Plugin_Mthr_VaapiHEVCTranscode.js new file mode 100644 index 0000000..1c5438d --- /dev/null +++ b/tests/Community/Tdarr_Plugin_Mthr_VaapiHEVCTranscode.js @@ -0,0 +1,107 @@ +/* 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: ' -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi ,-map 0:v -map 0:a -map 0:s? -map 0:d? -map 0:t? -c copy -c:v:0 hevc_vaapi -b:v 758k -minrate 530k -maxrate 985k -bufsize 1M -max_muxing_queue_size 1024 ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: false, + infoLog: '☒ Video stream 0 is not HEVC, transcode required.\n' + + ' ☑ Stream analysis complete, processing required.\n' + + ' ', + container: 'mp4', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: false, + infoLog: '☑ Stream analysis complete, no processing required.\n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: { + minBitrate: '4000', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ' -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi ,-map 0:v -map 0:a -map 0:s? -map 0:d? -map 0:t? -c copy ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: false, + infoLog: "☒ Input file's bitrate 1517 is lower than the minimum bitrate threshold of 4000. Skipping this plugin.\n" + + '☑ Stream analysis complete, processing required.\n' + + ' ', + container: 'mp4', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: { + remuxOnly: 'true', + }, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: false, + infoLog: '☒ RemuxOnly is enabled and file is not a remux. Unable to process.\n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_2.json')); + file.file = `remux ${file.file}`; + return file; + })(), + librarySettings: {}, + inputs: { + remuxOnly: 'true', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ' -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi ,-map 0:v -map 0:a -map 0:s? -map 0:d? -map 0:t? -c copy -c:v:0 hevc_vaapi -b:v 3933k -minrate 2753k -maxrate 5112k -bufsize 1M -max_muxing_queue_size 1024 ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: false, + infoLog: '☒ Video stream 0 is not HEVC, transcode required.\n' + + ' ☑ Stream analysis complete, processing required.\n' + + ' ', + container: 'mkv', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_a37x_Drawmonster_MP4_No_Title_Meta.js b/tests/Community/Tdarr_Plugin_a37x_Drawmonster_MP4_No_Title_Meta.js new file mode 100644 index 0000000..22d571d --- /dev/null +++ b/tests/Community/Tdarr_Plugin_a37x_Drawmonster_MP4_No_Title_Meta.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: true, + preset: ',-map_metadata -1 -map 0 -c copy', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒File has title metadata \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: false, + infoLog: '☑File has no title metadata \n☑File meets conditions! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_a8hc_HaveAGitGat_HandBrake_H264_VeryFast1080p30.js b/tests/Community/Tdarr_Plugin_a8hc_HaveAGitGat_HandBrake_H264_VeryFast1080p30.js new file mode 100644 index 0000000..805c984 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_a8hc_HaveAGitGat_HandBrake_H264_VeryFast1080p30.js @@ -0,0 +1,66 @@ +/* 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 -c copy', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is already in h264! \n☑File has no subs \n☒File has title metadata \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-Z "Very Fast 1080p30"', + container: '.mp4', + handBrakeMode: true, + FFmpegMode: false, + 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 subs \n' + + '☑File has no title metadata☑File has aac track \n' + + '☑File meets conditions! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_a9hc_HaveAGitGat_HandBrake_H264_Fast1080p30.js b/tests/Community/Tdarr_Plugin_a9hc_HaveAGitGat_HandBrake_H264_Fast1080p30.js new file mode 100644 index 0000000..47cc98c --- /dev/null +++ b/tests/Community/Tdarr_Plugin_a9hc_HaveAGitGat_HandBrake_H264_Fast1080p30.js @@ -0,0 +1,66 @@ +/* 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 -c copy', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is already in h264! \n☑File has no subs \n☒File has title metadata \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-Z "Fast 1080p30"', + container: '.mp4', + handBrakeMode: true, + FFmpegMode: false, + 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 subs \n' + + '☑File has no title metadata☑File has aac track \n' + + '☑File meets conditions! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_a9hd_FFMPEG_Transcode_Specific_Audio_Stream_Codecs.js b/tests/Community/Tdarr_Plugin_a9hd_FFMPEG_Transcode_Specific_Audio_Stream_Codecs.js new file mode 100644 index 0000000..4bf0913 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_a9hd_FFMPEG_Transcode_Specific_Audio_Stream_Codecs.js @@ -0,0 +1,45 @@ +/* eslint max-len: 0 */ +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: '☑ File does not have any streams that need to be transcoded! \n', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + codecs_to_transcode: 'aac', + codec: 'eac3', + bitrate: '640k', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -c copy -map 0:v -map 0:1 -c:1 eac3 -b:a 640k -map 0:s? -map 0:d? -max_muxing_queue_size 9999', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: "☒ File has streams which aren't in desired codec! \n", + }, + }, +]; + +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 new file mode 100644 index 0000000..7e1de0d --- /dev/null +++ b/tests/Community/Tdarr_Plugin_a9he_New_file_size_check.js @@ -0,0 +1,68 @@ +/* eslint max-len: 0 */ +const _ = require('lodash'); +const run = require('../helpers/run'); + +const tests = [ + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: {}, + otherArguments: { + originalLibraryFile: require('../sampleData/media/sampleH264_1.json'), + }, + }, + output: { + processFile: false, + preset: '', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'New file has size 1.008 MB which is 100% of original file size: 1.008 MB', + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + upperBound: '110', + lowerBound: '35', + }, + otherArguments: { + originalLibraryFile: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.file_size = 3; + return file; + })(), + }, + }, + output: 'New file size not within limits. New file has size 1.008 MB which is 33% of original file size: 3.000 MB. lowerBound is 35%', + error: { + shouldThrow: true, + }, + }, + { + input: { + file: require('../sampleData/media/sampleH264_1.json'), + librarySettings: {}, + inputs: { + upperBound: '120', + lowerBound: '35', + }, + otherArguments: { + originalLibraryFile: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.file_size = 0.1; + return file; + })(), + }, + }, + output: 'New file size not within limits. New file has size 1.008 MB which is 1007% of original file size: 0.100 MB. upperBound is 120%', + error: { + shouldThrow: true, + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_b38x_Nosirus_h265_aac_no_meta.js b/tests/Community/Tdarr_Plugin_b38x_Nosirus_h265_aac_no_meta.js new file mode 100644 index 0000000..9c01863 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_b38x_Nosirus_h265_aac_no_meta.js @@ -0,0 +1,45 @@ +/* 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 -c copy -c:v:0 libx265 -preset:v slow -pix_fmt yuv420p10le -x265-params "crf=22:aq-mode=3"', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒File is not in hevc! \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: '☑File is already in hevc! \n' + + '☑ All audio streams are in aac! \n' + + '☑File has no title metadata \n' + + '☑File meets conditions! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_b39x_the1poet_surround_sound_to_ac3.js b/tests/Community/Tdarr_Plugin_b39x_the1poet_surround_sound_to_ac3.js new file mode 100644 index 0000000..a3b9e80 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_b39x_the1poet_surround_sound_to_ac3.js @@ -0,0 +1,59 @@ +/* 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 -c:v copy -c:a copy -c:a:0 ac3 -c:s copy -c:d copy', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒ File has surround audio which is NOT in ac3! \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_2.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: '☑ All surround audio streams are in ac3! \n☑File meets conditions! \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: '☑ All surround audio streams are in ac3! \n☑File meets conditions! \n', + }, + }, +]; + +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 new file mode 100644 index 0000000..336f2f0 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js @@ -0,0 +1,86 @@ +/* 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: '-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', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: { + container: 'mp4', + encoder_speedpreset: 'fast', + enable_10bit: 'true', + }, + 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', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: { + container: 'mp4', + encoder_speedpreset: 'fast', + enable_10bit: 'true', + bitrate_cutoff: '2000', + }, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑ It looks like the current bitrate is 1517k. \n' + + '☑ Current bitrate is below set cutoff of 2000k. Cancelling plugin. \n', + container: '.mp4', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_c0r1_SetDefaultAudioStream.js b/tests/Community/Tdarr_Plugin_c0r1_SetDefaultAudioStream.js new file mode 100644 index 0000000..1c012bf --- /dev/null +++ b/tests/Community/Tdarr_Plugin_c0r1_SetDefaultAudioStream.js @@ -0,0 +1,49 @@ +/* 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, + infoLog: '☑ No 2 channel audio stream exists. \n ', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_2.json')); + + file.ffProbeData.streams[1].channels = 6; + return file; + })(), + librarySettings: {}, + inputs: { + channels: '6', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0 -c copy -disposition:1 default -disposition:2 0 -disposition:3 0 -disposition:4 0 -disposition:5 0 ', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + infoLog: '☒ Matching audio stream is not set to default. \n' + + '☒ Setting 6 channel matching audio stream to default. Remove default from all other audio streams \n', + reQueueAfter: true, + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_d5d3_iiDrakeii_FFMPEG_NVENC_Tiered_MKV.js b/tests/Community/Tdarr_Plugin_d5d3_iiDrakeii_FFMPEG_NVENC_Tiered_MKV.js new file mode 100644 index 0000000..455b2ca --- /dev/null +++ b/tests/Community/Tdarr_Plugin_d5d3_iiDrakeii_FFMPEG_NVENC_Tiered_MKV.js @@ -0,0 +1,50 @@ +/* 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 -pix_fmt p010le -qmin 0 -cq:v 30 -b:v 964k -maxrate:v 2964k -preset slow -rc-lookahead 32 -spatial_aq:v 1 -aq-strength:v 8 -a53cc 0 -c:a copy -c:s copy', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is a video! \n' + + '☒File is 720p!\n' + + '☒File is not hevc!\n' + + '☒File bitrate is 1205kb!\n' + + 'File bitrate is LOWER than the Default Target Bitrate!\n' + + '☒Target Bitrate set to 964kb!\n' + + 'File is being transcoded!\n', + maxmux: false, + }, + }, + { + 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', + maxmux: false, + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_d5d4_iiDrakeii_Not_A_Video_Mjpeg_Fix.js b/tests/Community/Tdarr_Plugin_d5d4_iiDrakeii_Not_A_Video_Mjpeg_Fix.js new file mode 100644 index 0000000..c80b3dc --- /dev/null +++ b/tests/Community/Tdarr_Plugin_d5d4_iiDrakeii_Not_A_Video_Mjpeg_Fix.js @@ -0,0 +1,47 @@ +/* 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: true, + infoLog: '☑File is a video Without Mjpeg! \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.ffProbeData.streams[0].codec_name = 'mjpeg'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: ',-map 0 -map -0:v:1 -c:v copy -c:a copy -c:s copy', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: true, + infoLog: '☒File is not a video but has Mjpeg Stream! \n' + + '☑File is a video With Mjpeg! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_da11_Dallas_FFmpeg_Presets_H264_MP4.js b/tests/Community/Tdarr_Plugin_da11_Dallas_FFmpeg_Presets_H264_MP4.js new file mode 100644 index 0000000..e382ca8 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_da11_Dallas_FFmpeg_Presets_H264_MP4.js @@ -0,0 +1,62 @@ +/* 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: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:a -c:v libx264 -preset medium -c:a aac -strict -2 -c:s mov_text', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒ File is not in h264!\n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: { + FFmpeg_preset: 'fast', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map_metadata -1 -map 0:V -map 0:a -c:v libx264 -preset fast -c:a aac -strict -2 -c:s mov_text', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒ File is not in h264!\n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_drdd_standardise_all_in_one.js b/tests/Community/Tdarr_Plugin_drdd_standardise_all_in_one.js new file mode 100644 index 0000000..250a2a7 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_drdd_standardise_all_in_one.js @@ -0,0 +1,110 @@ +/* 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: '.mkv', + FFmpegMode: true, + handBrakeMode: false, + infoLog: '☒ Will convert multi channel audio to AC3\n' + + '☒ Transcoding to HEVC (software)\n' + + 'Encoder configuration:\n' + + '• Original Bitrate: 1517\n' + + '• Target Bitrate: 1517\n' + + '• Minimum Bitrate: 1061\n' + + '• Maximum Bitrate: 1972\n' + + '\n' + + '☑ No subtitle processing necessary', + processFile: true, + preset: ',-map 0 -map -0:d -c:v libx265 -b:v 1517k -minrate 1061k -maxrate 1972k -bufsize 1517k -c:a copy -c:a:0 ac3 -c:s copy -max_muxing_queue_size 4096', + reQueueAfter: false, + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: { + nvenc: 'true', + }, + otherArguments: {}, + }, + output: { + container: '.mkv', + FFmpegMode: true, + handBrakeMode: false, + infoLog: '☒ Will convert multi channel audio to AC3\n' + + '☒ Transcoding to HEVC using NVidia NVENC\n' + + 'Encoder configuration:\n' + + '• Original Bitrate: 1517\n' + + '• Target Bitrate: 1517\n' + + '• Minimum Bitrate: 1061\n' + + '• Maximum Bitrate: 1972\n' + + '\n' + + '☑ No subtitle processing necessary', + processFile: true, + preset: '-c:v h264_cuvid,-map 0 -map -0:d -c:v hevc_nvenc -cq:v 19 -b:v 1517k -minrate 1061k -maxrate 1972k -bufsize 1517k -spatial_aq:v 1 -rc-lookahead:v 32 -c:a copy -c:a:0 ac3 -c:s copy -max_muxing_queue_size 4096', + reQueueAfter: false, + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: { + nvenc: 'false', + qsv: 'true', + }, + otherArguments: {}, + }, + output: { + container: '.mkv', + FFmpegMode: true, + handBrakeMode: false, + infoLog: '☒ Will convert multi channel audio to AC3\n' + + '☒ Transcoding to HEVC using VAAPI\n' + + 'Encoder configuration:\n' + + '• Original Bitrate: 1517\n' + + '• Target Bitrate: 1517\n' + + '• Minimum Bitrate: 1061\n' + + '• Maximum Bitrate: 1972\n' + + '\n' + + '☑ No subtitle processing necessary', + processFile: true, + preset: '-hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi,-map 0 -map -0:d -c:v hevc_vaapi -b:v 1517k -minrate 1061k -maxrate 1972k -bufsize 1517k -c:a copy -c:a:0 ac3 -c:s copy -max_muxing_queue_size 4096', + reQueueAfter: false, + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + container: '.mkv', + FFmpegMode: true, + handBrakeMode: false, + infoLog: '☑ No multi channel audio found\n' + + '☑ No audio processing necessary\n' + + '☑ File is in HEVC codec and in MKV\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 -c:a copy -c:s copy -max_muxing_queue_size 4096', + reQueueAfter: false, + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_e3jc_Tharic_H.264_MKV_480p30_No_Subs_No_Title_Meta.js b/tests/Community/Tdarr_Plugin_e3jc_Tharic_H.264_MKV_480p30_No_Subs_No_Title_Meta.js new file mode 100644 index 0000000..edbb610 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_e3jc_Tharic_H.264_MKV_480p30_No_Subs_No_Title_Meta.js @@ -0,0 +1,97 @@ +/* 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.264 MKV 480p30"', + container: '.mkv', + handBrakeMode: true, + FFmpegMode: false, + reQueueAfter: true, + infoLog: '☒File is not h264 480p! \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-Z "H.264 MKV 480p30"', + container: '.mkv', + handBrakeMode: true, + FFmpegMode: false, + reQueueAfter: true, + infoLog: '☒File is not h264 480p! \n', + }, + }, + + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.ffProbeData.streams[0].width = 720; + file.ffProbeData.streams[0].height = 480; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map_metadata -1 -map 0 -c copy', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is h264 480p! \n' + + '☑File has no title and has no subs \n' + + '☒File has title metadata \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.ffProbeData.streams[0].width = 720; + file.ffProbeData.streams[0].height = 480; + + file.meta.Title = undefined; + file.container = 'mkv'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: false, + infoLog: '☑File is h264 480p! \n' + + '☑File has no title and has no subs \n' + + '☑File has no title metadata \n' + + '☑File has no subs \n' + + '☑File is in mkv container! \n' + + '☑File meets conditions! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_e3jd_Tharic_H.264_MKV_720p30_No_Subs_No_Title_Meta.js b/tests/Community/Tdarr_Plugin_e3jd_Tharic_H.264_MKV_720p30_No_Subs_No_Title_Meta.js new file mode 100644 index 0000000..4371d6c --- /dev/null +++ b/tests/Community/Tdarr_Plugin_e3jd_Tharic_H.264_MKV_720p30_No_Subs_No_Title_Meta.js @@ -0,0 +1,99 @@ +/* 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 -c copy', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is h264 720p! \n' + + '☑File has no title and has no subs \n' + + '☒File has title metadata \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-Z "H.264 MKV 720p30"', + container: '.mkv', + handBrakeMode: true, + FFmpegMode: false, + reQueueAfter: true, + infoLog: '☒File is not h264 720p! \n', + }, + }, + + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.ffProbeData.streams[0].width = 1280; + file.ffProbeData.streams[0].height = 720; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map_metadata -1 -map 0 -c copy', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is h264 720p! \n' + + '☑File has no title and has no subs \n' + + '☒File has title metadata \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.ffProbeData.streams[0].width = 1280; + file.ffProbeData.streams[0].height = 720; + + file.meta.Title = undefined; + file.container = 'mkv'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: false, + infoLog: '☑File is h264 720p! \n' + + '☑File has no title and has no subs \n' + + '☑File has no title metadata \n' + + '☑File has no subs \n' + + '☑File is in mkv container! \n' + + '☑File meets conditions! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_e3je_Tharic_H.264_MKV_1080p30_No_Subs_No_Title_Meta.js b/tests/Community/Tdarr_Plugin_e3je_Tharic_H.264_MKV_1080p30_No_Subs_No_Title_Meta.js new file mode 100644 index 0000000..046e210 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_e3je_Tharic_H.264_MKV_1080p30_No_Subs_No_Title_Meta.js @@ -0,0 +1,96 @@ +/* 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 -c copy', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is h264 1080p!☑File has no title and has no subs \n' + + '☒File has title metadata \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: '-Z "H.264 MKV 1080p30"', + container: '.mkv', + handBrakeMode: true, + FFmpegMode: false, + reQueueAfter: true, + infoLog: '☒File is not h264 1080p! \n', + }, + }, + + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.ffProbeData.streams[0].width = 1920; + file.ffProbeData.streams[0].height = 1080; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map_metadata -1 -map 0 -c copy', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is h264 1080p!☑File has no title and has no subs \n' + + '☒File has title metadata \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.ffProbeData.streams[0].width = 1920; + file.ffProbeData.streams[0].height = 1080; + + file.meta.Title = undefined; + file.container = 'mkv'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: false, + infoLog: '☑File is h264 1080p!☑File has no title and has no subs \n' + + '☑File has no title metadata \n' + + '☑File has no subs \n' + + '☑File is in mkv container! \n' + + '☑File meets conditions! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_e5c3_CnT_Keep_Preferred_Audio.js b/tests/Community/Tdarr_Plugin_e5c3_CnT_Keep_Preferred_Audio.js new file mode 100644 index 0000000..5a70598 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_e5c3_CnT_Keep_Preferred_Audio.js @@ -0,0 +1,94 @@ +/* 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:v', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: 'Removing unwanted audio...\n' + + 'Found unwanted: und: 1\n' + + 'Found unwanted: und: 1\n' + + 'No unwanted audio found!\n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: ', -map 0:v -map 0:1', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: false, + reQueueAfter: false, + infoLog: 'Removing unwanted audio...\nAdded undefined: 1\nNo unwanted audio found!\n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_2.json')), + librarySettings: {}, + inputs: { + languages: 'fre', + container: 'mp4', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map 0:v -map 0:4 -map 0:s? -c copy', + container: 'mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'Removing unwanted audio...\n' + + 'Found wanted fre: 4\n' + + 'Found unwanted audio\n' + + 'It will be removed\n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_2.json')), + librarySettings: {}, + inputs: { + languages: 'eng', + container: 'mp4', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map 0:v -map 0:1 -map 0:2 -map 0:3 -map 0:5 -map 0:s? -c copy', + container: 'mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'Removing unwanted audio...\n' + + 'Found wanted eng: 1\n' + + 'Found wanted eng: 2\n' + + 'Found wanted eng: 3\n' + + 'Found wanted eng: 5\n' + + 'Found unwanted audio\n' + + 'It will be removed\n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_fd5T_Sparticus_4K_AC3_No_Subs.js b/tests/Community/Tdarr_Plugin_fd5T_Sparticus_4K_AC3_No_Subs.js new file mode 100644 index 0000000..86bb3c1 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_fd5T_Sparticus_4K_AC3_No_Subs.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: true, + reQueueAfter: false, + infoLog: '☒File is not a 4K video \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_2.json')); + file.video_resolution = '4KUHD'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-sn -map 0 -c copy', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File does not have only AC3 track commentaries! \n' + + '☑File has AC3 track! \n' + + '☒File has subs! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_henk_Add_Specific_Audio_Codec.js b/tests/Community/Tdarr_Plugin_henk_Add_Specific_Audio_Codec.js new file mode 100644 index 0000000..71c8098 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_henk_Add_Specific_Audio_Codec.js @@ -0,0 +1,85 @@ +/* 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: ', -c copy -map 0:v ', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: false, + infoLog: '☒File is not mkv \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_2.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: ', -c copy -map 0:v -map 0:a:0? -c:a:0 copy -map 0:a:1? -c:a:1 copy -map 0:a:2? -c:a:2 copy -map 0:a:3? -c:a:3 copy -map 0:a:4? -c:a:4 copy ', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: false, + infoLog: "☑File doesn't contain audio tracks with the specified codec.\n", + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_2.json')), + librarySettings: {}, + inputs: { + input_codecs: 'aac', + output_codec: 'eac3', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -c copy -map 0:v -map 0:a:0? -c:a:0 copy -map 0:a:1? -c:a:1 copy -map 0:a:2? -c:a:2 copy -map 0:a:3? -c:a:3 copy -map 0:a:3? -c:a:4 eac3 -b:a:4 128k -metadata:s:a:4 title="" -metadata:s:a:4 copyright="henk_asac" -disposition:a:4 0 -map 0:a:4? -c:a:5 copy -map 0:a:4? -c:a:6 eac3 -b:a:6 128k -metadata:s:a:6 title="" -metadata:s:a:6 copyright="henk_asac" -disposition:a:6 0 -map 0:s? ', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_2.json')), + librarySettings: {}, + inputs: { + input_codecs: 'aac', + output_codec: 'eac3', + bitrate: '256', + auto_adjust: 'false', + position_new_audio: 'before', + }, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -c copy -map 0:v -map 0:a:0? -c:a:0 copy -map 0:a:1? -c:a:1 copy -map 0:a:2? -c:a:2 copy -map 0:a:3? -c:a:3 eac3 -b:a:3 256k -metadata:s:a:3 title="" -metadata:s:a:3 copyright="henk_asac" -disposition:a:3 0 -map 0:a:3? -c:a:4 copy -map 0:a:4? -c:a:5 eac3 -b:a:5 256k -metadata:s:a:5 title="" -metadata:s:a:5 copyright="henk_asac" -disposition:a:5 0 -map 0:a:4? -c:a:6 copy -map 0:s? ', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_hk75_Drawmonster_MP4_AAC_No_Subs_No_metaTitle.js b/tests/Community/Tdarr_Plugin_hk75_Drawmonster_MP4_AAC_No_Subs_No_metaTitle.js new file mode 100644 index 0000000..894d3a0 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_hk75_Drawmonster_MP4_AAC_No_Subs_No_metaTitle.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: {}, + }, + output: { + processFile: true, + preset: ',-map_metadata -1 -c:v copy -c:a copy', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒File has title metadata \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -c:v copy -c:a copy', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File has no title metadata \n' + + '☑File has no subs \n' + + '☒File is not in mp4 container! \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH265_1.json')); + file.container = 'mp4'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: false, + infoLog: '☑File has no title metadata \n' + + '☑File has no subs \n' + + '☑File is in mp4 container! \n' + + '☑File meets conditions! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_hk76_GilbN_MP4_AAC_No_metaTitle.js b/tests/Community/Tdarr_Plugin_hk76_GilbN_MP4_AAC_No_metaTitle.js new file mode 100644 index 0000000..df39e53 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_hk76_GilbN_MP4_AAC_No_metaTitle.js @@ -0,0 +1,66 @@ +/* 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 -c copy', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is in mp4 container! \n☒File has title metadata \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ', -map 0 -c copy', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒File is not in mp4 container! \n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH265_1.json')); + file.container = 'mp4'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: false, + infoLog: '☑File is in mp4 container! \n' + + '☑File has no title metadata \n' + + '☑File has aac track \n' + + '☑File meets conditions! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_jeons001_Downmix_to_stereo_and_apply_DRC.js b/tests/Community/Tdarr_Plugin_jeons001_Downmix_to_stereo_and_apply_DRC.js new file mode 100644 index 0000000..229b051 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_jeons001_Downmix_to_stereo_and_apply_DRC.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: true, + preset: '-sn -vcodec copy -scodec copy -acodec aac -filter:a "dynaudnorm,pan=stereo|FL < 1.0*FL + 0.707*FC + 0.707*BL|FR < 1.0*FR + 0.707*FC + 0.707*BR"', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'File matches requirements for processing. Downmixing and applying DRC!', + container: '.mp4', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_2.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'File has more than 1 audio track - not processing', + container: '.mkv', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_lmg1_Reorder_Streams.js b/tests/Community/Tdarr_Plugin_lmg1_Reorder_Streams.js new file mode 100644 index 0000000..197cc39 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_lmg1_Reorder_Streams.js @@ -0,0 +1,50 @@ +/* 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 video in first stream\n File meets conditions!\n', + }, + }, + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + + const audio = file.ffProbeData.streams[1]; + // eslint-disable-next-line prefer-destructuring + file.ffProbeData.streams[1] = file.ffProbeData.streams[0]; + file.ffProbeData.streams[0] = audio; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0:v? -map 0:a? -map 0:s? -map 0:d? -map 0:t? -c copy', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: 'Video is not in the first stream', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_nc7x_Drawmonster_No_Title_Meta.js b/tests/Community/Tdarr_Plugin_nc7x_Drawmonster_No_Title_Meta.js new file mode 100644 index 0000000..9dfabae --- /dev/null +++ b/tests/Community/Tdarr_Plugin_nc7x_Drawmonster_No_Title_Meta.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: true, + preset: ',-map_metadata -1 -map 0 -c copy', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☒File has title metadata \n', + }, + }, + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH265_1.json')), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: false, + infoLog: '☑File has no title metadata \n☑File meets conditions! \n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_r002_rootuser_FFMPEG_HQ_HEVC_MKV_Animation.js b/tests/Community/Tdarr_Plugin_r002_rootuser_FFMPEG_HQ_HEVC_MKV_Animation.js new file mode 100644 index 0000000..4acaaaf --- /dev/null +++ b/tests/Community/Tdarr_Plugin_r002_rootuser_FFMPEG_HQ_HEVC_MKV_Animation.js @@ -0,0 +1,44 @@ +/* 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 -c:s copy -movflags use_metadata_tags -c:a aac -b:a 512k -c:v:0 libx265 -preset medium -x265-params crf=18:tune=animation:qcomp=0.7:aq-strength=1.1 -pix_fmt yuv420p10le -f matroska', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is a video! \n' + + '☒File is 720p but is not hevc!\n' + + '☒File will be 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', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_raf4_Floorpie_FFmpeg_Tiered_HEVC_MKV.js b/tests/Community/Tdarr_Plugin_raf4_Floorpie_FFmpeg_Tiered_HEVC_MKV.js new file mode 100644 index 0000000..3cdab96 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_raf4_Floorpie_FFmpeg_Tiered_HEVC_MKV.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: true, + preset: ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 25', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is a video! \n' + + '☒File is 720p but is not hevc!\n' + + '☒File will be 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: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_2.json')); + file.video_resolution = '480p'; + return file; + })(), + librarySettings: {}, + inputs: {}, + otherArguments: {}, + }, + output: { + processFile: true, + preset: ',-map 0:v -map 0:s? -c:s srt -map 0:a -c copy -c:v:0 libx265 -preset fast -crf 27', + container: '.mkv', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑File is a video! \n' + + '☒File is 480p but is not hevc!\n' + + '☒File will be transcoded!\n', + }, + }, +]; + +run(tests); diff --git a/tests/Community/Tdarr_Plugin_s7x8_winsome_h265.js b/tests/Community/Tdarr_Plugin_s7x8_winsome_h265.js new file mode 100644 index 0000000..36ea9c2 --- /dev/null +++ b/tests/Community/Tdarr_Plugin_s7x8_winsome_h265.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', + 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/checkPlugins.js b/tests/checkPlugins.js index 725531a..13bab9d 100644 --- a/tests/checkPlugins.js +++ b/tests/checkPlugins.js @@ -1,12 +1,16 @@ /* eslint no-console: 0 */ // --> OFF +/* eslint max-len: 0 */ const fs = require('fs'); +const chalk = require('chalk'); const folders = [ './Community', './examples', ]; +let errorEncountered = false; + folders.forEach((folder) => { const files = fs.readdirSync(folder).filter((row) => row.includes('.js')); @@ -28,16 +32,16 @@ folders.forEach((folder) => { const importLib = 'const lib = require(\'../methods/lib\')();'; if (!read.includes(importLib)) { - console.log(`Plugin error: '${folder}/${files[i]}' does not contain ${importLib}`); + console.log(chalk.red(`Plugin error: '${folder}/${files[i]}' does not contain ${importLib}`)); read = `${importLib}\n${read}`; // fs.writeFileSync(`${folder}/${files[i]}`, read) - process.exit(1); + errorEncountered = true; } const detailsText = 'const details = () =>'; if (!read.includes(detailsText)) { - console.log(`Plugin error: '${folder}/${files[i]}' does not contain ${detailsText}`); - process.exit(1); + console.log(chalk.red(`Plugin error: '${folder}/${files[i]}' does not contain ${detailsText}`)); + errorEncountered = true; } const syncText = 'const plugin = (file, librarySettings, inputs, otherArguments) => {'; @@ -46,27 +50,27 @@ folders.forEach((folder) => { if (!read.includes(syncText) && !read.includes(asyncText) ) { - console.log(`Plugin error: '${folder}/${files[i]}' does not contain ${syncText} or ${asyncText}`); - process.exit(1); + console.log(chalk.red(`Plugin error: '${folder}/${files[i]}' does not contain ${syncText} or ${asyncText}`)); + errorEncountered = true; } const inputsText = 'inputs = lib.loadDefaultValues(inputs, details);'; if (!read.includes(inputsText) ) { - console.log(`Plugin error: '${folder}/${files[i]}' does not contain ${inputsText}`); - process.exit(1); + console.log(chalk.red(`Plugin error: '${folder}/${files[i]}' does not contain ${inputsText}`)); + errorEncountered = true; } const exportText = `module.exports.details = details; module.exports.plugin = plugin;`; if (!read.includes(exportText)) { - console.log(`Plugin error: '${folder}/${files[i]}' does not contain ${exportText}`); + console.log(chalk.red(`Plugin error: '${folder}/${files[i]}' does not contain ${exportText}`)); read = read.replace('module.exports.details = details;', ''); read = read.replace('module.exports.plugin = plugin;', ''); read += `\n${exportText}`; // fs.writeFileSync(`${folder}/${files[i]}`, read) - process.exit(1); + errorEncountered = true; } // check deps are within functions @@ -80,8 +84,8 @@ module.exports.plugin = plugin;`; const countOpen = allBefore.join(keyWord).split('{').length - 1; const countClose = allBefore.join(keyWord).split('}').length - 1; if (countOpen === countClose) { - console.log(`Plugin has requires outside of function '${folder}/${files[i]}'`); - process.exit(1); + console.log(chalk.red(`Plugin has requires outside of function '${folder}/${files[i]}'`)); + errorEncountered = true; } } } @@ -91,64 +95,66 @@ module.exports.plugin = plugin;`; // eslint-disable-next-line import/no-dynamic-require,global-require pluginDetails = require(`.${folder}/${files[i]}`).details(); } catch (err) { - console.log(err.message); - process.exit(1); + console.log(chalk.red(err.message)); + errorEncountered = true; } const detailsKeys = Object.keys(pluginDetails); + // eslint-disable-next-line no-loop-func detailsOrder.forEach((detail) => { if (detailsKeys.indexOf(detail) === -1) { - console.log(`Plugin details is missing '${folder}/${files[i]}' : ${detail}`); - process.exit(1); + console.log(chalk.red(`Plugin details is missing '${folder}/${files[i]}' : ${detail}`)); + errorEncountered = true; } }); + // eslint-disable-next-line no-loop-func detailsKeys.forEach((detail, index) => { if (detailsOrder[index] !== detail) { - console.log(`Plugin details keys are not in the correct order: '${folder}/${files[i]}' ${detail}`); - process.exit(1); + console.log(chalk.red(`Plugin details keys are not in the correct order: '${folder}/${files[i]}' ${detail}`)); + errorEncountered = true; } }); if (detailsKeys.length < detailsOrder.length) { - console.log(`Plugin details are too few '${folder}/${files[i]}'`); - process.exit(1); + console.log(chalk.red(`Plugin details are too few '${folder}/${files[i]}'`)); + errorEncountered = true; } if (!['Pre-processing', 'Post-processing'].includes(pluginDetails.Stage)) { - console.log(`Plugin does not have a valid Type'${folder}/${files[i]}'`); - process.exit(1); + console.log(chalk.red(`Plugin does not have a valid Type'${folder}/${files[i]}'`)); + errorEncountered = true; } if (!['Video', 'Audio', 'Subtitle', 'Any'].includes(pluginDetails.Type)) { - console.log(`Plugin does not have a valid Type'${folder}/${files[i]}'`); - process.exit(1); + console.log(chalk.red(`Plugin does not have a valid Type'${folder}/${files[i]}'`)); + errorEncountered = true; } if (files[i].split('.js').join('') !== pluginDetails.id) { - console.log(`Plugin file name does not match details id'${folder}/${files[i]}'`); - process.exit(1); + console.log(chalk.red(`Plugin file name does not match details id'${folder}/${files[i]}'`)); + errorEncountered = true; } if (!['Transcode', 'Filter'].includes(pluginDetails.Operation)) { - console.log(`Plugin does not have a valid Operation '${folder}/${files[i]}'`); - process.exit(1); + console.log(chalk.red(`Plugin does not have a valid Operation '${folder}/${files[i]}'`)); + errorEncountered = true; } else if (detailsKeys.length > detailsOrder.length) { - console.log(`Plugin details are too many '${folder}/${files[i]}'`); - process.exit(1); + console.log(chalk.red(`Plugin details are too many '${folder}/${files[i]}'`)); + errorEncountered = true; } else if (pluginDetails.Inputs && !Array.isArray(pluginDetails.Inputs)) { // Check default values are set; - console.log(`Plugin Inputs is not an array: ${files[i]}`); - process.exit(1); + console.log(chalk.red(`Plugin Inputs is not an array: ${files[i]}`)); + errorEncountered = true; } else if (pluginDetails.Inputs && Array.isArray(pluginDetails.Inputs)) { const inputs = pluginDetails.Inputs; const savedInputs = {}; for (let j = 0; j < inputs.length; j += 1) { // Prevent duplicate plugin inputs if (savedInputs[inputs[j].name] === true) { - console.log(`Plugin Input already exists: '${folder}/${files[i]}' : ${inputs[j].name}`); - process.exit(1); + console.log(chalk.red(`Plugin Input already exists: '${folder}/${files[i]}' : ${inputs[j].name}`)); + errorEncountered = true; } else { savedInputs[inputs[j].name] = true; } @@ -161,31 +167,31 @@ module.exports.plugin = plugin;`; || inputKeys[3] !== 'inputUI' || inputKeys[4] !== 'tooltip' ) { - console.log(`Plugin Input keys are not in correct order: '${folder}/${files[i]}' : ${inputs[j].name}`); - process.exit(1); + console.log(chalk.red(`Plugin Input keys are not in correct order: '${folder}/${files[i]}' : ${inputs[j].name}`)); + errorEncountered = true; } else if (inputs[j].type === undefined || !pluginInputTypes.includes(inputs[j].type)) { - console.log(`Plugin Input does not have a type: '${folder}/${files[i]}' : ${inputs[j].name}`); - process.exit(1); + console.log(chalk.red(`Plugin Input does not have a type: '${folder}/${files[i]}' : ${inputs[j].name}`)); + errorEncountered = true; } else if ( (inputs[j].type === 'string' && typeof inputs[j].defaultValue !== 'string') || (inputs[j].type === 'number' && typeof inputs[j].defaultValue !== 'number') || (inputs[j].type === 'boolean' && typeof inputs[j].defaultValue !== 'boolean') ) { - console.log(`Plugin Input type does not match defaultValue type: - '${folder}/${files[i]}' : ${inputs[j].name}`); - process.exit(1); + console.log(chalk.red(`Plugin Input type does not match defaultValue type: + '${folder}/${files[i]}' : ${inputs[j].name}`)); + errorEncountered = true; } else if (!['text', 'dropdown'].includes(inputs[j].inputUI.type)) { - console.log(`Plugin Input inputUI is invalid: '${folder}/${files[i]}' : ${inputs[j].name}`); - process.exit(1); + console.log(chalk.red(`Plugin Input inputUI is invalid: '${folder}/${files[i]}' : ${inputs[j].name}`)); + errorEncountered = true; } else if (inputs[j].defaultValue === undefined) { - console.log(`Plugin Input does not have a default value: '${folder}/${files[i]}' : ${inputs[j].name}`); - process.exit(1); + console.log(chalk.red(`Plugin Input does not have a default value: '${folder}/${files[i]}' : ${inputs[j].name}`)); + errorEncountered = true; } const count = read.split(inputs[j].name).length - 1; if (count === 1) { - console.log(`Plugin Input is not used: '${folder}/${files[i]}' : ${inputs[j].name}`); - process.exit(1); + console.log(chalk.red(`Plugin Input is not used: '${folder}/${files[i]}' : ${inputs[j].name}`)); + errorEncountered = true; } } } @@ -195,3 +201,8 @@ module.exports.plugin = plugin;`; }); console.log('Done!'); + +if (errorEncountered) { + console.log('Errors encountered'); + process.exit(1); +} diff --git a/tests/helpers/run.js b/tests/helpers/run.js new file mode 100644 index 0000000..58b6e05 --- /dev/null +++ b/tests/helpers/run.js @@ -0,0 +1,55 @@ +const path = require('path'); +const chai = require('chai'); +const _ = require('lodash'); +const importFresh = require('import-fresh'); + +const scriptName = path.basename(process.mainModule.filename); + +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}`); + 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!'); + } + } else { + chai.assert.deepEqual(testOutput, test.output); + } + } + } catch (err) { + // eslint-disable-next-line no-console + console.error(err); + process.exit(1); + } +}; + +module.exports = run; diff --git a/tests/runTests.js b/tests/runTests.js new file mode 100644 index 0000000..d5d7285 --- /dev/null +++ b/tests/runTests.js @@ -0,0 +1,51 @@ +/* eslint no-console: 0 */ // --> OFF + +const fs = require('fs'); +const chalk = require('chalk'); +const childProcess = require('child_process'); + +const filenames = fs.readdirSync(`${process.cwd()}/Community`).reverse(); + +const run = async () => { + for (let i = 0; i < filenames.length; i += 1) { + const pluginPath = `${process.cwd()}/Community/${filenames[i]}`; + const text = fs.readFileSync(pluginPath); + const pluginTestpath = `${__dirname}/Community/${filenames[i]}`; + + let shouldRunTest = true; + if (!text.includes('// tdarrSkipTest') && !fs.existsSync(pluginTestpath)) { + console.log(chalk.red(`${filenames[i]} 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`)); + } else if (text.includes('// tdarrSkipTest') && fs.existsSync(pluginTestpath)) { + console.log(chalk.red(`${filenames[i]} 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; + } + + 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(); + } + }); + }); + } + } +}; + +run(); diff --git a/tests/sampleData/media/sampleAAC_1.json b/tests/sampleData/media/sampleAAC_1.json new file mode 100644 index 0000000..81d53e6 --- /dev/null +++ b/tests/sampleData/media/sampleAAC_1.json @@ -0,0 +1,334 @@ +{ + "_id": "C:/Transcode/Source Folder/qsv_h265.mkv", + "file": "C:/Transcode/Source Folder/qsv_h265.mkv", + "DB": "2MY5YD7P8", + "footprintId": "xkZP3IPR6g", + "hasClosedCaptions": false, + "container": "mkv", + "scannerReads": { + "ffProbeRead": "success", + "exiftoolRead": "success", + "mediaInfoRead": "success", + "closedCaptionRead": "\"Unable to run CCExtractor\"" + }, + "ffProbeData": { + "streams": [ + { + "index": 0, + "codec_name": "hevc", + "codec_long_name": "H.265 / HEVC (High Efficiency Video Coding)", + "profile": "Main", + "codec_type": "video", + "codec_tag_string": "[0][0][0][0]", + "codec_tag": "0x0000", + "width": 1920, + "height": 1080, + "coded_width": 1920, + "coded_height": 1088, + "closed_captions": 0, + "has_b_frames": 1, + "sample_aspect_ratio": "1:1", + "display_aspect_ratio": "16:9", + "pix_fmt": "yuv420p", + "level": 150, + "color_range": "tv", + "color_space": "bt709", + "color_transfer": "bt709", + "color_primaries": "bt709", + "chroma_location": "left", + "refs": 1, + "r_frame_rate": "25/1", + "avg_frame_rate": "25/1", + "time_base": "1/1000", + "start_pts": 21, + "start_time": "0.021000", + "disposition": { + "default": 1, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "DURATION": "00:00:21.341000000" + } + }, + { + "index": 1, + "codec_name": "aac", + "codec_long_name": "AAC (Advanced Audio Coding)", + "profile": "LC", + "codec_type": "audio", + "codec_tag_string": "[0][0][0][0]", + "codec_tag": "0x0000", + "sample_fmt": "fltp", + "sample_rate": "48000", + "channels": 2, + "channel_layout": "stereo", + "bits_per_sample": 0, + "r_frame_rate": "0/0", + "avg_frame_rate": "0/0", + "time_base": "1/1000", + "start_pts": 0, + "start_time": "0.000000", + "disposition": { + "default": 1, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "title": "Stereo", + "DURATION": "00:00:21.375000000" + } + } + ], + "format": { + "filename": "C:/Transcode/Source Folder/qsv_h265.mkv", + "nb_streams": 2, + "nb_programs": 0, + "format_name": "matroska,webm", + "format_long_name": "Matroska / WebM", + "start_time": "0.000000", + "duration": "21.375000", + "size": "8569883", + "bit_rate": "3207441", + "probe_score": 100, + "tags": { + "creation_time": "2019-09-13T16:46:14.000000Z", + "ENCODER": "Lavf58.20.100" + } + } + }, + "file_size": 8.172877311706543, + "video_resolution": "1080p", + "fileMedium": "video", + "video_codec_name": "hevc", + "audio_codec_name": "", + "lastPluginDetails": "none", + "createdAt": 1653029410394, + "bit_rate": 3207441, + "duration": 21, + "statSync": { + "dev": 3832468976, + "mode": 33060, + "nlink": 1, + "uid": 0, + "gid": 0, + "rdev": 0, + "blksize": 4096, + "ino": 1970324841360027, + "size": 8569883, + "blocks": 16744, + "atimeMs": 1653029410381.1382, + "mtimeMs": 1568393195000, + "ctimeMs": 1650864287188.087, + "birthtimeMs": 1650864302270.2063, + "atime": "2022-05-20T06:50:10.381Z", + "mtime": "2019-09-13T16:46:35.000Z", + "ctime": "2022-04-25T05:24:47.188Z", + "birthtime": "2022-04-25T05:25:02.270Z" + }, + "HealthCheck": "", + "TranscodeDecisionMaker": "", + "lastHealthCheckDate": 0, + "holdUntil": 0, + "lastTranscodeDate": 0, + "bumped": false, + "history": "", + "oldSize": 0, + "newSize": 0, + "videoStreamIndex": 0, + "lastUpdate": 1653027918258, + "meta": { + "SourceFile": "C:/Transcode/Source Folder/qsv_h265.mkv", + "errors": [], + "Duration": 21.375, + "ExifToolVersion": 12.4, + "FileName": "qsv_h265.mkv", + "Directory": "C:/Transcode/Source Folder", + "FileSize": "8.2 MiB", + "FileModifyDate": { + "year": 2019, + "month": 9, + "day": 13, + "hour": 17, + "minute": 46, + "second": 35, + "millisecond": 0, + "tzoffsetMinutes": 60, + "rawValue": "2019:09:13 17:46:35+01:00" + }, + "FileAccessDate": { + "year": 2022, + "month": 5, + "day": 20, + "hour": 7, + "minute": 50, + "second": 9, + "millisecond": 0, + "tzoffsetMinutes": 60, + "rawValue": "2022:05:20 07:50:09+01:00" + }, + "FileCreateDate": { + "year": 2022, + "month": 4, + "day": 25, + "hour": 6, + "minute": 25, + "second": 2, + "millisecond": 0, + "tzoffsetMinutes": 60, + "rawValue": "2022:04:25 06:25:02+01:00" + }, + "FilePermissions": "-r--r--r--", + "FileType": "MKV", + "FileTypeExtension": "mkv", + "MIMEType": "video/x-matroska", + "EBMLVersion": 1, + "EBMLReadVersion": 1, + "DocType": "matroska", + "DocTypeVersion": 4, + "DocTypeReadVersion": 2, + "TimecodeScale": "1 ms", + "MuxingApp": "Lavf58.20.100", + "WritingApp": "HandBrake 1.2.2 2019022300", + "DateTimeOriginal": { + "year": 2019, + "month": 9, + "day": 13, + "hour": 16, + "minute": 46, + "second": 14, + "millisecond": 0, + "tzoffsetMinutes": 0, + "rawValue": "2019:09:13 16:46:14Z" + }, + "VideoFrameRate": 25, + "ImageWidth": 1920, + "ImageHeight": 1080, + "TrackNumber": 2, + "TrackName": "Stereo", + "TrackLanguage": "und", + "CodecID": "A_AAC", + "TrackType": "Audio", + "AudioChannels": 2, + "AudioSampleRate": 48000, + "TagName": "DURATION", + "TagString": "00:00:21.375000000", + "ImageSize": "1920x1080", + "Megapixels": 2.1 + }, + "mediaInfo": { + "@ref": "", + "track": [ + { + "@type": "General", + "UniqueID": "112612991515236890937117095733641799622", + "VideoCount": "1", + "AudioCount": "1", + "Format": "Matroska", + "Format_Version": "4", + "FileSize": "8569883", + "Duration": "21.375", + "OverallBitRate": "3207442", + "FrameRate": "25.000", + "FrameCount": "533", + "IsStreamable": "Yes", + "Encoded_Date": "UTC 2019-09-13 16:46:14", + "Encoded_Application": "HandBrake 1.2.2 2019022300", + "Encoded_Library": "Lavf58.20.100", + "extra": { + "ErrorDetectionType": "Per level 1" + } + }, + { + "@type": "Video", + "StreamOrder": "0", + "ID": "1", + "UniqueID": "1", + "Format": "HEVC", + "Format_Profile": "Main", + "Format_Level": "5", + "Format_Tier": "Main", + "CodecID": "V_MPEGH/ISO/HEVC", + "Duration": "21.320000000", + "Width": "1920", + "Height": "1080", + "Stored_Height": "1088", + "Sampled_Width": "1920", + "Sampled_Height": "1080", + "PixelAspectRatio": "1.000", + "DisplayAspectRatio": "1.778", + "FrameRate_Mode": "CFR", + "FrameRate": "25.000", + "FrameCount": "533", + "ColorSpace": "YUV", + "ChromaSubsampling": "4:2:0", + "BitDepth": "8", + "Delay": "0.021", + "Default": "Yes", + "Forced": "No", + "colour_description_present": "Yes", + "colour_description_present_Source": "Stream", + "colour_range": "Limited", + "colour_range_Source": "Stream", + "colour_primaries": "BT.709", + "colour_primaries_Source": "Stream", + "transfer_characteristics": "BT.709", + "transfer_characteristics_Source": "Stream", + "matrix_coefficients": "BT.709", + "matrix_coefficients_Source": "Stream" + }, + { + "@type": "Audio", + "StreamOrder": "1", + "ID": "2", + "UniqueID": "2", + "Format": "AAC", + "Format_Settings_SBR": "No (Explicit)", + "Format_AdditionalFeatures": "LC", + "CodecID": "A_AAC-2", + "Duration": "21.375000000", + "Channels": "2", + "ChannelPositions": "Front: L R", + "ChannelLayout": "L R", + "SamplesPerFrame": "1024", + "SamplingRate": "48000", + "SamplingCount": "1026000", + "FrameRate": "46.875", + "Compression_Mode": "Lossy", + "Delay": "0.000", + "Delay_Source": "Container", + "Title": "Stereo", + "Default": "Yes", + "Forced": "No" + } + ] + } + } \ No newline at end of file diff --git a/tests/sampleData/media/sampleH264_1.json b/tests/sampleData/media/sampleH264_1.json new file mode 100644 index 0000000..9833f8d --- /dev/null +++ b/tests/sampleData/media/sampleH264_1.json @@ -0,0 +1,432 @@ +{ + "_id": "C:/Transcode/Source Folder/SampleVideo_1280x720_1mb.mp4", + "file": "C:/Transcode/Source Folder/SampleVideo_1280x720_1mb.mp4", + "DB": "2MY5YD7P8", + "footprintId": "KA_y0Hm3Ld", + "hasClosedCaptions": false, + "container": "mp4", + "scannerReads": { + "ffProbeRead": "success", + "exiftoolRead": "success", + "mediaInfoRead": "success", + "closedCaptionRead": "\"Unable to run CCExtractor\"" + }, + "ffProbeData": { + "streams": [ + { + "index": 0, + "codec_name": "h264", + "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10", + "profile": "Main", + "codec_type": "video", + "codec_tag_string": "avc1", + "codec_tag": "0x31637661", + "width": 1280, + "height": 720, + "coded_width": 1280, + "coded_height": 720, + "closed_captions": 0, + "has_b_frames": 0, + "sample_aspect_ratio": "1:1", + "display_aspect_ratio": "16:9", + "pix_fmt": "yuv420p", + "level": 31, + "chroma_location": "left", + "refs": 1, + "is_avc": "true", + "nal_length_size": "4", + "r_frame_rate": "25/1", + "avg_frame_rate": "25/1", + "time_base": "1/12800", + "start_pts": 0, + "start_time": "0.000000", + "duration_ts": 67584, + "duration": "5.280000", + "bit_rate": "1205959", + "bits_per_raw_sample": "8", + "nb_frames": "132", + "disposition": { + "default": 1, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "creation_time": "1970-01-01T00:00:00.000000Z", + "language": "und", + "handler_name": "VideoHandler", + "vendor_id": "[0][0][0][0]" + } + }, + { + "index": 1, + "codec_name": "aac", + "codec_long_name": "AAC (Advanced Audio Coding)", + "profile": "LC", + "codec_type": "audio", + "codec_tag_string": "mp4a", + "codec_tag": "0x6134706d", + "sample_fmt": "fltp", + "sample_rate": "48000", + "channels": 6, + "channel_layout": "5.1", + "bits_per_sample": 0, + "r_frame_rate": "0/0", + "avg_frame_rate": "0/0", + "time_base": "1/48000", + "start_pts": 0, + "start_time": "0.000000", + "duration_ts": 254976, + "duration": "5.312000", + "bit_rate": "384828", + "nb_frames": "249", + "disposition": { + "default": 1, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "creation_time": "1970-01-01T00:00:00.000000Z", + "language": "und", + "handler_name": "SoundHandler", + "vendor_id": "[0][0][0][0]" + } + } + ], + "format": { + "filename": "C:/Transcode/Source Folder/SampleVideo_1280x720_1mb.mp4", + "nb_streams": 2, + "nb_programs": 0, + "format_name": "mov,mp4,m4a,3gp,3g2,mj2", + "format_long_name": "QuickTime / MOV", + "start_time": "0.000000", + "duration": "5.312000", + "size": "1056519", + "bit_rate": "1591143", + "probe_score": 100, + "tags": { + "major_brand": "isom", + "minor_version": "512", + "compatible_brands": "isomiso2avc1mp41", + "creation_time": "1970-01-08T00:00:00.000000Z", + "encoder": "Lavf53.24.2", + "title": "Sample title test", + "composer": "th", + "date": "2018", + "genre": "this", + "artist": "hhj", + "comment": "hhk" + } + } + }, + "file_size": 1.0075750350952148, + "video_resolution": "720p", + "fileMedium": "video", + "video_codec_name": "h264", + "audio_codec_name": "", + "lastPluginDetails": "none", + "createdAt": 1653029288316, + "bit_rate": 1591143, + "duration": 5, + "statSync": { + "dev": 3832468976, + "mode": 33060, + "nlink": 1, + "uid": 0, + "gid": 0, + "rdev": 0, + "blksize": 4096, + "ino": 1688849864649366, + "size": 1056519, + "blocks": 2064, + "atimeMs": 1653029288299.0342, + "mtimeMs": 1569306262000, + "ctimeMs": 1650864287160.0793, + "birthtimeMs": 1652683715285.7583, + "atime": "2022-05-20T06:48:08.299Z", + "mtime": "2019-09-24T06:24:22.000Z", + "ctime": "2022-04-25T05:24:47.160Z", + "birthtime": "2022-05-16T06:48:35.286Z" + }, + "HealthCheck": "", + "TranscodeDecisionMaker": "", + "lastHealthCheckDate": 0, + "holdUntil": 0, + "lastTranscodeDate": 0, + "bumped": false, + "history": "", + "oldSize": 0, + "newSize": 0, + "videoStreamIndex": 0, + "lastUpdate": 1653028721083, + "meta": { + "SourceFile": "C:/Transcode/Source Folder/SampleVideo_1280x720_1mb.mp4", + "errors": [], + "Duration": 5.312, + "PreviewDuration": 0, + "SelectionDuration": 0, + "TrackDuration": 5.28, + "MediaDuration": 5.28, + "ExifToolVersion": 12.4, + "FileName": "SampleVideo_1280x720_1mb.mp4", + "Directory": "C:/Transcode/Source Folder", + "FileSize": "1032 KiB", + "FileModifyDate": { + "year": 2019, + "month": 9, + "day": 24, + "hour": 7, + "minute": 24, + "second": 22, + "millisecond": 0, + "tzoffsetMinutes": 60, + "rawValue": "2019:09:24 07:24:22+01:00" + }, + "FileAccessDate": { + "year": 2022, + "month": 5, + "day": 20, + "hour": 7, + "minute": 48, + "second": 6, + "millisecond": 0, + "tzoffsetMinutes": 60, + "rawValue": "2022:05:20 07:48:06+01:00" + }, + "FileCreateDate": { + "year": 2022, + "month": 5, + "day": 16, + "hour": 7, + "minute": 48, + "second": 35, + "millisecond": 0, + "tzoffsetMinutes": 60, + "rawValue": "2022:05:16 07:48:35+01:00" + }, + "FilePermissions": "-r--r--r--", + "FileType": "MP4", + "FileTypeExtension": "mp4", + "MIMEType": "video/mp4", + "MajorBrand": "MP4 Base Media v1 [IS0 14496-12:2003]", + "MinorVersion": "0.2.0", + "CompatibleBrands": [ + "isom", + "iso2", + "avc1", + "mp41" + ], + "MediaDataSize": 0, + "MediaDataOffset": 1051515, + "MovieHeaderVersion": 0, + "CreateDate": { + "year": 1970, + "month": 1, + "day": 8, + "hour": 0, + "minute": 0, + "second": 0, + "millisecond": 0, + "rawValue": "1970:01:08 00:00:00" + }, + "ModifyDate": { + "year": 2014, + "month": 7, + "day": 19, + "hour": 17, + "minute": 15, + "second": 29, + "millisecond": 0, + "rawValue": "2014:07:19 17:15:29" + }, + "TimeScale": 1000, + "PreferredRate": 1, + "PreferredVolume": "100.00%", + "PreviewTime": "0 s", + "PosterTime": "0 s", + "SelectionTime": "0 s", + "CurrentTime": "0 s", + "NextTrackID": 3, + "TrackHeaderVersion": 0, + "TrackCreateDate": "0000:00:00 00:00:00", + "TrackModifyDate": "0000:00:00 00:00:00", + "TrackID": 1, + "TrackLayer": 0, + "TrackVolume": "0.00%", + "ImageWidth": 1280, + "ImageHeight": 720, + "GraphicsMode": "srcCopy", + "OpColor": "0 0 0", + "CompressorID": "avc1", + "SourceImageWidth": 1280, + "SourceImageHeight": 720, + "XResolution": 72, + "YResolution": 72, + "BitDepth": 24, + "VideoFrameRate": 25, + "MatrixStructure": "1 0 0 0 1 0 0 0 1", + "MediaHeaderVersion": 0, + "MediaCreateDate": "0000:00:00 00:00:00", + "MediaModifyDate": "0000:00:00 00:00:00", + "MediaTimeScale": 48000, + "MediaLanguageCode": "und", + "HandlerDescription": "SoundHandler", + "Balance": 0, + "AudioFormat": "mp4a", + "AudioChannels": 2, + "AudioBitsPerSample": 16, + "AudioSampleRate": 48000, + "HandlerType": "Metadata", + "HandlerVendorID": "Apple", + "Encoder": "Lavf53.24.2", + "Title": "Sample title test", + "Composer": "th", + "BeatsPerMinute": 0, + "ContentCreateDate": 2018, + "Genre": "this", + "Artist": "hhj", + "Comment": "hhk", + "Subtitle": "jj", + "Mood": "lik", + "ContentDistributor": "cont", + "Conductor": "jo", + "Writer": "writ", + "InitialKey": "ho", + "Producer": "prod", + "ParentalRating": "par", + "Director": "dir", + "Period": "pol", + "Publisher": "pub", + "PromotionURL": "prom", + "AuthorURL": "auth", + "EncodedBy": "enc", + "Category": "h", + "ImageSize": "1280x720", + "Megapixels": 0.922, + "AvgBitrate": "1.58 Mbps", + "Rotation": 0 + }, + "mediaInfo": { + "@ref": "", + "track": [ + { + "@type": "General", + "VideoCount": "1", + "AudioCount": "1", + "Format": "MPEG-4", + "Format_Profile": "Base Media", + "CodecID": "isom", + "CodecID_Compatible": "isom/iso2/avc1/mp41", + "FileSize": "1056519", + "Duration": "5.312", + "OverallBitRate_Mode": "VBR", + "OverallBitRate": "1591143", + "FrameRate": "25.000", + "FrameCount": "132", + "StreamSize": "5060", + "HeaderSize": "40", + "DataSize": "1051467", + "FooterSize": "5012", + "IsStreamable": "No", + "Title": "Sample title test", + "Movie": "Sample title test", + "Performer": "hhj", + "Composer": "th", + "Genre": "this", + "Recorded_Date": "2018", + "Encoded_Date": "UTC 1970-01-08 00:00:00", + "Tagged_Date": "UTC 2014-07-19 17:15:29", + "Encoded_Application": "Lavf53.24.2", + "Comment": "hhk" + }, + { + "@type": "Video", + "StreamOrder": "0", + "ID": "1", + "Format": "AVC", + "Format_Profile": "Main", + "Format_Level": "3.1", + "Format_Settings_CABAC": "Yes", + "Format_Settings_RefFrames": "1", + "CodecID": "avc1", + "Duration": "5.280", + "BitRate": "1205959", + "Width": "1280", + "Height": "720", + "Sampled_Width": "1280", + "Sampled_Height": "720", + "PixelAspectRatio": "1.000", + "DisplayAspectRatio": "1.778", + "Rotation": "0.000", + "FrameRate_Mode": "CFR", + "FrameRate_Mode_Original": "VFR", + "FrameRate": "25.000", + "FrameCount": "132", + "ColorSpace": "YUV", + "ChromaSubsampling": "4:2:0", + "BitDepth": "8", + "ScanType": "Progressive", + "StreamSize": "795933", + "Encoded_Date": "UTC 1970-01-01 00:00:00", + "Tagged_Date": "UTC 1970-01-01 00:00:00", + "extra": { + "CodecConfigurationBox": "avcC" + } + }, + { + "@type": "Audio", + "StreamOrder": "1", + "ID": "2", + "Format": "AAC", + "Format_AdditionalFeatures": "LC", + "CodecID": "mp4a-40-2", + "Duration": "5.312", + "BitRate_Mode": "VBR", + "BitRate": "384000", + "BitRate_Maximum": "400392", + "Channels": "6", + "ChannelPositions": "Front: L C R, Side: L R, LFE", + "ChannelLayout": "C L R Ls Rs LFE", + "SamplesPerFrame": "1024", + "SamplingRate": "48000", + "SamplingCount": "254976", + "FrameRate": "46.875", + "FrameCount": "249", + "Compression_Mode": "Lossy", + "StreamSize": "255526", + "StreamSize_Proportion": "0.24186", + "Default": "Yes", + "AlternateGroup": "1", + "Encoded_Date": "UTC 1970-01-01 00:00:00", + "Tagged_Date": "UTC 1970-01-01 00:00:00" + } + ] + } + } \ No newline at end of file diff --git a/tests/sampleData/media/sampleH264_2.json b/tests/sampleData/media/sampleH264_2.json new file mode 100644 index 0000000..7ad301b --- /dev/null +++ b/tests/sampleData/media/sampleH264_2.json @@ -0,0 +1,775 @@ +{ + "_id": "C:/Transcode/Source Folder/h264.mkv", + "file": "C:/Transcode/Source Folder/h264.mkv", + "DB": "2MY5YD7P8", + "footprintId": "asxmr-5Iij", + "hasClosedCaptions": false, + "container": "mkv", + "scannerReads": { + "ffProbeRead": "success", + "exiftoolRead": "success", + "mediaInfoRead": "success", + "closedCaptionRead": "success" + }, + "ffProbeData": { + "streams": [ + { + "index": 0, + "codec_name": "h264", + "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10", + "profile": "High", + "codec_type": "video", + "codec_tag_string": "[0][0][0][0]", + "codec_tag": "0x0000", + "width": 1918, + "height": 1080, + "coded_width": 1918, + "coded_height": 1080, + "closed_captions": 0, + "has_b_frames": 2, + "sample_aspect_ratio": "1:1", + "display_aspect_ratio": "959:540", + "pix_fmt": "yuv420p", + "level": 41, + "color_range": "tv", + "color_space": "bt709", + "chroma_location": "left", + "field_order": "progressive", + "refs": 1, + "is_avc": "true", + "nal_length_size": "4", + "r_frame_rate": "25/1", + "avg_frame_rate": "25/1", + "time_base": "1/1000", + "start_pts": 0, + "start_time": "0.000000", + "bits_per_raw_sample": "8", + "disposition": { + "default": 1, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "language": "fre", + "title": "title video", + "BPS-eng": "6453995", + "DURATION-eng": "00:01:03.960000000", + "NUMBER_OF_FRAMES-eng": "1599", + "NUMBER_OF_BYTES-eng": "51599695", + "_STATISTICS_WRITING_APP-eng": "mkvmerge v23.0.0 ('title') 64-bit", + "_STATISTICS_WRITING_DATE_UTC-eng": "2018-06-14 17:49:29", + "_STATISTICS_TAGS-eng": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES", + "DURATION": "00:01:03.986000000" + } + }, + { + "index": 1, + "codec_name": "flac", + "codec_long_name": "FLAC (Free Lossless Audio Codec)", + "codec_type": "audio", + "codec_tag_string": "[0][0][0][0]", + "codec_tag": "0x0000", + "sample_fmt": "s32", + "sample_rate": "48000", + "channels": 2, + "channel_layout": "stereo", + "bits_per_sample": 0, + "r_frame_rate": "0/0", + "avg_frame_rate": "0/0", + "time_base": "1/1000", + "start_pts": 5, + "start_time": "0.005000", + "bits_per_raw_sample": "24", + "disposition": { + "default": 0, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "language": "eng", + "title": "Anglais E-AC3 2.0", + "BPS-eng": "96000", + "DURATION-eng": "00:01:03.968000000", + "NUMBER_OF_FRAMES-eng": "1999", + "NUMBER_OF_BYTES-eng": "767616", + "_STATISTICS_WRITING_APP-eng": "mkvmerge v23.0.0 ('title') 64-bit", + "_STATISTICS_WRITING_DATE_UTC-eng": "2018-06-14 17:49:29", + "_STATISTICS_TAGS-eng": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES", + "ENCODER": "Lavc58.42.102 flac", + "DURATION": "00:01:04.005000000" + } + }, + { + "index": 2, + "codec_name": "ac3", + "codec_long_name": "ATSC A/52A (AC-3)", + "codec_type": "audio", + "codec_tag_string": "[0][0][0][0]", + "codec_tag": "0x0000", + "sample_fmt": "fltp", + "sample_rate": "48000", + "channels": 2, + "channel_layout": "stereo", + "bits_per_sample": 0, + "r_frame_rate": "0/0", + "avg_frame_rate": "0/0", + "time_base": "1/1000", + "start_pts": 0, + "start_time": "0.000000", + "bit_rate": "192000", + "disposition": { + "default": 0, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "language": "eng", + "title": "Anglais E-AC3 2.0", + "BPS-eng": "96000", + "DURATION-eng": "00:01:03.968000000", + "NUMBER_OF_FRAMES-eng": "1999", + "NUMBER_OF_BYTES-eng": "767616", + "_STATISTICS_WRITING_APP-eng": "mkvmerge v23.0.0 ('title') 64-bit", + "_STATISTICS_WRITING_DATE_UTC-eng": "2018-06-14 17:49:29", + "_STATISTICS_TAGS-eng": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES", + "ENCODER": "Lavc58.42.102 ac3", + "DURATION": "00:01:04.000000000" + } + }, + { + "index": 3, + "codec_name": "eac3", + "codec_long_name": "ATSC A/52B (AC-3, E-AC-3)", + "codec_type": "audio", + "codec_tag_string": "[0][0][0][0]", + "codec_tag": "0x0000", + "sample_fmt": "fltp", + "sample_rate": "48000", + "channels": 2, + "channel_layout": "stereo", + "bits_per_sample": 0, + "r_frame_rate": "0/0", + "avg_frame_rate": "0/0", + "time_base": "1/1000", + "start_pts": 0, + "start_time": "0.000000", + "bit_rate": "192000", + "disposition": { + "default": 0, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "language": "eng", + "title": "Anglais E-AC3 2.0", + "BPS-eng": "96000", + "DURATION-eng": "00:01:03.968000000", + "NUMBER_OF_FRAMES-eng": "1999", + "NUMBER_OF_BYTES-eng": "767616", + "_STATISTICS_WRITING_APP-eng": "mkvmerge v23.0.0 ('title') 64-bit", + "_STATISTICS_WRITING_DATE_UTC-eng": "2018-06-14 17:49:29", + "_STATISTICS_TAGS-eng": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES", + "ENCODER": "Lavc58.42.102 eac3", + "DURATION": "00:01:04.000000000" + } + }, + { + "index": 4, + "codec_name": "aac", + "codec_long_name": "AAC (Advanced Audio Coding)", + "profile": "LC", + "codec_type": "audio", + "codec_tag_string": "[0][0][0][0]", + "codec_tag": "0x0000", + "sample_fmt": "fltp", + "sample_rate": "48000", + "channels": 2, + "channel_layout": "stereo", + "bits_per_sample": 0, + "r_frame_rate": "0/0", + "avg_frame_rate": "0/0", + "time_base": "1/1000", + "start_pts": 5, + "start_time": "0.005000", + "disposition": { + "default": 1, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "language": "fre", + "title": "Français E-AC3 2.0", + "BPS-eng": "96000", + "DURATION-eng": "00:01:03.968000000", + "NUMBER_OF_FRAMES-eng": "1999", + "NUMBER_OF_BYTES-eng": "767616", + "_STATISTICS_WRITING_APP-eng": "mkvmerge v23.0.0 ('title') 64-bit", + "_STATISTICS_WRITING_DATE_UTC-eng": "2018-06-14 17:49:29", + "_STATISTICS_TAGS-eng": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES", + "ENCODER": "Lavc58.42.102 aac", + "DURATION": "00:01:04.004000000" + } + }, + { + "index": 5, + "codec_name": "aac", + "codec_long_name": "AAC (Advanced Audio Coding)", + "profile": "LC", + "codec_type": "audio", + "codec_tag_string": "[0][0][0][0]", + "codec_tag": "0x0000", + "sample_fmt": "fltp", + "sample_rate": "48000", + "channels": 2, + "channel_layout": "stereo", + "bits_per_sample": 0, + "r_frame_rate": "0/0", + "avg_frame_rate": "0/0", + "time_base": "1/1000", + "start_pts": 5, + "start_time": "0.005000", + "disposition": { + "default": 0, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "language": "eng", + "title": "Anglais E-AC3 2.0", + "BPS-eng": "96000", + "DURATION-eng": "00:01:03.968000000", + "NUMBER_OF_FRAMES-eng": "1999", + "NUMBER_OF_BYTES-eng": "767616", + "_STATISTICS_WRITING_APP-eng": "mkvmerge v23.0.0 ('title') 64-bit", + "_STATISTICS_WRITING_DATE_UTC-eng": "2018-06-14 17:49:29", + "_STATISTICS_TAGS-eng": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES", + "ENCODER": "Lavc58.42.102 aac", + "DURATION": "00:01:04.004000000" + } + }, + { + "index": 6, + "codec_name": "subrip", + "codec_long_name": "SubRip subtitle", + "codec_type": "subtitle", + "codec_tag_string": "[0][0][0][0]", + "codec_tag": "0x0000", + "r_frame_rate": "0/0", + "avg_frame_rate": "0/0", + "time_base": "1/1000", + "start_pts": 0, + "start_time": "0.000000", + "duration_ts": 66031, + "duration": "66.031000", + "disposition": { + "default": 0, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "language": "fre", + "title": "Français", + "BPS-eng": "46", + "DURATION-eng": "00:01:05.840000000", + "NUMBER_OF_FRAMES-eng": "12", + "NUMBER_OF_BYTES-eng": "381", + "_STATISTICS_WRITING_APP-eng": "mkvmerge v23.0.0 ('title') 64-bit", + "_STATISTICS_WRITING_DATE_UTC-eng": "2018-06-14 17:49:29", + "_STATISTICS_TAGS-eng": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES", + "DURATION": "00:01:06.031000000" + } + } + ], + "format": { + "filename": "C:/Transcode/Source Folder/h264.mkv", + "nb_streams": 7, + "nb_programs": 0, + "format_name": "matroska,webm", + "format_long_name": "Matroska / WebM", + "start_time": "0.000000", + "duration": "66.031000", + "size": "68084120", + "bit_rate": "8248746", + "probe_score": 100, + "tags": { + "ENCODER": "Lavf58.24.101" + } + } + }, + "file_size": 64.9300765991211, + "video_resolution": "1080p", + "fileMedium": "video", + "video_codec_name": "h264", + "audio_codec_name": "", + "lastPluginDetails": "none", + "createdAt": 1653139154025, + "bit_rate": 8248746, + "duration": 66, + "statSync": { + "dev": 3832468976, + "mode": 33206, + "nlink": 1, + "uid": 0, + "gid": 0, + "rdev": 0, + "blksize": 4096, + "ino": 64176294690080990, + "size": 68084120, + "blocks": 132984, + "atimeMs": 1653139154001.7666, + "mtimeMs": 1594420078270.8928, + "ctimeMs": 1653139134390.225, + "birthtimeMs": 1653139123219.1018, + "atime": "2022-05-21T13:19:14.002Z", + "mtime": "2020-07-10T22:27:58.271Z", + "ctime": "2022-05-21T13:18:54.390Z", + "birthtime": "2022-05-21T13:18:43.219Z" + }, + "HealthCheck": "", + "TranscodeDecisionMaker": "", + "lastHealthCheckDate": 0, + "holdUntil": 0, + "lastTranscodeDate": 0, + "bumped": false, + "history": "", + "oldSize": 0, + "newSize": 0, + "videoStreamIndex": 0, + "meta": { + "SourceFile": "C:/Transcode/Source Folder/h264.mkv", + "errors": [], + "Duration": 66.031, + "ExifToolVersion": 12.4, + "FileName": "h264.mkv", + "Directory": "C:/Transcode/Source Folder", + "FileSize": "65 MiB", + "FileModifyDate": { + "year": 2020, + "month": 7, + "day": 10, + "hour": 23, + "minute": 27, + "second": 58, + "millisecond": 0, + "tzoffsetMinutes": 60, + "rawValue": "2020:07:10 23:27:58+01:00" + }, + "FileAccessDate": { + "year": 2022, + "month": 5, + "day": 21, + "hour": 14, + "minute": 19, + "second": 11, + "millisecond": 0, + "tzoffsetMinutes": 60, + "rawValue": "2022:05:21 14:19:11+01:00" + }, + "FileCreateDate": { + "year": 2022, + "month": 5, + "day": 21, + "hour": 14, + "minute": 18, + "second": 43, + "millisecond": 0, + "tzoffsetMinutes": 60, + "rawValue": "2022:05:21 14:18:43+01:00" + }, + "FilePermissions": "-rw-rw-rw-", + "FileType": "MKV", + "FileTypeExtension": "mkv", + "MIMEType": "video/x-matroska", + "EBMLVersion": 1, + "EBMLReadVersion": 1, + "DocType": "matroska", + "DocTypeVersion": 4, + "DocTypeReadVersion": 2, + "TimecodeScale": "1 ms", + "MuxingApp": "Lavf58.24.101", + "WritingApp": "Lavf58.24.101", + "VideoFrameRate": 25, + "ImageWidth": 1918, + "ImageHeight": 1080, + "VideoScanType": "Unknown (2)", + "AudioChannels": 2, + "AudioSampleRate": 48000, + "AudioBitsPerSample": 32, + "TrackNumber": 7, + "TrackName": "Français", + "TrackLanguage": "fre", + "TrackDefault": "No", + "CodecID": "S_TEXT/UTF8", + "TrackType": "Subtitle", + "TagLanguage": "eng", + "TagName": "DURATION", + "TagString": "00:01:06.031000000", + "ImageSize": "1918x1080", + "Megapixels": 2.1 + }, + "mediaInfo": { + "@ref": "", + "track": [ + { + "@type": "General", + "UniqueID": "191657682055212276795239999260924509108", + "VideoCount": "1", + "AudioCount": "5", + "TextCount": "1", + "Format": "Matroska", + "Format_Version": "4", + "FileSize": "68084120", + "Duration": "66.031", + "OverallBitRate_Mode": "VBR", + "OverallBitRate": "8248746", + "FrameRate": "25.000", + "FrameCount": "1599", + "StreamSize": "12645964", + "IsStreamable": "Yes", + "Encoded_Application": "Lavf58.24.101", + "Encoded_Library": "Lavf58.24.101", + "extra": { + "ErrorDetectionType": "Per level 1" + } + }, + { + "@type": "Video", + "StreamOrder": "0", + "ID": "1", + "UniqueID": "1", + "Format": "AVC", + "Format_Profile": "High", + "Format_Level": "4.1", + "Format_Settings_CABAC": "Yes", + "Format_Settings_RefFrames": "4", + "CodecID": "V_MPEG4/ISO/AVC", + "Duration": "63.986000000", + "BitRate": "6453995", + "Width": "1918", + "Height": "1080", + "Stored_Width": "1920", + "Stored_Height": "1088", + "Sampled_Width": "1918", + "Sampled_Height": "1080", + "PixelAspectRatio": "1.000", + "DisplayAspectRatio": "1.776", + "FrameRate_Mode": "VFR", + "FrameRate": "25.000", + "FrameCount": "1599", + "ColorSpace": "YUV", + "ChromaSubsampling": "4:2:0", + "BitDepth": "8", + "ScanType": "Progressive", + "Delay": "0.000", + "StreamSize": "51599695", + "Title": "title video", + "Language": "fr", + "Default": "Yes", + "Forced": "No", + "colour_description_present": "Yes", + "colour_description_present_Source": "Container / Stream", + "colour_range": "Limited", + "colour_range_Source": "Container / Stream", + "colour_primaries_Source": "Stream", + "transfer_characteristics_Source": "Stream", + "matrix_coefficients": "BT.709", + "matrix_coefficients_Source": "Container / Stream" + }, + { + "@type": "Audio", + "@typeorder": "1", + "StreamOrder": "1", + "ID": "2", + "UniqueID": "2", + "Format": "FLAC", + "CodecID": "A_FLAC", + "Duration": "64.005000000", + "BitRate_Mode": "VBR", + "BitRate": "96000", + "Channels": "2", + "ChannelPositions": "Front: L R", + "ChannelLayout": "L R", + "SamplesPerFrame": "1537", + "SamplingRate": "48000", + "SamplingCount": "3072240", + "FrameRate": "31.232", + "FrameCount": "1999", + "BitDepth": "24", + "Compression_Mode": "Lossless", + "Delay": "0.005", + "Delay_Source": "Container", + "StreamSize": "767616", + "StreamSize_Proportion": "0.01127", + "Title": "Anglais E-AC3 2.0", + "Encoded_Library": "Lavc58.42.102 flac", + "Language": "en", + "Default": "No", + "Forced": "No" + }, + { + "@type": "Audio", + "@typeorder": "2", + "StreamOrder": "2", + "ID": "3", + "UniqueID": "3", + "Format": "AC-3", + "Format_Commercial_IfAny": "Dolby Digital", + "Format_Settings_Endianness": "Big", + "CodecID": "A_AC3", + "Duration": "64.000000000", + "BitRate_Mode": "CBR", + "BitRate": "192000", + "Channels": "2", + "ChannelPositions": "Front: L R", + "ChannelLayout": "L R", + "SamplesPerFrame": "1536", + "SamplingRate": "48000", + "SamplingCount": "3072000", + "FrameRate": "31.250", + "FrameCount": "1999", + "BitDepth": "32", + "Compression_Mode": "Lossy", + "Delay": "0.000", + "Delay_Source": "Container", + "StreamSize": "767616", + "StreamSize_Proportion": "0.01127", + "Title": "Anglais E-AC3 2.0", + "Encoded_Library": "Lavc58.42.102 ac3", + "Language": "en", + "ServiceKind": "CM", + "Default": "No", + "Forced": "No", + "extra": { + "bsid": "8", + "dialnorm": "-31", + "dsurmod": "0", + "acmod": "2", + "lfeon": "0", + "dialnorm_Average": "-31", + "dialnorm_Minimum": "-31" + } + }, + { + "@type": "Audio", + "@typeorder": "3", + "StreamOrder": "3", + "ID": "4", + "UniqueID": "4", + "Format": "E-AC-3", + "Format_Commercial_IfAny": "Dolby Digital Plus", + "Format_Settings_Endianness": "Big", + "CodecID": "A_EAC3", + "Duration": "64.000000000", + "BitRate_Mode": "CBR", + "BitRate": "192000", + "Channels": "2", + "ChannelPositions": "Front: L R", + "ChannelLayout": "L R", + "SamplesPerFrame": "1536", + "SamplingRate": "48000", + "SamplingCount": "3072000", + "FrameRate": "31.250", + "FrameCount": "1999", + "BitDepth": "32", + "Compression_Mode": "Lossy", + "Delay": "0.000", + "Delay_Source": "Container", + "StreamSize": "767616", + "StreamSize_Proportion": "0.01127", + "Title": "Anglais E-AC3 2.0", + "Encoded_Library": "Lavc58.42.102 eac3", + "Language": "en", + "ServiceKind": "CM", + "Default": "No", + "Forced": "No", + "extra": { + "bsid": "16", + "dialnorm": "-31", + "dsurmod": "0", + "acmod": "2", + "lfeon": "0", + "dialnorm_Average": "-31", + "dialnorm_Minimum": "-31" + } + }, + { + "@type": "Audio", + "@typeorder": "4", + "StreamOrder": "4", + "ID": "5", + "UniqueID": "5", + "Format": "AAC", + "Format_Settings_SBR": "No (Explicit)", + "Format_AdditionalFeatures": "LC", + "CodecID": "A_AAC-2", + "Duration": "64.004000000", + "BitRate": "96000", + "Channels": "2", + "ChannelPositions": "Front: L R", + "ChannelLayout": "L R", + "SamplesPerFrame": "1024", + "SamplingRate": "48000", + "SamplingCount": "3072192", + "FrameRate": "46.875", + "FrameCount": "1999", + "Compression_Mode": "Lossy", + "Delay": "0.005", + "Delay_Source": "Container", + "StreamSize": "767616", + "StreamSize_Proportion": "0.01127", + "Title": "Français E-AC3 2.0", + "Encoded_Library": "Lavc58.42.102 aac", + "Language": "fr", + "Default": "Yes", + "Forced": "No" + }, + { + "@type": "Audio", + "@typeorder": "5", + "StreamOrder": "5", + "ID": "6", + "UniqueID": "6", + "Format": "AAC", + "Format_Settings_SBR": "No (Explicit)", + "Format_AdditionalFeatures": "LC", + "CodecID": "A_AAC-2", + "Duration": "64.004000000", + "BitRate": "96000", + "Channels": "2", + "ChannelPositions": "Front: L R", + "ChannelLayout": "L R", + "SamplesPerFrame": "1024", + "SamplingRate": "48000", + "SamplingCount": "3072192", + "FrameRate": "46.875", + "FrameCount": "1999", + "Compression_Mode": "Lossy", + "Delay": "0.005", + "Delay_Source": "Container", + "StreamSize": "767616", + "StreamSize_Proportion": "0.01127", + "Title": "Anglais E-AC3 2.0", + "Encoded_Library": "Lavc58.42.102 aac", + "Language": "en", + "Default": "No", + "Forced": "No" + }, + { + "@type": "Text", + "StreamOrder": "6", + "ID": "7", + "UniqueID": "7", + "Format": "UTF-8", + "CodecID": "S_TEXT/UTF8", + "Duration": "66.031000000", + "BitRate": "46", + "FrameRate": "0.182", + "FrameCount": "12", + "ElementCount": "12", + "StreamSize": "381", + "Title": "Français", + "Language": "fr", + "Default": "No", + "Forced": "No" + } + ] + } +} \ No newline at end of file diff --git a/tests/sampleData/media/sampleH264_3.json b/tests/sampleData/media/sampleH264_3.json new file mode 100644 index 0000000..13ed394 --- /dev/null +++ b/tests/sampleData/media/sampleH264_3.json @@ -0,0 +1,821 @@ +{ + "_id": "C:/Transcode/Source Folder/h264.mkv", + "file": "C:/Transcode/Source Folder/h264.mkv", + "DB": "2MY5YD7P8", + "footprintId": "asxmr-5Iij", + "hasClosedCaptions": false, + "container": "mkv", + "scannerReads": { + "ffProbeRead": "success", + "exiftoolRead": "success", + "mediaInfoRead": "success", + "closedCaptionRead": "success" + }, + "ffProbeData": { + "streams": [ + { + "index": 0, + "codec_name": "h264", + "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10", + "profile": "High", + "codec_type": "video", + "codec_tag_string": "[0][0][0][0]", + "codec_tag": "0x0000", + "width": 1918, + "height": 1080, + "coded_width": 1918, + "coded_height": 1080, + "closed_captions": 0, + "has_b_frames": 2, + "sample_aspect_ratio": "1:1", + "display_aspect_ratio": "959:540", + "pix_fmt": "yuv420p", + "level": 41, + "color_range": "tv", + "color_space": "bt709", + "chroma_location": "left", + "field_order": "progressive", + "refs": 1, + "is_avc": "true", + "nal_length_size": "4", + "r_frame_rate": "25/1", + "avg_frame_rate": "25/1", + "time_base": "1/1000", + "start_pts": 0, + "start_time": "0.000000", + "bits_per_raw_sample": "8", + "disposition": { + "default": 1, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "language": "fre", + "title": "title video", + "BPS-eng": "6453995", + "DURATION-eng": "00:01:03.960000000", + "NUMBER_OF_FRAMES-eng": "1599", + "NUMBER_OF_BYTES-eng": "51599695", + "_STATISTICS_WRITING_APP-eng": "mkvmerge v23.0.0 ('title') 64-bit", + "_STATISTICS_WRITING_DATE_UTC-eng": "2018-06-14 17:49:29", + "_STATISTICS_TAGS-eng": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES", + "DURATION": "00:01:03.986000000" + } + }, + { + "index": 1, + "codec_name": "flac", + "codec_long_name": "FLAC (Free Lossless Audio Codec)", + "codec_type": "audio", + "codec_tag_string": "[0][0][0][0]", + "codec_tag": "0x0000", + "sample_fmt": "s32", + "sample_rate": "48000", + "channels": 2, + "channel_layout": "stereo", + "bits_per_sample": 0, + "r_frame_rate": "0/0", + "avg_frame_rate": "0/0", + "time_base": "1/1000", + "start_pts": 5, + "start_time": "0.005000", + "bits_per_raw_sample": "24", + "disposition": { + "default": 0, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "language": "eng", + "title": "Anglais E-AC3 2.0", + "BPS-eng": "96000", + "DURATION-eng": "00:01:03.968000000", + "NUMBER_OF_FRAMES-eng": "1999", + "NUMBER_OF_BYTES-eng": "767616", + "_STATISTICS_WRITING_APP-eng": "mkvmerge v23.0.0 ('title') 64-bit", + "_STATISTICS_WRITING_DATE_UTC-eng": "2018-06-14 17:49:29", + "_STATISTICS_TAGS-eng": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES", + "ENCODER": "Lavc58.42.102 flac", + "DURATION": "00:01:04.005000000" + } + }, + { + "index": 2, + "codec_name": "ac3", + "codec_long_name": "ATSC A/52A (AC-3)", + "codec_type": "audio", + "codec_tag_string": "[0][0][0][0]", + "codec_tag": "0x0000", + "sample_fmt": "fltp", + "sample_rate": "48000", + "channels": 2, + "channel_layout": "stereo", + "bits_per_sample": 0, + "r_frame_rate": "0/0", + "avg_frame_rate": "0/0", + "time_base": "1/1000", + "start_pts": 0, + "start_time": "0.000000", + "bit_rate": "192000", + "disposition": { + "default": 0, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "language": "eng", + "title": "Anglais E-AC3 2.0", + "BPS-eng": "96000", + "DURATION-eng": "00:01:03.968000000", + "NUMBER_OF_FRAMES-eng": "1999", + "NUMBER_OF_BYTES-eng": "767616", + "_STATISTICS_WRITING_APP-eng": "mkvmerge v23.0.0 ('title') 64-bit", + "_STATISTICS_WRITING_DATE_UTC-eng": "2018-06-14 17:49:29", + "_STATISTICS_TAGS-eng": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES", + "ENCODER": "Lavc58.42.102 ac3", + "DURATION": "00:01:04.000000000" + } + }, + { + "index": 3, + "codec_name": "eac3", + "codec_long_name": "ATSC A/52B (AC-3, E-AC-3)", + "codec_type": "audio", + "codec_tag_string": "[0][0][0][0]", + "codec_tag": "0x0000", + "sample_fmt": "fltp", + "sample_rate": "48000", + "channels": 2, + "channel_layout": "stereo", + "bits_per_sample": 0, + "r_frame_rate": "0/0", + "avg_frame_rate": "0/0", + "time_base": "1/1000", + "start_pts": 0, + "start_time": "0.000000", + "bit_rate": "192000", + "disposition": { + "default": 0, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "language": "eng", + "title": "Anglais E-AC3 2.0", + "BPS-eng": "96000", + "DURATION-eng": "00:01:03.968000000", + "NUMBER_OF_FRAMES-eng": "1999", + "NUMBER_OF_BYTES-eng": "767616", + "_STATISTICS_WRITING_APP-eng": "mkvmerge v23.0.0 ('title') 64-bit", + "_STATISTICS_WRITING_DATE_UTC-eng": "2018-06-14 17:49:29", + "_STATISTICS_TAGS-eng": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES", + "ENCODER": "Lavc58.42.102 eac3", + "DURATION": "00:01:04.000000000" + } + }, + { + "index": 4, + "codec_name": "aac", + "codec_long_name": "AAC (Advanced Audio Coding)", + "profile": "LC", + "codec_type": "audio", + "codec_tag_string": "[0][0][0][0]", + "codec_tag": "0x0000", + "sample_fmt": "fltp", + "sample_rate": "48000", + "channels": 2, + "channel_layout": "stereo", + "bits_per_sample": 0, + "r_frame_rate": "0/0", + "avg_frame_rate": "0/0", + "time_base": "1/1000", + "start_pts": 5, + "start_time": "0.005000", + "disposition": { + "default": 1, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "language": "fre", + "title": "Français E-AC3 2.0", + "BPS-eng": "96000", + "DURATION-eng": "00:01:03.968000000", + "NUMBER_OF_FRAMES-eng": "1999", + "NUMBER_OF_BYTES-eng": "767616", + "_STATISTICS_WRITING_APP-eng": "mkvmerge v23.0.0 ('title') 64-bit", + "_STATISTICS_WRITING_DATE_UTC-eng": "2018-06-14 17:49:29", + "_STATISTICS_TAGS-eng": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES", + "ENCODER": "Lavc58.42.102 aac", + "DURATION": "00:01:04.004000000" + } + }, + { + "index": 5, + "codec_name": "aac", + "codec_long_name": "AAC (Advanced Audio Coding)", + "profile": "LC", + "codec_type": "audio", + "codec_tag_string": "[0][0][0][0]", + "codec_tag": "0x0000", + "sample_fmt": "fltp", + "sample_rate": "48000", + "channels": 2, + "channel_layout": "stereo", + "bits_per_sample": 0, + "r_frame_rate": "0/0", + "avg_frame_rate": "0/0", + "time_base": "1/1000", + "start_pts": 5, + "start_time": "0.005000", + "disposition": { + "default": 0, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "language": "eng", + "title": "Anglais E-AC3 2.0", + "BPS-eng": "96000", + "DURATION-eng": "00:01:03.968000000", + "NUMBER_OF_FRAMES-eng": "1999", + "NUMBER_OF_BYTES-eng": "767616", + "_STATISTICS_WRITING_APP-eng": "mkvmerge v23.0.0 ('title') 64-bit", + "_STATISTICS_WRITING_DATE_UTC-eng": "2018-06-14 17:49:29", + "_STATISTICS_TAGS-eng": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES", + "ENCODER": "Lavc58.42.102 aac", + "DURATION": "00:01:04.004000000" + } + }, + { + "index": 6, + "codec_name": "subrip", + "codec_long_name": "SubRip subtitle", + "codec_type": "subtitle", + "codec_tag_string": "[0][0][0][0]", + "codec_tag": "0x0000", + "r_frame_rate": "0/0", + "avg_frame_rate": "0/0", + "time_base": "1/1000", + "start_pts": 0, + "start_time": "0.000000", + "duration_ts": 66031, + "duration": "66.031000", + "disposition": { + "default": 0, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "language": "en", + "title": "Français", + "BPS-eng": "46", + "DURATION-eng": "00:01:05.840000000", + "NUMBER_OF_FRAMES-eng": "12", + "NUMBER_OF_BYTES-eng": "381", + "_STATISTICS_WRITING_APP-eng": "mkvmerge v23.0.0 ('title') 64-bit", + "_STATISTICS_WRITING_DATE_UTC-eng": "2018-06-14 17:49:29", + "_STATISTICS_TAGS-eng": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES", + "DURATION": "00:01:06.031000000" + } + }, + { + "index": 7, + "codec_name": "subrip", + "codec_long_name": "SubRip subtitle", + "codec_type": "subtitle", + "codec_tag_string": "[0][0][0][0]", + "codec_tag": "0x0000", + "r_frame_rate": "0/0", + "avg_frame_rate": "0/0", + "time_base": "1/1000", + "start_pts": 0, + "start_time": "0.000000", + "duration_ts": 66031, + "duration": "66.031000", + "disposition": { + "default": 0, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "language": "fre", + "title": "Français", + "BPS-eng": "46", + "DURATION-eng": "00:01:05.840000000", + "NUMBER_OF_FRAMES-eng": "12", + "NUMBER_OF_BYTES-eng": "381", + "_STATISTICS_WRITING_APP-eng": "mkvmerge v23.0.0 ('title') 64-bit", + "_STATISTICS_WRITING_DATE_UTC-eng": "2018-06-14 17:49:29", + "_STATISTICS_TAGS-eng": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES", + "DURATION": "00:01:06.031000000" + } + } + ], + "format": { + "filename": "C:/Transcode/Source Folder/h264.mkv", + "nb_streams": 7, + "nb_programs": 0, + "format_name": "matroska,webm", + "format_long_name": "Matroska / WebM", + "start_time": "0.000000", + "duration": "66.031000", + "size": "68084120", + "bit_rate": "8248746", + "probe_score": 100, + "tags": { + "ENCODER": "Lavf58.24.101" + } + } + }, + "file_size": 64.9300765991211, + "video_resolution": "1080p", + "fileMedium": "video", + "video_codec_name": "h264", + "audio_codec_name": "", + "lastPluginDetails": "none", + "createdAt": 1653139154025, + "bit_rate": 8248746, + "duration": 66, + "statSync": { + "dev": 3832468976, + "mode": 33206, + "nlink": 1, + "uid": 0, + "gid": 0, + "rdev": 0, + "blksize": 4096, + "ino": 64176294690080990, + "size": 68084120, + "blocks": 132984, + "atimeMs": 1653139154001.7666, + "mtimeMs": 1594420078270.8928, + "ctimeMs": 1653139134390.225, + "birthtimeMs": 1653139123219.1018, + "atime": "2022-05-21T13:19:14.002Z", + "mtime": "2020-07-10T22:27:58.271Z", + "ctime": "2022-05-21T13:18:54.390Z", + "birthtime": "2022-05-21T13:18:43.219Z" + }, + "HealthCheck": "", + "TranscodeDecisionMaker": "", + "lastHealthCheckDate": 0, + "holdUntil": 0, + "lastTranscodeDate": 0, + "bumped": false, + "history": "", + "oldSize": 0, + "newSize": 0, + "videoStreamIndex": 0, + "meta": { + "SourceFile": "C:/Transcode/Source Folder/h264.mkv", + "errors": [], + "Duration": 66.031, + "ExifToolVersion": 12.4, + "FileName": "h264.mkv", + "Directory": "C:/Transcode/Source Folder", + "FileSize": "65 MiB", + "FileModifyDate": { + "year": 2020, + "month": 7, + "day": 10, + "hour": 23, + "minute": 27, + "second": 58, + "millisecond": 0, + "tzoffsetMinutes": 60, + "rawValue": "2020:07:10 23:27:58+01:00" + }, + "FileAccessDate": { + "year": 2022, + "month": 5, + "day": 21, + "hour": 14, + "minute": 19, + "second": 11, + "millisecond": 0, + "tzoffsetMinutes": 60, + "rawValue": "2022:05:21 14:19:11+01:00" + }, + "FileCreateDate": { + "year": 2022, + "month": 5, + "day": 21, + "hour": 14, + "minute": 18, + "second": 43, + "millisecond": 0, + "tzoffsetMinutes": 60, + "rawValue": "2022:05:21 14:18:43+01:00" + }, + "FilePermissions": "-rw-rw-rw-", + "FileType": "MKV", + "FileTypeExtension": "mkv", + "MIMEType": "video/x-matroska", + "EBMLVersion": 1, + "EBMLReadVersion": 1, + "DocType": "matroska", + "DocTypeVersion": 4, + "DocTypeReadVersion": 2, + "TimecodeScale": "1 ms", + "MuxingApp": "Lavf58.24.101", + "WritingApp": "Lavf58.24.101", + "VideoFrameRate": 25, + "ImageWidth": 1918, + "ImageHeight": 1080, + "VideoScanType": "Unknown (2)", + "AudioChannels": 2, + "AudioSampleRate": 48000, + "AudioBitsPerSample": 32, + "TrackNumber": 7, + "TrackName": "Français", + "TrackLanguage": "fre", + "TrackDefault": "No", + "CodecID": "S_TEXT/UTF8", + "TrackType": "Subtitle", + "TagLanguage": "eng", + "TagName": "DURATION", + "TagString": "00:01:06.031000000", + "ImageSize": "1918x1080", + "Megapixels": 2.1 + }, + "mediaInfo": { + "@ref": "", + "track": [ + { + "@type": "General", + "UniqueID": "191657682055212276795239999260924509108", + "VideoCount": "1", + "AudioCount": "5", + "TextCount": "1", + "Format": "Matroska", + "Format_Version": "4", + "FileSize": "68084120", + "Duration": "66.031", + "OverallBitRate_Mode": "VBR", + "OverallBitRate": "8248746", + "FrameRate": "25.000", + "FrameCount": "1599", + "StreamSize": "12645964", + "IsStreamable": "Yes", + "Encoded_Application": "Lavf58.24.101", + "Encoded_Library": "Lavf58.24.101", + "extra": { + "ErrorDetectionType": "Per level 1" + } + }, + { + "@type": "Video", + "StreamOrder": "0", + "ID": "1", + "UniqueID": "1", + "Format": "AVC", + "Format_Profile": "High", + "Format_Level": "4.1", + "Format_Settings_CABAC": "Yes", + "Format_Settings_RefFrames": "4", + "CodecID": "V_MPEG4/ISO/AVC", + "Duration": "63.986000000", + "BitRate": "6453995", + "Width": "1918", + "Height": "1080", + "Stored_Width": "1920", + "Stored_Height": "1088", + "Sampled_Width": "1918", + "Sampled_Height": "1080", + "PixelAspectRatio": "1.000", + "DisplayAspectRatio": "1.776", + "FrameRate_Mode": "VFR", + "FrameRate": "25.000", + "FrameCount": "1599", + "ColorSpace": "YUV", + "ChromaSubsampling": "4:2:0", + "BitDepth": "8", + "ScanType": "Progressive", + "Delay": "0.000", + "StreamSize": "51599695", + "Title": "title video", + "Language": "fr", + "Default": "Yes", + "Forced": "No", + "colour_description_present": "Yes", + "colour_description_present_Source": "Container / Stream", + "colour_range": "Limited", + "colour_range_Source": "Container / Stream", + "colour_primaries_Source": "Stream", + "transfer_characteristics_Source": "Stream", + "matrix_coefficients": "BT.709", + "matrix_coefficients_Source": "Container / Stream" + }, + { + "@type": "Audio", + "@typeorder": "1", + "StreamOrder": "1", + "ID": "2", + "UniqueID": "2", + "Format": "FLAC", + "CodecID": "A_FLAC", + "Duration": "64.005000000", + "BitRate_Mode": "VBR", + "BitRate": "96000", + "Channels": "2", + "ChannelPositions": "Front: L R", + "ChannelLayout": "L R", + "SamplesPerFrame": "1537", + "SamplingRate": "48000", + "SamplingCount": "3072240", + "FrameRate": "31.232", + "FrameCount": "1999", + "BitDepth": "24", + "Compression_Mode": "Lossless", + "Delay": "0.005", + "Delay_Source": "Container", + "StreamSize": "767616", + "StreamSize_Proportion": "0.01127", + "Title": "Anglais E-AC3 2.0", + "Encoded_Library": "Lavc58.42.102 flac", + "Language": "en", + "Default": "No", + "Forced": "No" + }, + { + "@type": "Audio", + "@typeorder": "2", + "StreamOrder": "2", + "ID": "3", + "UniqueID": "3", + "Format": "AC-3", + "Format_Commercial_IfAny": "Dolby Digital", + "Format_Settings_Endianness": "Big", + "CodecID": "A_AC3", + "Duration": "64.000000000", + "BitRate_Mode": "CBR", + "BitRate": "192000", + "Channels": "2", + "ChannelPositions": "Front: L R", + "ChannelLayout": "L R", + "SamplesPerFrame": "1536", + "SamplingRate": "48000", + "SamplingCount": "3072000", + "FrameRate": "31.250", + "FrameCount": "1999", + "BitDepth": "32", + "Compression_Mode": "Lossy", + "Delay": "0.000", + "Delay_Source": "Container", + "StreamSize": "767616", + "StreamSize_Proportion": "0.01127", + "Title": "Anglais E-AC3 2.0", + "Encoded_Library": "Lavc58.42.102 ac3", + "Language": "en", + "ServiceKind": "CM", + "Default": "No", + "Forced": "No", + "extra": { + "bsid": "8", + "dialnorm": "-31", + "dsurmod": "0", + "acmod": "2", + "lfeon": "0", + "dialnorm_Average": "-31", + "dialnorm_Minimum": "-31" + } + }, + { + "@type": "Audio", + "@typeorder": "3", + "StreamOrder": "3", + "ID": "4", + "UniqueID": "4", + "Format": "E-AC-3", + "Format_Commercial_IfAny": "Dolby Digital Plus", + "Format_Settings_Endianness": "Big", + "CodecID": "A_EAC3", + "Duration": "64.000000000", + "BitRate_Mode": "CBR", + "BitRate": "192000", + "Channels": "2", + "ChannelPositions": "Front: L R", + "ChannelLayout": "L R", + "SamplesPerFrame": "1536", + "SamplingRate": "48000", + "SamplingCount": "3072000", + "FrameRate": "31.250", + "FrameCount": "1999", + "BitDepth": "32", + "Compression_Mode": "Lossy", + "Delay": "0.000", + "Delay_Source": "Container", + "StreamSize": "767616", + "StreamSize_Proportion": "0.01127", + "Title": "Anglais E-AC3 2.0", + "Encoded_Library": "Lavc58.42.102 eac3", + "Language": "en", + "ServiceKind": "CM", + "Default": "No", + "Forced": "No", + "extra": { + "bsid": "16", + "dialnorm": "-31", + "dsurmod": "0", + "acmod": "2", + "lfeon": "0", + "dialnorm_Average": "-31", + "dialnorm_Minimum": "-31" + } + }, + { + "@type": "Audio", + "@typeorder": "4", + "StreamOrder": "4", + "ID": "5", + "UniqueID": "5", + "Format": "AAC", + "Format_Settings_SBR": "No (Explicit)", + "Format_AdditionalFeatures": "LC", + "CodecID": "A_AAC-2", + "Duration": "64.004000000", + "BitRate": "96000", + "Channels": "2", + "ChannelPositions": "Front: L R", + "ChannelLayout": "L R", + "SamplesPerFrame": "1024", + "SamplingRate": "48000", + "SamplingCount": "3072192", + "FrameRate": "46.875", + "FrameCount": "1999", + "Compression_Mode": "Lossy", + "Delay": "0.005", + "Delay_Source": "Container", + "StreamSize": "767616", + "StreamSize_Proportion": "0.01127", + "Title": "Français E-AC3 2.0", + "Encoded_Library": "Lavc58.42.102 aac", + "Language": "fr", + "Default": "Yes", + "Forced": "No" + }, + { + "@type": "Audio", + "@typeorder": "5", + "StreamOrder": "5", + "ID": "6", + "UniqueID": "6", + "Format": "AAC", + "Format_Settings_SBR": "No (Explicit)", + "Format_AdditionalFeatures": "LC", + "CodecID": "A_AAC-2", + "Duration": "64.004000000", + "BitRate": "96000", + "Channels": "2", + "ChannelPositions": "Front: L R", + "ChannelLayout": "L R", + "SamplesPerFrame": "1024", + "SamplingRate": "48000", + "SamplingCount": "3072192", + "FrameRate": "46.875", + "FrameCount": "1999", + "Compression_Mode": "Lossy", + "Delay": "0.005", + "Delay_Source": "Container", + "StreamSize": "767616", + "StreamSize_Proportion": "0.01127", + "Title": "Anglais E-AC3 2.0", + "Encoded_Library": "Lavc58.42.102 aac", + "Language": "en", + "Default": "No", + "Forced": "No" + }, + { + "@type": "Text", + "StreamOrder": "6", + "ID": "7", + "UniqueID": "7", + "Format": "UTF-8", + "CodecID": "S_TEXT/UTF8", + "Duration": "66.031000000", + "BitRate": "46", + "FrameRate": "0.182", + "FrameCount": "12", + "ElementCount": "12", + "StreamSize": "381", + "Title": "Français", + "Language": "fr", + "Default": "No", + "Forced": "No" + } + ] + } +} \ No newline at end of file diff --git a/tests/sampleData/media/sampleH265_1.json b/tests/sampleData/media/sampleH265_1.json new file mode 100644 index 0000000..81d53e6 --- /dev/null +++ b/tests/sampleData/media/sampleH265_1.json @@ -0,0 +1,334 @@ +{ + "_id": "C:/Transcode/Source Folder/qsv_h265.mkv", + "file": "C:/Transcode/Source Folder/qsv_h265.mkv", + "DB": "2MY5YD7P8", + "footprintId": "xkZP3IPR6g", + "hasClosedCaptions": false, + "container": "mkv", + "scannerReads": { + "ffProbeRead": "success", + "exiftoolRead": "success", + "mediaInfoRead": "success", + "closedCaptionRead": "\"Unable to run CCExtractor\"" + }, + "ffProbeData": { + "streams": [ + { + "index": 0, + "codec_name": "hevc", + "codec_long_name": "H.265 / HEVC (High Efficiency Video Coding)", + "profile": "Main", + "codec_type": "video", + "codec_tag_string": "[0][0][0][0]", + "codec_tag": "0x0000", + "width": 1920, + "height": 1080, + "coded_width": 1920, + "coded_height": 1088, + "closed_captions": 0, + "has_b_frames": 1, + "sample_aspect_ratio": "1:1", + "display_aspect_ratio": "16:9", + "pix_fmt": "yuv420p", + "level": 150, + "color_range": "tv", + "color_space": "bt709", + "color_transfer": "bt709", + "color_primaries": "bt709", + "chroma_location": "left", + "refs": 1, + "r_frame_rate": "25/1", + "avg_frame_rate": "25/1", + "time_base": "1/1000", + "start_pts": 21, + "start_time": "0.021000", + "disposition": { + "default": 1, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "DURATION": "00:00:21.341000000" + } + }, + { + "index": 1, + "codec_name": "aac", + "codec_long_name": "AAC (Advanced Audio Coding)", + "profile": "LC", + "codec_type": "audio", + "codec_tag_string": "[0][0][0][0]", + "codec_tag": "0x0000", + "sample_fmt": "fltp", + "sample_rate": "48000", + "channels": 2, + "channel_layout": "stereo", + "bits_per_sample": 0, + "r_frame_rate": "0/0", + "avg_frame_rate": "0/0", + "time_base": "1/1000", + "start_pts": 0, + "start_time": "0.000000", + "disposition": { + "default": 1, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "title": "Stereo", + "DURATION": "00:00:21.375000000" + } + } + ], + "format": { + "filename": "C:/Transcode/Source Folder/qsv_h265.mkv", + "nb_streams": 2, + "nb_programs": 0, + "format_name": "matroska,webm", + "format_long_name": "Matroska / WebM", + "start_time": "0.000000", + "duration": "21.375000", + "size": "8569883", + "bit_rate": "3207441", + "probe_score": 100, + "tags": { + "creation_time": "2019-09-13T16:46:14.000000Z", + "ENCODER": "Lavf58.20.100" + } + } + }, + "file_size": 8.172877311706543, + "video_resolution": "1080p", + "fileMedium": "video", + "video_codec_name": "hevc", + "audio_codec_name": "", + "lastPluginDetails": "none", + "createdAt": 1653029410394, + "bit_rate": 3207441, + "duration": 21, + "statSync": { + "dev": 3832468976, + "mode": 33060, + "nlink": 1, + "uid": 0, + "gid": 0, + "rdev": 0, + "blksize": 4096, + "ino": 1970324841360027, + "size": 8569883, + "blocks": 16744, + "atimeMs": 1653029410381.1382, + "mtimeMs": 1568393195000, + "ctimeMs": 1650864287188.087, + "birthtimeMs": 1650864302270.2063, + "atime": "2022-05-20T06:50:10.381Z", + "mtime": "2019-09-13T16:46:35.000Z", + "ctime": "2022-04-25T05:24:47.188Z", + "birthtime": "2022-04-25T05:25:02.270Z" + }, + "HealthCheck": "", + "TranscodeDecisionMaker": "", + "lastHealthCheckDate": 0, + "holdUntil": 0, + "lastTranscodeDate": 0, + "bumped": false, + "history": "", + "oldSize": 0, + "newSize": 0, + "videoStreamIndex": 0, + "lastUpdate": 1653027918258, + "meta": { + "SourceFile": "C:/Transcode/Source Folder/qsv_h265.mkv", + "errors": [], + "Duration": 21.375, + "ExifToolVersion": 12.4, + "FileName": "qsv_h265.mkv", + "Directory": "C:/Transcode/Source Folder", + "FileSize": "8.2 MiB", + "FileModifyDate": { + "year": 2019, + "month": 9, + "day": 13, + "hour": 17, + "minute": 46, + "second": 35, + "millisecond": 0, + "tzoffsetMinutes": 60, + "rawValue": "2019:09:13 17:46:35+01:00" + }, + "FileAccessDate": { + "year": 2022, + "month": 5, + "day": 20, + "hour": 7, + "minute": 50, + "second": 9, + "millisecond": 0, + "tzoffsetMinutes": 60, + "rawValue": "2022:05:20 07:50:09+01:00" + }, + "FileCreateDate": { + "year": 2022, + "month": 4, + "day": 25, + "hour": 6, + "minute": 25, + "second": 2, + "millisecond": 0, + "tzoffsetMinutes": 60, + "rawValue": "2022:04:25 06:25:02+01:00" + }, + "FilePermissions": "-r--r--r--", + "FileType": "MKV", + "FileTypeExtension": "mkv", + "MIMEType": "video/x-matroska", + "EBMLVersion": 1, + "EBMLReadVersion": 1, + "DocType": "matroska", + "DocTypeVersion": 4, + "DocTypeReadVersion": 2, + "TimecodeScale": "1 ms", + "MuxingApp": "Lavf58.20.100", + "WritingApp": "HandBrake 1.2.2 2019022300", + "DateTimeOriginal": { + "year": 2019, + "month": 9, + "day": 13, + "hour": 16, + "minute": 46, + "second": 14, + "millisecond": 0, + "tzoffsetMinutes": 0, + "rawValue": "2019:09:13 16:46:14Z" + }, + "VideoFrameRate": 25, + "ImageWidth": 1920, + "ImageHeight": 1080, + "TrackNumber": 2, + "TrackName": "Stereo", + "TrackLanguage": "und", + "CodecID": "A_AAC", + "TrackType": "Audio", + "AudioChannels": 2, + "AudioSampleRate": 48000, + "TagName": "DURATION", + "TagString": "00:00:21.375000000", + "ImageSize": "1920x1080", + "Megapixels": 2.1 + }, + "mediaInfo": { + "@ref": "", + "track": [ + { + "@type": "General", + "UniqueID": "112612991515236890937117095733641799622", + "VideoCount": "1", + "AudioCount": "1", + "Format": "Matroska", + "Format_Version": "4", + "FileSize": "8569883", + "Duration": "21.375", + "OverallBitRate": "3207442", + "FrameRate": "25.000", + "FrameCount": "533", + "IsStreamable": "Yes", + "Encoded_Date": "UTC 2019-09-13 16:46:14", + "Encoded_Application": "HandBrake 1.2.2 2019022300", + "Encoded_Library": "Lavf58.20.100", + "extra": { + "ErrorDetectionType": "Per level 1" + } + }, + { + "@type": "Video", + "StreamOrder": "0", + "ID": "1", + "UniqueID": "1", + "Format": "HEVC", + "Format_Profile": "Main", + "Format_Level": "5", + "Format_Tier": "Main", + "CodecID": "V_MPEGH/ISO/HEVC", + "Duration": "21.320000000", + "Width": "1920", + "Height": "1080", + "Stored_Height": "1088", + "Sampled_Width": "1920", + "Sampled_Height": "1080", + "PixelAspectRatio": "1.000", + "DisplayAspectRatio": "1.778", + "FrameRate_Mode": "CFR", + "FrameRate": "25.000", + "FrameCount": "533", + "ColorSpace": "YUV", + "ChromaSubsampling": "4:2:0", + "BitDepth": "8", + "Delay": "0.021", + "Default": "Yes", + "Forced": "No", + "colour_description_present": "Yes", + "colour_description_present_Source": "Stream", + "colour_range": "Limited", + "colour_range_Source": "Stream", + "colour_primaries": "BT.709", + "colour_primaries_Source": "Stream", + "transfer_characteristics": "BT.709", + "transfer_characteristics_Source": "Stream", + "matrix_coefficients": "BT.709", + "matrix_coefficients_Source": "Stream" + }, + { + "@type": "Audio", + "StreamOrder": "1", + "ID": "2", + "UniqueID": "2", + "Format": "AAC", + "Format_Settings_SBR": "No (Explicit)", + "Format_AdditionalFeatures": "LC", + "CodecID": "A_AAC-2", + "Duration": "21.375000000", + "Channels": "2", + "ChannelPositions": "Front: L R", + "ChannelLayout": "L R", + "SamplesPerFrame": "1024", + "SamplingRate": "48000", + "SamplingCount": "1026000", + "FrameRate": "46.875", + "Compression_Mode": "Lossy", + "Delay": "0.000", + "Delay_Source": "Container", + "Title": "Stereo", + "Default": "Yes", + "Forced": "No" + } + ] + } + } \ No newline at end of file diff --git a/tests/sampleData/media/sampleMP3_1.json b/tests/sampleData/media/sampleMP3_1.json new file mode 100644 index 0000000..6c7dd81 --- /dev/null +++ b/tests/sampleData/media/sampleMP3_1.json @@ -0,0 +1,314 @@ +{ + "_id": "C:/Transcode/Source Folder/sample__-__-__libmp3lame__30s__audio.mkv", + "file": "C:/Transcode/Source Folder/sample__-__-__libmp3lame__30s__audio.mkv", + "DB": "2MY5YD7P8", + "footprintId": "xpsr-dmmd", + "hasClosedCaptions": false, + "container": "mkv", + "scannerReads": { + "ffProbeRead": "success", + "exiftoolRead": "success", + "mediaInfoRead": "success", + "closedCaptionRead": "\"Unable to run CCExtractor\"" + }, + "ffProbeData": { + "streams": [ + { + "index": 0, + "codec_name": "mp3", + "codec_long_name": "MP3 (MPEG audio layer 3)", + "codec_type": "audio", + "codec_tag_string": "[0][0][0][0]", + "codec_tag": "0x0000", + "sample_fmt": "fltp", + "sample_rate": "48000", + "channels": 2, + "channel_layout": "stereo", + "bits_per_sample": 0, + "r_frame_rate": "0/0", + "avg_frame_rate": "0/0", + "time_base": "1/1000", + "start_pts": 0, + "start_time": "0.000000", + "bit_rate": "128000", + "disposition": { + "default": 1, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "HANDLER_NAME": "GPAC ISO Audio Handler", + "ENCODER": "Lavc57.107.100 libmp3lame", + "DURATION": "00:00:30.023000000" + } + }, + { + "index": 1, + "codec_name": "mp3", + "codec_long_name": "MP3 (MPEG audio layer 3)", + "codec_type": "audio", + "codec_tag_string": "[0][0][0][0]", + "codec_tag": "0x0000", + "sample_fmt": "fltp", + "sample_rate": "48000", + "channels": 2, + "channel_layout": "stereo", + "bits_per_sample": 0, + "r_frame_rate": "0/0", + "avg_frame_rate": "0/0", + "time_base": "1/1000", + "start_pts": 0, + "start_time": "0.000000", + "bit_rate": "128000", + "disposition": { + "default": 1, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "HANDLER_NAME": "GPAC ISO Audio Handler", + "ENCODER": "Lavc57.107.100 libmp3lame", + "DURATION": "00:00:30.023000000" + } + } + ], + "format": { + "filename": "C:/Transcode/Source Folder/sample__-__-__libmp3lame__30s__audio.mkv", + "nb_streams": 2, + "nb_programs": 0, + "format_name": "matroska,webm", + "format_long_name": "Matroska / WebM", + "start_time": "0.000000", + "duration": "30.023000", + "size": "979815", + "bit_rate": "261083", + "probe_score": 100, + "tags": { + "title": "Big Buck Bunny, Sunflower version", + "GENRE": "Animation", + "MAJOR_BRAND": "isom", + "MINOR_VERSION": "1", + "COMPATIBLE_BRANDS": "isomavc1", + "COMPOSER": "Sacha Goedegebure", + "ARTIST": "Blender Foundation 2008, Janus Bager Kristensen 2013", + "COMMENT": "Creative Commons Attribution 3.0 - http://bbb3d.renderfarming.net", + "ENCODER": "Lavf57.83.100" + } + } + }, + "file_size": 0.9344244003295898, + "video_resolution": "", + "fileMedium": "audio", + "video_codec_name": "", + "audio_codec_name": "mp3", + "lastPluginDetails": "none", + "createdAt": 1653224430511, + "bit_rate": 261083, + "duration": 30, + "statSync": { + "dev": 3832468976, + "mode": 33206, + "nlink": 1, + "uid": 0, + "gid": 0, + "rdev": 0, + "blksize": 4096, + "ino": 10133099162447292, + "size": 979815, + "blocks": 1920, + "atimeMs": 1653224430487.7, + "mtimeMs": 1653224386734.2915, + "ctimeMs": 1653224395573.211, + "birthtimeMs": 1653224386247.453, + "atime": "2022-05-22T13:00:30.488Z", + "mtime": "2022-05-22T12:59:46.734Z", + "ctime": "2022-05-22T12:59:55.573Z", + "birthtime": "2022-05-22T12:59:46.247Z" + }, + "HealthCheck": "", + "TranscodeDecisionMaker": "", + "lastHealthCheckDate": 0, + "holdUntil": 0, + "lastTranscodeDate": 0, + "bumped": false, + "history": "", + "oldSize": 0, + "newSize": 0, + "videoStreamIndex": -1, + "meta": { + "SourceFile": "C:/Transcode/Source Folder/sample__-__-__libmp3lame__30s__audio.mkv", + "errors": [], + "Duration": 30.023, + "ExifToolVersion": 12.4, + "FileName": "sample__-__-__libmp3lame__30s__audio.mkv", + "Directory": "C:/Transcode/Source Folder", + "FileSize": "957 KiB", + "ZoneIdentifier": "Exists", + "FileModifyDate": { + "year": 2022, + "month": 5, + "day": 22, + "hour": 13, + "minute": 59, + "second": 46, + "millisecond": 0, + "tzoffsetMinutes": 60, + "rawValue": "2022:05:22 13:59:46+01:00" + }, + "FileAccessDate": { + "year": 2022, + "month": 5, + "day": 22, + "hour": 14, + "minute": 0, + "second": 29, + "millisecond": 0, + "tzoffsetMinutes": 60, + "rawValue": "2022:05:22 14:00:29+01:00" + }, + "FileCreateDate": { + "year": 2022, + "month": 5, + "day": 22, + "hour": 13, + "minute": 59, + "second": 46, + "millisecond": 0, + "tzoffsetMinutes": 60, + "rawValue": "2022:05:22 13:59:46+01:00" + }, + "FilePermissions": "-rw-rw-rw-", + "FileType": "MKA", + "FileTypeExtension": "mka", + "MIMEType": "audio/x-matroska", + "EBMLVersion": 1, + "EBMLReadVersion": 1, + "DocType": "matroska", + "DocTypeVersion": 4, + "DocTypeReadVersion": 2, + "TimecodeScale": "1 ms", + "Title": "Big Buck Bunny, Sunflower version", + "MuxingApp": "Lavf57.83.100", + "WritingApp": "Lavf57.83.100", + "TrackNumber": 2, + "TrackLanguage": "und", + "CodecID": "A_MPEG/L3", + "TrackType": "Audio", + "AudioChannels": 2, + "AudioSampleRate": 48000, + "AudioBitsPerSample": 32, + "TagName": "DURATION", + "TagString": "00:00:30.023000000" + }, + "mediaInfo": { + "@ref": "", + "track": [ + { + "@type": "General", + "UniqueID": "301354878049300200919944107613778820882", + "AudioCount": "2", + "Format": "Matroska", + "Format_Version": "4", + "FileSize": "979815", + "Duration": "30.023", + "OverallBitRate_Mode": "CBR", + "OverallBitRate": "261084", + "StreamSize": "19079", + "IsStreamable": "Yes", + "Title": "Big Buck Bunny, Sunflower version", + "Track": "Big Buck Bunny, Sunflower version", + "Encoded_Application": "Lavf57.83.100", + "Encoded_Library": "Lavf57.83.100", + "Comment": "Creative Commons Attribution 3.0 - http://bbb3d.renderfarming.net", + "extra": { + "ErrorDetectionType": "Per level 1", + "ARTIST": "Blender Foundation 2008, Janus Bager Kristensen 2013", + "COMPOSER": "Sacha Goedegebure", + "GENRE": "Animation" + } + }, + { + "@type": "Audio", + "@typeorder": "1", + "StreamOrder": "0", + "ID": "1", + "UniqueID": "1", + "Format": "MPEG Audio", + "Format_Version": "1", + "Format_Profile": "Layer 3", + "Format_Settings_Mode": "Joint stereo", + "Format_Settings_ModeExtension": "MS Stereo", + "CodecID": "A_MPEG/L3", + "Duration": "30.023000000", + "BitRate_Mode": "CBR", + "BitRate": "128000", + "Channels": "2", + "SamplingRate": "48000", + "SamplingCount": "1441104", + "Compression_Mode": "Lossy", + "Delay": "0.000", + "Delay_Source": "Container", + "StreamSize": "480368", + "StreamSize_Proportion": "0.49026", + "Encoded_Library": "Lavc57.107.100 libmp3lame", + "Default": "Yes", + "Forced": "No" + }, + { + "@type": "Audio", + "@typeorder": "2", + "StreamOrder": "1", + "ID": "2", + "UniqueID": "2", + "Format": "MPEG Audio", + "Format_Version": "1", + "Format_Profile": "Layer 3", + "Format_Settings_Mode": "Joint stereo", + "Format_Settings_ModeExtension": "MS Stereo", + "CodecID": "A_MPEG/L3", + "Duration": "30.023000000", + "BitRate_Mode": "CBR", + "BitRate": "128000", + "Channels": "2", + "SamplingRate": "48000", + "SamplingCount": "1441104", + "Compression_Mode": "Lossy", + "Delay": "0.000", + "Delay_Source": "Container", + "StreamSize": "480368", + "StreamSize_Proportion": "0.49026", + "Encoded_Library": "Lavc57.107.100 libmp3lame", + "Default": "Yes", + "Forced": "No" + } + ] + } +} \ No newline at end of file