diff --git a/package.json b/package.json index d2ca30c..63656cf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "publikator", - "version": "0.4.0", + "version": "0.5.0", "main": "index.js", "repository": "https://github.com/aengl/publikator.git", "author": "Lynn Smeria ", @@ -12,11 +12,13 @@ "node": ">=8" }, "dependencies": { + "@types/mime-types": "2.1.0", "caporal": "0.10.0", "debug": "3.1.0", "fs-extra": "7.0.0", "js-yaml": "3.12.0", "lodash": "4.17.10", + "mime-types": "2.1.19", "music-metadata": "2.6.0", "sanitize-filename": "1.6.1", "walkdir": "0.0.12" diff --git a/src/organise.js b/src/organise.js index 160343b..3b21913 100644 --- a/src/organise.js +++ b/src/organise.js @@ -3,14 +3,35 @@ const path = require('path'); const _ = require('lodash'); const sanitize = require('sanitize-filename'); const debug = require('debug')('publikator:organise'); +const mime = require('mime-types'); const tags = require('./tags'); const getFolderName = file => file.common.album.replace(/ /g, '_'); + const getFileName = file => `${file.common.track.no}-${file.common.title}${path.extname( file.path )}`.replace(/ /g, '_'); +/** + * Extracts the cover art and saves it to a file with the same name. + */ +const extractCoverArt = async filePath => { + const pictures = await tags.extractCoverArt(filePath); + if (pictures) { + await Promise.all( + pictures.map(async picture => { + const pictureExt = mime.extension(picture.format); + const picturePath = `${filePath.replace( + path.extname(filePath), + '' + )}.${pictureExt}`; + await fs.writeFile(picturePath, picture.data); + }) + ); + } +}; + module.exports = { /** * Organises tracks into a new folder structure in `root`, as follows: @@ -42,13 +63,14 @@ module.exports = { folders.map(album => fs.ensureDir(path.resolve(root, sanitize(album)))) ); - debug(`copying tracks`); + debug(`copying tracks & extracting covers`); return Promise.all( files.map(async file => { const folderName = getFolderName(file); const fileName = getFileName(file); const newPath = path.resolve(root, folderName, fileName); await fs.copyFile(file.path, newPath); + await extractCoverArt(newPath); return _.assign( {}, { diff --git a/src/tags.js b/src/tags.js index 6bf4a3e..a8ebc3b 100644 --- a/src/tags.js +++ b/src/tags.js @@ -10,9 +10,21 @@ module.exports = { mm.parseFile(file, { duration: true, native: true, - skipCovers: false, + skipCovers: true, }), + /** + * Extracts the cover art into a file stream. + */ + extractCoverArt: async file => { + const data = await mm.parseFile(file, { + duration: false, + native: false, + skipCovers: false, + }); + return data.common.picture; + }, + /** * Returns true if a file has all required tags. */ diff --git a/yarn.lock b/yarn.lock index 7019418..dcf33a2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,10 @@ # yarn lockfile v1 +"@types/mime-types@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/mime-types/-/mime-types-2.1.0.tgz#9ca52cda363f699c69466c2a6ccdaad913ea7a73" + abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -1592,6 +1596,16 @@ micromist@^1.0.1: dependencies: lodash.camelcase "^4.3.0" +mime-db@~1.35.0: + version "1.35.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.35.0.tgz#0569d657466491283709663ad379a99b90d9ab47" + +mime-types@2.1.19: + version "2.1.19" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.19.tgz#71e464537a7ef81c15f2db9d97e913fc0ff606f0" + dependencies: + mime-db "~1.35.0" + mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"