Compare commits

...

3 commits

Author SHA1 Message Date
AnimeDL
7c363b155d [CR] Only use second key
If first key is used, occasionally the episode will fail to decrypt?
2024-03-30 15:30:46 -07:00
AnimeDL
852558a245 Update mp4decryptjs 2024-03-30 15:30:04 -07:00
AnimeDL
368f1fd306 Implement a mp4decrypt native module 2024-03-29 15:49:11 -07:00
7 changed files with 311 additions and 109 deletions

View file

@ -1,4 +1,3 @@
ffmpeg: "ffmpeg.exe"
mkvmerge: "mkvmerge.exe"
ffprobe: "ffprobe.exe"
mp4decrypt: "mp4decrypt.exe"

View file

@ -10,7 +10,6 @@ import { console } from './modules/log';
import shlp from 'sei-helper';
import m3u8 from 'm3u8-parsed';
import streamdl, { M3U8Json } from './modules/hls-download';
import { exec } from './modules/sei-helper-fixes';
// custom modules
import * as fontsData from './modules/module.fontsData';
@ -19,6 +18,7 @@ import * as yamlCfg from './modules/module.cfg-loader';
import * as yargs from './modules/module.app-args';
import Merger, { Font, MergerInput, SubtitleInput } from './modules/module.merger';
import getKeys, { canDecrypt } from './modules/widevine';
import mp4decrypt from 'mp4decryptjs';
//import vttConvert from './modules/module.vttconvert';
// args
@ -1408,7 +1408,7 @@ export default class Crunchy implements ServiceClass {
if (
(s.match(/hls/) || s.match(/dash/))
&& !(s.match(/hls/) && s.match(/drm/))
&& !((!canDecrypt || !this.cfg.bin.mp4decrypt) && s.match(/drm/))
//&& !((!canDecrypt || !this.cfg.bin.mp4decrypt) && s.match(/drm/))
&& !s.match(/trailer/)
) {
const pb = Object.values(pbStreams[s]).map(v => {
@ -1681,7 +1681,7 @@ export default class Crunchy implements ServiceClass {
}
//Handle Decryption if needed
if ((chosenVideoSegments.pssh || chosenAudioSegments.pssh) && (videoDownloaded || audioDownloaded)) {
if ((chosenVideoSegments.pssh || chosenAudioSegments.pssh) && (videoDownloaded || audioDownloaded) && canDecrypt) {
const assetIdRegex = chosenVideoSegments.segments[0].uri.match(/\/assets\/(?:p\/)?([^_,]+)/);
const assetId = assetIdRegex ? assetIdRegex[1] : null;
const sessionId = new Date().getUTCMilliseconds().toString().padStart(3, '0') + process.hrtime.bigint().toString().slice(0, 13);
@ -1709,61 +1709,57 @@ export default class Crunchy implements ServiceClass {
console.error('Failed to get encryption keys');
return undefined;
}
/*const keys = {} as Record<string, string>;
encryptionKeys.forEach(function(key) {
const keys = {} as Record<string, string>;
/*encryptionKeys.forEach(function(key) {
keys[key.kid] = key.key;
});*/
//Only use second key, if first key is used too, occasionally it can fail?
keys[encryptionKeys[1].kid] = encryptionKeys[1].key;
if (this.cfg.bin.mp4decrypt) {
const commandBase = `--show-progress --key ${encryptionKeys[1].kid}:${encryptionKeys[1].key} `;
const commandVideo = commandBase+`"${tsFile}.video.enc.ts" "${tsFile}.video.ts"`;
const commandAudio = commandBase+`"${tsFile}.audio.enc.ts" "${tsFile}.audio.ts"`;
if (videoDownloaded) {
console.info('Started decrypting video');
const decryptVideo = exec('mp4decrypt', `"${this.cfg.bin.mp4decrypt}"`, commandVideo);
if (!decryptVideo.isOk) {
console.error(decryptVideo.err);
console.error(`Decryption failed with exit code ${decryptVideo.err.code}`);
return undefined;
} else {
console.info('Decryption done for video');
if (!options.nocleanup) {
fs.removeSync(`${tsFile}.video.enc.ts`);
}
files.push({
type: 'Video',
path: `${tsFile}.video.ts`,
lang: lang,
isPrimary: isPrimary
});
if (videoDownloaded) {
console.info('Started decrypting video');
const decryptVideo = await mp4decrypt(`${tsFile}.video.enc.ts`, `${tsFile}.video.ts`, keys);
if (!decryptVideo) {
console.error('Decryption of video failed');
return undefined;
} else {
console.info('Decryption done for video');
if (!options.nocleanup) {
fs.removeSync(`${tsFile}.video.enc.ts`);
}
files.push({
type: 'Video',
path: `${tsFile}.video.ts`,
lang: lang,
isPrimary: isPrimary
});
}
}
if (audioDownloaded) {
console.info('Started decrypting audio');
const decryptAudio = exec('mp4decrypt', `"${this.cfg.bin.mp4decrypt}"`, commandAudio);
if (!decryptAudio.isOk) {
console.error(decryptAudio.err);
console.error(`Decryption failed with exit code ${decryptAudio.err.code}`);
return undefined;
} else {
if (!options.nocleanup) {
fs.removeSync(`${tsFile}.audio.enc.ts`);
}
files.push({
type: 'Audio',
path: `${tsFile}.audio.ts`,
lang: lang,
isPrimary: isPrimary
});
console.info('Decryption done for audio');
if (audioDownloaded) {
console.info('Started decrypting audio');
const decryptAudio = await mp4decrypt(`${tsFile}.audio.enc.ts`, `${tsFile}.audio.ts`, keys);
if (!decryptAudio) {
console.error('Decryption of audio failed');
return undefined;
} else {
if (!options.nocleanup) {
fs.removeSync(`${tsFile}.audio.enc.ts`);
}
files.push({
type: 'Audio',
path: `${tsFile}.audio.ts`,
lang: lang,
isPrimary: isPrimary
});
console.info('Decryption done for audio');
}
} else {
console.warn('mp4decrypt not found, files need decryption. Decryption Keys:', encryptionKeys);
}
} else {
if (!canDecrypt) {
console.error('CDM Missing, unable to decrypt.');
return undefined;
}
files.push({
type: 'Video',
path: `${tsFile}.video.enc.ts`,

View file

@ -20,7 +20,6 @@ By default this application uses the following paths to programs (main executabl
* `ffmpeg.exe` (From PATH)
* `ffprobe.exe` (From PATH)
* `mkvmerge.exe` (From PATH)
* `mp4decrypt.exe` (From PATH)
To change these paths you need to edit `bin-path.yml` in `./config/` directory.
@ -63,10 +62,11 @@ Dependencies that are only required for running from code. These are not require
* NodeJS >= 14.6.0 (https://nodejs.org/)
* NPM >= 6.9.0 (https://www.npmjs.org/)
* PNPM >= 7.0.0 (https://pnpm.io/)
* CMake >= ??? (https://cmake.org/)
### Build Instructions
Please note that NodeJS, NPM, and PNPM must be installed on your system. For instructions on how to install pnpm, check (https://pnpm.io/installation)
Please note that NodeJS, NPM, PNPM, and CMake must be installed on your system. For instructions on how to install pnpm, check (https://pnpm.io/installation)
First clone this repo `git clone https://github.com/anidl/multi-downloader-nx.git`.
@ -79,10 +79,10 @@ If you want to package the application, run pnpm run build-`{platform}`-`{type}`
## DRM Decryption
### Decryption Requirements
* mp4decrypt >= Any (http://www.bento4.com/) - Only required for decrypting
### Instructions
In order to decrypt DRM content, you will need to have a dumped CDM, after that you will need to place the CDM files (`device_client_id_blob` and `device_private_key`) into the `./widevine/` directory. For legal reasons we do not include the CDM with the software, and you will have to source one yourself.
In order to decrypt DRM content, you will need to have a dumped CDM, after that you will need to place the CDM files (blob file and pem file) into the `./widevine/` directory. For legal reasons we do not include the CDM with the software, and you will have to source one yourself.
### Disclaimer
We do not support nor condone piracy

View file

@ -19,6 +19,9 @@ import * as yamlCfg from './modules/module.cfg-loader';
import * as yargs from './modules/module.app-args';
import Merger, { Font, MergerInput, SubtitleInput } from './modules/module.merger';
import vtt2ass from './modules/module.vtt2ass';
import getKeys, { canDecrypt } from './modules/widevine';
import { KeyContainer } from './modules/license';
import mp4decrypt from 'mp4decryptjs';
// load req
import { domain, api } from './modules/module.api-urls';
@ -40,9 +43,6 @@ import { Episode, NewHidiveEpisodeExtra, NewHidiveSeason, NewHidiveSeriesExtra }
import { NewHidiveEpisode } from './@types/newHidiveEpisode';
import { NewHidivePlayback, Subtitle } from './@types/newHidivePlayback';
import { MPDParsed, parse } from './modules/module.transform-mpd';
import getKeys, { canDecrypt } from './modules/widevine';
import { exec } from './modules/sei-helper-fixes';
import { KeyContainer } from './modules/license';
export default class Hidive implements ServiceClass {
public cfg: yamlCfg.ConfigObject;
@ -1130,6 +1130,7 @@ export default class Hidive implements ServiceClass {
const subsMargin = 0;
const chosenFontSize = options.originalFontSize ? undefined : options.fontSize;
let encryptionKeys: KeyContainer[] = [];
const keys: Record<string, string> = {};
if (!canDecrypt) console.warn('Decryption not enabled!');
if (!this.cfg.bin.ffmpeg)
@ -1237,11 +1238,14 @@ export default class Hidive implements ServiceClass {
console.info(`Selected (Available) Audio Languages: ${chosenAudios.map(a => a.language.name).join(', ')}`);
console.info('Stream URL:', chosenVideoSegments.segments[0].map.uri.split('/init.mp4')[0]);
if (chosenAudios[0].pssh || chosenVideoSegments.pssh) {
if ((chosenAudios[0].pssh || chosenVideoSegments.pssh) && canDecrypt) {
encryptionKeys = await getKeys(chosenVideoSegments.pssh, 'https://shield-drm.imggaming.com/api/v2/license', {
'Authorization': `Bearer ${selectedEpisode.jwtToken}`,
'X-Drm-Info': 'eyJzeXN0ZW0iOiJjb20ud2lkZXZpbmUuYWxwaGEifQ==',
});
encryptionKeys.forEach(function(key) {
keys[key.kid] = key.key;
});
}
if (!options.novids) {
@ -1288,30 +1292,22 @@ export default class Hidive implements ServiceClass {
console.error('Failed to get encryption keys');
return undefined;
}
if (this.cfg.bin.mp4decrypt) {
const commandBase = `--show-progress --key ${encryptionKeys[1].kid}:${encryptionKeys[1].key} `;
const commandVideo = commandBase+`"${tsFile}.video.enc.ts" "${tsFile}.video.ts"`;
console.info('Started decrypting video');
const decryptVideo = exec('mp4decrypt', `"${this.cfg.bin.mp4decrypt}"`, commandVideo);
if (!decryptVideo.isOk) {
console.error(decryptVideo.err);
console.error(`Decryption failed with exit code ${decryptVideo.err.code}`);
return undefined;
} else {
console.info('Decryption done for video');
if (!options.nocleanup) {
fs.removeSync(`${tsFile}.video.enc.ts`);
}
files.push({
type: 'Video',
path: `${tsFile}.video.ts`,
lang: chosenAudios[0].language,
isPrimary: true
});
}
console.info('Started decrypting video');
const decryptVideo = await mp4decrypt(`${tsFile}.video.enc.ts`, `${tsFile}.video.ts`, keys);
if (!decryptVideo) {
console.error('Decryption of video failed');
return undefined;
} else {
console.warn('mp4decrypt not found, files need decryption. Decryption Keys:', encryptionKeys);
console.info('Decryption done for video');
if (!options.nocleanup) {
fs.removeSync(`${tsFile}.video.enc.ts`);
}
files.push({
type: 'Video',
path: `${tsFile}.video.ts`,
lang: chosenAudios[0].language,
isPrimary: true
});
}
}
}
@ -1366,30 +1362,22 @@ export default class Hidive implements ServiceClass {
console.error('Failed to get encryption keys');
return undefined;
}
if (this.cfg.bin.mp4decrypt) {
const commandBase = `--show-progress --key ${encryptionKeys[1].kid}:${encryptionKeys[1].key} `;
const commandAudio = commandBase+`"${tsFile}.audio.enc.ts" "${tsFile}.audio.ts"`;
console.info('Started decrypting audio');
const decryptAudio = exec('mp4decrypt', `"${this.cfg.bin.mp4decrypt}"`, commandAudio);
if (!decryptAudio.isOk) {
console.error(decryptAudio.err);
console.error(`Decryption failed with exit code ${decryptAudio.err.code}`);
return undefined;
} else {
if (!options.nocleanup) {
fs.removeSync(`${tsFile}.audio.enc.ts`);
}
files.push({
type: 'Audio',
path: `${tsFile}.audio.ts`,
lang: chosenAudioSegments.language,
isPrimary: chosenAudioSegments.default
});
console.info('Decryption done for audio');
}
console.info('Started decrypting audio');
const decryptAudio = await mp4decrypt(`${tsFile}.audio.enc.ts`, `${tsFile}.audio.ts`, keys);
if (!decryptAudio) {
console.error('Decryption of audio failed');
return undefined;
} else {
console.warn('mp4decrypt not found, files need decryption. Decryption Keys:', encryptionKeys);
if (!options.nocleanup) {
fs.removeSync(`${tsFile}.audio.enc.ts`);
}
files.push({
type: 'Audio',
path: `${tsFile}.audio.ts`,
lang: chosenAudioSegments.language,
isPrimary: chosenAudioSegments.default
});
console.info('Decryption done for audio');
}
}
}

View file

@ -84,7 +84,6 @@ export type ConfigObject = {
ffmpeg?: string,
mkvmerge?: string,
ffprobe?: string,
mp4decrypt?: string
},
cli: {
[key: string]: any
@ -149,7 +148,6 @@ const loadBinCfg = async () => {
ffmpeg: 'ffmpeg',
mkvmerge: 'mkvmerge',
ffprobe: 'ffprobe',
mp4decrypt: 'mp4decrypt'
};
const keys = Object.keys(defaultBin) as (keyof typeof defaultBin)[];
for(const dir of keys){

View file

@ -1,7 +1,7 @@
{
"name": "multi-downloader-nx",
"short_name": "aniDL",
"version": "4.5.2",
"version": "4.6.0",
"description": "Downloader for Crunchyroll, Funimation, or Hidive via CLI or GUI",
"keywords": [
"download",
@ -61,6 +61,7 @@
"long": "^5.2.3",
"lookpath": "^1.2.2",
"m3u8-parsed": "^1.3.0",
"mp4decryptjs": "^1.0.2",
"mpd-parser": "^1.3.0",
"open": "^8.4.2",
"protobufjs": "^7.2.5",

View file

@ -62,6 +62,9 @@ dependencies:
m3u8-parsed:
specifier: ^1.3.0
version: 1.3.0
mp4decryptjs:
specifier: ^1.0.2
version: 1.0.2
mpd-parser:
specifier: ^1.3.0
version: 1.3.0
@ -2373,6 +2376,18 @@ packages:
dependencies:
color-convert: 2.0.1
/aproba@2.0.0:
resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==}
dev: false
/are-we-there-yet@3.0.1:
resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==}
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
dependencies:
delegates: 1.0.0
readable-stream: 3.6.2
dev: false
/arg@4.1.3:
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
dev: true
@ -2460,6 +2475,16 @@ packages:
engines: {node: '>=4'}
dev: true
/axios@1.6.8(debug@4.3.4):
resolution: {integrity: sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==}
dependencies:
follow-redirects: 1.15.6(debug@4.3.4)
form-data: 4.0.0
proxy-from-env: 1.1.0
transitivePeerDependencies:
- debug
dev: false
/axobject-query@3.1.1:
resolution: {integrity: sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==}
dependencies:
@ -2558,6 +2583,12 @@ packages:
chainsaw: 0.1.0
dev: true
/bindings@1.5.0:
resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
dependencies:
file-uri-to-path: 1.0.0
dev: false
/bl@4.1.0:
resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
dependencies:
@ -2738,6 +2769,11 @@ packages:
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
dev: false
/chownr@2.0.0:
resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
engines: {node: '>=10'}
dev: false
/cliui@7.0.4:
resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==}
dependencies:
@ -2783,6 +2819,28 @@ packages:
readable-stream: 2.3.8
dev: true
/cmake-js@7.3.0:
resolution: {integrity: sha512-dXs2zq9WxrV87bpJ+WbnGKv8WUBXDw8blNiwNHoRe/it+ptscxhQHKB1SJXa1w+kocLMeP28Tk4/eTCezg4o+w==}
engines: {node: '>= 14.15.0'}
hasBin: true
dependencies:
axios: 1.6.8(debug@4.3.4)
debug: 4.3.4
fs-extra: 11.2.0
lodash.isplainobject: 4.0.6
memory-stream: 1.0.0
node-api-headers: 1.1.0
npmlog: 6.0.2
rc: 1.2.8
semver: 7.5.4
tar: 6.2.1
url-join: 4.0.1
which: 2.0.2
yargs: 17.7.2
transitivePeerDependencies:
- supports-color
dev: false
/color-convert@1.9.3:
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
dependencies:
@ -2800,6 +2858,11 @@ packages:
/color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
/color-support@1.1.3:
resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==}
hasBin: true
dev: false
/combined-stream@1.0.8:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
@ -2814,6 +2877,10 @@ packages:
resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==}
dev: true
/console-control-strings@1.1.0:
resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
dev: false
/content-disposition@0.5.4:
resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
engines: {node: '>= 0.6'}
@ -3004,6 +3071,10 @@ packages:
engines: {node: '>=0.4.0'}
dev: false
/delegates@1.0.0:
resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==}
dev: false
/depd@2.0.0:
resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
engines: {node: '>= 0.8'}
@ -3699,6 +3770,10 @@ packages:
dependencies:
flat-cache: 3.0.4
/file-uri-to-path@1.0.0:
resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
dev: false
/fill-range@7.0.1:
resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
engines: {node: '>=8'}
@ -3737,6 +3812,18 @@ packages:
/flatted@3.2.7:
resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==}
/follow-redirects@1.15.6(debug@4.3.4):
resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==}
engines: {node: '>=4.0'}
peerDependencies:
debug: '*'
peerDependenciesMeta:
debug:
optional: true
dependencies:
debug: 4.3.4
dev: false
/for-each@0.3.3:
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
dependencies:
@ -3788,6 +3875,15 @@ packages:
universalify: 2.0.0
dev: false
/fs-extra@11.2.0:
resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==}
engines: {node: '>=14.14'}
dependencies:
graceful-fs: 4.2.11
jsonfile: 6.1.0
universalify: 2.0.0
dev: false
/fs-extra@8.1.0:
resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==}
engines: {node: '>=6 <7 || >=8'}
@ -3807,6 +3903,13 @@ packages:
universalify: 2.0.0
dev: false
/fs-minipass@2.1.0:
resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==}
engines: {node: '>= 8'}
dependencies:
minipass: 3.3.6
dev: false
/fs.realpath@1.0.0:
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
@ -3835,6 +3938,20 @@ packages:
/functions-have-names@1.2.3:
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
/gauge@4.0.4:
resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==}
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
dependencies:
aproba: 2.0.0
color-support: 1.1.3
console-control-strings: 1.1.0
has-unicode: 2.0.1
signal-exit: 3.0.7
string-width: 4.2.3
strip-ansi: 6.0.1
wide-align: 1.1.5
dev: false
/gensync@1.0.0-beta.2:
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
engines: {node: '>=6.9.0'}
@ -3987,6 +4104,10 @@ packages:
dependencies:
has-symbols: 1.0.3
/has-unicode@2.0.1:
resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==}
dev: false
/has@1.0.3:
resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
engines: {node: '>= 0.4.0'}
@ -4377,6 +4498,10 @@ packages:
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
dev: true
/lodash.isplainobject@4.0.6:
resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
dev: false
/lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
@ -4452,6 +4577,12 @@ packages:
engines: {node: '>= 0.6'}
dev: false
/memory-stream@1.0.0:
resolution: {integrity: sha512-Wm13VcsPIMdG96dzILfij09PvuS3APtcKNh7M28FsCA/w6+1mjR7hhPmfFNoilX9xU7wTdhsH5lJAm6XNzdtww==}
dependencies:
readable-stream: 3.6.2
dev: false
/merge-descriptors@1.0.1:
resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==}
dev: false
@ -4514,6 +4645,26 @@ packages:
/minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
/minipass@3.3.6:
resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==}
engines: {node: '>=8'}
dependencies:
yallist: 4.0.0
dev: false
/minipass@5.0.0:
resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==}
engines: {node: '>=8'}
dev: false
/minizlib@2.1.2:
resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==}
engines: {node: '>= 8'}
dependencies:
minipass: 3.3.6
yallist: 4.0.0
dev: false
/mkdirp-classic@0.5.3:
resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
dev: false
@ -4525,6 +4676,23 @@ packages:
minimist: 1.2.8
dev: true
/mkdirp@1.0.4:
resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
engines: {node: '>=10'}
hasBin: true
dev: false
/mp4decryptjs@1.0.2:
resolution: {integrity: sha512-U/Uo+2jOQpUg9RprwrmtGdzNQAh9Tdc0ARGTvlqO12PvD8HFxiP+u76f4f1Km8xgINiKeaMdw50rrNnE0S1IDg==}
requiresBuild: true
dependencies:
bindings: 1.5.0
cmake-js: 7.3.0
node-addon-api: 6.1.0
transitivePeerDependencies:
- supports-color
dev: false
/mpd-parser@1.3.0:
resolution: {integrity: sha512-WgeIwxAqkmb9uTn4ClicXpEQYCEduDqRKfmUdp4X8vmghKfBNXZLYpREn9eqrDx/Tf5LhzRcJLSpi4ohfV742Q==}
hasBin: true
@ -4579,6 +4747,14 @@ packages:
semver: 7.5.4
dev: false
/node-addon-api@6.1.0:
resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==}
dev: false
/node-api-headers@1.1.0:
resolution: {integrity: sha512-ucQW+SbYCUPfprvmzBsnjT034IGRB2XK8rRc78BgjNKhTdFKgAwAmgW704bKIBmcYW48it0Gkjpkd39Azrwquw==}
dev: false
/node-domexception@1.0.0:
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
engines: {node: '>=10.5.0'}
@ -4617,6 +4793,16 @@ packages:
engines: {node: '>=10'}
dev: false
/npmlog@6.0.2:
resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==}
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
dependencies:
are-we-there-yet: 3.0.1
console-control-strings: 1.1.0
gauge: 4.0.4
set-blocking: 2.0.0
dev: false
/nth-check@2.1.1:
resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
dependencies:
@ -4886,6 +5072,10 @@ packages:
ipaddr.js: 1.9.1
dev: false
/proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
dev: false
/pump@3.0.0:
resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==}
dependencies:
@ -5155,6 +5345,10 @@ packages:
- supports-color
dev: false
/set-blocking@2.0.0:
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
dev: false
/setimmediate@1.0.5:
resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
dev: true
@ -5180,6 +5374,10 @@ packages:
get-intrinsic: 1.2.0
object-inspect: 1.12.3
/signal-exit@3.0.7:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
dev: false
/simple-concat@1.0.1:
resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==}
dev: false
@ -5339,6 +5537,18 @@ packages:
readable-stream: 3.6.2
dev: false
/tar@6.2.1:
resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==}
engines: {node: '>=10'}
dependencies:
chownr: 2.0.0
fs-minipass: 2.1.0
minipass: 5.0.0
minizlib: 2.1.2
mkdirp: 1.0.4
yallist: 4.0.0
dev: false
/text-table@0.2.0:
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
@ -5580,6 +5790,10 @@ packages:
dependencies:
punycode: 2.3.0
/url-join@4.0.1:
resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==}
dev: false
/url-toolkit@2.2.5:
resolution: {integrity: sha512-mtN6xk+Nac+oyJ/PrI7tzfmomRVNFIWKUbG8jdYFt52hxbiReFAXIjYskvu64/dvuW71IcB7lV8l0HvZMac6Jg==}
dev: false
@ -5670,6 +5884,12 @@ packages:
dependencies:
isexe: 2.0.0
/wide-align@1.1.5:
resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==}
dependencies:
string-width: 4.2.3
dev: false
/wrap-ansi@7.0.0:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
engines: {node: '>=10'}