added vfr detection, to improve preview generation performance (#3376)

This commit is contained in:
JoeSmithStarkers
2023-02-17 13:59:36 +11:00
committed by GitHub
parent f92ba7ba53
commit 390f72207c
2 changed files with 22 additions and 12 deletions

View File

@@ -44,7 +44,7 @@ func (t *GeneratePreviewTask) Start(ctx context.Context) {
return return
} }
if err := t.generateVideo(videoChecksum, videoFile.VideoStreamDuration); err != nil { if err := t.generateVideo(videoChecksum, videoFile.VideoStreamDuration, videoFile.FrameRate); err != nil {
logger.Errorf("error generating preview: %v", err) logger.Errorf("error generating preview: %v", err)
logErrorOutput(err) logErrorOutput(err)
return return
@@ -59,12 +59,18 @@ func (t *GeneratePreviewTask) Start(ctx context.Context) {
} }
} }
func (t GeneratePreviewTask) generateVideo(videoChecksum string, videoDuration float64) error { func (t GeneratePreviewTask) generateVideo(videoChecksum string, videoDuration float64, videoFrameRate float64) error {
videoFilename := t.Scene.Path videoFilename := t.Scene.Path
useVsync2 := false
if err := t.generator.PreviewVideo(context.TODO(), videoFilename, videoDuration, videoChecksum, t.Options, false); err != nil { if videoFrameRate <= 0.01 {
logger.Errorf("[generator] Video framerate very low/high (%f) most likely vfr so using -vsync 2", videoFrameRate)
useVsync2 = true
}
if err := t.generator.PreviewVideo(context.TODO(), videoFilename, videoDuration, videoChecksum, t.Options, false, useVsync2); err != nil {
logger.Warnf("[generator] failed generating scene preview, trying fallback") logger.Warnf("[generator] failed generating scene preview, trying fallback")
if err := t.generator.PreviewVideo(context.TODO(), videoFilename, videoDuration, videoChecksum, t.Options, true); err != nil { if err := t.generator.PreviewVideo(context.TODO(), videoFilename, videoDuration, videoChecksum, t.Options, true, useVsync2); err != nil {
return err return err
} }
} }

View File

@@ -68,7 +68,7 @@ func (g PreviewOptions) getStepSizeAndOffset(videoDuration float64) (stepSize fl
return return
} }
func (g Generator) PreviewVideo(ctx context.Context, input string, videoDuration float64, hash string, options PreviewOptions, fallback bool) error { func (g Generator) PreviewVideo(ctx context.Context, input string, videoDuration float64, hash string, options PreviewOptions, fallback bool, useVsync2 bool) error {
lockCtx := g.LockManager.ReadLock(ctx, input) lockCtx := g.LockManager.ReadLock(ctx, input)
defer lockCtx.Cancel() defer lockCtx.Cancel()
@@ -81,7 +81,7 @@ func (g Generator) PreviewVideo(ctx context.Context, input string, videoDuration
logger.Infof("[generator] generating video preview for %s", input) logger.Infof("[generator] generating video preview for %s", input)
if err := g.generateFile(lockCtx, g.ScenePaths, mp4Pattern, output, g.previewVideo(input, videoDuration, options, fallback)); err != nil { if err := g.generateFile(lockCtx, g.ScenePaths, mp4Pattern, output, g.previewVideo(input, videoDuration, options, fallback, useVsync2)); err != nil {
return err return err
} }
@@ -90,10 +90,10 @@ func (g Generator) PreviewVideo(ctx context.Context, input string, videoDuration
return nil return nil
} }
func (g *Generator) previewVideo(input string, videoDuration float64, options PreviewOptions, fallback bool) generateFn { func (g *Generator) previewVideo(input string, videoDuration float64, options PreviewOptions, fallback bool, useVsync2 bool) generateFn {
// #2496 - generate a single preview video for videos shorter than segments * segment duration // #2496 - generate a single preview video for videos shorter than segments * segment duration
if videoDuration < options.SegmentDuration*float64(options.Segments) { if videoDuration < options.SegmentDuration*float64(options.Segments) {
return g.previewVideoSingle(input, videoDuration, options, fallback) return g.previewVideoSingle(input, videoDuration, options, fallback, useVsync2)
} }
return func(lockCtx *fsutil.LockContext, tmpFn string) error { return func(lockCtx *fsutil.LockContext, tmpFn string) error {
@@ -131,7 +131,7 @@ func (g *Generator) previewVideo(input string, videoDuration float64, options Pr
Preset: options.Preset, Preset: options.Preset,
} }
if err := g.previewVideoChunk(lockCtx, input, chunkOptions, fallback); err != nil { if err := g.previewVideoChunk(lockCtx, input, chunkOptions, fallback, useVsync2); err != nil {
return err return err
} }
} }
@@ -150,7 +150,7 @@ func (g *Generator) previewVideo(input string, videoDuration float64, options Pr
} }
} }
func (g *Generator) previewVideoSingle(input string, videoDuration float64, options PreviewOptions, fallback bool) generateFn { func (g *Generator) previewVideoSingle(input string, videoDuration float64, options PreviewOptions, fallback bool, useVsync2 bool) generateFn {
return func(lockCtx *fsutil.LockContext, tmpFn string) error { return func(lockCtx *fsutil.LockContext, tmpFn string) error {
chunkOptions := previewChunkOptions{ chunkOptions := previewChunkOptions{
StartTime: 0, StartTime: 0,
@@ -160,7 +160,7 @@ func (g *Generator) previewVideoSingle(input string, videoDuration float64, opti
Preset: options.Preset, Preset: options.Preset,
} }
return g.previewVideoChunk(lockCtx, input, chunkOptions, fallback) return g.previewVideoChunk(lockCtx, input, chunkOptions, fallback, useVsync2)
} }
} }
@@ -172,7 +172,7 @@ type previewChunkOptions struct {
Preset string Preset string
} }
func (g Generator) previewVideoChunk(lockCtx *fsutil.LockContext, fn string, options previewChunkOptions, fallback bool) error { func (g Generator) previewVideoChunk(lockCtx *fsutil.LockContext, fn string, options previewChunkOptions, fallback bool, useVsync2 bool) error {
var videoFilter ffmpeg.VideoFilter var videoFilter ffmpeg.VideoFilter
videoFilter = videoFilter.ScaleWidth(scenePreviewWidth) videoFilter = videoFilter.ScaleWidth(scenePreviewWidth)
@@ -189,6 +189,10 @@ func (g Generator) previewVideoChunk(lockCtx *fsutil.LockContext, fn string, opt
"-strict", "-2", "-strict", "-2",
) )
if useVsync2 {
videoArgs = append(videoArgs, "-vsync", "2")
}
trimOptions := transcoder.TranscodeOptions{ trimOptions := transcoder.TranscodeOptions{
OutputPath: options.OutputPath, OutputPath: options.OutputPath,
StartTime: options.StartTime, StartTime: options.StartTime,