diff --git a/ffmpeg_linux_test.go b/ffmpeg_linux_test.go new file mode 100644 index 0000000..f9fc62e --- /dev/null +++ b/ffmpeg_linux_test.go @@ -0,0 +1,27 @@ +package ffmpeg_go + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCompileWithOptions(t *testing.T) { + out := Input("dummy.mp4").Output("dummy2.mp4") + cmd := out.Compile(SeparateProcessGroup()) + assert.Equal(t, 0, cmd.SysProcAttr.Pgid) + assert.True(t, cmd.SysProcAttr.Setpgid) +} + +func TestGlobalCommandOptions(t *testing.T) { + out := Input("dummy.mp4").Output("dummy2.mp4") + GlobalCommandOptions = append(GlobalCommandOptions, func(cmd *exec.Cmd) { + cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true, Pgid: 0} + }) + defer func() { + GlobalCommandOptions = GlobalCommandOptions[0 : len(GlobalCommandOptions)-1] + }() + cmd := out.Compile() + assert.Equal(t, 0, cmd.SysProcAttr.Pgid) + assert.True(t, cmd.SysProcAttr.Setpgid) +} diff --git a/ffmpeg_test.go b/ffmpeg_test.go index fe137a8..7eb2af7 100644 --- a/ffmpeg_test.go +++ b/ffmpeg_test.go @@ -277,13 +277,6 @@ func TestCompile(t *testing.T) { assert.Equal(t, out.Compile().Args, []string{"ffmpeg", "-i", "dummy.mp4", "dummy2.mp4"}) } -func TestCompileWithOptions(t *testing.T) { - out := Input("dummy.mp4").Output("dummy2.mp4") - cmd := out.Compile(SeparateProcessGroup()) - assert.Equal(t, cmd.SysProcAttr.Pgid, 0) - assert.True(t, cmd.SysProcAttr.Setpgid) -} - func TestPipe(t *testing.T) { width, height := 32, 32 diff --git a/ffmpeg_windows_test.go b/ffmpeg_windows_test.go new file mode 100644 index 0000000..68a677c --- /dev/null +++ b/ffmpeg_windows_test.go @@ -0,0 +1,35 @@ +package ffmpeg_go + +import ( + "os/exec" + "syscall" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCompileWithOptions(t *testing.T) { + out := Input("dummy.mp4").Output("dummy2.mp4") + cmd := out.Compile(func(s *Stream, cmd *exec.Cmd) { + if cmd.SysProcAttr == nil { + cmd.SysProcAttr = &syscall.SysProcAttr{} + } + cmd.SysProcAttr.HideWindow = true + }) + assert.Equal(t, true, cmd.SysProcAttr.HideWindow) +} + +func TestGlobalCommandOptions(t *testing.T) { + out := Input("dummy.mp4").Output("dummy2.mp4") + GlobalCommandOptions = append(GlobalCommandOptions, func(cmd *exec.Cmd) { + if cmd.SysProcAttr == nil { + cmd.SysProcAttr = &syscall.SysProcAttr{} + } + cmd.SysProcAttr.HideWindow = true + }) + defer func() { + GlobalCommandOptions = GlobalCommandOptions[0 : len(GlobalCommandOptions)-1] + }() + cmd := out.Compile() + assert.Equal(t, true, cmd.SysProcAttr.HideWindow) +} diff --git a/probe.go b/probe.go index 7f1318a..93ea902 100644 --- a/probe.go +++ b/probe.go @@ -34,6 +34,9 @@ func ProbeWithTimeoutExec(fileName string, timeOut time.Duration, kwargs KwArgs) cmd := exec.CommandContext(ctx, "ffprobe", args...) buf := bytes.NewBuffer(nil) cmd.Stdout = buf + for _, option := range GlobalCommandOptions { + option(cmd) + } err := cmd.Run() if err != nil { return "", err diff --git a/run.go b/run.go index c852dda..c08c9f2 100644 --- a/run.go +++ b/run.go @@ -9,7 +9,6 @@ import ( "os/exec" "sort" "strings" - "syscall" "time" ) @@ -237,16 +236,11 @@ func (s *Stream) ErrorToStdOut() *Stream { return s.WithErrorOutput(os.Stdout) } -type CompilationOption func(s *Stream, cmd *exec.Cmd) +type CommandOption func(cmd *exec.Cmd) -// SeparateProcessGroup ensures that the command is run in a separate process -// group. This is useful to enable handling of signals such as SIGINT without -// propagating them to the ffmpeg process. -func SeparateProcessGroup() CompilationOption { - return func(s *Stream, cmd *exec.Cmd) { - cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true, Pgid: 0} - } -} +var GlobalCommandOptions = make([]CommandOption, 0) + +type CompilationOption func(s *Stream, cmd *exec.Cmd) func (s *Stream) SetFfmpegPath(path string) *Stream { s.FfmpegPath = path @@ -271,10 +265,10 @@ func (s *Stream) Compile(options ...CompilationOption) *exec.Cmd { if a, ok := s.Context.Value("Stderr").(io.Writer); ok { cmd.Stderr = a } - for _, option := range options { - option(s, cmd) + for _, option := range GlobalCommandOptions { + option(cmd) } - if LogCompiledCommand { + if LogCompiledCommand { log.Printf("compiled command: ffmpeg %s\n", strings.Join(args, " ")) } return cmd diff --git a/run_linux.go b/run_linux.go index afe8213..641a167 100644 --- a/run_linux.go +++ b/run_linux.go @@ -140,3 +140,12 @@ func (s *Stream) RunLinux() error { return cmd.Wait() } + +// SeparateProcessGroup ensures that the command is run in a separate process +// group. This is useful to enable handling of signals such as SIGINT without +// propagating them to the ffmpeg process. +func SeparateProcessGroup() CompilationOption { + return func(s *Stream, cmd *exec.Cmd) { + cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true, Pgid: 0} + } +}