diff --git a/client/pages/audiobook/_id/manage.vue b/client/pages/audiobook/_id/manage.vue index 9f858a81..a45979dc 100644 --- a/client/pages/audiobook/_id/manage.vue +++ b/client/pages/audiobook/_id/manage.vue @@ -91,6 +91,10 @@ A backup of your original audio files will be stored in /metadata/cache/items/{{ libraryItemId }}/. Make sure to periodically purge items cache.
+Chapters are not embedded in multi-track audiobooks.
+Encoding can take up to 30 minutes.
diff --git a/server/controllers/LibraryItemController.js b/server/controllers/LibraryItemController.js index b1f3f77d..56b181c2 100644 --- a/server/controllers/LibraryItemController.js +++ b/server/controllers/LibraryItemController.js @@ -398,7 +398,8 @@ class LibraryItemController { } const useTone = req.query.tone === '1' - this.audioMetadataManager.updateMetadataForItem(req.user, req.libraryItem, useTone) + const forceEmbedChapters = req.query.forceEmbedChapters === '1' + this.audioMetadataManager.updateMetadataForItem(req.user, req.libraryItem, useTone, forceEmbedChapters) res.sendStatus(200) } diff --git a/server/managers/AbMergeManager.js b/server/managers/AbMergeManager.js index 0bc89be3..72343d50 100644 --- a/server/managers/AbMergeManager.js +++ b/server/managers/AbMergeManager.js @@ -62,7 +62,7 @@ class AbMergeManager { targetFilename, targetFilepath: Path.join(libraryItem.path, targetFilename), itemCachePath, - toneMetadataObject: null + toneJsonObject: null } const taskDescription = `Encoding audiobook "${libraryItem.media.metadata.title}" into a single m4b file.` task.setData('encode-m4b', 'Encoding M4b', taskDescription, taskData) @@ -122,23 +122,18 @@ class AbMergeManager { var toneJsonPath = null try { - toneJsonPath = Path.join(itemCacheDir, 'metadata.json') - await toneHelpers.writeToneMetadataJsonFile(libraryItem, libraryItem.media.chapters, toneJsonPath) + toneJsonPath = Path.join(task.data.itemCachePath, 'metadata.json') + await toneHelpers.writeToneMetadataJsonFile(libraryItem, libraryItem.media.chapters, toneJsonPath, 1) } catch (error) { - Logger.error(`[AudioMetadataManager] Write metadata.json failed`, error) + Logger.error(`[AbMergeManager] 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) - var workerData = { inputs: ffmpegInputs, options: ffmpegOptions, diff --git a/server/managers/AudioMetadataManager.js b/server/managers/AudioMetadataManager.js index c76e3fe2..25a93583 100644 --- a/server/managers/AudioMetadataManager.js +++ b/server/managers/AudioMetadataManager.js @@ -15,9 +15,9 @@ class AudioMetadataMangaer { this.clientEmitter = clientEmitter } - updateMetadataForItem(user, libraryItem, useTone = true) { + updateMetadataForItem(user, libraryItem, useTone, forceEmbedChapters) { if (useTone) { - this.updateMetadataForItemWithTone(user, libraryItem) + this.updateMetadataForItemWithTone(user, libraryItem, forceEmbedChapters) } else { this.updateMetadataForItemWithFfmpeg(user, libraryItem) } @@ -30,7 +30,7 @@ class AudioMetadataMangaer { return toneHelpers.getToneMetadataObject(libraryItem) } - async updateMetadataForItemWithTone(user, libraryItem) { + async updateMetadataForItemWithTone(user, libraryItem, forceEmbedChapters) { var audioFiles = libraryItem.media.includedAudioFiles const itemAudioMetadataPayload = { @@ -49,7 +49,8 @@ class AudioMetadataMangaer { try { toneJsonPath = Path.join(itemCacheDir, 'metadata.json') - await toneHelpers.writeToneMetadataJsonFile(libraryItem, audioFiles.length == 1 && libraryItem.media.chapters, toneJsonPath) + const chapters = (audioFiles.length == 1 || forceEmbedChapters) ? libraryItem.media.chapters : null + await toneHelpers.writeToneMetadataJsonFile(libraryItem, chapters, toneJsonPath, audioFiles.length) } catch (error) { Logger.error(`[AudioMetadataManager] Write metadata.json failed`, error) toneJsonPath = null diff --git a/server/utils/toneHelpers.js b/server/utils/toneHelpers.js index fcdd1440..dac6fa40 100644 --- a/server/utils/toneHelpers.js +++ b/server/utils/toneHelpers.js @@ -72,14 +72,14 @@ module.exports.getToneMetadataObject = (libraryItem, chaptersFile) => { return metadataObject } -module.exports.writeToneMetadataJsonFile = (libraryItem, chapters, filePath) => { +module.exports.writeToneMetadataJsonFile = (libraryItem, chapters, filePath, trackTotal) => { const bookMetadata = libraryItem.media.metadata const coverPath = libraryItem.media.coverPath const metadataObject = { 'album': bookMetadata.title || '', 'title': bookMetadata.title || '', - 'trackTotal': libraryItem.media.tracks.length, + 'trackTotal': trackTotal, 'additionalFields': {} } if (bookMetadata.subtitle) { @@ -133,7 +133,7 @@ module.exports.writeToneMetadataJsonFile = (libraryItem, chapters, filePath) => metadataObject['chapters'] = metadataChapters } - return fs.writeFile(filePath, JSON.stringify({ meta: metadataObject })) + return fs.writeFile(filePath, JSON.stringify({ meta: metadataObject }, null, 2)) } module.exports.tagAudioFile = (filePath, payload) => {