mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-02-28 21:19:42 +00:00
Add series metadata tags to FFmpeg encoding
This commit is contained in:
parent
e7a980d55a
commit
cbd63de17d
1 changed files with 44 additions and 1 deletions
|
|
@ -392,6 +392,34 @@ function escapeFFMetadataValue(value) {
|
|||
return value.replace(/([;=\n\\#])/g, '\\$1')
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the ALBUMSORT tag for proper series ordering.
|
||||
* Format:
|
||||
* - No series: "Title" or "Title - Subtitle"
|
||||
* - In series: "Series Name 001 - Title" (zero-padded sequence)
|
||||
*
|
||||
* @param {import('../models/LibraryItem')} libraryItem
|
||||
* @returns {string}
|
||||
*/
|
||||
function computeAlbumSort(libraryItem) {
|
||||
const title = libraryItem.media.title || ''
|
||||
const subtitle = libraryItem.media.subtitle
|
||||
const series = libraryItem.media.series?.[0]
|
||||
|
||||
if (series?.name) {
|
||||
// In series: "Series Name 001 - Title"
|
||||
const sequence = series.bookSeries?.sequence || ''
|
||||
const paddedSequence = sequence ? String(sequence).padStart(3, '0') : ''
|
||||
return `${series.name} ${paddedSequence} - ${title}`.trim()
|
||||
}
|
||||
|
||||
// Not in series: "Title" or "Title - Subtitle"
|
||||
if (subtitle) {
|
||||
return `${title} - ${subtitle}`
|
||||
}
|
||||
return title
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the FFmpeg metadata object for a given library item.
|
||||
*
|
||||
|
|
@ -408,6 +436,11 @@ function getFFMetadataObject(libraryItem, audioFilesLength) {
|
|||
format = 'unabridged'
|
||||
}
|
||||
|
||||
// Get first series for series tags (multiple series not widely supported)
|
||||
const primarySeries = libraryItem.media.series?.[0]
|
||||
const seriesName = primarySeries?.name
|
||||
const seriesSequence = primarySeries?.bookSeries?.sequence
|
||||
|
||||
const ffmetadata = {
|
||||
title: libraryItem.media.title,
|
||||
artist: libraryItem.media.authorName,
|
||||
|
|
@ -431,7 +464,17 @@ function getFFMetadataObject(libraryItem, audioFilesLength) {
|
|||
LANGUAGE: libraryItem.media.language,
|
||||
EXPLICIT: libraryItem.media.explicit ? '1' : null,
|
||||
ITUNESADVISORY: libraryItem.media.explicit ? '1' : '2', // 1 = explicit, 2 = clean
|
||||
FORMAT: format
|
||||
FORMAT: format,
|
||||
// Series tags (Mp3tag standard)
|
||||
SERIES: seriesName,
|
||||
'SERIES-PART': seriesSequence,
|
||||
PART: seriesSequence, // Libation uses PART
|
||||
// M4B-specific series tags
|
||||
MOVEMENTNAME: seriesName,
|
||||
MOVEMENT: seriesSequence,
|
||||
SHOWMOVEMENT: seriesName ? '1' : null,
|
||||
// Album sort for proper series ordering
|
||||
ALBUMSORT: computeAlbumSort(libraryItem)
|
||||
}
|
||||
Object.keys(ffmetadata).forEach((key) => {
|
||||
if (!ffmetadata[key]) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue