Add ability to customize frames to analyze
This commit is contained in:
parent
9880d2adf5
commit
2bc4d26b94
|
@ -417,6 +417,14 @@ remote_runners:
|
|||
live: '30 seconds'
|
||||
vod: '2 minutes'
|
||||
|
||||
thumbnails:
|
||||
# When automatically generating a thumbnail from the video
|
||||
generation_from_video:
|
||||
# How many frames to analyze at the middle of the video to select the most appropriate one
|
||||
# Increasing this value will increase CPU and memory usage when generating the thumbnail, especially for high video resolution
|
||||
# Minimum value is 2
|
||||
frames_to_analyze: 50
|
||||
|
||||
cache:
|
||||
previews:
|
||||
size: 500 # Max number of previews you want to cache
|
||||
|
|
|
@ -415,6 +415,14 @@ remote_runners:
|
|||
live: '30 seconds'
|
||||
vod: '2 minutes'
|
||||
|
||||
thumbnails:
|
||||
# When automatically generating a thumbnail from the video
|
||||
generation_from_video:
|
||||
# How many frames to analyze at the middle of the video to select the most appropriate one
|
||||
# Increasing this value will increase CPU and memory usage when generating the thumbnail, especially for high video resolution
|
||||
# Minimum value is 2
|
||||
frames_to_analyze: 50
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# From this point, almost all following keys can be overridden by the web interface
|
||||
|
|
|
@ -39,16 +39,17 @@ export class FFmpegImage {
|
|||
async generateThumbnailFromVideo (options: {
|
||||
fromPath: string
|
||||
output: string
|
||||
framesToAnalyze: number
|
||||
ffprobe?: FfprobeData
|
||||
}) {
|
||||
const { fromPath, output, ffprobe } = options
|
||||
const { fromPath, output, ffprobe, framesToAnalyze } = options
|
||||
|
||||
let duration = await getVideoStreamDuration(fromPath, ffprobe)
|
||||
if (isNaN(duration)) duration = 0
|
||||
|
||||
this.commandWrapper.buildCommand(fromPath)
|
||||
.seekInput(duration / 2)
|
||||
.videoFilter('thumbnail=50')
|
||||
.videoFilter('thumbnail=' + framesToAnalyze)
|
||||
.outputOption('-frames:v 1')
|
||||
.output(output)
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ function checkConfig () {
|
|||
checkLiveConfig()
|
||||
checkObjectStorageConfig()
|
||||
checkVideoStudioConfig()
|
||||
checkThumbnailsConfig()
|
||||
}
|
||||
|
||||
// We get db by param to not import it in this file (import orders)
|
||||
|
@ -331,3 +332,9 @@ function checkVideoStudioConfig () {
|
|||
throw new Error('Video studio cannot be enabled if transcoding is disabled')
|
||||
}
|
||||
}
|
||||
|
||||
function checkThumbnailsConfig () {
|
||||
if (CONFIG.THUMBNAILS.GENERATION_FROM_VIDEO.FRAMES_TO_ANALYZE < 2) {
|
||||
throw new Error('thumbnails.generation_from_video.frames_to_analyze must be a number greater than 1')
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ function checkMissedConfig () {
|
|||
'video_studio.enabled', 'video_studio.remote_runners.enabled',
|
||||
'video_file.update.enabled',
|
||||
'remote_runners.stalled_jobs.vod', 'remote_runners.stalled_jobs.live',
|
||||
'thumbnails.generation_from_video.frames_to_analyze',
|
||||
'import.videos.http.enabled', 'import.videos.torrent.enabled', 'import.videos.concurrency', 'import.videos.timeout',
|
||||
'import.video_channel_synchronization.enabled', 'import.video_channel_synchronization.max_per_user',
|
||||
'import.video_channel_synchronization.check_interval', 'import.video_channel_synchronization.videos_limit_per_synchronization',
|
||||
|
|
|
@ -344,6 +344,11 @@ const CONFIG = {
|
|||
VOD: parseDurationToMs(config.get<string>('remote_runners.stalled_jobs.vod'))
|
||||
}
|
||||
},
|
||||
THUMBNAILS: {
|
||||
GENERATION_FROM_VIDEO: {
|
||||
FRAMES_TO_ANALYZE: config.get<number>('thumbnails.generation_from_video.frames_to_analyze')
|
||||
}
|
||||
},
|
||||
ADMIN: {
|
||||
get EMAIL () { return config.get<string>('admin.email') }
|
||||
},
|
||||
|
|
|
@ -379,7 +379,8 @@ async function generateImageFromVideoFile (options: {
|
|||
const pendingImagePath = join(folder, pendingImageName)
|
||||
|
||||
try {
|
||||
await generateThumbnailFromVideo({ fromPath, output: pendingImagePath, ffprobe })
|
||||
const framesToAnalyze = CONFIG.THUMBNAILS.GENERATION_FROM_VIDEO.FRAMES_TO_ANALYZE
|
||||
await generateThumbnailFromVideo({ fromPath, output: pendingImagePath, framesToAnalyze, ffprobe })
|
||||
|
||||
const destination = join(folder, imageName)
|
||||
await processImageFromWorker({ path: pendingImagePath, destination, newSize: size })
|
||||
|
|
Loading…
Reference in New Issue