mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-05-31 04:05:40 -04:00
Update:RSS feeds only use chapter titles for episode titles if all audio tracks match chapter times #2543
This commit is contained in:
parent
399ba314a3
commit
3906dca04e
@ -84,6 +84,24 @@ class Feed {
|
|||||||
return episode.fullPath
|
return episode.fullPath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If chapters for an audiobook match the audio tracks then use chapter titles instead of audio file names
|
||||||
|
*
|
||||||
|
* @param {import('../objects/LibraryItem')} libraryItem
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
checkUseChapterTitlesForEpisodes(libraryItem) {
|
||||||
|
const tracks = libraryItem.media.tracks
|
||||||
|
const chapters = libraryItem.media.chapters
|
||||||
|
if (tracks.length !== chapters.length) return false
|
||||||
|
for (let i = 0; i < tracks.length; i++) {
|
||||||
|
if (Math.abs(chapters[i].start - tracks[i].startOffset) >= 1) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
setFromItem(userId, slug, libraryItem, serverAddress, preventIndexing = true, ownerName = null, ownerEmail = null) {
|
setFromItem(userId, slug, libraryItem, serverAddress, preventIndexing = true, ownerName = null, ownerEmail = null) {
|
||||||
const media = libraryItem.media
|
const media = libraryItem.media
|
||||||
const mediaMetadata = media.metadata
|
const mediaMetadata = media.metadata
|
||||||
@ -128,9 +146,10 @@ class Feed {
|
|||||||
this.episodes.push(feedEpisode)
|
this.episodes.push(feedEpisode)
|
||||||
})
|
})
|
||||||
} else { // AUDIOBOOK EPISODES
|
} else { // AUDIOBOOK EPISODES
|
||||||
|
const useChapterTitles = this.checkUseChapterTitlesForEpisodes(libraryItem)
|
||||||
media.tracks.forEach((audioTrack) => {
|
media.tracks.forEach((audioTrack) => {
|
||||||
const feedEpisode = new FeedEpisode()
|
const feedEpisode = new FeedEpisode()
|
||||||
feedEpisode.setFromAudiobookTrack(libraryItem, serverAddress, slug, audioTrack, this.meta)
|
feedEpisode.setFromAudiobookTrack(libraryItem, serverAddress, slug, audioTrack, this.meta, useChapterTitles)
|
||||||
this.episodes.push(feedEpisode)
|
this.episodes.push(feedEpisode)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -168,9 +187,10 @@ class Feed {
|
|||||||
this.episodes.push(feedEpisode)
|
this.episodes.push(feedEpisode)
|
||||||
})
|
})
|
||||||
} else { // AUDIOBOOK EPISODES
|
} else { // AUDIOBOOK EPISODES
|
||||||
|
const useChapterTitles = this.checkUseChapterTitlesForEpisodes(libraryItem)
|
||||||
media.tracks.forEach((audioTrack) => {
|
media.tracks.forEach((audioTrack) => {
|
||||||
const feedEpisode = new FeedEpisode()
|
const feedEpisode = new FeedEpisode()
|
||||||
feedEpisode.setFromAudiobookTrack(libraryItem, this.serverAddress, this.slug, audioTrack, this.meta)
|
feedEpisode.setFromAudiobookTrack(libraryItem, this.serverAddress, this.slug, audioTrack, this.meta, useChapterTitles)
|
||||||
this.episodes.push(feedEpisode)
|
this.episodes.push(feedEpisode)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -214,9 +234,10 @@ class Feed {
|
|||||||
itemsWithTracks.forEach((item, index) => {
|
itemsWithTracks.forEach((item, index) => {
|
||||||
if (item.updatedAt > this.entityUpdatedAt) this.entityUpdatedAt = item.updatedAt
|
if (item.updatedAt > this.entityUpdatedAt) this.entityUpdatedAt = item.updatedAt
|
||||||
|
|
||||||
|
const useChapterTitles = this.checkUseChapterTitlesForEpisodes(item)
|
||||||
item.media.tracks.forEach((audioTrack) => {
|
item.media.tracks.forEach((audioTrack) => {
|
||||||
const feedEpisode = new FeedEpisode()
|
const feedEpisode = new FeedEpisode()
|
||||||
feedEpisode.setFromAudiobookTrack(item, serverAddress, slug, audioTrack, this.meta, index)
|
feedEpisode.setFromAudiobookTrack(item, serverAddress, slug, audioTrack, this.meta, useChapterTitles, index)
|
||||||
this.episodes.push(feedEpisode)
|
this.episodes.push(feedEpisode)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -245,9 +266,10 @@ class Feed {
|
|||||||
itemsWithTracks.forEach((item, index) => {
|
itemsWithTracks.forEach((item, index) => {
|
||||||
if (item.updatedAt > this.entityUpdatedAt) this.entityUpdatedAt = item.updatedAt
|
if (item.updatedAt > this.entityUpdatedAt) this.entityUpdatedAt = item.updatedAt
|
||||||
|
|
||||||
|
const useChapterTitles = this.checkUseChapterTitlesForEpisodes(item)
|
||||||
item.media.tracks.forEach((audioTrack) => {
|
item.media.tracks.forEach((audioTrack) => {
|
||||||
const feedEpisode = new FeedEpisode()
|
const feedEpisode = new FeedEpisode()
|
||||||
feedEpisode.setFromAudiobookTrack(item, this.serverAddress, this.slug, audioTrack, this.meta, index)
|
feedEpisode.setFromAudiobookTrack(item, this.serverAddress, this.slug, audioTrack, this.meta, useChapterTitles, index)
|
||||||
this.episodes.push(feedEpisode)
|
this.episodes.push(feedEpisode)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -295,9 +317,10 @@ class Feed {
|
|||||||
itemsWithTracks.forEach((item, index) => {
|
itemsWithTracks.forEach((item, index) => {
|
||||||
if (item.updatedAt > this.entityUpdatedAt) this.entityUpdatedAt = item.updatedAt
|
if (item.updatedAt > this.entityUpdatedAt) this.entityUpdatedAt = item.updatedAt
|
||||||
|
|
||||||
|
const useChapterTitles = this.checkUseChapterTitlesForEpisodes(item)
|
||||||
item.media.tracks.forEach((audioTrack) => {
|
item.media.tracks.forEach((audioTrack) => {
|
||||||
const feedEpisode = new FeedEpisode()
|
const feedEpisode = new FeedEpisode()
|
||||||
feedEpisode.setFromAudiobookTrack(item, serverAddress, slug, audioTrack, this.meta, index)
|
feedEpisode.setFromAudiobookTrack(item, serverAddress, slug, audioTrack, this.meta, useChapterTitles, index)
|
||||||
this.episodes.push(feedEpisode)
|
this.episodes.push(feedEpisode)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -329,9 +352,10 @@ class Feed {
|
|||||||
itemsWithTracks.forEach((item, index) => {
|
itemsWithTracks.forEach((item, index) => {
|
||||||
if (item.updatedAt > this.entityUpdatedAt) this.entityUpdatedAt = item.updatedAt
|
if (item.updatedAt > this.entityUpdatedAt) this.entityUpdatedAt = item.updatedAt
|
||||||
|
|
||||||
|
const useChapterTitles = this.checkUseChapterTitlesForEpisodes(item)
|
||||||
item.media.tracks.forEach((audioTrack) => {
|
item.media.tracks.forEach((audioTrack) => {
|
||||||
const feedEpisode = new FeedEpisode()
|
const feedEpisode = new FeedEpisode()
|
||||||
feedEpisode.setFromAudiobookTrack(item, this.serverAddress, this.slug, audioTrack, this.meta, index)
|
feedEpisode.setFromAudiobookTrack(item, this.serverAddress, this.slug, audioTrack, this.meta, useChapterTitles, index)
|
||||||
this.episodes.push(feedEpisode)
|
this.episodes.push(feedEpisode)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -97,7 +97,17 @@ class FeedEpisode {
|
|||||||
this.fullPath = episode.audioFile.metadata.path
|
this.fullPath = episode.audioFile.metadata.path
|
||||||
}
|
}
|
||||||
|
|
||||||
setFromAudiobookTrack(libraryItem, serverAddress, slug, audioTrack, meta, additionalOffset = null) {
|
/**
|
||||||
|
*
|
||||||
|
* @param {import('../objects/LibraryItem')} libraryItem
|
||||||
|
* @param {string} serverAddress
|
||||||
|
* @param {string} slug
|
||||||
|
* @param {import('../objects/files/AudioTrack')} audioTrack
|
||||||
|
* @param {Object} meta
|
||||||
|
* @param {boolean} useChapterTitles
|
||||||
|
* @param {number} [additionalOffset]
|
||||||
|
*/
|
||||||
|
setFromAudiobookTrack(libraryItem, serverAddress, slug, audioTrack, meta, useChapterTitles, additionalOffset = null) {
|
||||||
// Example: <pubDate>Fri, 04 Feb 2015 00:00:00 GMT</pubDate>
|
// Example: <pubDate>Fri, 04 Feb 2015 00:00:00 GMT</pubDate>
|
||||||
let timeOffset = isNaN(audioTrack.index) ? 0 : (Number(audioTrack.index) * 1000) // Offset pubdate to ensure correct order
|
let timeOffset = isNaN(audioTrack.index) ? 0 : (Number(audioTrack.index) * 1000) // Offset pubdate to ensure correct order
|
||||||
let episodeId = uuidv4()
|
let episodeId = uuidv4()
|
||||||
@ -119,10 +129,10 @@ class FeedEpisode {
|
|||||||
if (libraryItem.media.tracks.length == 1) { // If audiobook is a single file, use book title instead of chapter/file title
|
if (libraryItem.media.tracks.length == 1) { // If audiobook is a single file, use book title instead of chapter/file title
|
||||||
title = libraryItem.media.metadata.title
|
title = libraryItem.media.metadata.title
|
||||||
} else {
|
} else {
|
||||||
if (libraryItem.media.chapters.length) {
|
if (useChapterTitles) {
|
||||||
// If audio track start and chapter start are within 1 seconds of eachother then use the chapter title
|
// If audio track start and chapter start are within 1 seconds of eachother then use the chapter title
|
||||||
var matchingChapter = libraryItem.media.chapters.find(ch => Math.abs(ch.start - audioTrack.startOffset) < 1)
|
const matchingChapter = libraryItem.media.chapters.find(ch => Math.abs(ch.start - audioTrack.startOffset) < 1)
|
||||||
if (matchingChapter && matchingChapter.title) title = matchingChapter.title
|
if (matchingChapter?.title) title = matchingChapter.title
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user