From e64edcfda978a00158597665dec7ad76c5f1743c Mon Sep 17 00:00:00 2001 From: aler9 <46489434+aler9@users.noreply.github.com> Date: Fri, 18 Jun 2021 21:15:49 +0200 Subject: [PATCH] RTSP source: support proxing with UDP-multicast --- go.mod | 2 +- go.sum | 4 ++-- internal/conf/path.go | 31 ++++++++++++++++++------------- internal/rtspsource/source.go | 6 +++--- main_rtspreadpub_test.go | 14 +++++++------- rtsp-simple-server.yml | 4 ++-- 6 files changed, 33 insertions(+), 28 deletions(-) diff --git a/go.mod b/go.mod index 07d86524..60842f30 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.15 require ( github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect - github.com/aler9/gortsplib v0.0.0-20210617144524-db28e87ecb0c + github.com/aler9/gortsplib v0.0.0-20210618154725-9595e298f812 github.com/asticode/go-astits v0.0.0-00010101000000-000000000000 github.com/davecgh/go-spew v1.1.1 // indirect github.com/fsnotify/fsnotify v1.4.9 diff --git a/go.sum b/go.sum index 4b0b34c3..9d281e5b 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,8 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2c github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/aler9/go-astits v0.0.0-20210423195926-582b09ed7c04 h1:CXgQLsU4uxWAmsXNOjGLbj0A+0IlRcpZpMgI13fmVwo= github.com/aler9/go-astits v0.0.0-20210423195926-582b09ed7c04/go.mod h1:DkOWmBNQpnr9mv24KfZjq4JawCFX1FCqjLVGvO0DygQ= -github.com/aler9/gortsplib v0.0.0-20210617144524-db28e87ecb0c h1:IqV2N1yifhnVPafY8SknenVL6k66gGa5jhrujcbjl5Q= -github.com/aler9/gortsplib v0.0.0-20210617144524-db28e87ecb0c/go.mod h1:ozu0NvgZMhb4AT6VdyV6OfmgPviSiZImRkaTwW1nEKc= +github.com/aler9/gortsplib v0.0.0-20210618154725-9595e298f812 h1:8MJKyFmw6GMsWfTmG4t2r2BVrjsd5Zgrqu0tvXXj1F4= +github.com/aler9/gortsplib v0.0.0-20210618154725-9595e298f812/go.mod h1:ozu0NvgZMhb4AT6VdyV6OfmgPviSiZImRkaTwW1nEKc= github.com/aler9/rtmp v0.0.0-20210403095203-3be4a5535927 h1:95mXJ5fUCYpBRdSOnLAQAdJHHKxxxJrVCiaqDi965YQ= github.com/aler9/rtmp v0.0.0-20210403095203-3be4a5535927/go.mod h1:vzuE21rowz+lT1NGsWbreIvYulgBpCGnQyeTyFblUHc= github.com/asticode/go-astikit v0.20.0 h1:+7N+J4E4lWx2QOkRdOf6DafWJMv6O4RRfgClwQokrH8= diff --git a/internal/conf/path.go b/internal/conf/path.go index ccd601b3..3035fdb9 100644 --- a/internal/conf/path.go +++ b/internal/conf/path.go @@ -9,6 +9,7 @@ import ( "strings" "time" + "github.com/aler9/gortsplib" "github.com/aler9/gortsplib/pkg/base" ) @@ -68,17 +69,17 @@ type PathConf struct { Regexp *regexp.Regexp `yaml:"-" json:"-"` // source - Source string `yaml:"source"` - SourceProtocol string `yaml:"sourceProtocol"` - SourceProtocolParsed *base.StreamProtocol `yaml:"-" json:"-"` - SourceAnyPortEnable bool `yaml:"sourceAnyPortEnable"` - SourceFingerprint string `yaml:"sourceFingerprint" json:"sourceFingerprint"` - SourceOnDemand bool `yaml:"sourceOnDemand"` - SourceOnDemandStartTimeout time.Duration `yaml:"sourceOnDemandStartTimeout"` - SourceOnDemandCloseAfter time.Duration `yaml:"sourceOnDemandCloseAfter"` - SourceRedirect string `yaml:"sourceRedirect"` - DisablePublisherOverride bool `yaml:"disablePublisherOverride"` - Fallback string `yaml:"fallback"` + Source string `yaml:"source"` + SourceProtocol string `yaml:"sourceProtocol"` + SourceProtocolParsed *gortsplib.ClientProtocol `yaml:"-" json:"-"` + SourceAnyPortEnable bool `yaml:"sourceAnyPortEnable"` + SourceFingerprint string `yaml:"sourceFingerprint" json:"sourceFingerprint"` + SourceOnDemand bool `yaml:"sourceOnDemand"` + SourceOnDemandStartTimeout time.Duration `yaml:"sourceOnDemandStartTimeout"` + SourceOnDemandCloseAfter time.Duration `yaml:"sourceOnDemandCloseAfter"` + SourceRedirect string `yaml:"sourceRedirect"` + DisablePublisherOverride bool `yaml:"disablePublisherOverride"` + Fallback string `yaml:"fallback"` // authentication PublishUser string `yaml:"publishUser"` @@ -148,11 +149,15 @@ func (pconf *PathConf) fillAndCheck(name string) error { switch pconf.SourceProtocol { case "udp": - v := base.StreamProtocolUDP + v := gortsplib.ClientProtocolUDP + pconf.SourceProtocolParsed = &v + + case "multicast": + v := gortsplib.ClientProtocolMulticast pconf.SourceProtocolParsed = &v case "tcp": - v := base.StreamProtocolTCP + v := gortsplib.ClientProtocolTCP pconf.SourceProtocolParsed = &v case "automatic": diff --git a/internal/rtspsource/source.go b/internal/rtspsource/source.go index 94256d47..727973e9 100644 --- a/internal/rtspsource/source.go +++ b/internal/rtspsource/source.go @@ -34,7 +34,7 @@ type Parent interface { // Source is a RTSP external source. type Source struct { ur string - proto *base.StreamProtocol + proto *gortsplib.ClientProtocol anyPortEnable bool fingerprint string readTimeout time.Duration @@ -53,7 +53,7 @@ type Source struct { func New( ctxParent context.Context, ur string, - proto *base.StreamProtocol, + proto *gortsplib.ClientProtocol, anyPortEnable bool, fingerprint string, readTimeout time.Duration, @@ -136,7 +136,7 @@ func (s *Source) runInner() bool { s.log(logger.Debug, "connecting") client := &gortsplib.Client{ - StreamProtocol: s.proto, + Protocol: s.proto, TLSConfig: &tls.Config{ InsecureSkipVerify: true, VerifyConnection: func(cs tls.ConnectionState) error { diff --git a/main_rtspreadpub_test.go b/main_rtspreadpub_test.go index 13e4d147..077b81ff 100644 --- a/main_rtspreadpub_test.go +++ b/main_rtspreadpub_test.go @@ -361,7 +361,7 @@ func TestClientRTSPAuthFail(t *testing.T) { "rtsp://"+ca.user+":"+ca.pass+"@localhost:8554/test/stream", gortsplib.Tracks{track}, ) - require.Equal(t, "wrong status code: 401 (Unauthorized)", err.Error()) + require.Equal(t, "invalid status code: 401 (Unauthorized)", err.Error()) }) } @@ -399,7 +399,7 @@ func TestClientRTSPAuthFail(t *testing.T) { _, err := gortsplib.DialRead( "rtsp://" + ca.user + ":" + ca.pass + "@localhost:8554/test/stream", ) - require.Equal(t, "wrong status code: 401 (Unauthorized)", err.Error()) + require.Equal(t, "invalid status code: 401 (Unauthorized)", err.Error()) }) } @@ -419,7 +419,7 @@ func TestClientRTSPAuthFail(t *testing.T) { "rtsp://localhost:8554/test/stream", gortsplib.Tracks{track}, ) - require.Equal(t, "wrong status code: 401 (Unauthorized)", err.Error()) + require.Equal(t, "invalid status code: 401 (Unauthorized)", err.Error()) }) } @@ -548,8 +548,8 @@ func TestClientRTSPNonCompliantFrameSize(t *testing.T) { require.NoError(t, err) client := &gortsplib.Client{ - StreamProtocol: func() *base.StreamProtocol { - v := base.StreamProtocolTCP + Protocol: func() *gortsplib.ClientProtocol { + v := gortsplib.ClientProtocolTCP return &v }(), ReadBufferSize: 4500, @@ -598,8 +598,8 @@ func TestClientRTSPNonCompliantFrameSize(t *testing.T) { require.NoError(t, err) client := &gortsplib.Client{ - StreamProtocol: func() *base.StreamProtocol { - v := base.StreamProtocolTCP + Protocol: func() *gortsplib.ClientProtocol { + v := gortsplib.ClientProtocolTCP return &v }(), ReadBufferSize: 4500, diff --git a/rtsp-simple-server.yml b/rtsp-simple-server.yml index af480f0a..df0c310e 100644 --- a/rtsp-simple-server.yml +++ b/rtsp-simple-server.yml @@ -116,8 +116,8 @@ paths: source: record # if the source is an RTSP or RTSPS URL, this is the protocol that will be used to - # pull the stream. available options are "automatic", "udp", "tcp". - # the tcp protocol can help to overcome the error "no UDP packets received recently". + # pull the stream. available options are "automatic", "udp", "multicast", "tcp". + # the TCP protocol can help to overcome the error "no UDP packets received recently". sourceProtocol: automatic # if the source is an RTSP or RTSPS URL, this allows to support cameras that