RTSP source: support proxing with UDP-multicast
This commit is contained in:
parent
75e1e3e4dc
commit
e64edcfda9
2
go.mod
2
go.mod
|
@ -5,7 +5,7 @@ go 1.15
|
||||||
require (
|
require (
|
||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
|
||||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // 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/asticode/go-astits v0.0.0-00010101000000-000000000000
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.4.9
|
github.com/fsnotify/fsnotify v1.4.9
|
||||||
|
|
4
go.sum
4
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/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 h1:CXgQLsU4uxWAmsXNOjGLbj0A+0IlRcpZpMgI13fmVwo=
|
||||||
github.com/aler9/go-astits v0.0.0-20210423195926-582b09ed7c04/go.mod h1:DkOWmBNQpnr9mv24KfZjq4JawCFX1FCqjLVGvO0DygQ=
|
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-20210618154725-9595e298f812 h1:8MJKyFmw6GMsWfTmG4t2r2BVrjsd5Zgrqu0tvXXj1F4=
|
||||||
github.com/aler9/gortsplib v0.0.0-20210617144524-db28e87ecb0c/go.mod h1:ozu0NvgZMhb4AT6VdyV6OfmgPviSiZImRkaTwW1nEKc=
|
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 h1:95mXJ5fUCYpBRdSOnLAQAdJHHKxxxJrVCiaqDi965YQ=
|
||||||
github.com/aler9/rtmp v0.0.0-20210403095203-3be4a5535927/go.mod h1:vzuE21rowz+lT1NGsWbreIvYulgBpCGnQyeTyFblUHc=
|
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=
|
github.com/asticode/go-astikit v0.20.0 h1:+7N+J4E4lWx2QOkRdOf6DafWJMv6O4RRfgClwQokrH8=
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/aler9/gortsplib"
|
||||||
"github.com/aler9/gortsplib/pkg/base"
|
"github.com/aler9/gortsplib/pkg/base"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -68,17 +69,17 @@ type PathConf struct {
|
||||||
Regexp *regexp.Regexp `yaml:"-" json:"-"`
|
Regexp *regexp.Regexp `yaml:"-" json:"-"`
|
||||||
|
|
||||||
// source
|
// source
|
||||||
Source string `yaml:"source"`
|
Source string `yaml:"source"`
|
||||||
SourceProtocol string `yaml:"sourceProtocol"`
|
SourceProtocol string `yaml:"sourceProtocol"`
|
||||||
SourceProtocolParsed *base.StreamProtocol `yaml:"-" json:"-"`
|
SourceProtocolParsed *gortsplib.ClientProtocol `yaml:"-" json:"-"`
|
||||||
SourceAnyPortEnable bool `yaml:"sourceAnyPortEnable"`
|
SourceAnyPortEnable bool `yaml:"sourceAnyPortEnable"`
|
||||||
SourceFingerprint string `yaml:"sourceFingerprint" json:"sourceFingerprint"`
|
SourceFingerprint string `yaml:"sourceFingerprint" json:"sourceFingerprint"`
|
||||||
SourceOnDemand bool `yaml:"sourceOnDemand"`
|
SourceOnDemand bool `yaml:"sourceOnDemand"`
|
||||||
SourceOnDemandStartTimeout time.Duration `yaml:"sourceOnDemandStartTimeout"`
|
SourceOnDemandStartTimeout time.Duration `yaml:"sourceOnDemandStartTimeout"`
|
||||||
SourceOnDemandCloseAfter time.Duration `yaml:"sourceOnDemandCloseAfter"`
|
SourceOnDemandCloseAfter time.Duration `yaml:"sourceOnDemandCloseAfter"`
|
||||||
SourceRedirect string `yaml:"sourceRedirect"`
|
SourceRedirect string `yaml:"sourceRedirect"`
|
||||||
DisablePublisherOverride bool `yaml:"disablePublisherOverride"`
|
DisablePublisherOverride bool `yaml:"disablePublisherOverride"`
|
||||||
Fallback string `yaml:"fallback"`
|
Fallback string `yaml:"fallback"`
|
||||||
|
|
||||||
// authentication
|
// authentication
|
||||||
PublishUser string `yaml:"publishUser"`
|
PublishUser string `yaml:"publishUser"`
|
||||||
|
@ -148,11 +149,15 @@ func (pconf *PathConf) fillAndCheck(name string) error {
|
||||||
|
|
||||||
switch pconf.SourceProtocol {
|
switch pconf.SourceProtocol {
|
||||||
case "udp":
|
case "udp":
|
||||||
v := base.StreamProtocolUDP
|
v := gortsplib.ClientProtocolUDP
|
||||||
|
pconf.SourceProtocolParsed = &v
|
||||||
|
|
||||||
|
case "multicast":
|
||||||
|
v := gortsplib.ClientProtocolMulticast
|
||||||
pconf.SourceProtocolParsed = &v
|
pconf.SourceProtocolParsed = &v
|
||||||
|
|
||||||
case "tcp":
|
case "tcp":
|
||||||
v := base.StreamProtocolTCP
|
v := gortsplib.ClientProtocolTCP
|
||||||
pconf.SourceProtocolParsed = &v
|
pconf.SourceProtocolParsed = &v
|
||||||
|
|
||||||
case "automatic":
|
case "automatic":
|
||||||
|
|
|
@ -34,7 +34,7 @@ type Parent interface {
|
||||||
// Source is a RTSP external source.
|
// Source is a RTSP external source.
|
||||||
type Source struct {
|
type Source struct {
|
||||||
ur string
|
ur string
|
||||||
proto *base.StreamProtocol
|
proto *gortsplib.ClientProtocol
|
||||||
anyPortEnable bool
|
anyPortEnable bool
|
||||||
fingerprint string
|
fingerprint string
|
||||||
readTimeout time.Duration
|
readTimeout time.Duration
|
||||||
|
@ -53,7 +53,7 @@ type Source struct {
|
||||||
func New(
|
func New(
|
||||||
ctxParent context.Context,
|
ctxParent context.Context,
|
||||||
ur string,
|
ur string,
|
||||||
proto *base.StreamProtocol,
|
proto *gortsplib.ClientProtocol,
|
||||||
anyPortEnable bool,
|
anyPortEnable bool,
|
||||||
fingerprint string,
|
fingerprint string,
|
||||||
readTimeout time.Duration,
|
readTimeout time.Duration,
|
||||||
|
@ -136,7 +136,7 @@ func (s *Source) runInner() bool {
|
||||||
s.log(logger.Debug, "connecting")
|
s.log(logger.Debug, "connecting")
|
||||||
|
|
||||||
client := &gortsplib.Client{
|
client := &gortsplib.Client{
|
||||||
StreamProtocol: s.proto,
|
Protocol: s.proto,
|
||||||
TLSConfig: &tls.Config{
|
TLSConfig: &tls.Config{
|
||||||
InsecureSkipVerify: true,
|
InsecureSkipVerify: true,
|
||||||
VerifyConnection: func(cs tls.ConnectionState) error {
|
VerifyConnection: func(cs tls.ConnectionState) error {
|
||||||
|
|
|
@ -361,7 +361,7 @@ func TestClientRTSPAuthFail(t *testing.T) {
|
||||||
"rtsp://"+ca.user+":"+ca.pass+"@localhost:8554/test/stream",
|
"rtsp://"+ca.user+":"+ca.pass+"@localhost:8554/test/stream",
|
||||||
gortsplib.Tracks{track},
|
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(
|
_, err := gortsplib.DialRead(
|
||||||
"rtsp://" + ca.user + ":" + ca.pass + "@localhost:8554/test/stream",
|
"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",
|
"rtsp://localhost:8554/test/stream",
|
||||||
gortsplib.Tracks{track},
|
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)
|
require.NoError(t, err)
|
||||||
|
|
||||||
client := &gortsplib.Client{
|
client := &gortsplib.Client{
|
||||||
StreamProtocol: func() *base.StreamProtocol {
|
Protocol: func() *gortsplib.ClientProtocol {
|
||||||
v := base.StreamProtocolTCP
|
v := gortsplib.ClientProtocolTCP
|
||||||
return &v
|
return &v
|
||||||
}(),
|
}(),
|
||||||
ReadBufferSize: 4500,
|
ReadBufferSize: 4500,
|
||||||
|
@ -598,8 +598,8 @@ func TestClientRTSPNonCompliantFrameSize(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
client := &gortsplib.Client{
|
client := &gortsplib.Client{
|
||||||
StreamProtocol: func() *base.StreamProtocol {
|
Protocol: func() *gortsplib.ClientProtocol {
|
||||||
v := base.StreamProtocolTCP
|
v := gortsplib.ClientProtocolTCP
|
||||||
return &v
|
return &v
|
||||||
}(),
|
}(),
|
||||||
ReadBufferSize: 4500,
|
ReadBufferSize: 4500,
|
||||||
|
|
|
@ -116,8 +116,8 @@ paths:
|
||||||
source: record
|
source: record
|
||||||
|
|
||||||
# if the source is an RTSP or RTSPS URL, this is the protocol that will be used to
|
# 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".
|
# pull the stream. available options are "automatic", "udp", "multicast", "tcp".
|
||||||
# the tcp protocol can help to overcome the error "no UDP packets received recently".
|
# the TCP protocol can help to overcome the error "no UDP packets received recently".
|
||||||
sourceProtocol: automatic
|
sourceProtocol: automatic
|
||||||
|
|
||||||
# if the source is an RTSP or RTSPS URL, this allows to support cameras that
|
# if the source is an RTSP or RTSPS URL, this allows to support cameras that
|
||||||
|
|
Loading…
Reference in New Issue