mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-02-19 00:18:56 +01:00
Fix folder browser, fix track number parsed from filename too large, add mp4 audiobook support
This commit is contained in:
parent
04f92c33c2
commit
120c70622a
@ -5,7 +5,7 @@
|
|||||||
<p class="font-book text-3xl text-white truncate">{{ title }}</p>
|
<p class="font-book text-3xl text-white truncate">{{ title }}</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="p-4 w-full text-sm py-6 rounded-lg bg-bg shadow-lg border border-black-300 relative overflow-hidden" style="min-height: 200px; max-height: 80vh">
|
<div v-if="show" class="p-4 w-full text-sm py-6 rounded-lg bg-bg shadow-lg border border-black-300 relative overflow-hidden" style="min-height: 200px; max-height: 80vh">
|
||||||
<div v-if="!showAddLibrary" class="w-full h-full flex flex-col justify-center px-4">
|
<div v-if="!showAddLibrary" class="w-full h-full flex flex-col justify-center px-4">
|
||||||
<div class="flex items-center mb-4">
|
<div class="flex items-center mb-4">
|
||||||
<p>{{ libraries.length }} Libraries</p>
|
<p>{{ libraries.length }} Libraries</p>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "audiobookshelf-client",
|
"name": "audiobookshelf-client",
|
||||||
"version": "1.4.4",
|
"version": "1.4.5",
|
||||||
"description": "Audiobook manager and player",
|
"description": "Audiobook manager and player",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -129,9 +129,9 @@ export default {
|
|||||||
title: null,
|
title: null,
|
||||||
author: null,
|
author: null,
|
||||||
series: null,
|
series: null,
|
||||||
acceptedAudioFormats: ['.mp3', '.m4b', '.m4a', '.flac', '.opus'],
|
acceptedAudioFormats: ['.mp3', '.m4b', '.m4a', '.flac', '.opus', '.mp4'],
|
||||||
acceptedImageFormats: ['.png', '.jpg', '.jpeg', '.webp'],
|
acceptedImageFormats: ['.png', '.jpg', '.jpeg', '.webp'],
|
||||||
inputAccept: '.png, .jpg, .jpeg, .webp, .mp3, .m4b, .m4a, .flac, .opus',
|
inputAccept: '.png, .jpg, .jpeg, .webp, .mp3, .m4b, .m4a, .flac, .opus, .mp4',
|
||||||
isDragOver: false,
|
isDragOver: false,
|
||||||
showUploader: true,
|
showUploader: true,
|
||||||
validAudioFiles: [],
|
validAudioFiles: [],
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "audiobookshelf",
|
"name": "audiobookshelf",
|
||||||
"version": "1.4.4",
|
"version": "1.4.5",
|
||||||
"description": "Self-hosted audiobook server for managing and playing audiobooks",
|
"description": "Self-hosted audiobook server for managing and playing audiobooks",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -692,7 +692,7 @@ class ApiController {
|
|||||||
var path = Path.join(relpath, dirname)
|
var path = Path.join(relpath, dirname)
|
||||||
|
|
||||||
var isDir = (await fs.lstat(fullPath)).isDirectory()
|
var isDir = (await fs.lstat(fullPath)).isDirectory()
|
||||||
if (isDir && !excludedDirs.includes(dirname)) {
|
if (isDir && !excludedDirs.includes(path) && dirname !== 'node_modules') {
|
||||||
return {
|
return {
|
||||||
path,
|
path,
|
||||||
dirname,
|
dirname,
|
||||||
@ -713,12 +713,16 @@ class ApiController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getFileSystemPaths(req, res) {
|
async getFileSystemPaths(req, res) {
|
||||||
var excludedDirs = ['node_modules', 'client', 'server', '.git', 'static', 'build', 'dist', 'metadata', 'config', 'sys', 'proc']
|
var excludedDirs = ['node_modules', 'client', 'server', '.git', 'static', 'build', 'dist', 'metadata', 'config', 'sys', 'proc'].map(dirname => {
|
||||||
|
return Path.sep + dirname
|
||||||
|
})
|
||||||
|
|
||||||
// Do not include existing mapped library paths in response
|
// Do not include existing mapped library paths in response
|
||||||
this.db.libraries.forEach(lib => {
|
this.db.libraries.forEach(lib => {
|
||||||
lib.folders.forEach((folder) => {
|
lib.folders.forEach((folder) => {
|
||||||
excludedDirs.push(Path.basename(folder.fullPath))
|
var dir = folder.fullPath
|
||||||
|
if (dir.includes(global.appRoot)) dir = dir.replace(global.appRoot, '')
|
||||||
|
excludedDirs.push(dir)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -456,11 +456,12 @@ class Audiobook {
|
|||||||
|
|
||||||
var current_index = 1
|
var current_index = 1
|
||||||
var missingParts = []
|
var missingParts = []
|
||||||
|
|
||||||
for (let i = 0; i < this.tracks.length; i++) {
|
for (let i = 0; i < this.tracks.length; i++) {
|
||||||
var _track = this.tracks[i]
|
var _track = this.tracks[i]
|
||||||
if (_track.index > current_index) {
|
if (_track.index > current_index) {
|
||||||
var num_parts_missing = _track.index - current_index
|
var num_parts_missing = _track.index - current_index
|
||||||
for (let x = 0; x < num_parts_missing; x++) {
|
for (let x = 0; x < num_parts_missing && x < 9999; x++) {
|
||||||
missingParts.push(current_index + x)
|
missingParts.push(current_index + x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,6 @@ class Backup {
|
|||||||
this.filename = this.id + '.audiobookshelf'
|
this.filename = this.id + '.audiobookshelf'
|
||||||
this.path = Path.join('backups', this.filename)
|
this.path = Path.join('backups', this.filename)
|
||||||
this.fullPath = Path.join(this.backupDirPath, this.filename)
|
this.fullPath = Path.join(this.backupDirPath, this.filename)
|
||||||
console.log('Backup fullpath', this.fullPath)
|
|
||||||
|
|
||||||
this.createdAt = Date.now()
|
this.createdAt = Date.now()
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ function getDefaultAudioStream(audioStreams) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function scan(path) {
|
async function scan(path) {
|
||||||
|
Logger.debug(`Scanning path "${path}"`)
|
||||||
var probeData = await prober(path)
|
var probeData = await prober(path)
|
||||||
if (!probeData || !probeData.audio_streams || !probeData.audio_streams.length) {
|
if (!probeData || !probeData.audio_streams || !probeData.audio_streams.length) {
|
||||||
return {
|
return {
|
||||||
@ -86,7 +87,7 @@ function getTrackNumberFromFilename(title, author, series, publishYear, filename
|
|||||||
// Remove eg. "disc 1" from path
|
// Remove eg. "disc 1" from path
|
||||||
partbasename = partbasename.replace(/ disc \d\d? /i, '')
|
partbasename = partbasename.replace(/ disc \d\d? /i, '')
|
||||||
|
|
||||||
var numbersinpath = partbasename.match(/\d+/g)
|
var numbersinpath = partbasename.match(/\d{1,4}/g)
|
||||||
if (!numbersinpath) return null
|
if (!numbersinpath) return null
|
||||||
|
|
||||||
var number = numbersinpath.length ? parseInt(numbersinpath[0]) : null
|
var number = numbersinpath.length ? parseInt(numbersinpath[0]) : null
|
||||||
@ -99,6 +100,8 @@ async function scanAudioFiles(audiobook, newAudioFiles) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger.debug('[AudioFileScanner] Scanning audio files')
|
||||||
|
|
||||||
var tracks = []
|
var tracks = []
|
||||||
var numDuplicateTracks = 0
|
var numDuplicateTracks = 0
|
||||||
var numInvalidTracks = 0
|
var numInvalidTracks = 0
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
const globals = {
|
const globals = {
|
||||||
SupportedImageTypes: ['png', 'jpg', 'jpeg', 'webp'],
|
SupportedImageTypes: ['png', 'jpg', 'jpeg', 'webp'],
|
||||||
SupportedAudioTypes: ['m4b', 'mp3', 'm4a', 'flac', 'opus'],
|
SupportedAudioTypes: ['m4b', 'mp3', 'm4a', 'flac', 'opus', 'mp4'],
|
||||||
SupportedEbookTypes: ['epub', 'pdf', 'mobi']
|
SupportedEbookTypes: ['epub', 'pdf', 'mobi']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
const Path = require('path')
|
const Path = require('path')
|
||||||
|
const fs = require('fs-extra')
|
||||||
const dir = require('node-dir')
|
const dir = require('node-dir')
|
||||||
const Logger = require('../Logger')
|
const Logger = require('../Logger')
|
||||||
const { getIno } = require('./index')
|
const { getIno } = require('./index')
|
||||||
@ -120,6 +121,12 @@ async function scanRootDir(folder, serverSettings = {}) {
|
|||||||
var folderPath = folder.fullPath
|
var folderPath = folder.fullPath
|
||||||
var parseSubtitle = !!serverSettings.scannerParseSubtitle
|
var parseSubtitle = !!serverSettings.scannerParseSubtitle
|
||||||
|
|
||||||
|
var pathExists = await fs.pathExists(folderPath)
|
||||||
|
if (!pathExists) {
|
||||||
|
Logger.error(`[scandir] Invalid folder path does not exist "${folderPath}"`)
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
var pathdata = await getPaths(folderPath)
|
var pathdata = await getPaths(folderPath)
|
||||||
var filepaths = pathdata.files.map(filepath => {
|
var filepaths = pathdata.files.map(filepath => {
|
||||||
return Path.normalize(filepath).replace(folderPath, '')
|
return Path.normalize(filepath).replace(folderPath, '')
|
||||||
|
Loading…
Reference in New Issue
Block a user