mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 04:44:37 +03:00
Add in-memory screenshot generation for sprites and phash (#1316)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
package ffmpeg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -62,7 +62,7 @@ func KillRunningEncoders(path string) {
|
||||
|
||||
for _, process := range processes {
|
||||
// assume it worked, don't check for error
|
||||
fmt.Printf("Killing encoder process for file: %s", path)
|
||||
logger.Infof("Killing encoder process for file: %s", path)
|
||||
process.Kill()
|
||||
|
||||
// wait for the process to die before returning
|
||||
@@ -82,7 +82,8 @@ func KillRunningEncoders(path string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Encoder) run(probeResult VideoFile, args []string) (string, error) {
|
||||
// FFmpeg runner with progress output, used for transcodes
|
||||
func (e *Encoder) runTranscode(probeResult VideoFile, args []string) (string, error) {
|
||||
cmd := exec.Command(e.Path, args...)
|
||||
|
||||
stderr, err := cmd.StderrPipe()
|
||||
@@ -137,3 +138,26 @@ func (e *Encoder) run(probeResult VideoFile, args []string) (string, error) {
|
||||
|
||||
return stdoutString, nil
|
||||
}
|
||||
|
||||
func (e *Encoder) run(probeResult VideoFile, args []string) (string, error) {
|
||||
cmd := exec.Command(e.Path, args...)
|
||||
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = &stderr
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
registerRunningEncoder(probeResult.Path, cmd.Process)
|
||||
err := waitAndDeregister(probeResult.Path, cmd)
|
||||
|
||||
if err != nil {
|
||||
// error message should be in the stderr stream
|
||||
logger.Errorf("ffmpeg error when running command <%s>: %s", strings.Join(cmd.Args, " "), stderr.String())
|
||||
return stdout.String(), err
|
||||
}
|
||||
|
||||
return stdout.String(), nil
|
||||
}
|
||||
|
||||
38
pkg/ffmpeg/encoder_sprite_screenshot.go
Normal file
38
pkg/ffmpeg/encoder_sprite_screenshot.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package ffmpeg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type SpriteScreenshotOptions struct {
|
||||
Time float64
|
||||
Width int
|
||||
}
|
||||
|
||||
func (e *Encoder) SpriteScreenshot(probeResult VideoFile, options SpriteScreenshotOptions) (image.Image, error) {
|
||||
args := []string{
|
||||
"-v", "error",
|
||||
"-ss", fmt.Sprintf("%v", options.Time),
|
||||
"-i", probeResult.Path,
|
||||
"-vframes", "1",
|
||||
"-vf", fmt.Sprintf("scale=%v:-1", options.Width),
|
||||
"-c:v", "bmp",
|
||||
"-f", "rawvideo",
|
||||
"-",
|
||||
}
|
||||
data, err := e.run(probeResult, args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reader := strings.NewReader(data)
|
||||
|
||||
img, _, err := image.Decode(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return img, err
|
||||
}
|
||||
@@ -64,7 +64,7 @@ func (e *Encoder) Transcode(probeResult VideoFile, options TranscodeOptions) {
|
||||
"-strict", "-2",
|
||||
options.OutputPath,
|
||||
}
|
||||
_, _ = e.run(probeResult, args)
|
||||
_, _ = e.runTranscode(probeResult, args)
|
||||
}
|
||||
|
||||
//transcode the video, remove the audio
|
||||
@@ -84,7 +84,7 @@ func (e *Encoder) TranscodeVideo(probeResult VideoFile, options TranscodeOptions
|
||||
"-vf", "scale=" + scale,
|
||||
options.OutputPath,
|
||||
}
|
||||
_, _ = e.run(probeResult, args)
|
||||
_, _ = e.runTranscode(probeResult, args)
|
||||
}
|
||||
|
||||
//copy the video stream as is, transcode audio
|
||||
@@ -96,7 +96,7 @@ func (e *Encoder) TranscodeAudio(probeResult VideoFile, options TranscodeOptions
|
||||
"-strict", "-2",
|
||||
options.OutputPath,
|
||||
}
|
||||
_, _ = e.run(probeResult, args)
|
||||
_, _ = e.runTranscode(probeResult, args)
|
||||
}
|
||||
|
||||
//copy the video stream as is, drop audio
|
||||
@@ -107,5 +107,5 @@ func (e *Encoder) CopyVideo(probeResult VideoFile, options TranscodeOptions) {
|
||||
"-c:v", "copy",
|
||||
options.OutputPath,
|
||||
}
|
||||
_, _ = e.run(probeResult, args)
|
||||
_, _ = e.runTranscode(probeResult, args)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user