Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added VFR Detection #3376

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions internal/manager/task_generate_preview.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (t *GeneratePreviewTask) Start(ctx context.Context) {
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)
logErrorOutput(err)
return
Expand All @@ -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
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")
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
}
}
Expand Down
20 changes: 12 additions & 8 deletions pkg/scene/generate/preview.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func (g PreviewOptions) getStepSizeAndOffset(videoDuration float64) (stepSize fl
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)
defer lockCtx.Cancel()

Expand All @@ -81,7 +81,7 @@ func (g Generator) PreviewVideo(ctx context.Context, input string, videoDuration

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
}

Expand All @@ -90,10 +90,10 @@ func (g Generator) PreviewVideo(ctx context.Context, input string, videoDuration
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
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 {
Expand Down Expand Up @@ -131,7 +131,7 @@ func (g *Generator) previewVideo(input string, videoDuration float64, options Pr
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
}
}
Expand All @@ -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 {
chunkOptions := previewChunkOptions{
StartTime: 0,
Expand All @@ -160,7 +160,7 @@ func (g *Generator) previewVideoSingle(input string, videoDuration float64, opti
Preset: options.Preset,
}

return g.previewVideoChunk(lockCtx, input, chunkOptions, fallback)
return g.previewVideoChunk(lockCtx, input, chunkOptions, fallback, useVsync2)
}
}

Expand All @@ -172,7 +172,7 @@ type previewChunkOptions struct {
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
videoFilter = videoFilter.ScaleWidth(scenePreviewWidth)

Expand All @@ -189,6 +189,10 @@ func (g Generator) previewVideoChunk(lockCtx *fsutil.LockContext, fn string, opt
"-strict", "-2",
)

if useVsync2 {
videoArgs = append(videoArgs, "-vsync", "2")
}

trimOptions := transcoder.TranscodeOptions{
OutputPath: options.OutputPath,
StartTime: options.StartTime,
Expand Down