Metadata embed and m4b merge fixes and cleanup

This commit is contained in:
advplyr 2022-11-05 13:13:52 -05:00
parent 3824154c15
commit 1118b8b782
5 changed files with 18 additions and 17 deletions

View File

@ -91,6 +91,10 @@
A backup of your original audio files will be stored in <span class="rounded-md bg-neutral-600 text-sm text-white py-0.5 px-1 font-mono">/metadata/cache/items/{{ libraryItemId }}/</span>. Make sure to periodically purge items cache. A backup of your original audio files will be stored in <span class="rounded-md bg-neutral-600 text-sm text-white py-0.5 px-1 font-mono">/metadata/cache/items/{{ libraryItemId }}/</span>. Make sure to periodically purge items cache.
</p> </p>
</div> </div>
<div v-if="selectedTool === 'embed' && audioFiles.length > 1" class="flex items-start mb-2">
<span class="material-icons text-base text-warning pt-1">star</span>
<p class="text-gray-200 ml-2">Chapters are not embedded in multi-track audiobooks.</p>
</div>
<div v-if="selectedTool === 'm4b'" class="flex items-start mb-2"> <div v-if="selectedTool === 'm4b'" class="flex items-start mb-2">
<span class="material-icons text-base text-warning pt-1">star</span> <span class="material-icons text-base text-warning pt-1">star</span>
<p class="text-gray-200 ml-2">Encoding can take up to 30 minutes.</p> <p class="text-gray-200 ml-2">Encoding can take up to 30 minutes.</p>

View File

@ -398,7 +398,8 @@ class LibraryItemController {
} }
const useTone = req.query.tone === '1' 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) res.sendStatus(200)
} }

View File

@ -62,7 +62,7 @@ class AbMergeManager {
targetFilename, targetFilename,
targetFilepath: Path.join(libraryItem.path, targetFilename), targetFilepath: Path.join(libraryItem.path, targetFilename),
itemCachePath, itemCachePath,
toneMetadataObject: null toneJsonObject: null
} }
const taskDescription = `Encoding audiobook "${libraryItem.media.metadata.title}" into a single m4b file.` const taskDescription = `Encoding audiobook "${libraryItem.media.metadata.title}" into a single m4b file.`
task.setData('encode-m4b', 'Encoding M4b', taskDescription, taskData) task.setData('encode-m4b', 'Encoding M4b', taskDescription, taskData)
@ -122,23 +122,18 @@ class AbMergeManager {
var toneJsonPath = null var toneJsonPath = null
try { try {
toneJsonPath = Path.join(itemCacheDir, 'metadata.json') toneJsonPath = Path.join(task.data.itemCachePath, 'metadata.json')
await toneHelpers.writeToneMetadataJsonFile(libraryItem, libraryItem.media.chapters, toneJsonPath) await toneHelpers.writeToneMetadataJsonFile(libraryItem, libraryItem.media.chapters, toneJsonPath, 1)
} catch (error) { } catch (error) {
Logger.error(`[AudioMetadataManager] Write metadata.json failed`, error) Logger.error(`[AbMergeManager] Write metadata.json failed`, error)
toneJsonPath = null toneJsonPath = null
} }
const toneMetadataObject = toneHelpers.getToneMetadataObject(libraryItem, chaptersFilePath)
toneMetadataObject.TrackNumber = 1
task.data.toneMetadataObject = toneMetadataObject
task.data.toneJsonObject = { task.data.toneJsonObject = {
'ToneJsonFile': toneJsonPath, 'ToneJsonFile': toneJsonPath,
'TrackNumber': 1, 'TrackNumber': 1,
} }
Logger.debug(`[AbMergeManager] Book "${libraryItem.media.metadata.title}" tone metadata object=`, toneMetadataObject)
var workerData = { var workerData = {
inputs: ffmpegInputs, inputs: ffmpegInputs,
options: ffmpegOptions, options: ffmpegOptions,

View File

@ -15,9 +15,9 @@ class AudioMetadataMangaer {
this.clientEmitter = clientEmitter this.clientEmitter = clientEmitter
} }
updateMetadataForItem(user, libraryItem, useTone = true) { updateMetadataForItem(user, libraryItem, useTone, forceEmbedChapters) {
if (useTone) { if (useTone) {
this.updateMetadataForItemWithTone(user, libraryItem) this.updateMetadataForItemWithTone(user, libraryItem, forceEmbedChapters)
} else { } else {
this.updateMetadataForItemWithFfmpeg(user, libraryItem) this.updateMetadataForItemWithFfmpeg(user, libraryItem)
} }
@ -30,7 +30,7 @@ class AudioMetadataMangaer {
return toneHelpers.getToneMetadataObject(libraryItem) return toneHelpers.getToneMetadataObject(libraryItem)
} }
async updateMetadataForItemWithTone(user, libraryItem) { async updateMetadataForItemWithTone(user, libraryItem, forceEmbedChapters) {
var audioFiles = libraryItem.media.includedAudioFiles var audioFiles = libraryItem.media.includedAudioFiles
const itemAudioMetadataPayload = { const itemAudioMetadataPayload = {
@ -49,7 +49,8 @@ class AudioMetadataMangaer {
try { try {
toneJsonPath = Path.join(itemCacheDir, 'metadata.json') 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) { } catch (error) {
Logger.error(`[AudioMetadataManager] Write metadata.json failed`, error) Logger.error(`[AudioMetadataManager] Write metadata.json failed`, error)
toneJsonPath = null toneJsonPath = null

View File

@ -72,14 +72,14 @@ module.exports.getToneMetadataObject = (libraryItem, chaptersFile) => {
return metadataObject return metadataObject
} }
module.exports.writeToneMetadataJsonFile = (libraryItem, chapters, filePath) => { module.exports.writeToneMetadataJsonFile = (libraryItem, chapters, filePath, trackTotal) => {
const bookMetadata = libraryItem.media.metadata const bookMetadata = libraryItem.media.metadata
const coverPath = libraryItem.media.coverPath const coverPath = libraryItem.media.coverPath
const metadataObject = { const metadataObject = {
'album': bookMetadata.title || '', 'album': bookMetadata.title || '',
'title': bookMetadata.title || '', 'title': bookMetadata.title || '',
'trackTotal': libraryItem.media.tracks.length, 'trackTotal': trackTotal,
'additionalFields': {} 'additionalFields': {}
} }
if (bookMetadata.subtitle) { if (bookMetadata.subtitle) {
@ -133,7 +133,7 @@ module.exports.writeToneMetadataJsonFile = (libraryItem, chapters, filePath) =>
metadataObject['chapters'] = metadataChapters 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) => { module.exports.tagAudioFile = (filePath, payload) => {