Fix pwd no longer being included in ffmpeg binary search (#4749)

* fix(go): fix pwd no longer being included in ffmpeg binary search. Closes #4747

* fix: updates per feedback
This commit is contained in:
Gabe Kangas
2026-01-17 14:23:39 -08:00
committed by GitHub
parent 93868574a5
commit 0ff73d5e1e
2 changed files with 102 additions and 4 deletions
+9 -4
View File
@@ -260,10 +260,15 @@ func ValidatedFfmpegPath(ffmpegPath string) string {
log.Warnln(ffmpegPath, "is an invalid path to ffmpeg will try to use a copy in your path, if possible")
}
// Look for ffmpeg in the system path or in the current working directory.
ffmpegPath, err := exec.LookPath("ffmpeg")
if ffmpegPath == "" || (err != nil && !errors.Is(err, exec.ErrDot)) || VerifyFFMpegPath(ffmpegPath) != nil {
log.Fatalln("Unable to locate ffmpeg. Either install it globally on your system or put the ffmpeg binary in the same directory as Owncast. The binary must be named ffmpeg.")
// First, check for ffmpeg in the current working directory.
if err := VerifyFFMpegPath("./ffmpeg"); err == nil {
ffmpegPath = "./ffmpeg"
} else {
// Fall back to looking for ffmpeg in the system path.
ffmpegPath, err = exec.LookPath("ffmpeg")
if err != nil || VerifyFFMpegPath(ffmpegPath) != nil {
log.Fatalln("Unable to locate ffmpeg. Either install it globally on your system or put the ffmpeg binary in the same directory as Owncast. The binary must be named ffmpeg.")
}
}
// Resolve to an absolute path.
+93
View File
@@ -1,6 +1,9 @@
package utils
import (
"os"
"path/filepath"
"runtime"
"testing"
)
@@ -26,3 +29,93 @@ func TestPercentageUtilsTest(t *testing.T) {
t.Error("Incorrect percentage calculation.")
}
}
func TestValidatedFfmpegPathPrefersLocalBinary(t *testing.T) {
// Skip on Windows as executable permissions work differently.
if runtime.GOOS == "windows" {
t.Skip("Skipping test on Windows")
}
// Create a temporary directory to act as our working directory.
tempDir, err := os.MkdirTemp("", "ffmpeg-test")
if err != nil {
t.Fatalf("Failed to create temp directory: %v", err)
}
defer os.RemoveAll(tempDir)
// Create a fake ffmpeg executable in the temp directory.
fakeFfmpegPath := filepath.Join(tempDir, "ffmpeg")
if err := os.WriteFile(fakeFfmpegPath, []byte("#!/bin/sh\necho fake"), 0o755); err != nil {
t.Fatalf("Failed to create fake ffmpeg: %v", err)
}
// Save the current working directory and change to the temp directory.
originalWd, err := os.Getwd()
if err != nil {
t.Fatalf("Failed to get current working directory: %v", err)
}
if err := os.Chdir(tempDir); err != nil {
t.Fatalf("Failed to change to temp directory: %v", err)
}
defer os.Chdir(originalWd)
// Call ValidatedFfmpegPath with an empty string to trigger auto-detection.
result := ValidatedFfmpegPath("")
// The result should be the absolute path to our local fake ffmpeg,
// not the system ffmpeg in /usr/bin or similar.
expectedPath, err := filepath.Abs("./ffmpeg")
if err != nil {
t.Fatalf("Failed to get absolute path for fake ffmpeg: %v", err)
}
if result != expectedPath {
t.Errorf("Expected local ffmpeg path %q, got %q", expectedPath, result)
}
}
func TestVerifyFFMpegPath(t *testing.T) {
// Test with non-existent path.
err := VerifyFFMpegPath("/nonexistent/path/to/ffmpeg")
if err == nil {
t.Error("Expected error for non-existent path")
}
// Test with a directory instead of a file.
tempDir, err := os.MkdirTemp("", "ffmpeg-dir-test")
if err != nil {
t.Fatalf("Failed to create temp directory: %v", err)
}
defer os.RemoveAll(tempDir)
err = VerifyFFMpegPath(tempDir)
if err == nil {
t.Error("Expected error when path is a directory")
}
// Test with a non-executable file (Unix only).
if runtime.GOOS != "windows" {
nonExecFile := filepath.Join(tempDir, "nonexec")
if err := os.WriteFile(nonExecFile, []byte("test"), 0o644); err != nil {
t.Fatalf("Failed to create non-executable file: %v", err)
}
err = VerifyFFMpegPath(nonExecFile)
if err == nil {
t.Error("Expected error for non-executable file")
}
}
// Test with a valid executable file.
if runtime.GOOS != "windows" {
execFile := filepath.Join(tempDir, "executable")
if err := os.WriteFile(execFile, []byte("#!/bin/sh\necho test"), 0o755); err != nil {
t.Fatalf("Failed to create executable file: %v", err)
}
err = VerifyFFMpegPath(execFile)
if err != nil {
t.Errorf("Expected no error for valid executable, got: %v", err)
}
}
}