diff --git a/badger-am.js b/badger-am.js index d7cd7a7..123797e 100755 --- a/badger-am.js +++ b/badger-am.js @@ -5,7 +5,6 @@ const os = require('os'); const path = require('path'); const async = require('async'); const commander = require('commander'); -const recursive = require('recursive-readdir'); const app = require('./package.json'); const audio = require('./lib/audio'); const util = require('./lib/util'); @@ -51,82 +50,39 @@ function run() { commander.parse(process.argv); } -// create config object -function getConfig(input, output, options, commander) { - return { +// convert files +function convert(input, output, options) { + audio.batchConvert({ input: path.normalize(input), output: path.normalize(output), concurrency: commander.concurrency || os.cpus().length, bitrate: options.bitrate || 320, format: options.format || '.flac' - } -} - -// convert files -function convert(input, output, options) { - audio.batchConvert(getConfig(input, output, options, commander), function (err) { + }, function (err) { cli.exit(err); }); } // sort files function sort(input, output, options) { - util.batchSort(getConfig(input, output, options, commander), function (err) { + util.batchSort({ + input: path.normalize(input), + output: path.normalize(output), + concurrency: commander.concurrency || os.cpus().length, + bitrate: options.bitrate || 320, + format: options.format || '.flac' + }, function (err) { cli.exit(err); - }) -} - -// move file to location defined by its metadata -function processFileSort(output, sourceFile, callback) { - async.waterfall([ - function (asyncCallback) { - audio.extractMetadata(sourceFile, asyncCallback) - }, - function (sourceFile, metadata, asyncCallback) { - util.pathFromMetadata(sourceFile, output, metadata, asyncCallback); - }, - function (targetFile, asyncCallback) { - util.moveFile(sourceFile, targetFile, asyncCallback); - } - ], function (err, results) { - if (err) { - return callback(err); - } - callback(null, results); }); } // extract artwork function artwork(input, options) { - async.waterfall([ - function (asyncCallback) { - recursive(input, [ignoreFilter], asyncCallback); - }, - function (files, asyncCallback) { - console.log(files.length + ' \'' + options.format + '\' files found'); - // display progressbar - const bar = util.createProgressBar(files.length); - // handle each file - async.eachLimit(files, commander.concurrency, function (file, eachCallback) { - audio.extractArtwork(file, function (err) { - bar.tick(); - if (err) { - return eachCallback(err); - } - eachCallback(); - }); - }, function (err) { - if (err) { - return asyncCallback(err); - } - asyncCallback(); - }); - } - ], function (err, result) { - util.exit(err, start); + audio.batchArtwork({ + input: path.normalize(input), + concurrency: commander.concurrency || os.cpus().length, + format: options.format || '.flac' + }, function (err) { + cli.exit(err); }); - - function ignoreFilter(file, stats) { - return !stats.isDirectory() && path.extname(file).indexOf(options.format) == -1; - } } \ No newline at end of file diff --git a/lib/audio.js b/lib/audio.js index 9ee125f..da82255 100644 --- a/lib/audio.js +++ b/lib/audio.js @@ -73,27 +73,57 @@ function convert(source, config, callback) { ], callback); } -// extract cover artwork -function extractArtwork(sourceFile, callback) { +// +function batchArtwork(config, callback) { async.waterfall([ - function (asyncCallback) { - extractMetadata(sourceFile, asyncCallback); + // get files + function (waterfallCallback) { + util.readDirRecursive(config.input, config.format, waterfallCallback); }, - function (metadata, asyncCallback) { - metadata.picture.forEach(function (picture) { - const pic = path.join(path.dirname(sourceFile), path.basename(sourceFile, path.extname(sourceFile)) + '.' + picture.format); - const stream = fs.createWriteStream(pic); - stream.write(picture.data); - stream.end(); - asyncCallback(); + // display info, prompt user and create progressbar + function (files, waterfallCallback) { + cli.askForConfirmation(files.length + ' files found.\nstart artwork extraction now?', ['yes', 'y'], function (err) { + if (err) { + return waterfallCallback(err); + } + waterfallCallback(null, files, cli.createProgressBar(files.length)); }); + }, + // process each file + function (files, bar, waterfallCallback) { + async.eachLimit(files, config.concurrency, function (file, eachCallback) { + extractArtwork(file, function (err) { + bar.tick(); + if (err) { + return eachCallback(err); + } + eachCallback(); + }); + }, waterfallCallback); } - ], function (err, result) { - if (err) { - return callback(err); + ], callback); +} + +// extract cover artwork +function extractArtwork(source, callback) { + async.waterfall([ + // get metadata + function (waterfallCallback) { + extractMetadata(source, waterfallCallback); + }, + // write image to disk + function (metadata, waterfallCallback) { + if (!metadata.picture) { + waterfallCallback(); + } + for (let counter = 0, length = metadata.picture.length; counter < length; counter++) { + const stream = fs.createWriteStream(path.join(path.dirname(source), path.basename(source, path.extname(source)) + '.' + metadata.picture[counter].format)); + stream.write(metadata.picture[counter].data); + stream.end(); + } + waterfallCallback(); } - callback(); - }); + ], callback); } // extract metadata for further processing @@ -109,7 +139,8 @@ function extractMetadata(sourceFile, callback) { } // api -exports.convert = convert; exports.batchConvert = batchConvert; +exports.convert = convert; +exports.batchArtwork = batchArtwork; exports.extractArtwork = extractArtwork; exports.extractMetadata = extractMetadata; \ No newline at end of file diff --git a/package.json b/package.json index 954129d..218c8af 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "badger-am", - "version": "0.5.1", + "version": "0.5.2", "license": "MIT", "description": "audio manager", "author": "Daniel Sommer ",