mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +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