mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-31 10:27:01 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			113 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| const tone = require('node-tone')
 | |
| const fs = require('../libs/fsExtra')
 | |
| const Logger = require('../Logger')
 | |
| 
 | |
| function getToneMetadataObject(libraryItem, chapters, trackTotal, mimeType = null) {
 | |
|   const bookMetadata = libraryItem.media.metadata
 | |
|   const coverPath = libraryItem.media.coverPath
 | |
| 
 | |
|   const isMp4 = mimeType === 'audio/mp4'
 | |
|   const isMp3 = mimeType === 'audio/mpeg'
 | |
| 
 | |
|   const metadataObject = {
 | |
|     'album': bookMetadata.title || '',
 | |
|     'title': bookMetadata.title || '',
 | |
|     'trackTotal': trackTotal,
 | |
|     '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) {
 | |
|     if (!isMp3) {
 | |
|       metadataObject.additionalFields['----:com.pilabor.tone:SERIES'] = bookMetadata.firstSeriesName
 | |
|     }
 | |
|     metadataObject['movementName'] = bookMetadata.firstSeriesName
 | |
|   }
 | |
|   if (bookMetadata.firstSeriesSequence) {
 | |
|     // Non-mp3 
 | |
|     if (!isMp3) {
 | |
|       metadataObject.additionalFields['----:com.pilabor.tone:PART'] = bookMetadata.firstSeriesSequence
 | |
|     }
 | |
|     // MP3 Files with non-integer sequence
 | |
|     const isNonIntegerSequence = String(bookMetadata.firstSeriesSequence).includes('.') || isNaN(bookMetadata.firstSeriesSequence)
 | |
|     if (isMp3 && isNonIntegerSequence) {
 | |
|       metadataObject.additionalFields['PART'] = bookMetadata.firstSeriesSequence
 | |
|     }
 | |
|     if (!isNonIntegerSequence) {
 | |
|       metadataObject['movement'] = bookMetadata.firstSeriesSequence
 | |
|     }
 | |
|   }
 | |
|   if (bookMetadata.genres.length) {
 | |
|     metadataObject['genre'] = bookMetadata.genres.join('/')
 | |
|   }
 | |
|   if (bookMetadata.publisher) {
 | |
|     metadataObject['publisher'] = bookMetadata.publisher
 | |
|   }
 | |
|   if (bookMetadata.asin) {
 | |
|     if (!isMp3) {
 | |
|       metadataObject.additionalFields['----:com.pilabor.tone:AUDIBLE_ASIN'] = bookMetadata.asin
 | |
|     }
 | |
|     if (!isMp4) {
 | |
|       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: Math.round(chapter.start * 1000),
 | |
|         length: Math.round((chapter.end - chapter.start) * 1000),
 | |
|         title: chapter.title,
 | |
|       })
 | |
|     }
 | |
|     metadataObject['chapters'] = metadataChapters
 | |
|   }
 | |
| 
 | |
|   return metadataObject
 | |
| }
 | |
| module.exports.getToneMetadataObject = getToneMetadataObject
 | |
| 
 | |
| module.exports.writeToneMetadataJsonFile = (libraryItem, chapters, filePath, trackTotal, mimeType) => {
 | |
|   const metadataObject = getToneMetadataObject(libraryItem, chapters, trackTotal, mimeType)
 | |
|   return fs.writeFile(filePath, JSON.stringify({ meta: metadataObject }, null, 2))
 | |
| }
 | |
| 
 | |
| module.exports.tagAudioFile = (filePath, payload) => {
 | |
|   if (process.env.TONE_PATH) {
 | |
|     tone.TONE_PATH = process.env.TONE_PATH
 | |
|   }
 | |
| 
 | |
|   return tone.tag(filePath, payload).then((data) => {
 | |
|     return true
 | |
|   }).catch((error) => {
 | |
|     Logger.error(`[toneHelpers] tagAudioFile: Failed for "${filePath}"`, error)
 | |
|     return false
 | |
|   })
 | |
| }
 | |
| 
 | |
| function parsePublishedYear(publishedYear) {
 | |
|   if (isNaN(publishedYear) || !publishedYear || Number(publishedYear) <= 0) return null
 | |
|   return `01/01/${publishedYear}`
 | |
| } |