diff --git a/pkg/ffmpeg/ffmpeg.go b/pkg/ffmpeg/ffmpeg.go index a7ca71c73..90c500520 100644 --- a/pkg/ffmpeg/ffmpeg.go +++ b/pkg/ffmpeg/ffmpeg.go @@ -54,7 +54,15 @@ func (a *Args) HasFilters(filters ...string) bool { func (a *Args) String() string { b := bytes.NewBuffer(make([]byte, 0, 512)) - b.WriteString(a.Bin) + // quote binary path with spaces (ex. C:\Program Files\ffmpeg.exe), + // so shell.QuoteSplit keeps it as a single argument + if strings.Contains(a.Bin, " ") { + b.WriteByte('"') + b.WriteString(a.Bin) + b.WriteByte('"') + } else { + b.WriteString(a.Bin) + } if a.Global != "" { b.WriteByte(' ') diff --git a/pkg/ffmpeg/ffmpeg_test.go b/pkg/ffmpeg/ffmpeg_test.go new file mode 100644 index 000000000..0d33f4ea1 --- /dev/null +++ b/pkg/ffmpeg/ffmpeg_test.go @@ -0,0 +1,25 @@ +package ffmpeg + +import ( + "testing" + + "github.com/AlexxIT/go2rtc/pkg/shell" + "github.com/stretchr/testify/require" +) + +func TestBinWithSpaces(t *testing.T) { + args := Args{ + Bin: `C:\Program Files\Symcon\ffmpeg.exe`, + Global: "-hide_banner", + Input: "-i rtsp://example.com", + Output: "-f mjpeg -", + } + + s := args.String() + require.Equal(t, `"C:\Program Files\Symcon\ffmpeg.exe" -hide_banner -i rtsp://example.com -f mjpeg -`, s) + + // shell.QuoteSplit is how internal/exec parses this string back + split := shell.QuoteSplit(s) + require.Equal(t, `C:\Program Files\Symcon\ffmpeg.exe`, split[0]) + require.Equal(t, "-hide_banner", split[1]) +}