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/package-lock.json b/package-lock.json index 5a261a7..de6ded3 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", @@ -230,6 +236,21 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, + "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", @@ -281,6 +302,12 @@ } } }, + "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 +373,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", @@ -790,6 +826,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", @@ -1094,6 +1136,15 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "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", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -1296,6 +1347,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", @@ -1577,6 +1634,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..4ff2e19 100644 --- a/package.json +++ b/package.json @@ -5,13 +5,14 @@ "main": "Tdarr_Plugin_aaaa_Pre_Proc_Example.js", "dependencies": {}, "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_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/helpers/run.js b/tests/helpers/run.js new file mode 100644 index 0000000..3cb7f52 --- /dev/null +++ b/tests/helpers/run.js @@ -0,0 +1,30 @@ +const path = require('path'); +const chai = require('chai'); + +const scriptName = path.basename(process.mainModule.filename); +// eslint-disable-next-line import/no-dynamic-require +const { plugin } = require(`../../Community/${scriptName}`); + +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]; + // eslint-disable-next-line no-await-in-loop + const testOutput = await plugin( + test.input.file, + test.input.librarySettings, + test.input.inputs, + test.input.otherArguments, + ); + chai.assert.deepEqual(testOutput, test.output); + } + } catch (err) { + // eslint-disable-next-line no-console + console.log(err); + process.exit(1); + } +}; + +module.exports = run; diff --git a/tests/runTests.js b/tests/runTests.js new file mode 100644 index 0000000..476fc3c --- /dev/null +++ b/tests/runTests.js @@ -0,0 +1,31 @@ +/* eslint no-console: 0 */ // --> OFF + +const fs = require('fs'); +const childProcess = require('child_process'); + +const filenames = fs.readdirSync(`${__dirname}/Community`); + +const run = async () => { + for (let i = 0; i < filenames.length; i += 1) { + const path = `${__dirname}/Community/${filenames[i]}`; + // eslint-disable-next-line no-await-in-loop + await new Promise((resolve) => { + childProcess.exec(`node ${path}`, (err, stdout, stderr) => { + if (err) { + console.log(err); + } + console.log(stdout); + console.log(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/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/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