mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-08-02 09:14:40 +02:00
Update scanner, music meta tags and fix issue with force update
This commit is contained in:
parent
5410aae8fc
commit
9de7be1cb4
11 changed files with 388 additions and 110 deletions
|
@ -73,7 +73,7 @@ function tryGrabChannelLayout(stream) {
|
|||
function tryGrabTags(stream, ...tags) {
|
||||
if (!stream.tags) return null
|
||||
for (let i = 0; i < tags.length; i++) {
|
||||
var value = stream.tags[tags[i]] || stream.tags[tags[i].toUpperCase()]
|
||||
const value = stream.tags[tags[i]] || stream.tags[tags[i].toUpperCase()]
|
||||
if (value && value.trim()) return value.trim()
|
||||
}
|
||||
return null
|
||||
|
@ -182,6 +182,15 @@ function parseTags(format, verbose) {
|
|||
file_tag_isbn: tryGrabTags(format, 'isbn'),
|
||||
file_tag_language: tryGrabTags(format, 'language', 'lang'),
|
||||
file_tag_asin: tryGrabTags(format, 'asin'),
|
||||
file_tag_originalyear: tryGrabTags(format, 'originalyear'),
|
||||
file_tag_releasecountry: tryGrabTags(format, 'MusicBrainz Album Release Country', 'releasecountry'),
|
||||
file_tag_releasestatus: tryGrabTags(format, 'MusicBrainz Album Status', 'releasestatus', 'musicbrainz_albumstatus'),
|
||||
file_tag_releasetype: tryGrabTags(format, 'MusicBrainz Album Type', 'releasetype', 'musicbrainz_albumtype'),
|
||||
file_tag_isrc: tryGrabTags(format, 'tsrc', 'isrc'),
|
||||
file_tag_musicbrainz_trackid: tryGrabTags(format, 'MusicBrainz Release Track Id', 'musicbrainz_releasetrackid'),
|
||||
file_tag_musicbrainz_albumid: tryGrabTags(format, 'MusicBrainz Album Id', 'musicbrainz_albumid'),
|
||||
file_tag_musicbrainz_albumartistid: tryGrabTags(format, 'MusicBrainz Album Artist Id', 'musicbrainz_albumartistid'),
|
||||
file_tag_musicbrainz_artistid: tryGrabTags(format, 'MusicBrainz Artist Id', 'musicbrainz_artistid'),
|
||||
|
||||
// Not sure if these are actually used yet or not
|
||||
file_tag_creation_time: tryGrabTags(format, 'creation_time'),
|
||||
|
@ -213,20 +222,18 @@ function getDefaultAudioStream(audioStreams) {
|
|||
|
||||
function parseProbeData(data, verbose = false) {
|
||||
try {
|
||||
var { format, streams, chapters } = data
|
||||
const { format, streams, chapters } = data
|
||||
|
||||
var sizeBytes = !isNaN(format.size) ? Number(format.size) : null
|
||||
var sizeMb = sizeBytes !== null ? Number((sizeBytes / (1024 * 1024)).toFixed(2)) : null
|
||||
const sizeBytes = !isNaN(format.size) ? Number(format.size) : null
|
||||
const sizeMb = sizeBytes !== null ? Number((sizeBytes / (1024 * 1024)).toFixed(2)) : null
|
||||
|
||||
// Logger.debug('Parsing Data for', Path.basename(format.filename))
|
||||
var tags = parseTags(format, verbose)
|
||||
var cleanedData = {
|
||||
let cleanedData = {
|
||||
format: format.format_long_name || format.name || 'Unknown',
|
||||
duration: !isNaN(format.duration) ? Number(format.duration) : null,
|
||||
size: sizeBytes,
|
||||
sizeMb,
|
||||
bit_rate: !isNaN(format.bit_rate) ? Number(format.bit_rate) : null,
|
||||
...tags
|
||||
tags: parseTags(format, verbose)
|
||||
}
|
||||
if (verbose && format.tags) {
|
||||
cleanedData.rawTags = format.tags
|
||||
|
@ -234,11 +241,11 @@ function parseProbeData(data, verbose = false) {
|
|||
|
||||
const cleaned_streams = streams.map(s => parseMediaStreamInfo(s, streams, cleanedData.bit_rate))
|
||||
cleanedData.video_stream = cleaned_streams.find(s => s.type === 'video')
|
||||
var audioStreams = cleaned_streams.filter(s => s.type === 'audio')
|
||||
const audioStreams = cleaned_streams.filter(s => s.type === 'audio')
|
||||
cleanedData.audio_stream = getDefaultAudioStream(audioStreams)
|
||||
|
||||
if (cleanedData.audio_stream && cleanedData.video_stream) {
|
||||
var videoBitrate = cleanedData.video_stream.bit_rate
|
||||
const videoBitrate = cleanedData.video_stream.bit_rate
|
||||
// If audio stream bitrate larger then video, most likely incorrect
|
||||
if (cleanedData.audio_stream.bit_rate > videoBitrate) {
|
||||
cleanedData.video_stream.bit_rate = cleanedData.bit_rate
|
||||
|
@ -247,10 +254,9 @@ function parseProbeData(data, verbose = false) {
|
|||
|
||||
// If format does not have tags, check audio stream (https://github.com/advplyr/audiobookshelf/issues/256)
|
||||
if (!format.tags && cleanedData.audio_stream && cleanedData.audio_stream.tags) {
|
||||
var tags = parseTags(cleanedData.audio_stream)
|
||||
cleanedData = {
|
||||
...cleanedData,
|
||||
...tags
|
||||
tags: parseTags(cleanedData.audio_stream, verbose)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -277,13 +283,13 @@ function probe(filepath, verbose = false) {
|
|||
}
|
||||
}
|
||||
|
||||
var rawProbeData = parseProbeData(raw, verbose)
|
||||
const rawProbeData = parseProbeData(raw, verbose)
|
||||
if (!rawProbeData || (!rawProbeData.audio_stream && !rawProbeData.video_stream)) {
|
||||
return {
|
||||
error: rawProbeData ? 'Invalid media file: no audio or video streams found' : 'Probe Failed'
|
||||
}
|
||||
} else {
|
||||
var probeData = new MediaProbeData()
|
||||
const probeData = new MediaProbeData()
|
||||
probeData.setData(rawProbeData)
|
||||
return probeData
|
||||
}
|
||||
|
|
|
@ -95,11 +95,7 @@ function groupFileItemsIntoLibraryItemDirs(mediaType, fileItems) {
|
|||
if (mediaType === 'music') {
|
||||
const audioFileGroup = {}
|
||||
fileItems.filter(i => isMediaFile(mediaType, i.extension)).forEach((item) => {
|
||||
if (!item.reldirpath) {
|
||||
audioFileGroup[item.name] = item.name
|
||||
} else {
|
||||
audioFileGroup[item.reldirpath] = [item.name]
|
||||
}
|
||||
audioFileGroup[item.path] = item.path
|
||||
})
|
||||
return audioFileGroup
|
||||
}
|
||||
|
@ -201,7 +197,14 @@ async function scanFolder(libraryMediaType, folder, serverSettings = {}) {
|
|||
let isFile = false // item is not in a folder
|
||||
let libraryItemData = null
|
||||
let fileObjs = []
|
||||
if (libraryItemPath === libraryItemGrouping[libraryItemPath]) {
|
||||
if (libraryMediaType === 'music') {
|
||||
libraryItemData = {
|
||||
path: Path.posix.join(folderPath, libraryItemPath),
|
||||
relPath: libraryItemPath
|
||||
}
|
||||
fileObjs = await cleanFileObjects(folderPath, [libraryItemPath])
|
||||
isFile = true
|
||||
} else if (libraryItemPath === libraryItemGrouping[libraryItemPath]) {
|
||||
// Media file in root only get title
|
||||
libraryItemData = {
|
||||
mediaMetadata: {
|
||||
|
@ -344,23 +347,8 @@ function getPodcastDataFromDir(folderPath, relPath) {
|
|||
}
|
||||
}
|
||||
|
||||
function getMusicDataFromDir(folderPath, relPath, fileNames) {
|
||||
relPath = relPath.replace(/\\/g, '/')
|
||||
|
||||
const firstFileName = fileNames.length ? fileNames[0] : ''
|
||||
return {
|
||||
mediaMetadata: {
|
||||
title: Path.basename(firstFileName, Path.extname(firstFileName))
|
||||
},
|
||||
relPath: relPath, // relative music audio file path i.e. /Some Folder/..
|
||||
path: Path.posix.join(folderPath, relPath) // i.e. /music/Some Folder/..
|
||||
}
|
||||
}
|
||||
|
||||
function getDataFromMediaDir(libraryMediaType, folderPath, relPath, serverSettings, fileNames) {
|
||||
if (libraryMediaType === 'music') {
|
||||
return getMusicDataFromDir(folderPath, relPath, fileNames)
|
||||
} else if (libraryMediaType === 'podcast') {
|
||||
if (libraryMediaType === 'podcast') {
|
||||
return getPodcastDataFromDir(folderPath, relPath)
|
||||
} else if (libraryMediaType === 'book') {
|
||||
var parseSubtitle = !!serverSettings.scannerParseSubtitle
|
||||
|
|
|
@ -147,7 +147,7 @@ module.exports.probe = (filepath, verbose = false) => {
|
|||
}
|
||||
const rawProbeData = parseProbeDump(dumpPayload)
|
||||
const probeData = new MediaProbeData()
|
||||
probeData.setData(rawProbeData)
|
||||
probeData.setDataFromTone(rawProbeData)
|
||||
return probeData
|
||||
}).catch((error) => {
|
||||
Logger.error(`[toneProber] Failed to probe file at path "${filepath}"`, error)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue