mirror of
https://github.com/u2takey/ffmpeg-go.git
synced 2025-10-04 15:42:41 +08:00
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.
This commit is contained in:
@@ -277,6 +277,13 @@ func TestCompile(t *testing.T) {
|
|||||||
assert.Equal(t, out.Compile().Args, []string{"ffmpeg", "-i", "dummy.mp4", "dummy2.mp4"})
|
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) {
|
func TestPipe(t *testing.T) {
|
||||||
|
|
||||||
width, height := 32, 32
|
width, height := 32, 32
|
||||||
|
23
run.go
23
run.go
@@ -9,6 +9,7 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -91,7 +92,7 @@ func _allocateFilterStreamNames(nodes []*Node, outOutingEdgeMaps map[int]map[Lab
|
|||||||
// todo sort
|
// todo sort
|
||||||
for _, l := range _getAllLabelsSorted(om) {
|
for _, l := range _getAllLabelsSorted(om) {
|
||||||
if len(om[l]) > 1 {
|
if len(om[l]) > 1 {
|
||||||
panic(fmt.Sprintf(`encountered %s with multiple outgoing edges
|
panic(fmt.Sprintf(`encountered %s with multiple outgoing edges
|
||||||
with same upstream label %s; a 'split'' filter is probably required`, n.name, l))
|
with same upstream label %s; a 'split'' filter is probably required`, n.name, l))
|
||||||
}
|
}
|
||||||
streamNameMap[fmt.Sprintf("%d%s", n.Hash(), l)] = fmt.Sprintf("s%d", sc)
|
streamNameMap[fmt.Sprintf("%d%s", n.Hash(), l)] = fmt.Sprintf("s%d", sc)
|
||||||
@@ -236,8 +237,19 @@ func (s *Stream) ErrorToStdOut() *Stream {
|
|||||||
return s.WithErrorOutput(os.Stdout)
|
return s.WithErrorOutput(os.Stdout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CompilationOption func(s *Stream, 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}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// for test
|
// for test
|
||||||
func (s *Stream) Compile() *exec.Cmd {
|
func (s *Stream) Compile(options ...CompilationOption) *exec.Cmd {
|
||||||
args := s.GetArgs()
|
args := s.GetArgs()
|
||||||
cmd := exec.CommandContext(s.Context, "ffmpeg", args...)
|
cmd := exec.CommandContext(s.Context, "ffmpeg", args...)
|
||||||
if a, ok := s.Context.Value("Stdin").(io.Reader); ok {
|
if a, ok := s.Context.Value("Stdin").(io.Reader); ok {
|
||||||
@@ -249,11 +261,14 @@ func (s *Stream) Compile() *exec.Cmd {
|
|||||||
if a, ok := s.Context.Value("Stderr").(io.Writer); ok {
|
if a, ok := s.Context.Value("Stderr").(io.Writer); ok {
|
||||||
cmd.Stderr = a
|
cmd.Stderr = a
|
||||||
}
|
}
|
||||||
|
for _, option := range options {
|
||||||
|
option(s, cmd)
|
||||||
|
}
|
||||||
log.Printf("compiled command: ffmpeg %s\n", strings.Join(args, " "))
|
log.Printf("compiled command: ffmpeg %s\n", strings.Join(args, " "))
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Stream) Run() error {
|
func (s *Stream) Run(options ...CompilationOption) error {
|
||||||
if s.Context.Value("run_hook") != nil {
|
if s.Context.Value("run_hook") != nil {
|
||||||
hook := s.Context.Value("run_hook").(*RunHook)
|
hook := s.Context.Value("run_hook").(*RunHook)
|
||||||
go hook.f()
|
go hook.f()
|
||||||
@@ -264,5 +279,5 @@ func (s *Stream) Run() error {
|
|||||||
<-hook.done
|
<-hook.done
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
return s.Compile().Run()
|
return s.Compile(options...).Run()
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user