mirror of
https://github.com/BobbyWibowo/lolisafe.git
synced 2025-01-19 01:31:34 +00:00
More fixes to thumbnailers
Use fluent-ffmpeg's .screenshots() function instead, with some countermeasures for weird situations. No more selective error suppressions.
This commit is contained in:
parent
4225819b98
commit
0b8b1ed026
@ -254,59 +254,49 @@ self.generateThumbs = async (name, extname, force) => {
|
|||||||
}
|
}
|
||||||
} else if (self.videoExts.includes(extname)) {
|
} else if (self.videoExts.includes(extname)) {
|
||||||
const metadata = await self.ffprobe(input)
|
const metadata = await self.ffprobe(input)
|
||||||
const duration = parseInt(metadata.format.duration)
|
|
||||||
|
|
||||||
// Skip files that have neither video streams/channels nor valid duration metadata
|
const duration = parseInt(metadata.format.duration)
|
||||||
if (!metadata.streams || !metadata.streams.some(s => s.codec_type === 'video') || isNaN(duration))
|
if (isNaN(duration))
|
||||||
throw 'File does not have valid required data'
|
throw 'Warning: File does not have valid duration metadata'
|
||||||
|
|
||||||
|
const videoStream = metadata.streams && metadata.streams.find(s => s.codec_type === 'video')
|
||||||
|
if (!videoStream || !videoStream.width || !videoStream.height)
|
||||||
|
throw 'Warning: File does not have valid video stream metadata'
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
ffmpeg(input)
|
ffmpeg(input)
|
||||||
.seekInput(duration * 20 / 100)
|
.on('error', error => reject(error))
|
||||||
.frames(1)
|
.on('end', () => resolve())
|
||||||
.videoFilters([
|
.screenshots({
|
||||||
{
|
folder: paths.thumbs,
|
||||||
filter: 'select',
|
filename: name.slice(0, -extname.length) + '.png',
|
||||||
options: 'eq(pict_type\\,I)'
|
timestamps: ['20%'],
|
||||||
},
|
size: videoStream.width >= videoStream.height
|
||||||
{
|
? `${self.thumbsSize}x?`
|
||||||
filter: 'scale',
|
: `?x${self.thumbsSize}`
|
||||||
options: `${self.thumbsSize}:${self.thumbsSize}:force_original_aspect_ratio=decrease`
|
|
||||||
}
|
|
||||||
])
|
|
||||||
.output(thumbname)
|
|
||||||
.on('error', async error => {
|
|
||||||
// Try to unlink thumbnail,
|
|
||||||
// since ffmpeg may have created an incomplete thumbnail
|
|
||||||
try {
|
|
||||||
await paths.unlink(thumbname)
|
|
||||||
} catch (err) {
|
|
||||||
if (err && err.code !== 'ENOENT')
|
|
||||||
logger.error(`[${name}]: ${err.toString()}`)
|
|
||||||
}
|
|
||||||
return reject(error)
|
|
||||||
})
|
})
|
||||||
.on('end', () => resolve(true))
|
})
|
||||||
.run()
|
.catch(error => error) // Error passthrough
|
||||||
|
.then(async error => {
|
||||||
|
// FFMPEG would just warn instead of exiting with errors when dealing with incomplete files
|
||||||
|
// Sometimes FFMPEG would throw errors but actually somehow succeeded in making the thumbnails
|
||||||
|
// (this could be a fallback mechanism of fluent-ffmpeg library instead)
|
||||||
|
// So instead we check if the thumbnail exists to really make sure
|
||||||
|
try {
|
||||||
|
await paths.lstat(thumbname)
|
||||||
|
return true
|
||||||
|
} catch (err) {
|
||||||
|
if (err.code === 'ENOENT')
|
||||||
|
throw error || 'Warning: FFMPEG exited with empty output file'
|
||||||
|
else
|
||||||
|
throw error || err
|
||||||
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// TODO: Parse ffmpeg/ffprobe errors into concise error messages (get rid of versions info)
|
logger.error(`[${name}]: ${error.toString().trim()}`)
|
||||||
// Suppress error logging for errors matching these patterns
|
|
||||||
const errorString = error.toString()
|
|
||||||
const suppress = [
|
|
||||||
/Input file contains unsupported image format/,
|
|
||||||
/Invalid data found when processing input/,
|
|
||||||
/File does not have valid required data/,
|
|
||||||
/Could not find codec parameters/,
|
|
||||||
/Duplicate element/
|
|
||||||
]
|
|
||||||
|
|
||||||
if (!suppress.some(t => t.test(errorString)))
|
|
||||||
logger.error(`[${name}]: ${errorString}`)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await paths.symlink(paths.thumbPlaceholder, thumbname)
|
await paths.symlink(paths.thumbPlaceholder, thumbname)
|
||||||
return true
|
return true
|
||||||
|
Loading…
Reference in New Issue
Block a user