refactored artwork extraction
This commit is contained in:
parent
b1d7fffb2d
commit
33c725f7ae
3 changed files with 66 additions and 79 deletions
78
badger-am.js
78
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;
|
||||
}
|
||||
}
|
65
lib/audio.js
65
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;
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "badger-am",
|
||||
"version": "0.5.1",
|
||||
"version": "0.5.2",
|
||||
"license": "MIT",
|
||||
"description": "audio manager",
|
||||
"author": "Daniel Sommer <daniel.sommer@velvettear.de>",
|
||||
|
|
Loading…
Reference in a new issue