Skip to content

Commit 205828f

Browse files
committed
Add support for compilation options
Add options to the Compile function, and in turn, the Run function in order to modify the compiled command instance before executing it. This is helpful to, for example, specify that the command should be run in a separate process group in order for ffmpeg not to react on SIGINTs sent to the parent proces.
1 parent 98a5c5c commit 205828f

2 files changed

Lines changed: 26 additions & 4 deletions

File tree

ffmpeg_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,13 @@ func TestCompile(t *testing.T) {
277277
assert.Equal(t, out.Compile().Args, []string{"ffmpeg", "-i", "dummy.mp4", "dummy2.mp4"})
278278
}
279279

280+
func TestCompileWithOptions(t *testing.T) {
281+
out := Input("dummy.mp4").Output("dummy2.mp4")
282+
cmd := out.Compile(SeparateProcessGroup())
283+
assert.Equal(t, cmd.SysProcAttr.Pgid, 0)
284+
assert.True(t, cmd.SysProcAttr.Setpgid)
285+
}
286+
280287
func TestPipe(t *testing.T) {
281288

282289
width, height := 32, 32

run.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"os/exec"
1010
"sort"
1111
"strings"
12+
"syscall"
1213
"time"
1314
)
1415

@@ -91,7 +92,7 @@ func _allocateFilterStreamNames(nodes []*Node, outOutingEdgeMaps map[int]map[Lab
9192
// todo sort
9293
for _, l := range _getAllLabelsSorted(om) {
9394
if len(om[l]) > 1 {
94-
panic(fmt.Sprintf(`encountered %s with multiple outgoing edges
95+
panic(fmt.Sprintf(`encountered %s with multiple outgoing edges
9596
with same upstream label %s; a 'split'' filter is probably required`, n.name, l))
9697
}
9798
streamNameMap[fmt.Sprintf("%d%s", n.Hash(), l)] = fmt.Sprintf("s%d", sc)
@@ -236,8 +237,19 @@ func (s *Stream) ErrorToStdOut() *Stream {
236237
return s.WithErrorOutput(os.Stdout)
237238
}
238239

240+
type CompilationOption func(s *Stream, cmd *exec.Cmd)
241+
242+
// SeparateProcessGroup ensures that the command is run in a separate process
243+
// group. This is useful to enable handling of signals such as SIGINT without
244+
// propagating them to the ffmpeg process.
245+
func SeparateProcessGroup() CompilationOption {
246+
return func(s *Stream, cmd *exec.Cmd) {
247+
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true, Pgid: 0}
248+
}
249+
}
250+
239251
// for test
240-
func (s *Stream) Compile() *exec.Cmd {
252+
func (s *Stream) Compile(options ...CompilationOption) *exec.Cmd {
241253
args := s.GetArgs()
242254
cmd := exec.CommandContext(s.Context, "ffmpeg", args...)
243255
if a, ok := s.Context.Value("Stdin").(io.Reader); ok {
@@ -249,11 +261,14 @@ func (s *Stream) Compile() *exec.Cmd {
249261
if a, ok := s.Context.Value("Stderr").(io.Writer); ok {
250262
cmd.Stderr = a
251263
}
264+
for _, option := range options {
265+
option(s, cmd)
266+
}
252267
log.Printf("compiled command: ffmpeg %s\n", strings.Join(args, " "))
253268
return cmd
254269
}
255270

256-
func (s *Stream) Run() error {
271+
func (s *Stream) Run(options ...CompilationOption) error {
257272
if s.Context.Value("run_hook") != nil {
258273
hook := s.Context.Value("run_hook").(*RunHook)
259274
go hook.f()
@@ -264,5 +279,5 @@ func (s *Stream) Run() error {
264279
<-hook.done
265280
}()
266281
}
267-
return s.Compile().Run()
282+
return s.Compile(options...).Run()
268283
}

0 commit comments

Comments
 (0)