mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 04:14:39 +03:00
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:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user