Remove sharp in favor of ffmpeg, fallback to cover

This commit is contained in:
Keagan Hilliard 2021-12-13 11:29:31 -08:00
parent 9452d0eca9
commit d6ae50f89a
5 changed files with 42 additions and 34 deletions

View File

@ -45,7 +45,6 @@
"podcast": "^1.3.0",
"read-chunk": "^3.1.0",
"recursive-readdir-async": "^1.1.8",
"sharp": "^0.29.3",
"socket.io": "^4.1.3",
"string-strip-html": "^8.3.0",
"watcher": "^1.2.0",

View File

@ -1,8 +1,8 @@
const Path = require('path')
const fs = require('fs-extra')
const stream = require('stream')
const resize = require('./utils/resizeImage')
const Logger = require('./Logger')
const { resizeImage } = require('./utils/ffmpegHelpers')
class CacheManager {
constructor(MetadataPath) {
@ -18,7 +18,7 @@ class CacheManager {
res.type(`image/${format}`)
var path = Path.join(this.CoverCachePath, audiobook.id) + '.' + format
var path = Path.join(this.CoverCachePath, `${audiobook.id}_${width}${height ? `x${height}` : ''}`) + '.' + format
// Cache exists
if (await fs.pathExists(path)) {
@ -35,22 +35,22 @@ class CacheManager {
// Write cache
await fs.ensureDir(this.CoverCachePath)
var readStream = resize(audiobook.book.coverFullPath, width, height, format)
var writeStream = fs.createWriteStream(path)
writeStream.on('error', (e) => {
Logger.error(`[CacheManager] Cache write error ${e.message}`)
})
readStream.pipe(writeStream)
let writtenFile = await resizeImage(audiobook.book.coverFullPath || audiobook.book.cover, path, width, height)
var readStream = fs.createReadStream(writtenFile)
readStream.pipe(res)
}
purgeCoverCache(audiobookId) {
var basepath = Path.join(this.CoverCachePath, audiobookId)
// Remove both webp and jpg caches if exist
var webpPath = basepath + '.webp'
var jpgPath = basepath + '.jpg'
return Promise.all([this.removeCache(webpPath), this.removeCache(jpgPath)])
async purgeCoverCache(audiobookId) {
// If purgeAll has been called... The cover cache directory no longer exists
await fs.ensureDir(this.CoverCachePath)
return Promise.all((await fs.readdir(this.CoverCachePath)).reduce((promises, file) => {
if (file.startsWith(audiobookId)) {
Logger.debug(`[CacheManager] Going to purge ${file}`);
promises.push(this.removeCache(Path.join(this.CoverCachePath, file)))
}
return promises
}, []))
}
removeCache(path) {

View File

@ -234,7 +234,7 @@ class BookController {
async getCover(req, res) {
let { query: { width, height, format }, params: { id } } = req
var audiobook = this.db.audiobooks.find(a => a.id === id)
if (!audiobook || !audiobook.book.coverFullPath) return res.sendStatus(404)
if (!audiobook || (!audiobook.book.coverFullPath && !audiobook.book.cover)) return res.sendStatus(404)
// Check user can access this audiobooks library
if (!req.user.checkCanAccessLibrary(audiobook.libraryId)) {
@ -242,7 +242,7 @@ class BookController {
}
const options = {
format: format || (reqSupportsWebp(req) ? 'webp' : 'jpg'),
format: format || (reqSupportsWebp(req) ? 'webp' : 'jpeg'),
height: height ? parseInt(height) : null,
width: width ? parseInt(width) : null
}

View File

@ -93,3 +93,28 @@ async function extractCoverArt(filepath, outputpath) {
})
}
module.exports.extractCoverArt = extractCoverArt
//This should convert based on the output file extension as well
async function resizeImage(filePath, outputPath, width, height) {
var dirname = Path.dirname(outputPath);
await fs.ensureDir(dirname);
return new Promise((resolve) => {
var ffmpeg = Ffmpeg(filePath)
ffmpeg.addOption(['-vf', `scale=${width || -1}:${height || -1}`])
ffmpeg.addOutput(outputPath)
ffmpeg.on('start', (cmd) => {
Logger.debug(`[FfmpegHelpers] Resize Image Cmd: ${cmd}`)
})
ffmpeg.on('error', (err, stdout, stderr) => {
Logger.error(`[FfmpegHelpers] Resize Image Error ${err}`)
resolve(false)
})
ffmpeg.on('end', () => {
Logger.debug(`[FfmpegHelpers] Image resized Successfully`)
resolve(outputPath)
})
ffmpeg.run()
})
}
module.exports.resizeImage = resizeImage

View File

@ -1,16 +0,0 @@
const sharp = require('sharp')
const fs = require('fs')
function resize(filePath, width, height, format = 'webp') {
const readStream = fs.createReadStream(filePath);
let sharpie = sharp()
sharpie.toFormat(format)
if (width || height) {
sharpie.resize(width, height, { withoutEnlargement: true })
}
return readStream.pipe(sharpie)
}
module.exports = resize;