Preview generation fallback (#725)

* Added preview generation fallback feature.
When a preview generation fails (often for wmv/avi files), the new code tries with less stricted (no xerror) and more time consuming options (slow+fast seek).
Fix a minor issue when stash downloads ffmpeg/ffprobe, but doesn't re-detect their paths.
This commit is contained in:
JoeSmithStarkers
2020-08-17 09:21:58 +10:00
committed by GitHub
parent 44c32a91d3
commit ecc42e4e24
6 changed files with 72 additions and 14 deletions

View File

@@ -14,12 +14,51 @@ type ScenePreviewChunkOptions struct {
OutputPath string
}
func (e *Encoder) ScenePreviewVideoChunk(probeResult VideoFile, options ScenePreviewChunkOptions, preset string) {
func (e *Encoder) ScenePreviewVideoChunk(probeResult VideoFile, options ScenePreviewChunkOptions, preset string, fallback bool) error {
var fastSeek float64
var slowSeek float64
fallbackMinSlowSeek := 20.0
args := []string{
"-v", "error",
"-xerror",
"-ss", strconv.FormatFloat(options.StartTime, 'f', 2, 64),
"-i", probeResult.Path,
}
// Non-fallback: enable xerror.
// "-xerror" causes ffmpeg to fail on warnings, often the preview is fine but could be broken.
if !fallback {
args = append(args, "-xerror")
fastSeek = options.StartTime
slowSeek = 0
} else {
// In fallback mode, disable "-xerror" and try a combination of fast/slow seek instead of just fastseek
// Commonly with avi/wmv ffmpeg doesn't seem to always predict the right start point to begin decoding when
// using fast seek. If you force ffmpeg to decode more, it avoids the "blocky green artifact" issue.
if options.StartTime > fallbackMinSlowSeek {
// Handle seeks longer than fallbackMinSlowSeek with fast/slow seeks
// Allow for at least fallbackMinSlowSeek seconds of slow seek
fastSeek = options.StartTime - fallbackMinSlowSeek
slowSeek = fallbackMinSlowSeek
} else {
// Handle seeks shorter than fallbackMinSlowSeek with only slow seeks.
slowSeek = options.StartTime
fastSeek = 0
}
}
if fastSeek > 0 {
args = append(args, "-ss")
args = append(args, strconv.FormatFloat(fastSeek, 'f', 2, 64))
}
args = append(args, "-i")
args = append(args, probeResult.Path)
if slowSeek > 0 {
args = append(args, "-ss")
args = append(args, strconv.FormatFloat(slowSeek, 'f', 2, 64))
}
args2 := []string{
"-t", strconv.FormatFloat(options.Duration, 'f', 2, 64),
"-max_muxing_queue_size", "1024", // https://trac.ffmpeg.org/ticket/6375
"-y",
@@ -36,10 +75,14 @@ func (e *Encoder) ScenePreviewVideoChunk(probeResult VideoFile, options ScenePre
"-strict", "-2",
options.OutputPath,
}
_, _ = e.run(probeResult, args)
finalArgs := append(args, args2...)
_, err := e.run(probeResult, finalArgs)
return err
}
func (e *Encoder) ScenePreviewVideoChunkCombine(probeResult VideoFile, concatFilePath string, outputPath string) {
func (e *Encoder) ScenePreviewVideoChunkCombine(probeResult VideoFile, concatFilePath string, outputPath string) error {
args := []string{
"-v", "error",
"-f", "concat",
@@ -48,7 +91,8 @@ func (e *Encoder) ScenePreviewVideoChunkCombine(probeResult VideoFile, concatFil
"-c", "copy",
outputPath,
}
_, _ = e.run(probeResult, args)
_, err := e.run(probeResult, args)
return err
}
func (e *Encoder) ScenePreviewVideoToImage(probeResult VideoFile, width int, videoPreviewPath string, outputPath string) error {