diff --git a/@types/crunchyTypes.d.ts b/@types/crunchyTypes.d.ts index 4f07e7e..898020a 100644 --- a/@types/crunchyTypes.d.ts +++ b/@types/crunchyTypes.d.ts @@ -15,6 +15,7 @@ export type CrunchyDownloadOptions = { x: number; q: number; fileName: string; + outputDir?: string; numbers: number; partsize: number; callbackMaker?: (data: DownloadInfo) => HLSCallback; diff --git a/adn.ts b/adn.ts index d4592e8..114a1bf 100644 --- a/adn.ts +++ b/adn.ts @@ -965,10 +965,29 @@ export default class AnimationDigitalNetwork implements ServiceClass { console.info('Subtitles downloading skipped!'); } + console.info('\x1b[32m[MDNX] All stream downloads & decryption completed.\x1b[0m'); + + let finalOutBase = './unknown'; + if (fileName) { + let targetDir = this.cfg.dir.content; + + if (options.outputDir) { + const parsedDir = parseFileName(options.outputDir, variables, options.numbers, options.override).join(path.sep); + targetDir = path.isAbsolute(parsedDir) ? parsedDir : path.join(this.cfg.dir.content, parsedDir); + + if (!fs.existsSync(targetDir)) { + fs.mkdirSync(targetDir, { recursive: true }); + } + } + + const finalNamePart = path.isAbsolute(fileName) ? path.basename(fileName) : fileName; + finalOutBase = path.join(targetDir, finalNamePart); + } + return { error: dlFailed, data: files, - fileName: fileName ? (path.isAbsolute(fileName) ? fileName : path.join(this.cfg.dir.content, fileName)) || './unknown' : './unknown' + fileName: finalOutBase }; } diff --git a/crunchy.ts b/crunchy.ts index df35438..6a3cf9d 100644 --- a/crunchy.ts +++ b/crunchy.ts @@ -3032,10 +3032,29 @@ export default class Crunchy implements ServiceClass { await this.sleep(options.waittime); } + console.info('\x1b[32m[MDNX] All stream downloads & decryption completed.\x1b[0m'); + + let finalOutBase = './unknown'; + if (fileName) { + let targetDir = this.cfg.dir.content; + + if (options.outputDir) { + const parsedDir = parseFileName(options.outputDir, variables, options.numbers, options.override).join(path.sep); + targetDir = path.isAbsolute(parsedDir) ? parsedDir : path.join(this.cfg.dir.content, parsedDir); + + if (!fs.existsSync(targetDir)) { + fs.mkdirSync(targetDir, { recursive: true }); + } + } + + const finalNamePart = path.isAbsolute(fileName) ? path.basename(fileName) : fileName; + finalOutBase = path.join(targetDir, finalNamePart); + } + return { error: dlFailed, data: files, - fileName: fileName ? (path.isAbsolute(fileName) ? fileName : path.join(this.cfg.dir.content, fileName)) || './unknown' : './unknown' + fileName: finalOutBase }; } diff --git a/docs/DOCUMENTATION.md b/docs/DOCUMENTATION.md index 4fbdd0a..02ed630 100644 --- a/docs/DOCUMENTATION.md +++ b/docs/DOCUMENTATION.md @@ -472,6 +472,7 @@ Possible Values: und, eng, eng, spa, spa-419, spa-ES, por, por, fra, deu, ara-ME Set the filename template. Use ${variable_name} to insert variables. You can also create folders by inserting a path seperator in the filename You may use 'title', 'episode', 'showTitle', 'seriesTitle', 'season', 'width', 'height', 'service' as variables. + #### `--numbers` | **Service** | **Usage** | **Type** | **Required** | **Alias** | **Default** |**cli-default Entry** | --- | --- | --- | --- | --- | --- | ---| diff --git a/hidive.ts b/hidive.ts index da588ca..a6e52d9 100644 --- a/hidive.ts +++ b/hidive.ts @@ -1117,10 +1117,29 @@ export default class Hidive implements ServiceClass { console.info('Subtitles downloading skipped!'); } + console.info('\x1b[32m[MDNX] All stream downloads & decryption completed.\x1b[0m'); + + let finalOutBase = './unknown'; + if (fileName) { + let targetDir = this.cfg.dir.content; + + if (options.outputDir) { + const parsedDir = parseFileName(options.outputDir, variables, options.numbers, options.override).join(path.sep); + targetDir = path.isAbsolute(parsedDir) ? parsedDir : path.join(this.cfg.dir.content, parsedDir); + + if (!fs.existsSync(targetDir)) { + fs.mkdirSync(targetDir, { recursive: true }); + } + } + + const finalNamePart = path.isAbsolute(fileName) ? path.basename(fileName) : fileName; + finalOutBase = path.join(targetDir, finalNamePart); + } + return { error: dlFailed, data: files, - fileName: fileName ? (path.isAbsolute(fileName) ? fileName : path.join(this.cfg.dir.content, fileName)) || './unknown' : './unknown' + fileName: finalOutBase }; } diff --git a/modules/module.app-args.ts b/modules/module.app-args.ts index 9a06b2c..6bf7460 100644 --- a/modules/module.app-args.ts +++ b/modules/module.app-args.ts @@ -68,6 +68,7 @@ export let argvC: { mp4: boolean; skipmux: boolean | undefined; fileName: string; + outputDir: string; numbers: number; nosess: string; debug: boolean | undefined; diff --git a/modules/module.args.ts b/modules/module.args.ts index f8bc37c..6c81d14 100644 --- a/modules/module.args.ts +++ b/modules/module.args.ts @@ -666,6 +666,18 @@ const args: TAppArg[] = [ default: '[${service}] ${showTitle} - S${season}E${episode} [${height}p]' } }, + { + name: 'outputDir', + group: 'fileName', + describe: 'Set a custom directory for the final muxed file (supports template variables). Temporary files remain in the default content folder.', + docDescribe: true, + service: ['all'], + type: 'string', + usage: '${outputDir}', + default: { + default: '' + } + }, { name: 'numbers', group: 'fileName',