mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 12:24:38 +03:00
Change ffmpeg handling (#4688)
* Make ffmpeg/ffprobe settable and remove auto download * Detect when ffmpeg not present in setup * Add download ffmpeg task * Add download ffmpeg button in system settings * Download ffmpeg during setup
This commit is contained in:
@@ -3,11 +3,96 @@ package ffmpeg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
stashExec "github.com/stashapp/stash/pkg/exec"
|
||||
"github.com/stashapp/stash/pkg/fsutil"
|
||||
"github.com/stashapp/stash/pkg/logger"
|
||||
)
|
||||
|
||||
func ValidateFFMpeg(ffmpegPath string) error {
|
||||
cmd := stashExec.Command(ffmpegPath, "-h")
|
||||
bytes, err := cmd.CombinedOutput()
|
||||
output := string(bytes)
|
||||
if err != nil {
|
||||
var exitErr *exec.ExitError
|
||||
if errors.As(err, &exitErr) {
|
||||
return fmt.Errorf("error running ffmpeg: %v", output)
|
||||
}
|
||||
|
||||
return fmt.Errorf("error running ffmpeg: %v", err)
|
||||
}
|
||||
|
||||
if !strings.Contains(output, "--enable-libopus") {
|
||||
return fmt.Errorf("ffmpeg is missing libopus support")
|
||||
}
|
||||
if !strings.Contains(output, "--enable-libvpx") {
|
||||
return fmt.Errorf("ffmpeg is missing libvpx support")
|
||||
}
|
||||
if !strings.Contains(output, "--enable-libx264") {
|
||||
return fmt.Errorf("ffmpeg is missing libx264 support")
|
||||
}
|
||||
if !strings.Contains(output, "--enable-libx265") {
|
||||
return fmt.Errorf("ffmpeg is missing libx265 support")
|
||||
}
|
||||
if !strings.Contains(output, "--enable-libwebp") {
|
||||
return fmt.Errorf("ffmpeg is missing libwebp support")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func LookPathFFMpeg() string {
|
||||
ret, _ := exec.LookPath(getFFMpegFilename())
|
||||
|
||||
if ret != "" {
|
||||
// ensure ffmpeg has the correct flags
|
||||
if err := ValidateFFMpeg(ret); err != nil {
|
||||
logger.Warnf("ffmpeg found in PATH (%s), but it is missing required flags: %v", ret, err)
|
||||
ret = ""
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func FindFFMpeg(path string) string {
|
||||
ret := fsutil.FindInPaths([]string{path}, getFFMpegFilename())
|
||||
|
||||
if ret != "" {
|
||||
// ensure ffmpeg has the correct flags
|
||||
if err := ValidateFFMpeg(ret); err != nil {
|
||||
logger.Warnf("ffmpeg found (%s), but it is missing required flags: %v", ret, err)
|
||||
ret = ""
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// ResolveFFMpeg attempts to resolve the path to the ffmpeg executable.
|
||||
// It first looks in the provided path, then resolves from the environment, and finally looks in the fallback path.
|
||||
// Returns an empty string if a valid ffmpeg cannot be found.
|
||||
func ResolveFFMpeg(path string, fallbackPath string) string {
|
||||
// look in the provided path first
|
||||
ret := FindFFMpeg(path)
|
||||
if ret != "" {
|
||||
return ret
|
||||
}
|
||||
|
||||
// then resolve from the environment
|
||||
ret = LookPathFFMpeg()
|
||||
if ret != "" {
|
||||
return ret
|
||||
}
|
||||
|
||||
// finally, look in the fallback path
|
||||
ret = FindFFMpeg(fallbackPath)
|
||||
return ret
|
||||
}
|
||||
|
||||
// FFMpeg provides an interface to ffmpeg.
|
||||
type FFMpeg struct {
|
||||
ffmpeg string
|
||||
@@ -27,3 +112,7 @@ func NewEncoder(ffmpegPath string) *FFMpeg {
|
||||
func (f *FFMpeg) Command(ctx context.Context, args []string) *exec.Cmd {
|
||||
return stashExec.CommandContext(ctx, string(f.ffmpeg), args...)
|
||||
}
|
||||
|
||||
func (f *FFMpeg) Path() string {
|
||||
return f.ffmpeg
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user