From 8ffa1d53e9c69db014fdd742d0779f0adfbc2b7e Mon Sep 17 00:00:00 2001 From: aler9 <46489434+aler9@users.noreply.github.com> Date: Fri, 31 Jul 2020 18:12:42 +0200 Subject: [PATCH] add runOnInit --- README.md | 27 +++++++-------------------- conf.go | 5 +++-- main.go | 21 +++++++++++++++++++++ rtsp-simple-server.yml | 5 +++++ 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 71cbe3ff..3692bc62 100644 --- a/README.md +++ b/README.md @@ -87,26 +87,18 @@ paths: source: rtsp://original-url ``` -Start the server: -``` -./rtsp-simple-server -``` - -Users can then connect to `rtsp://localhost:8554/proxied`, instead of connecting to the original url. The server supports any number of source streams, it's enough to add additional entries to the `paths` section. +After starting the server, users can connect to `rtsp://localhost:8554/proxied`, instead of connecting to the original url. The server supports any number of source streams, it's enough to add additional entries to the `paths` section. #### Convert a webcam into a RTSP server -Start the server: -``` -./rtsp-simple-server +Edit `rtsp-simple-server.yml` and replace everything inside section `paths` with the following content: +```yaml +paths: + webcam: + runOnInit: ffmpeg -f v4l2 -i /dev/video0 -f rtsp rtsp://localhost:8554/mystream ``` -Publish the webcam: -``` -ffmpeg -f v4l2 -i /dev/video0 -f rtsp rtsp://localhost:8554/mystream -``` - -The last command works only on Linux; for Windows and Mac equivalents, read the [ffmpeg wiki](https://trac.ffmpeg.org/wiki/Capture/Webcam). +After starting the server, the webcam can be opened with `rtsp://localhost:8554/webcam`. The ffmpeg command works only on Linux; for Windows and Mac equivalents, read the [ffmpeg wiki](https://trac.ffmpeg.org/wiki/Capture/Webcam). #### On-demand publishing @@ -141,11 +133,6 @@ paths: publishPass: mypassword ``` -Start the server: -``` -./rtsp-simple-server -``` - Only publishers that provide both username and password will be able to proceed: ``` ffmpeg -re -stream_loop -1 -i file.ts -c copy -f rtsp rtsp://admin:mypassword@localhost:8554/mystream diff --git a/conf.go b/conf.go index 870f7d8e..991706b5 100644 --- a/conf.go +++ b/conf.go @@ -18,6 +18,7 @@ type confPath struct { SourceProtocol string `yaml:"sourceProtocol"` sourceProtocolParsed gortsplib.StreamProtocol `` SourceOnDemand bool `yaml:"sourceOnDemand"` + RunOnInit string `yaml:"runOnInit"` RunOnDemand string `yaml:"runOnDemand"` RunOnPublish string `yaml:"runOnPublish"` RunOnRead string `yaml:"runOnRead"` @@ -185,7 +186,7 @@ func loadConf(fpath string, stdin io.Reader) (*conf, error) { if confp.Source != "record" { if path == "all" { - return nil, fmt.Errorf("path 'all' cannot have a RTSP source") + return nil, fmt.Errorf("path 'all' cannot have a RTSP source; use another path") } if confp.SourceProtocol == "" { @@ -260,7 +261,7 @@ func loadConf(fpath string, stdin io.Reader) (*conf, error) { } if confp.RunOnDemand != "" && path == "all" { - return nil, fmt.Errorf("option 'runOnDemand' cannot be used in path 'all'") + return nil, fmt.Errorf("path 'all' does not support option 'runOnDemand'; use another path") } } diff --git a/main.go b/main.go index b59fff2e..307a4007 100644 --- a/main.go +++ b/main.go @@ -8,6 +8,7 @@ import ( "net/http" _ "net/http/pprof" "os" + "os/exec" "time" "github.com/aler9/gortsplib" @@ -176,6 +177,7 @@ type program struct { sources []*source clients map[*client]struct{} paths map[string]*path + cmds []*exec.Cmd publisherCount int readerCount int @@ -263,6 +265,20 @@ func newProgram(args []string, stdin io.Reader) (*program, error) { return nil, err } + for _, confp := range conf.Paths { + if confp.RunOnInit != "" { + onInitCmd := exec.Command("/bin/sh", "-c", confp.RunOnInit) + onInitCmd.Stdout = os.Stdout + onInitCmd.Stderr = os.Stderr + err := onInitCmd.Start() + if err != nil { + p.log("ERR: %s", err) + } + + p.cmds = append(p.cmds, onInitCmd) + } + } + if p.metrics != nil { go p.metrics.run() } @@ -495,6 +511,11 @@ outer: } }() + for _, cmd := range p.cmds { + cmd.Process.Signal(os.Interrupt) + cmd.Wait() + } + for _, s := range p.sources { s.events <- sourceEventTerminate{} <-s.done diff --git a/rtsp-simple-server.yml b/rtsp-simple-server.yml index 74a3c971..67db2919 100644 --- a/rtsp-simple-server.yml +++ b/rtsp-simple-server.yml @@ -40,6 +40,11 @@ paths: # is connected, saving bandwidth sourceOnDemand: no + # command to run when this path is loaded by the program. + # this can be used, for example, to publish a stream and keep it always opened. + # This is terminated with SIGINT when the program closes. + runOnInit: + # command to run when this path is requested. # This can be used, for example, to publish a stream on demand. # This is terminated with SIGINT when the path is not requested anymore.