diff --git a/deemix/tagger.js b/deemix/tagger.js index 2476e31..1085b8b 100644 --- a/deemix/tagger.js +++ b/deemix/tagger.js @@ -1,25 +1,26 @@ -const ID3Writer = require('browser-id3-writer') +const ID3Writer = require('./utils/id3-writer.js') const Metaflac = require('metaflac-js2') const fs = require('fs') function tagID3(path, track, save){ const songBuffer = fs.readFileSync(path) const tag = new ID3Writer(songBuffer) + if (save.useNullSeparator) tag.separator = String.fromCharCode(0) if (save.title) tag.setFrame('TIT2', track.title) if (save.artist && track.artists.length){ if (save.multiArtistSeparator == "default"){ - tag.setFrame('TPE1', track.artists) + tag.setArrayFrame('TPE1', track.artists) }else{ if (save.multiArtistSeparator == "nothing"){ - tag.setFrame('TPE1', track.mainArtist.name) + tag.setArrayFrame('TPE1', [track.mainArtist.name]) } else { - tag.setFrame('TPE1', track.artistString) + tag.setArrayFrame('TPE1', [track.artistString]) } // Tag ARTISTS is added to keep the multiartist support when using a non standard tagging method // https://picard-docs.musicbrainz.org/en/appendices/tag_mapping.html#artists - tag.setFrame('TXXX', { + tag.setArrayFrame('TXXX', { description: 'ARTISTS', value: track.artists }) @@ -30,9 +31,9 @@ function tagID3(path, track, save){ if (save.albumArtist && track.album.artists.length){ if (save.singleAlbumArtist && track.album.mainArtist.save){ - tag.setFrame('TPE2', track.album.mainArtist.name) + tag.setArrayFrame('TPE2', [track.album.mainArtist.name]) } else { - tag.setFrame('TPE2', track.album.artists) + tag.setArrayFrame('TPE2', track.album.artists) } } @@ -47,7 +48,7 @@ function tagID3(path, track, save){ tag.setFrame('TPOS', discNumber) } - if (save.genre) tag.setFrame('TCON', track.album.genre) + if (save.genre) tag.setArrayFrame('TCON', track.album.genre) if (save.year) tag.setFrame('TYER', track.date.year) // Referencing ID3 standard diff --git a/deemix/utils/id3-writer.js b/deemix/utils/id3-writer.js new file mode 100644 index 0000000..62c687e --- /dev/null +++ b/deemix/utils/id3-writer.js @@ -0,0 +1,46 @@ +const ID3Writer = require('browser-id3-writer') + +class CustomID3Writer extends ID3Writer{ + constructor(buffer){ + super(buffer) + this.separator = undefined + } + + setArrayFrame(frameName, frameValue){ + switch (frameName) { + case 'TPE1': // song artists + case 'TCOM': // song composers + case 'TPE2': // album artist + case 'TCON': { // song genres + if (!Array.isArray(frameValue)) { + throw new Error(`${frameName} frame value should be an array of strings`) + } + + const delemiter = this.separator || (frameName === 'TCON' ? ';' : '/') + const value = frameValue.join(delemiter) + + this._setStringFrame(frameName, value) + break; + } + case 'TXXX': { // user defined text information + if (typeof frameValue !== 'object' || !('description' in frameValue) || !('value' in frameValue)) { + throw new Error('TXXX frame value should be an object with keys description and value'); + } + + if (Array.isArray(frameValue.value)) { + const delemiter = this.separator || '/'; + frameValue.value = frameValue.value.join(delemiter); + } + + this._setUserStringFrame(frameValue.description, frameValue.value); + break; + } + default: { + throw new Error(`Unsupported frame ${frameName} with array value`); + } + } + return this; + } +} + +module.exports = CustomID3Writer