From c1938f78c24feff8d81cf7bb4b7c17a714d8ad79 Mon Sep 17 00:00:00 2001 From: Keagan Hilliard Date: Wed, 2 Nov 2022 19:40:50 -0600 Subject: [PATCH] Added json file support --- server/managers/AbMergeManager.js | 22 +++++---- server/managers/AudioMetadataManager.js | 25 ++++------ server/utils/toneHelpers.js | 65 +++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 25 deletions(-) diff --git a/server/managers/AbMergeManager.js b/server/managers/AbMergeManager.js index 1b3801c0..25e571e2 100644 --- a/server/managers/AbMergeManager.js +++ b/server/managers/AbMergeManager.js @@ -120,20 +120,22 @@ class AbMergeManager { } } - var chaptersFilePath = null - if (libraryItem.media.chapters.length) { - chaptersFilePath = Path.join(task.data.itemCachePath, 'chapters.txt') - try { - await toneHelpers.writeToneChaptersFile(libraryItem.media.chapters, chaptersFilePath) - } catch (error) { - Logger.error(`[AbMergeManager] Write chapters.txt failed`, error) - chaptersFilePath = null - } + var toneJsonPath = null + try { + toneJsonPath = Path.join(itemCacheDir, 'metadata.json') + await toneHelpers.writeToneMetadataJsonFile(libraryItem, toneJsonPath) + } catch (error) { + Logger.error(`[AudioMetadataManager] Write metadata.json failed`, error) + toneJsonPath = null } const toneMetadataObject = toneHelpers.getToneMetadataObject(libraryItem, chaptersFilePath) toneMetadataObject.TrackNumber = 1 task.data.toneMetadataObject = toneMetadataObject + task.data.toneJsonObject = { + 'ToneJsonFile': toneJsonPath, + 'TrackNumber': 1, + } Logger.debug(`[AbMergeManager] Book "${libraryItem.media.metadata.title}" tone metadata object=`, toneMetadataObject) @@ -190,7 +192,7 @@ class AbMergeManager { } // Write metadata to merged file - const success = await toneHelpers.tagAudioFile(task.data.tempFilepath, task.data.toneMetadataObject) + const success = await toneHelpers.tagAudioFile(task.data.tempFilepath, task.data.toneJsonObject) if (!success) { Logger.error(`[AbMergeManager] Failed to write metadata to file "${task.data.tempFilepath}"`) task.setFailed('Failed to write metadata to m4b file') diff --git a/server/managers/AudioMetadataManager.js b/server/managers/AudioMetadataManager.js index 02a44ce1..bcf51aed 100644 --- a/server/managers/AudioMetadataManager.js +++ b/server/managers/AudioMetadataManager.js @@ -43,23 +43,18 @@ class AudioMetadataMangaer { this.emitter('audio_metadata_started', itemAudioMetadataPayload) // Write chapters file - var chaptersFilePath = null + var toneJsonPath = null const itemCacheDir = Path.join(global.MetadataPath, `cache/items/${libraryItem.id}`) await fs.ensureDir(itemCacheDir) - if (libraryItem.media.chapters.length) { - chaptersFilePath = Path.join(itemCacheDir, 'chapters.txt') - try { - await toneHelpers.writeToneChaptersFile(libraryItem.media.chapters, chaptersFilePath) - } catch (error) { - Logger.error(`[AudioMetadataManager] Write chapters.txt failed`, error) - chaptersFilePath = null - } + try { + toneJsonPath = Path.join(itemCacheDir, 'metadata.json') + await toneHelpers.writeToneMetadataJsonFile(libraryItem, toneJsonPath) + } catch (error) { + Logger.error(`[AudioMetadataManager] Write metadata.json failed`, error) + toneJsonPath = null } - const toneMetadataObject = toneHelpers.getToneMetadataObject(libraryItem, chaptersFilePath) - Logger.debug(`[AudioMetadataManager] Book "${libraryItem.media.metadata.title}" tone metadata object=`, toneMetadataObject) - const results = [] for (const af of audioFiles) { const result = await this.updateAudioFileMetadataWithTone(libraryItem.id, af, toneMetadataObject, itemCacheDir) @@ -74,7 +69,7 @@ class AudioMetadataMangaer { this.emitter('audio_metadata_finished', itemAudioMetadataPayload) } - async updateAudioFileMetadataWithTone(libraryItemId, audioFile, toneMetadataObject, itemCacheDir) { + async updateAudioFileMetadataWithTone(libraryItemId, audioFile, toneJsonPath, itemCacheDir) { const resultPayload = { libraryItemId, index: audioFile.index, @@ -93,8 +88,8 @@ class AudioMetadataMangaer { } const _toneMetadataObject = { - ...toneMetadataObject, - 'TrackNumber': audioFile.index + 'ToneJsonFile': toneJsonPath, + 'TrackNumber': audioFile.index, } resultPayload.success = await toneHelpers.tagAudioFile(audioFile.metadata.path, _toneMetadataObject) diff --git a/server/utils/toneHelpers.js b/server/utils/toneHelpers.js index fc88c169..54add6bd 100644 --- a/server/utils/toneHelpers.js +++ b/server/utils/toneHelpers.js @@ -72,6 +72,71 @@ module.exports.getToneMetadataObject = (libraryItem, chaptersFile) => { return metadataObject } +module.exports.writeToneMetadataJsonFile = (libraryItem, filePath) => { + const bookMetadata = libraryItem.media.metadata + const coverPath = libraryItem.media.coverPath + const chapters = libraryItem.media.chapters + + const metadataObject = { + 'album': bookMetadata.title || '', + 'title': bookMetadata.title || '', + 'trackTotal': libraryItem.media.tracks.length, + 'additionalFields': {} + } + if (bookMetadata.subtitle) { + metadataObject['subtitle'] = bookMetadata.subtitle + } + if (bookMetadata.authorName) { + metadataObject['artist'] = bookMetadata.authorName + metadataObject['albumArtist'] = bookMetadata.authorName + } + if (bookMetadata.description) { + metadataObject['comment'] = bookMetadata.description + metadataObject['description'] = bookMetadata.description + } + if (bookMetadata.narratorName) { + metadataObject['narrator'] = bookMetadata.narratorName + metadataObject['composer'] = bookMetadata.narratorName + } + if (bookMetadata.firstSeriesName) { + metadataObject['movementName'] = bookMetadata.firstSeriesName + } + if (bookMetadata.firstSeriesSequence) { + metadataObject['movement'] = bookMetadata.firstSeriesSequence + } + if (bookMetadata.genres.length) { + metadataObject['genre'] = bookMetadata.genres.join('/') + } + if (bookMetadata.publisher) { + metadataObject['publisher'] = bookMetadata.publisher + } + if (bookMetadata.asin) { + metadataObject.additionalFields['asin'] = bookMetadata.asin + } + if (bookMetadata.isbn) { + metadataObject.additionalFields['isbn'] = bookMetadata.isbn + } + if (coverPath) { + metadataObject['coverFile'] = coverPath + } + if (parsePublishedYear(bookMetadata.publishedYear)) { + metadataObject['publishingDate'] = parsePublishedYear(bookMetadata.publishedYear) + } + if (chapters && chapters.length > 0) { + let metadataChapters = [] + for (const chapter of chapters) { + metadataChapters.push({ + start: chapter.start, + length: chapter.end - chapter.start, + title: chapter.title, + }) + } + metadataObject['chapters'] = chaptersFile + } + + return fs.writeFile(filePath, JSON.stringify({ metadata: metadataObject })) +} + module.exports.tagAudioFile = (filePath, payload) => { return tone.tag(filePath, payload).then((data) => { return true