mirror of
https://github.com/bluenviron/mediamtx.git
synced 2025-12-29 06:22:00 -08:00
handle external commands with a dedicated struct
This commit is contained in:
parent
e9ce8a0d49
commit
3b79f6beb4
4 changed files with 60 additions and 53 deletions
17
client.go
17
client.go
|
|
@ -5,8 +5,6 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
|
|
@ -192,7 +190,7 @@ var errRunPlay = errors.New("play")
|
|||
var errRunRecord = errors.New("record")
|
||||
|
||||
func (c *client) run() {
|
||||
var onConnectCmd *exec.Cmd
|
||||
var onConnectCmd *externalCmd
|
||||
if c.p.conf.RunOnConnect != "" {
|
||||
var err error
|
||||
onConnectCmd, err = startExternalCommand(c.p.conf.RunOnConnect, "")
|
||||
|
|
@ -208,8 +206,7 @@ func (c *client) run() {
|
|||
}
|
||||
|
||||
if onConnectCmd != nil {
|
||||
onConnectCmd.Process.Signal(os.Interrupt)
|
||||
onConnectCmd.Wait()
|
||||
onConnectCmd.close()
|
||||
}
|
||||
|
||||
close(c.describe)
|
||||
|
|
@ -886,7 +883,7 @@ func (c *client) runPlay() bool {
|
|||
return "tracks"
|
||||
}(), c.streamProtocol)
|
||||
|
||||
var onReadCmd *exec.Cmd
|
||||
var onReadCmd *externalCmd
|
||||
if c.path.conf.RunOnRead != "" {
|
||||
var err error
|
||||
onReadCmd, err = startExternalCommand(c.path.conf.RunOnRead, c.path.name)
|
||||
|
|
@ -902,8 +899,7 @@ func (c *client) runPlay() bool {
|
|||
}
|
||||
|
||||
if onReadCmd != nil {
|
||||
onReadCmd.Process.Signal(os.Interrupt)
|
||||
onReadCmd.Wait()
|
||||
onReadCmd.close()
|
||||
}
|
||||
|
||||
return false
|
||||
|
|
@ -1037,7 +1033,7 @@ func (c *client) runRecord() bool {
|
|||
return "tracks"
|
||||
}(), c.streamProtocol)
|
||||
|
||||
var onPublishCmd *exec.Cmd
|
||||
var onPublishCmd *externalCmd
|
||||
if c.path.conf.RunOnPublish != "" {
|
||||
var err error
|
||||
onPublishCmd, err = startExternalCommand(c.path.conf.RunOnPublish, c.path.name)
|
||||
|
|
@ -1053,8 +1049,7 @@ func (c *client) runRecord() bool {
|
|||
}
|
||||
|
||||
if onPublishCmd != nil {
|
||||
onPublishCmd.Process.Signal(os.Interrupt)
|
||||
onPublishCmd.Wait()
|
||||
onPublishCmd.close()
|
||||
}
|
||||
|
||||
return false
|
||||
|
|
|
|||
49
externalcmd.go
Normal file
49
externalcmd.go
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type externalCmd struct {
|
||||
cmd *exec.Cmd
|
||||
}
|
||||
|
||||
func startExternalCommand(cmdstr string, pathName string) (*externalCmd, error) {
|
||||
var cmd *exec.Cmd
|
||||
if runtime.GOOS == "windows" {
|
||||
// in Windows the shell is not used and command is started directly
|
||||
// variables are replaced manually in order to allow
|
||||
// compatibility with linux commands
|
||||
cmdstr = strings.ReplaceAll(cmdstr, "$RTSP_SERVER_PATH", pathName)
|
||||
args := strings.Fields(cmdstr)
|
||||
cmd = exec.Command(args[0], args[1:]...)
|
||||
|
||||
} else {
|
||||
cmd = exec.Command("/bin/sh", "-c", "exec "+cmdstr)
|
||||
}
|
||||
|
||||
// variables are available through environment variables
|
||||
cmd.Env = append(os.Environ(),
|
||||
"RTSP_SERVER_PATH="+pathName,
|
||||
)
|
||||
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &externalCmd{
|
||||
cmd: cmd,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (e *externalCmd) close() {
|
||||
e.cmd.Process.Signal(os.Interrupt)
|
||||
e.cmd.Wait()
|
||||
}
|
||||
15
path.go
15
path.go
|
|
@ -2,8 +2,6 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
|
@ -29,8 +27,8 @@ type path struct {
|
|||
publisherSdp []byte
|
||||
lastDescribeReq time.Time
|
||||
lastDescribeActivation time.Time
|
||||
onInitCmd *exec.Cmd
|
||||
onDemandCmd *exec.Cmd
|
||||
onInitCmd *externalCmd
|
||||
onDemandCmd *externalCmd
|
||||
}
|
||||
|
||||
func newPath(p *program, name string, conf *pathConf) *path {
|
||||
|
|
@ -77,14 +75,12 @@ func (pa *path) onClose(wait bool) {
|
|||
|
||||
if pa.onInitCmd != nil {
|
||||
pa.log("stopping on init command (closing)")
|
||||
pa.onInitCmd.Process.Signal(os.Interrupt)
|
||||
pa.onInitCmd.Wait()
|
||||
pa.onInitCmd.close()
|
||||
}
|
||||
|
||||
if pa.onDemandCmd != nil {
|
||||
pa.log("stopping on demand command (closing)")
|
||||
pa.onDemandCmd.Process.Signal(os.Interrupt)
|
||||
pa.onDemandCmd.Wait()
|
||||
pa.onDemandCmd.close()
|
||||
}
|
||||
|
||||
for c := range pa.p.clients {
|
||||
|
|
@ -161,8 +157,7 @@ func (pa *path) onCheck() {
|
|||
!pa.hasClientReaders() &&
|
||||
time.Since(pa.lastDescribeReq) >= onDemandCmdStopAfterDescribeSecs {
|
||||
pa.log("stopping on demand command (not requested anymore)")
|
||||
pa.onDemandCmd.Process.Signal(os.Interrupt)
|
||||
pa.onDemandCmd.Wait()
|
||||
pa.onDemandCmd.close()
|
||||
pa.onDemandCmd = nil
|
||||
}
|
||||
|
||||
|
|
|
|||
32
utils.go
32
utils.go
|
|
@ -4,9 +4,7 @@ import (
|
|||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
|
|
@ -137,36 +135,6 @@ func checkPathName(name string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func startExternalCommand(cmdstr string, pathName string) (*exec.Cmd, error) {
|
||||
var cmd *exec.Cmd
|
||||
if runtime.GOOS == "windows" {
|
||||
// in Windows the shell is not used and command is started directly
|
||||
// variables are replaced manually in order to allow
|
||||
// compatibility with linux commands
|
||||
cmdstr = strings.ReplaceAll(cmdstr, "$RTSP_SERVER_PATH", pathName)
|
||||
args := strings.Fields(cmdstr)
|
||||
cmd = exec.Command(args[0], args[1:]...)
|
||||
|
||||
} else {
|
||||
cmd = exec.Command("/bin/sh", "-c", "exec "+cmdstr)
|
||||
}
|
||||
|
||||
// variables are available through environment variables
|
||||
cmd.Env = append(os.Environ(),
|
||||
"RTSP_SERVER_PATH="+pathName,
|
||||
)
|
||||
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func isBindError(err error) bool {
|
||||
if nerr, ok := err.(*net.OpError); ok {
|
||||
if serr, ok := nerr.Err.(*os.SyscallError); ok {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue