diff --git a/internal/clientman/clientman.go b/internal/clientman/clientman.go index e134311a..8d140d5c 100644 --- a/internal/clientman/clientman.go +++ b/internal/clientman/clientman.go @@ -10,8 +10,7 @@ import ( "github.com/aler9/rtsp-simple-server/internal/client" "github.com/aler9/rtsp-simple-server/internal/logger" "github.com/aler9/rtsp-simple-server/internal/pathman" - "github.com/aler9/rtsp-simple-server/internal/serverplain" - "github.com/aler9/rtsp-simple-server/internal/servertls" + "github.com/aler9/rtsp-simple-server/internal/serverrtsp" "github.com/aler9/rtsp-simple-server/internal/stats" ) @@ -29,8 +28,8 @@ type ClientManager struct { protocols map[base.StreamProtocol]struct{} stats *stats.Stats pathMan *pathman.PathManager - serverPlain *serverplain.Server - serverTLS *servertls.Server + serverPlain *serverrtsp.Server + serverTLS *serverrtsp.Server parent Parent clients map[*client.Client]struct{} @@ -53,8 +52,8 @@ func New( protocols map[base.StreamProtocol]struct{}, stats *stats.Stats, pathMan *pathman.PathManager, - serverPlain *serverplain.Server, - serverTLS *servertls.Server, + serverPlain *serverrtsp.Server, + serverTLS *serverrtsp.Server, parent Parent) *ClientManager { cm := &ClientManager{ diff --git a/internal/conf/conf.go b/internal/conf/conf.go index fff4332b..016cf84b 100644 --- a/internal/conf/conf.go +++ b/internal/conf/conf.go @@ -52,13 +52,13 @@ type Conf struct { LogDestinations []string `yaml:"logDestinations"` LogDestinationsParsed map[logger.Destination]struct{} `yaml:"-" json:"-"` LogFile string `yaml:"logFile"` + ListenIP string `yaml:"listenIP"` Protocols []string `yaml:"protocols"` ProtocolsParsed map[gortsplib.StreamProtocol]struct{} `yaml:"-" json:"-"` Encryption string `yaml:"encryption"` EncryptionParsed Encryption `yaml:"-" json:"-"` - ListenIP string `yaml:"listenIP"` - RtspPort int `yaml:"rtspPort"` - RtspsPort int `yaml:"rtspsPort"` + RTSPPort int `yaml:"rtspPort"` + RTSPSPort int `yaml:"rtspsPort"` RTPPort int `yaml:"rtpPort"` RTCPPort int `yaml:"rtcpPort"` ServerKey string `yaml:"serverKey"` @@ -68,6 +68,8 @@ type Conf struct { ReadTimeout time.Duration `yaml:"readTimeout"` WriteTimeout time.Duration `yaml:"writeTimeout"` ReadBufferCount uint64 `yaml:"readBufferCount"` + RTMPEnable bool `yaml:"rtmpEnable"` + RTMPPort int `yaml:"rtmpPort"` Metrics bool `yaml:"metrics"` Pprof bool `yaml:"pprof"` RunOnConnect string `yaml:"runOnConnect"` @@ -158,11 +160,11 @@ func (conf *Conf) fillAndCheck() error { return fmt.Errorf("unsupported encryption value: '%s'", conf.Encryption) } - if conf.RtspPort == 0 { - conf.RtspPort = 8554 + if conf.RTSPPort == 0 { + conf.RTSPPort = 8554 } - if conf.RtspsPort == 0 { - conf.RtspsPort = 8555 + if conf.RTSPSPort == 0 { + conf.RTSPSPort = 8555 } if conf.RTPPort == 0 { conf.RTPPort = 8000 @@ -210,6 +212,10 @@ func (conf *Conf) fillAndCheck() error { conf.ReadBufferCount = 512 } + if conf.RTMPPort == 0 { + conf.RTMPPort = 8888 + } + if len(conf.Paths) == 0 { conf.Paths = map[string]*PathConf{ "all": {}, diff --git a/internal/conf/conf_test.go b/internal/conf/conf_test.go index 6b0590ad..4d6746bb 100644 --- a/internal/conf/conf_test.go +++ b/internal/conf/conf_test.go @@ -79,7 +79,7 @@ func TestEnvironment(t *testing.T) { require.Equal(t, "test=cmd", conf.RunOnConnect) - require.Equal(t, 8555, conf.RtspPort) + require.Equal(t, 8555, conf.RTSPPort) require.Equal(t, true, conf.Metrics) diff --git a/internal/serverplain/server.go b/internal/serverrtsp/server.go similarity index 69% rename from internal/serverplain/server.go rename to internal/serverrtsp/server.go index 320aea58..f22678a2 100644 --- a/internal/serverplain/server.go +++ b/internal/serverrtsp/server.go @@ -1,8 +1,7 @@ -package serverplain +package serverrtsp import ( "strconv" - "time" "github.com/aler9/gortsplib" @@ -14,7 +13,7 @@ type Parent interface { Log(logger.Level, string, ...interface{}) } -// Server is a TCP/RTSP listener. +// Server is a TCP/TLS/RTSPS listener. type Server struct { parent Parent @@ -29,21 +28,9 @@ type Server struct { func New( listenIP string, port int, - readTimeout time.Duration, - writeTimeout time.Duration, - readBufferCount uint64, - udpRTPListener *gortsplib.ServerUDPListener, - udpRTCPListener *gortsplib.ServerUDPListener, + conf gortsplib.ServerConf, parent Parent) (*Server, error) { - conf := gortsplib.ServerConf{ - ReadTimeout: readTimeout, - WriteTimeout: writeTimeout, - ReadBufferCount: readBufferCount, - UDPRTPListener: udpRTPListener, - UDPRTCPListener: udpRTCPListener, - } - address := listenIP + ":" + strconv.FormatInt(int64(port), 10) srv, err := conf.Serve(address) if err != nil { @@ -57,7 +44,14 @@ func New( done: make(chan struct{}), } - parent.Log(logger.Info, "[TCP/RTSP listener] opened on %s", address) + label := func() string { + if conf.TLSConfig != nil { + return "TCP/TLS/RTSPS" + } + return "TCP/RTSP" + }() + + parent.Log(logger.Info, "[%s listener] opened on %s", label, address) go s.run() return s, nil diff --git a/internal/servertls/server.go b/internal/servertls/server.go deleted file mode 100644 index fde85a3b..00000000 --- a/internal/servertls/server.go +++ /dev/null @@ -1,100 +0,0 @@ -package servertls - -import ( - "crypto/tls" - "strconv" - "time" - - "github.com/aler9/gortsplib" - - "github.com/aler9/rtsp-simple-server/internal/logger" -) - -// Parent is implemented by program. -type Parent interface { - Log(logger.Level, string, ...interface{}) -} - -// Server is a TCP/TLS/RTSPS listener. -type Server struct { - parent Parent - - srv *gortsplib.Server - - // out - accept chan *gortsplib.ServerConn - done chan struct{} -} - -// New allocates a Server. -func New( - listenIP string, - port int, - readTimeout time.Duration, - writeTimeout time.Duration, - readBufferCount uint64, - serverKey string, - serverCert string, - parent Parent) (*Server, error) { - - cert, err := tls.LoadX509KeyPair(serverCert, serverKey) - if err != nil { - return nil, err - } - - conf := gortsplib.ServerConf{ - TLSConfig: &tls.Config{Certificates: []tls.Certificate{cert}}, - ReadTimeout: readTimeout, - WriteTimeout: writeTimeout, - ReadBufferCount: readBufferCount, - } - - address := listenIP + ":" + strconv.FormatInt(int64(port), 10) - srv, err := conf.Serve(address) - if err != nil { - return nil, err - } - - s := &Server{ - parent: parent, - srv: srv, - accept: make(chan *gortsplib.ServerConn), - done: make(chan struct{}), - } - - parent.Log(logger.Info, "[TCP/TLS/RTSPS listener] opened on %s", address) - - go s.run() - return s, nil -} - -// Close closes a Server. -func (s *Server) Close() { - go func() { - for co := range s.accept { - co.Close() - } - }() - s.srv.Close() - <-s.done -} - -func (s *Server) run() { - defer close(s.done) - - for { - conn, err := s.srv.Accept() - if err != nil { - break - } - - s.accept <- conn - } - - close(s.accept) -} - -// Accept returns a channel to accept incoming connections. -func (s *Server) Accept() chan *gortsplib.ServerConn { - return s.accept -} diff --git a/main.go b/main.go index a56fdebc..e7804141 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "crypto/tls" "fmt" "os" "reflect" @@ -16,8 +17,7 @@ import ( "github.com/aler9/rtsp-simple-server/internal/metrics" "github.com/aler9/rtsp-simple-server/internal/pathman" "github.com/aler9/rtsp-simple-server/internal/pprof" - "github.com/aler9/rtsp-simple-server/internal/serverplain" - "github.com/aler9/rtsp-simple-server/internal/servertls" + "github.com/aler9/rtsp-simple-server/internal/serverrtsp" "github.com/aler9/rtsp-simple-server/internal/serverudpl" "github.com/aler9/rtsp-simple-server/internal/stats" ) @@ -34,8 +34,8 @@ type program struct { pprof *pprof.Pprof serverUDPRTP *gortsplib.ServerUDPListener serverUDPRTCP *gortsplib.ServerUDPListener - serverPlain *serverplain.Server - serverTLS *servertls.Server + serverPlain *serverrtsp.Server + serverTLS *serverrtsp.Server pathMan *pathman.PathManager clientMan *clientman.ClientManager confWatcher *confwatcher.ConfWatcher @@ -211,14 +211,18 @@ func (p *program) createResources(initial bool) error { if p.serverPlain == nil { if p.conf.EncryptionParsed == conf.EncryptionNo || p.conf.EncryptionParsed == conf.EncryptionOptional { - p.serverPlain, err = serverplain.New( + conf := gortsplib.ServerConf{ + ReadTimeout: p.conf.ReadTimeout, + WriteTimeout: p.conf.WriteTimeout, + ReadBufferCount: p.conf.ReadBufferCount, + UDPRTPListener: p.serverUDPRTP, + UDPRTCPListener: p.serverUDPRTCP, + } + + p.serverPlain, err = serverrtsp.New( p.conf.ListenIP, - p.conf.RtspPort, - p.conf.ReadTimeout, - p.conf.WriteTimeout, - p.conf.ReadBufferCount, - p.serverUDPRTP, - p.serverUDPRTCP, + p.conf.RTSPPort, + conf, p) if err != nil { return err @@ -228,14 +232,22 @@ func (p *program) createResources(initial bool) error { if p.serverTLS == nil { if p.conf.EncryptionParsed == conf.EncryptionStrict || p.conf.EncryptionParsed == conf.EncryptionOptional { - p.serverTLS, err = servertls.New( + cert, err := tls.LoadX509KeyPair(p.conf.ServerCert, p.conf.ServerKey) + if err != nil { + return err + } + + conf := gortsplib.ServerConf{ + TLSConfig: &tls.Config{Certificates: []tls.Certificate{cert}}, + ReadTimeout: p.conf.ReadTimeout, + WriteTimeout: p.conf.WriteTimeout, + ReadBufferCount: p.conf.ReadBufferCount, + } + + p.serverTLS, err = serverrtsp.New( p.conf.ListenIP, - p.conf.RtspsPort, - p.conf.ReadTimeout, - p.conf.WriteTimeout, - p.conf.ReadBufferCount, - p.conf.ServerKey, - p.conf.ServerCert, + p.conf.RTSPSPort, + conf, p) if err != nil { return err @@ -245,7 +257,7 @@ func (p *program) createResources(initial bool) error { if p.pathMan == nil { p.pathMan = pathman.New( - p.conf.RtspPort, + p.conf.RTSPPort, p.conf.ReadTimeout, p.conf.WriteTimeout, p.conf.ReadBufferCount, @@ -257,7 +269,7 @@ func (p *program) createResources(initial bool) error { if p.clientMan == nil { p.clientMan = clientman.New( - p.conf.RtspPort, + p.conf.RTSPPort, p.conf.ReadTimeout, p.conf.RunOnConnect, p.conf.RunOnConnectRestart, @@ -316,7 +328,7 @@ func (p *program) closeResources(newConf *conf.Conf) { if newConf == nil || newConf.EncryptionParsed != p.conf.EncryptionParsed || newConf.ListenIP != p.conf.ListenIP || - newConf.RtspPort != p.conf.RtspPort || + newConf.RTSPPort != p.conf.RTSPPort || newConf.ReadTimeout != p.conf.ReadTimeout || newConf.WriteTimeout != p.conf.WriteTimeout || newConf.ReadBufferCount != p.conf.ReadBufferCount || @@ -329,7 +341,7 @@ func (p *program) closeResources(newConf *conf.Conf) { if newConf == nil || newConf.EncryptionParsed != p.conf.EncryptionParsed || newConf.ListenIP != p.conf.ListenIP || - newConf.RtspsPort != p.conf.RtspsPort || + newConf.RTSPSPort != p.conf.RTSPSPort || newConf.ReadTimeout != p.conf.ReadTimeout || newConf.WriteTimeout != p.conf.WriteTimeout || newConf.ReadBufferCount != p.conf.ReadBufferCount { @@ -338,7 +350,7 @@ func (p *program) closeResources(newConf *conf.Conf) { closePathMan := false if newConf == nil || - newConf.RtspPort != p.conf.RtspPort || + newConf.RTSPPort != p.conf.RTSPPort || newConf.ReadTimeout != p.conf.ReadTimeout || newConf.WriteTimeout != p.conf.WriteTimeout || newConf.ReadBufferCount != p.conf.ReadBufferCount || @@ -353,7 +365,7 @@ func (p *program) closeResources(newConf *conf.Conf) { closeServerPlain || closeServerTLS || closePathMan || - newConf.RtspPort != p.conf.RtspPort || + newConf.RTSPPort != p.conf.RTSPPort || newConf.ReadTimeout != p.conf.ReadTimeout || newConf.RunOnConnect != p.conf.RunOnConnect || newConf.RunOnConnectRestart != p.conf.RunOnConnectRestart ||