mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-07-23 04:14:46 +02:00
Update scanner, music meta tags and fix issue with force update
This commit is contained in:
parent
5410aae8fc
commit
9de7be1cb4
11 changed files with 388 additions and 110 deletions
|
@ -4,13 +4,31 @@ const { areEquivalent, copyValue, cleanStringForSearch, getTitleIgnorePrefix, ge
|
|||
class MusicMetadata {
|
||||
constructor(metadata) {
|
||||
this.title = null
|
||||
this.artist = null
|
||||
this.artists = [] // Array of strings
|
||||
this.album = null
|
||||
this.albumArtist = null
|
||||
this.genres = [] // Array of strings
|
||||
this.composer = null
|
||||
this.originalYear = null
|
||||
this.releaseDate = null
|
||||
this.releaseCountry = null
|
||||
this.releaseType = null
|
||||
this.releaseStatus = null
|
||||
this.recordLabel = null
|
||||
this.language = null
|
||||
this.explicit = false
|
||||
|
||||
this.discNumber = null
|
||||
this.discTotal = null
|
||||
this.trackNumber = null
|
||||
this.trackTotal = null
|
||||
|
||||
this.isrc = null
|
||||
this.musicBrainzTrackId = null
|
||||
this.musicBrainzAlbumId = null
|
||||
this.musicBrainzAlbumArtistId = null
|
||||
this.musicBrainzArtistId = null
|
||||
|
||||
if (metadata) {
|
||||
this.construct(metadata)
|
||||
}
|
||||
|
@ -18,23 +36,55 @@ class MusicMetadata {
|
|||
|
||||
construct(metadata) {
|
||||
this.title = metadata.title
|
||||
this.artist = metadata.artist
|
||||
this.artists = metadata.artists ? [...metadata.artists] : []
|
||||
this.album = metadata.album
|
||||
this.albumArtist = metadata.albumArtist
|
||||
this.genres = metadata.genres ? [...metadata.genres] : []
|
||||
this.composer = metadata.composer || null
|
||||
this.originalYear = metadata.originalYear || null
|
||||
this.releaseDate = metadata.releaseDate || null
|
||||
this.language = metadata.language
|
||||
this.releaseCountry = metadata.releaseCountry || null
|
||||
this.releaseType = metadata.releaseType || null
|
||||
this.releaseStatus = metadata.releaseStatus || null
|
||||
this.recordLabel = metadata.recordLabel || null
|
||||
this.language = metadata.language || null
|
||||
this.explicit = !!metadata.explicit
|
||||
this.discNumber = metadata.discNumber || null
|
||||
this.discTotal = metadata.discTotal || null
|
||||
this.trackNumber = metadata.trackNumber || null
|
||||
this.trackTotal = metadata.trackTotal || null
|
||||
this.isrc = metadata.isrc || null
|
||||
this.musicBrainzTrackId = metadata.musicBrainzTrackId || null
|
||||
this.musicBrainzAlbumId = metadata.musicBrainzAlbumId || null
|
||||
this.musicBrainzAlbumArtistId = metadata.musicBrainzAlbumArtistId || null
|
||||
this.musicBrainzArtistId = metadata.musicBrainzArtistId || null
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
title: this.title,
|
||||
artist: this.artist,
|
||||
artists: [...this.artists],
|
||||
album: this.album,
|
||||
albumArtist: this.albumArtist,
|
||||
genres: [...this.genres],
|
||||
composer: this.composer,
|
||||
originalYear: this.originalYear,
|
||||
releaseDate: this.releaseDate,
|
||||
releaseCountry: this.releaseCountry,
|
||||
releaseType: this.releaseType,
|
||||
releaseStatus: this.releaseStatus,
|
||||
recordLabel: this.recordLabel,
|
||||
language: this.language,
|
||||
explicit: this.explicit
|
||||
explicit: this.explicit,
|
||||
discNumber: this.discNumber,
|
||||
discTotal: this.discTotal,
|
||||
trackNumber: this.trackNumber,
|
||||
trackTotal: this.trackTotal,
|
||||
isrc: this.isrc,
|
||||
musicBrainzTrackId: this.musicBrainzTrackId,
|
||||
musicBrainzAlbumId: this.musicBrainzAlbumId,
|
||||
musicBrainzAlbumArtistId: this.musicBrainzAlbumArtistId,
|
||||
musicBrainzArtistId: this.musicBrainzArtistId
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,12 +92,28 @@ class MusicMetadata {
|
|||
return {
|
||||
title: this.title,
|
||||
titleIgnorePrefix: this.titlePrefixAtEnd,
|
||||
artist: this.artist,
|
||||
artists: [...this.artists],
|
||||
album: this.album,
|
||||
albumArtist: this.albumArtist,
|
||||
genres: [...this.genres],
|
||||
composer: this.composer,
|
||||
originalYear: this.originalYear,
|
||||
releaseDate: this.releaseDate,
|
||||
releaseCountry: this.releaseCountry,
|
||||
releaseType: this.releaseType,
|
||||
releaseStatus: this.releaseStatus,
|
||||
recordLabel: this.recordLabel,
|
||||
language: this.language,
|
||||
explicit: this.explicit
|
||||
explicit: this.explicit,
|
||||
discNumber: this.discNumber,
|
||||
discTotal: this.discTotal,
|
||||
trackNumber: this.trackNumber,
|
||||
trackTotal: this.trackTotal,
|
||||
isrc: this.isrc,
|
||||
musicBrainzTrackId: this.musicBrainzTrackId,
|
||||
musicBrainzAlbumId: this.musicBrainzAlbumId,
|
||||
musicBrainzAlbumArtistId: this.musicBrainzAlbumArtistId,
|
||||
musicBrainzArtistId: this.musicBrainzArtistId
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,7 +134,7 @@ class MusicMetadata {
|
|||
}
|
||||
|
||||
searchQuery(query) { // Returns key if match is found
|
||||
const keysToCheck = ['title', 'artist', 'album']
|
||||
const keysToCheck = ['title', 'album']
|
||||
for (const key of keysToCheck) {
|
||||
if (this[key] && cleanStringForSearch(String(this[key])).includes(query)) {
|
||||
return {
|
||||
|
@ -100,5 +166,154 @@ class MusicMetadata {
|
|||
}
|
||||
return hasUpdates
|
||||
}
|
||||
|
||||
parseArtistsTag(artistsTag) {
|
||||
if (!artistsTag || !artistsTag.length) return []
|
||||
const separators = ['/', '//', ';']
|
||||
for (let i = 0; i < separators.length; i++) {
|
||||
if (artistsTag.includes(separators[i])) {
|
||||
return artistsTag.split(separators[i]).map(artist => artist.trim()).filter(a => !!a)
|
||||
}
|
||||
}
|
||||
return [artistsTag]
|
||||
}
|
||||
|
||||
parseGenresTag(genreTag) {
|
||||
if (!genreTag || !genreTag.length) return []
|
||||
const separators = ['/', '//', ';']
|
||||
for (let i = 0; i < separators.length; i++) {
|
||||
if (genreTag.includes(separators[i])) {
|
||||
return genreTag.split(separators[i]).map(genre => genre.trim()).filter(g => !!g)
|
||||
}
|
||||
}
|
||||
return [genreTag]
|
||||
}
|
||||
|
||||
setDataFromAudioMetaTags(audioFileMetaTags, overrideExistingDetails = false) {
|
||||
const MetadataMapArray = [
|
||||
{
|
||||
tag: 'tagTitle',
|
||||
key: 'title',
|
||||
},
|
||||
{
|
||||
tag: 'tagArtist',
|
||||
key: 'artists'
|
||||
},
|
||||
{
|
||||
tag: 'tagAlbumArtist',
|
||||
key: 'albumArtist'
|
||||
},
|
||||
{
|
||||
tag: 'tagAlbum',
|
||||
key: 'album',
|
||||
},
|
||||
{
|
||||
tag: 'tagPublisher',
|
||||
key: 'recordLabel'
|
||||
},
|
||||
{
|
||||
tag: 'tagComposer',
|
||||
key: 'composer'
|
||||
},
|
||||
{
|
||||
tag: 'tagDate',
|
||||
key: 'releaseDate'
|
||||
},
|
||||
{
|
||||
tag: 'tagReleaseCountry',
|
||||
key: 'releaseCountry'
|
||||
},
|
||||
{
|
||||
tag: 'tagReleaseType',
|
||||
key: 'releaseType'
|
||||
},
|
||||
{
|
||||
tag: 'tagReleaseStatus',
|
||||
key: 'releaseStatus'
|
||||
},
|
||||
{
|
||||
tag: 'tagOriginalYear',
|
||||
key: 'originalYear'
|
||||
},
|
||||
{
|
||||
tag: 'tagGenre',
|
||||
key: 'genres'
|
||||
},
|
||||
{
|
||||
tag: 'tagLanguage',
|
||||
key: 'language'
|
||||
},
|
||||
{
|
||||
tag: 'tagLanguage',
|
||||
key: 'language'
|
||||
},
|
||||
{
|
||||
tag: 'tagISRC',
|
||||
key: 'isrc'
|
||||
},
|
||||
{
|
||||
tag: 'tagMusicBrainzTrackId',
|
||||
key: 'musicBrainzTrackId'
|
||||
},
|
||||
{
|
||||
tag: 'tagMusicBrainzAlbumId',
|
||||
key: 'musicBrainzAlbumId'
|
||||
},
|
||||
{
|
||||
tag: 'tagMusicBrainzAlbumArtistId',
|
||||
key: 'musicBrainzAlbumArtistId'
|
||||
},
|
||||
{
|
||||
tag: 'tagMusicBrainzArtistId',
|
||||
key: 'musicBrainzArtistId'
|
||||
},
|
||||
{
|
||||
tag: 'trackNumber',
|
||||
key: 'trackNumber'
|
||||
},
|
||||
{
|
||||
tag: 'trackTotal',
|
||||
key: 'trackTotal'
|
||||
},
|
||||
{
|
||||
tag: 'discNumber',
|
||||
key: 'discNumber'
|
||||
},
|
||||
{
|
||||
tag: 'discTotal',
|
||||
key: 'discTotal'
|
||||
}
|
||||
]
|
||||
|
||||
const updatePayload = {}
|
||||
|
||||
// Metadata is only mapped to the music track if it is empty
|
||||
MetadataMapArray.forEach((mapping) => {
|
||||
let value = audioFileMetaTags[mapping.tag]
|
||||
// let tagToUse = mapping.tag
|
||||
if (!value && mapping.altTag) {
|
||||
value = audioFileMetaTags[mapping.altTag]
|
||||
// tagToUse = mapping.altTag
|
||||
}
|
||||
|
||||
if (value && typeof value === 'string') {
|
||||
value = value.trim() // Trim whitespace
|
||||
|
||||
if (mapping.key === 'artists' && (!this.artists.length || overrideExistingDetails)) {
|
||||
updatePayload.artists = this.parseArtistsTag(value)
|
||||
} else if (mapping.key === 'genres' && (!this.genres.length || overrideExistingDetails)) {
|
||||
updatePayload.genres = this.parseGenresTag(value)
|
||||
} else if (!this[mapping.key] || overrideExistingDetails) {
|
||||
updatePayload[mapping.key] = value
|
||||
// Logger.debug(`[Book] Mapping metadata to key ${tagToUse} => ${mapping.key}: ${updatePayload[mapping.key]}`)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if (Object.keys(updatePayload).length) {
|
||||
return this.update(updatePayload)
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
module.exports = MusicMetadata
|
Loading…
Add table
Add a link
Reference in a new issue