mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-03-01 05:29:41 +00:00
feat: Embed AUDIBLE_ASIN metadata in m4b files
- Add AUDIBLE_ASIN tag to FFmpeg metadata object - Use -movflags use_metadata_tags to preserve custom tags in mp4/m4b - Fix .m4b extension detection for mp4 format handling - Remove redundant -map_metadata 0 option - Update tests to match new FFmpeg options The mp4 muxer in FFmpeg only writes standard iTunes tags by default. Custom tags like AUDIBLE_ASIN are silently dropped unless use_metadata_tags is specified. Tested and verified with ffprobe and mediainfo on clean m4b files.
This commit is contained in:
parent
fadd14484e
commit
194f0189fc
2 changed files with 13 additions and 12 deletions
|
|
@ -295,19 +295,18 @@ module.exports.writeFFMetadataFile = writeFFMetadataFile
|
|||
* @returns {Promise<void>} A promise that resolves if the operation is successful, rejects otherwise.
|
||||
*/
|
||||
async function addCoverAndMetadataToFile(audioFilePath, coverFilePath, metadataFilePath, track, mimeType, progressCB = null, ffmpeg = Ffmpeg(), copyFunc = copyToExisting) {
|
||||
const isMp4 = mimeType === 'audio/mp4'
|
||||
const isMp3 = mimeType === 'audio/mpeg'
|
||||
|
||||
const audioFileDir = Path.dirname(audioFilePath)
|
||||
const audioFileExt = Path.extname(audioFilePath)
|
||||
const audioFileBaseName = Path.basename(audioFilePath, audioFileExt)
|
||||
const tempFilePath = filePathToPOSIX(Path.join(audioFileDir, `${audioFileBaseName}.tmp${audioFileExt}`))
|
||||
|
||||
const isMp4 = mimeType === 'audio/mp4' || audioFileExt.toLowerCase() === '.m4b'
|
||||
const isMp3 = mimeType === 'audio/mpeg'
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
ffmpeg.input(audioFilePath).input(metadataFilePath).outputOptions([
|
||||
'-map 0:a', // map audio stream from input file
|
||||
'-map_metadata 1', // map metadata tags from metadata file first
|
||||
'-map_metadata 0', // add additional metadata tags from input file
|
||||
'-map_metadata 1', // map metadata tags from metadata file (contains all desired metadata)
|
||||
'-map_chapters 1', // map chapters from metadata file
|
||||
'-c copy' // copy streams
|
||||
])
|
||||
|
|
@ -318,7 +317,8 @@ async function addCoverAndMetadataToFile(audioFilePath, coverFilePath, metadataF
|
|||
|
||||
if (isMp4) {
|
||||
ffmpeg.outputOptions([
|
||||
'-f mp4' // force output format to mp4
|
||||
'-f mp4', // force output format to mp4
|
||||
'-movflags use_metadata_tags' // preserve custom tags like AUDIBLE_ASIN
|
||||
])
|
||||
} else if (isMp3) {
|
||||
ffmpeg.outputOptions([
|
||||
|
|
@ -414,7 +414,8 @@ function getFFMetadataObject(libraryItem, audioFilesLength) {
|
|||
copyright: libraryItem.media.publisher,
|
||||
publisher: libraryItem.media.publisher, // mp3 only
|
||||
TRACKTOTAL: `${audioFilesLength}`, // mp3 only
|
||||
grouping: libraryItem.media.series?.map((s) => s.name + (s.bookSeries.sequence ? ` #${s.bookSeries.sequence}` : '')).join('; ')
|
||||
grouping: libraryItem.media.series?.map((s) => s.name + (s.bookSeries.sequence ? ` #${s.bookSeries.sequence}` : '')).join('; '),
|
||||
AUDIBLE_ASIN: libraryItem.media.asin // Audible ASIN tag for m4b/mp4 files
|
||||
}
|
||||
Object.keys(ffmetadata).forEach((key) => {
|
||||
if (!ffmetadata[key]) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue