diff --git a/main/lib/artwork-cache/index.js b/main/lib/artwork-cache/index.js index 7286268..67f8dc6 100644 --- a/main/lib/artwork-cache/index.js +++ b/main/lib/artwork-cache/index.js @@ -4,7 +4,8 @@ var path = require('path') var pump = require('pump') var crypto = require('crypto') var mkdirp = require('mkdirp') -var { artwork, fromBuffer } = require('./util') +var { artwork } = require('./util') +var BufferList = require('bl') // var configPath = (electron.app || electron.remote.app).getPath('userData') // var artworkCachePath = path.join(configPath, 'artwork-cache') @@ -37,7 +38,7 @@ class ArtworkCache { return cb(null, blobPath) } else { var writeStream = self._blobs.createWriteStream() - pump(fromBuffer(buff), writeStream, function (err) { + pump((new BufferList()).append(buff), writeStream, function (err) { if (err) return cb(err) return self._blobs.resolve(writeStream.key, cb) }) diff --git a/main/lib/artwork-cache/test.js b/main/lib/artwork-cache/test.js index 2276c42..5a9dd35 100644 --- a/main/lib/artwork-cache/test.js +++ b/main/lib/artwork-cache/test.js @@ -1,5 +1,5 @@ var test = require('tape') -var {artwork, fromBuffer} = require('./util') +var {artwork} = require('./util') var path = require('path') var concatStream = require('concat-stream') var isBuffer = require('is-buffer') @@ -8,6 +8,7 @@ var bufferEqual = require('buffer-equal') var tmp = require('temporary-directory') var ArtworkCache = require('./index.js') var testData = require('./test-data') +var BufferList = require('bl') test('get artwork from file', function (t) { artwork(testData.mp3WithArtwork, function (err, imageBuf) { @@ -22,7 +23,8 @@ test('can stream buffers', function (t) { function bufferTests (err, imageBuf) { t.error(err, 'got artwork buffer') - var imageBufferStream = fromBuffer(imageBuf) + var imageBufferStream = new BufferList() + imageBufferStream.append(imageBuf) var concat = concatStream(gotPic) var streamedBuff diff --git a/main/lib/artwork-cache/util.js b/main/lib/artwork-cache/util.js index 635d08e..3fa502b 100644 --- a/main/lib/artwork-cache/util.js +++ b/main/lib/artwork-cache/util.js @@ -1,35 +1,19 @@ -var from = require('from2') -var fs = require('fs') var mm = require('music-metadata') var get = require('lodash.get') - -exports.fromBuffer = fromBuffer - -function fromBuffer (buffer) { - return from(function (size, next) { - if (buffer.length <= 0) return next(null, null) - var chunk = buffer.slice(0, size) - buffer = buffer.slice(size) - next(null, chunk) - }) -} +var fs = require('fs') function metadata (path, cb) { - var audioStream = fs.createReadStream(path) - var returned = false // TODO clean up racy code - audioStream.on('error', (err) => { - if (!returned) { - returned = true + fs.stat(path, function (err, stats) { + if (err) return cb(err) + mm.parseFile(path, { + native: true, + duration: true, + skipCovers: false + }).then(function (md) { + return cb(null, md) + }).catch(function (err) { return cb(err) - } - }) - mm.parseStream(audioStream, {native: true}, function (err, metadata) { - // important note, the stream is not closed by default. To prevent leaks, you must close it yourself - audioStream.destroy() - if (!returned) { - returned = true - return cb(err, err ? null : metadata) - } + }) }) } diff --git a/main/lib/audio-library/sort.js b/main/lib/audio-library/sort.js index 3b73d09..9359d4f 100644 --- a/main/lib/audio-library/sort.js +++ b/main/lib/audio-library/sort.js @@ -4,8 +4,8 @@ function sort ([keyA, aObj], [keyB, bObj]) { // if (aObj.albumartist[0] > bObj.albumartist[0]) return 1 // sort by artist - if (aObj.artist[0] < bObj.artist[0]) return -1 - if (aObj.artist[0] > bObj.artist[0]) return 1 + if (aObj.artist < bObj.artist) return -1 + if (aObj.artist > bObj.artist) return 1 // then by album if (aObj.album < bObj.album) return -1 diff --git a/main/track-dict.js b/main/track-dict.js index d072909..82d4f05 100644 --- a/main/track-dict.js +++ b/main/track-dict.js @@ -1,7 +1,6 @@ -var fs = require('fs') var path = require('path') var walker = require('folder-walker') -var mm = require('musicmetadata') +var mm = require('music-metadata') var writer = require('flush-write-stream') var filter = require('through2-filter') var pump = require('pump') @@ -18,6 +17,7 @@ function makeTrackDict (paths, cb) { function handleEos (err) { if (err) return cb(err) + console.log('') cb(null, newTrackDict) } } @@ -35,7 +35,7 @@ function concatTrackDict (obj) { parseMetadata(data, handleMeta) function handleMeta (err, meta) { - if (err) return cb(err) + if (err) throw err obj[meta.filepath] = meta cb(null) } @@ -45,25 +45,11 @@ function concatTrackDict (obj) { function parseMetadata (data, cb) { var { filepath } = data - var readableStream = fs.createReadStream(filepath) - mm(readableStream, { duration: true }, (err, meta) => { - readableStream.destroy() - if (err) { - switch (err.message) { - case 'Could not find metadata header': - console.warn(err.message += ` (file: ${filepath})`) - break - case 'expected frame header but was not found': - console.warn(err.message += ` (file: ${filepath})`) - break - default: - // Ignore errors - console.warn(err.message += ` (file: ${filepath})`) - return cb(null) - } - } - // delete meta.picture - // console.dir(meta, {colors: true, depth: 5}) + mm.parseFile(filepath, { + duration: true, + native: false, + skipCovers: true + }).then(meta => { var { albumartist, title, @@ -72,17 +58,17 @@ function parseMetadata (data, cb) { year, track, disk, - genre, - duration - } = meta + genre + } = meta.common + var { duration } = meta.format if (!title) { var { basename } = data var ext = path.extname(basename) title = path.basename(basename, ext) } - cb(null, { + return Promise.resolve({ albumartist, title, artist, @@ -94,5 +80,14 @@ function parseMetadata (data, cb) { disk, genre }) + }).catch(err => { + // Ignore errors + console.log(err.message += ` (file: ${filepath})`) + var { basename } = data + var ext = path.extname(basename) + var title = path.basename(basename, ext) + return Promise.resolve({ title, filepath }) + }).then(meta => { + cb(null, meta) }) } diff --git a/package.json b/package.json index 5c5e857..0c8270e 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ ], "dependencies": { "@bret/truthy": "^1.0.1", + "bl": "^1.2.1", "choo": "^6.0.0", "choo-devtools": "^1.5.0", "choo-log": "^7.2.1", @@ -53,7 +54,6 @@ "flush-write-stream": "^1.0.2", "folder-walker": "^3.0.0", "format-duration": "^1.0.0", - "from2": "^2.3.0", "fy-shuffle": "^1.0.0", "global": "^4.3.2", "lodash.debounce": "^4.0.8", @@ -61,8 +61,7 @@ "lodash.throttle": "^4.1.1", "mkdirp": "^0.5.1", "mousetrap": "^1.6.1", - "music-metadata": "^0.6.1", - "musicmetadata": "^2.0.4", + "music-metadata": "^0.8.7", "nanobus": "^4.1.0", "nanocomponent": "^6.0.0", "nanologger": "^1.3.0", diff --git a/renderer/lib/artwork.js b/renderer/lib/artwork.js deleted file mode 100644 index 7e7f387..0000000 --- a/renderer/lib/artwork.js +++ /dev/null @@ -1,23 +0,0 @@ -var get = require('lodash.get') -var nativeImage = require('electron').nativeImage -var metadata = require('./metadata') -var crypto = require('crypto') - -var artworkCache = {} - -function artwork (path, cb) { - metadata(path, lookupArtwork) - - function lookupArtwork (err, meta) { - if (err) return cb(err) - var artBuff = get(meta, 'common.picture[0].data') - if (!artBuff) return cb(null, null) - var hash = crypto.createHash('sha256').digest('hex') - var nativeBuff = nativeImage.createFromBuffer(artBuff) - var thumbnail = nativeBuff.getAspectRatio() >= 1 ? nativeBuff.resize({width: 175, quality: 'good'}) : nativeBuff.resize({height: 175, quality: 'good'}) - artworkCache[hash] = thumbnail.toDataURL() - cb(null, hash) - } -} - -module.exports = artwork diff --git a/renderer/lib/metadata.js b/renderer/lib/metadata.js deleted file mode 100644 index 0a93491..0000000 --- a/renderer/lib/metadata.js +++ /dev/null @@ -1,15 +0,0 @@ -var fs = require('fs') -var mm = require('music-metadata') - -function metadata (path, cb) { - var audioStream = fs.createReadStream(path) - mm.parseStream(audioStream, {native: true}, function (err, metadata) { - // important note, the stream is not closed by default. To prevent leaks, you must close it yourself - audioStream.close() - if (err) return cb(err) - - return cb(err, metadata) - }) -} - -module.exports = metadata