2017-03-24 17:05:14 +01:00
|
|
|
#!/usr/bin/env node
|
|
|
|
|
|
|
|
// requirements
|
|
|
|
const os = require('os');
|
|
|
|
const path = require('path');
|
|
|
|
const async = require('async');
|
|
|
|
const commander = require('commander');
|
|
|
|
const app = require('./package.json');
|
2017-03-24 22:05:51 +01:00
|
|
|
const audio = require('./lib/audio');
|
|
|
|
const util = require('./lib/util');
|
2017-03-27 22:28:35 +02:00
|
|
|
const cli = require('./lib/cli');
|
2017-03-24 17:05:14 +01:00
|
|
|
|
2017-03-27 22:28:35 +02:00
|
|
|
badger();
|
2017-03-24 21:46:09 +01:00
|
|
|
|
2017-03-28 14:54:51 +02:00
|
|
|
// main application
|
2017-03-27 22:28:35 +02:00
|
|
|
function badger() {
|
|
|
|
cli.printLogo();
|
2017-03-24 22:18:22 +01:00
|
|
|
// general options
|
|
|
|
commander
|
|
|
|
.version(app.version)
|
|
|
|
.usage('[options] <command>')
|
2017-03-29 13:28:07 +02:00
|
|
|
.option('-c, --concurrency <n>', 'specify concurrency level', os.cpus().length)
|
|
|
|
.option('-n, --no-confirm', 'disable confirmation messages');
|
2017-03-24 23:36:41 +01:00
|
|
|
// conversion
|
2017-03-24 22:18:22 +01:00
|
|
|
commander
|
|
|
|
.command('convert <input> <output>')
|
|
|
|
.description('convert .flac to .mp3 files')
|
|
|
|
.option('-b, --bitrate <n>', 'specify conversion bitrate', 320)
|
2017-03-24 22:56:05 +01:00
|
|
|
.action(convert);
|
2017-03-24 23:36:41 +01:00
|
|
|
// sort
|
2017-03-24 22:18:22 +01:00
|
|
|
commander
|
|
|
|
.command('sort <input> <output>')
|
|
|
|
.description('sort audio files by tags')
|
2017-03-28 14:54:51 +02:00
|
|
|
.option('-f, --format <format>', 'specify audio format (\'flac\', \'mp3\')', '.flac')
|
2017-03-24 22:18:22 +01:00
|
|
|
.action(sort);
|
2017-03-24 23:36:41 +01:00
|
|
|
// artwork
|
|
|
|
commander
|
2017-03-28 15:39:37 +02:00
|
|
|
.command('extract <input>')
|
2017-03-24 23:36:41 +01:00
|
|
|
.description('extract cover artwork')
|
2017-03-28 14:54:51 +02:00
|
|
|
.option('-f, --format <format>', 'specify audio format (\'flac\', \'mp3\')', '.flac')
|
2017-03-28 15:39:37 +02:00
|
|
|
.action(extract);
|
2017-03-28 14:54:51 +02:00
|
|
|
// scan
|
|
|
|
commander
|
|
|
|
.command('scan <input>')
|
|
|
|
.description('scan audio files for missing cover artwork')
|
|
|
|
.option('-f, --format <format>', 'specify audio format (\'flac\', \'mp3\')', '.flac')
|
|
|
|
.action(scan);
|
2017-03-24 22:18:22 +01:00
|
|
|
// parse command line arguments
|
|
|
|
commander.parse(process.argv);
|
|
|
|
}
|
2017-03-24 17:05:14 +01:00
|
|
|
|
2017-03-27 23:27:33 +02:00
|
|
|
// convert files
|
|
|
|
function convert(input, output, options) {
|
|
|
|
audio.batchConvert({
|
2017-03-27 22:28:35 +02:00
|
|
|
input: path.normalize(input),
|
|
|
|
output: path.normalize(output),
|
|
|
|
concurrency: commander.concurrency || os.cpus().length,
|
2017-03-29 13:28:07 +02:00
|
|
|
confirm: commander.confirm || false,
|
2017-03-27 22:28:35 +02:00
|
|
|
bitrate: options.bitrate || 320,
|
|
|
|
format: options.format || '.flac'
|
2017-03-28 14:54:51 +02:00
|
|
|
}, function (err, time) {
|
|
|
|
cli.exit(err, time);
|
2017-03-24 23:36:41 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-03-24 21:23:29 +01:00
|
|
|
// sort files
|
2017-03-24 17:05:14 +01:00
|
|
|
function sort(input, output, options) {
|
2017-03-27 23:27:33 +02:00
|
|
|
util.batchSort({
|
|
|
|
input: path.normalize(input),
|
|
|
|
output: path.normalize(output),
|
|
|
|
concurrency: commander.concurrency || os.cpus().length,
|
2017-03-29 13:28:07 +02:00
|
|
|
confirm: commander.confirm || false,
|
2017-03-27 23:27:33 +02:00
|
|
|
format: options.format || '.flac'
|
2017-03-28 16:08:01 +02:00
|
|
|
}, function (err, skipped, time) {
|
|
|
|
if (!skipped || skipped.length === 0) {
|
|
|
|
cli.exit(err, time);
|
|
|
|
} else {
|
|
|
|
console.log(skipped.length + ' files were skipped after ' + util.getTimeDiff(time) + ' seconds');
|
|
|
|
cli.askForConfirmation('list files now?', ['yes', 'y'], function (canceled) {
|
|
|
|
if (canceled) {
|
|
|
|
cli.exit(err, time);
|
|
|
|
}
|
|
|
|
skipped.forEach(function (file) {
|
|
|
|
console.log(file);
|
|
|
|
});
|
|
|
|
cli.exit(err);
|
|
|
|
});
|
|
|
|
}
|
2017-03-24 22:56:05 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-03-24 23:36:41 +01:00
|
|
|
// extract artwork
|
2017-03-28 15:39:37 +02:00
|
|
|
function extract(input, options) {
|
2017-03-27 23:27:33 +02:00
|
|
|
audio.batchArtwork({
|
|
|
|
input: path.normalize(input),
|
|
|
|
concurrency: commander.concurrency || os.cpus().length,
|
|
|
|
format: options.format || '.flac'
|
2017-03-28 14:54:51 +02:00
|
|
|
}, function (err, time) {
|
2017-03-28 15:39:37 +02:00
|
|
|
cli.exit(err, time);
|
2017-03-24 17:05:14 +01:00
|
|
|
});
|
2017-03-28 14:54:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// scan files
|
|
|
|
function scan(input, options) {
|
2017-03-28 15:39:37 +02:00
|
|
|
audio.batchScan({
|
|
|
|
input: path.normalize(input),
|
|
|
|
concurrency: commander.concurrency || os.cpus().length,
|
2017-03-29 13:28:07 +02:00
|
|
|
confirm: commander.confirm || false,
|
2017-03-28 15:39:37 +02:00
|
|
|
format: options.format || '.flac'
|
|
|
|
}, function (err, missing, time) {
|
|
|
|
if (!missing || missing.length === 0) {
|
|
|
|
console.log('no files with missing cover artwork found');
|
|
|
|
cli.exit(err, time);
|
|
|
|
} else {
|
|
|
|
console.log(missing.length + ' files with missing cover artwork found after ' + util.getTimeDiff(time) + ' seconds');
|
|
|
|
cli.askForConfirmation('list files now?', ['yes', 'y'], function (canceled) {
|
|
|
|
if (canceled) {
|
|
|
|
cli.exit(err, time);
|
|
|
|
}
|
|
|
|
missing.forEach(function (file) {
|
|
|
|
console.log(file);
|
|
|
|
});
|
|
|
|
cli.exit(err);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2017-03-24 22:18:57 +01:00
|
|
|
}
|