mirror of
https://github.com/snobu/destreamer.git
synced 2026-03-03 10:38:24 +00:00
Fix auto rename for duplicate video titles (#118)
* Fix `makeUniqueTitle` was not working with (custom) output format * Add option to skip already existing files * Update README to include --skip option Co-authored-by: molikuner <molikuner@gmail.com>
This commit is contained in:
@@ -88,8 +88,10 @@ Options:
|
|||||||
--acodec Re-encode audio track. Specify FFmpeg codec (e.g.
|
--acodec Re-encode audio track. Specify FFmpeg codec (e.g.
|
||||||
libopus) or set to "none" to disable audio.
|
libopus) or set to "none" to disable audio.
|
||||||
[string] [default: "copy"]
|
[string] [default: "copy"]
|
||||||
--format Output container format (mkv, mp4, mov, anything that FFmpeg supports)
|
--format Output container format (mkv, mp4, mov, anything that
|
||||||
[string] [default: "mkv"]
|
FFmpeg supports) [string] [default: "mkv"]
|
||||||
|
--skip Skip download if file already exists
|
||||||
|
[boolean] [default: false]
|
||||||
```
|
```
|
||||||
|
|
||||||
We default to `.mkv` for the output container. If you prefer something else (like `mp4`), pass `--format mp4`.
|
We default to `.mkv` for the output container. If you prefer something else (like `mp4`), pass `--format mp4`.
|
||||||
|
|||||||
@@ -79,6 +79,12 @@ export const argv = yargs.options({
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
default: 'mkv',
|
default: 'mkv',
|
||||||
demandOption: false
|
demandOption: false
|
||||||
|
},
|
||||||
|
skip: {
|
||||||
|
describe: 'Skip download if file already exists',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
demandOption: false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
/**
|
/**
|
||||||
@@ -207,4 +213,4 @@ function windowsFileExtensionBadBehaviorFix(argv: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { execSync } from 'child_process';
|
|||||||
import colors from 'colors';
|
import colors from 'colors';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
import { argv } from './CommandLineParser';
|
||||||
|
|
||||||
function sanitizeUrls(urls: string[]) {
|
function sanitizeUrls(urls: string[]) {
|
||||||
const rex = new RegExp(/(?:https:\/\/)?.*\/video\/[a-z0-9]{8}-(?:[a-z0-9]{4}\-){3}[a-z0-9]{12}$/, 'i');
|
const rex = new RegExp(/(?:https:\/\/)?.*\/video\/[a-z0-9]{8}-(?:[a-z0-9]{4}\-){3}[a-z0-9]{12}$/, 'i');
|
||||||
@@ -126,7 +127,7 @@ export function makeUniqueTitle(title: string, outDir: string) {
|
|||||||
let ntitle = title;
|
let ntitle = title;
|
||||||
let k = 0;
|
let k = 0;
|
||||||
|
|
||||||
while (fs.existsSync(outDir + path.sep + ntitle + '.mp4'))
|
while (!argv.skip && fs.existsSync(outDir + path.sep + ntitle + '.' + argv.format))
|
||||||
ntitle = title + ' - ' + (++k).toString();
|
ntitle = title + ' - ' + (++k).toString();
|
||||||
|
|
||||||
return ntitle;
|
return ntitle;
|
||||||
|
|||||||
@@ -218,7 +218,8 @@ async function downloadVideo(videoUrls: string[], outputDirectories: string[], s
|
|||||||
]));
|
]));
|
||||||
const ffmpegOutput = new FFmpegOutput(outputPath, new Map([
|
const ffmpegOutput = new FFmpegOutput(outputPath, new Map([
|
||||||
argv.acodec === 'none' ? ['an', null] : ['c:a', argv.acodec],
|
argv.acodec === 'none' ? ['an', null] : ['c:a', argv.acodec],
|
||||||
argv.vcodec === 'none' ? ['vn', null] : ['c:v', argv.vcodec]
|
argv.vcodec === 'none' ? ['vn', null] : ['c:v', argv.vcodec],
|
||||||
|
['n', null]
|
||||||
]));
|
]));
|
||||||
const ffmpegCmd = new FFmpegCommand();
|
const ffmpegCmd = new FFmpegCommand();
|
||||||
|
|
||||||
@@ -255,17 +256,23 @@ async function downloadVideo(videoUrls: string[], outputDirectories: string[], s
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ffmpegCmd.on('error', (error: any) => {
|
|
||||||
cleanupFn();
|
|
||||||
|
|
||||||
console.log(`\nffmpeg returned an error: ${error.message}`);
|
|
||||||
process.exit(ERROR_CODE.UNK_FFMPEG_ERROR);
|
|
||||||
});
|
|
||||||
|
|
||||||
process.on('SIGINT', cleanupFn);
|
process.on('SIGINT', cleanupFn);
|
||||||
|
|
||||||
// let the magic begin...
|
// let the magic begin...
|
||||||
await new Promise((resolve: any, reject: any) => {
|
await new Promise((resolve: any, reject: any) => {
|
||||||
|
ffmpegCmd.on('error', (error: any) => {
|
||||||
|
if (argv.skip && error.message.includes('exists') && error.message.includes(outputPath)) {
|
||||||
|
pbar.update(video.totalChunks); // set progress bar to 100%
|
||||||
|
console.log(colors.yellow(`\nFile already exists, skipping: ${outputPath}`));
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
cleanupFn();
|
||||||
|
|
||||||
|
console.log(`\nffmpeg returned an error: ${error.message}`);
|
||||||
|
process.exit(ERROR_CODE.UNK_FFMPEG_ERROR);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
ffmpegCmd.on('success', (data:any) => {
|
ffmpegCmd.on('success', (data:any) => {
|
||||||
pbar.update(video.totalChunks); // set progress bar to 100%
|
pbar.update(video.totalChunks); // set progress bar to 100%
|
||||||
console.log(colors.green(`\nDownload finished: ${outputPath}`));
|
console.log(colors.green(`\nDownload finished: ${outputPath}`));
|
||||||
|
|||||||
Reference in New Issue
Block a user