rtsp: support encrypting UDP and UDP-multicast streams (#4690)

This commit is contained in:
Alessandro Ros 2025-07-05 13:46:59 +02:00 committed by GitHub
parent 81af4075f0
commit c475f84e5d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 131 additions and 90 deletions

View file

@ -301,7 +301,14 @@ The RTSP protocol supports multiple underlying transport protocols, each with it
```sh ```sh
gst-launch-1.0 filesrc location=file.mp4 ! qtdemux name=d \ gst-launch-1.0 filesrc location=file.mp4 ! qtdemux name=d \
d.video_0 ! rtspclientsink protocols=tcp name=s location=rtsp://localhost:8554/mystream d.video_0 ! rtspclientsink location=rtsp://localhost:8554/mystream protocols=tcp
```
If encryption is enabled, the `tls-validation-flags` and `profiles` options must be specified too:
```sh
gst-launch-1.0 filesrc location=file.mp4 ! qtdemux name=d \
d.video_0 ! rtspclientsink location=rtsp://localhost:8554/mystream tls-validation-flags=0 profiles=GST_RTSP_PROFILE_SAVP
``` ```
The resulting stream is available in path `/mystream`. The resulting stream is available in path `/mystream`.
@ -2407,9 +2414,9 @@ ffmpeg -i rtsp://original-source \
The RTSP protocol supports different underlying transport protocols, that are chosen by clients during the handshake with the server: The RTSP protocol supports different underlying transport protocols, that are chosen by clients during the handshake with the server:
* UDP: the most performant, but doesn't work when there's a NAT/firewall between server and clients. It doesn't support encryption. * UDP: the most performant, but doesn't work when there's a NAT/firewall between server and clients.
* UDP-multicast: allows to save bandwidth when clients are all in the same LAN, by sending packets once to a fixed multicast IP. It doesn't support encryption. * UDP-multicast: allows to save bandwidth when clients are all in the same LAN, by sending packets once to a fixed multicast IP.
* TCP: the most versatile, does support encryption. * TCP: the most versatile.
The default transport protocol is UDP. To change the transport protocol, you have to tune the configuration of your client of choice. The default transport protocol is UDP. To change the transport protocol, you have to tune the configuration of your client of choice.
@ -2422,10 +2429,9 @@ openssl genrsa -out server.key 2048
openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650 openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650
``` ```
Edit `mediamtx.yml` and set the `rtspTransports`, `encryption`, `serverKey` and serverCert parameters: Edit `mediamtx.yml` and set the `encryption`, `serverKey` and serverCert parameters:
```yml ```yml
rtspTransports: [tcp]
rtspEncryption: optional rtspEncryption: optional
rtspServerKey: server.key rtspServerKey: server.key
rtspServerCert: server.crt rtspServerCert: server.crt

View file

@ -195,6 +195,14 @@ components:
type: integer type: integer
multicastRTCPPort: multicastRTCPPort:
type: integer type: integer
srtpAddress:
type: string
srtcpAddress:
type: string
multicastSRTPPort:
type: integer
multicastSRTCPPort:
type: integer
rtspServerKey: rtspServerKey:
type: string type: string
rtspServerCert: rtspServerCert:

4
go.mod
View file

@ -10,7 +10,7 @@ require (
github.com/alecthomas/kong v1.12.0 github.com/alecthomas/kong v1.12.0
github.com/asticode/go-astits v1.13.0 github.com/asticode/go-astits v1.13.0
github.com/bluenviron/gohlslib/v2 v2.2.0 github.com/bluenviron/gohlslib/v2 v2.2.0
github.com/bluenviron/gortsplib/v4 v4.14.1 github.com/bluenviron/gortsplib/v4 v4.14.2-0.20250705110245-9c1011567a97
github.com/bluenviron/mediacommon/v2 v2.2.0 github.com/bluenviron/mediacommon/v2 v2.2.0
github.com/datarhei/gosrt v0.9.0 github.com/datarhei/gosrt v0.9.0
github.com/fsnotify/fsnotify v1.9.0 github.com/fsnotify/fsnotify v1.9.0
@ -73,7 +73,7 @@ require (
github.com/pion/mdns/v2 v2.0.7 // indirect github.com/pion/mdns/v2 v2.0.7 // indirect
github.com/pion/randutil v0.1.0 // indirect github.com/pion/randutil v0.1.0 // indirect
github.com/pion/sctp v1.8.36 // indirect github.com/pion/sctp v1.8.36 // indirect
github.com/pion/srtp/v3 v3.0.4 // indirect github.com/pion/srtp/v3 v3.0.6 // indirect
github.com/pion/stun/v3 v3.0.0 // indirect github.com/pion/stun/v3 v3.0.0 // indirect
github.com/pion/transport/v3 v3.0.7 // indirect github.com/pion/transport/v3 v3.0.7 // indirect
github.com/pion/turn/v4 v4.0.0 // indirect github.com/pion/turn/v4 v4.0.0 // indirect

8
go.sum
View file

@ -35,8 +35,8 @@ github.com/benburkert/openpgp v0.0.0-20160410205803-c2471f86866c h1:8XZeJrs4+ZYh
github.com/benburkert/openpgp v0.0.0-20160410205803-c2471f86866c/go.mod h1:x1vxHcL/9AVzuk5HOloOEPrtJY0MaalYr78afXZ+pWI= github.com/benburkert/openpgp v0.0.0-20160410205803-c2471f86866c/go.mod h1:x1vxHcL/9AVzuk5HOloOEPrtJY0MaalYr78afXZ+pWI=
github.com/bluenviron/gohlslib/v2 v2.2.0 h1:eIsCai3IHP0F538h2tCPCRkhQ7XSOaxeceMyPns0o1k= github.com/bluenviron/gohlslib/v2 v2.2.0 h1:eIsCai3IHP0F538h2tCPCRkhQ7XSOaxeceMyPns0o1k=
github.com/bluenviron/gohlslib/v2 v2.2.0/go.mod h1:sLyKB5iM6Su1kucNHuDUU9aeN/Hw4WxsV2y9k2IHMGs= github.com/bluenviron/gohlslib/v2 v2.2.0/go.mod h1:sLyKB5iM6Su1kucNHuDUU9aeN/Hw4WxsV2y9k2IHMGs=
github.com/bluenviron/gortsplib/v4 v4.14.1 h1:v99NmXeeJFfbrO+ipPzPxYGibQaR5ZOUESOA9UQZhsI= github.com/bluenviron/gortsplib/v4 v4.14.2-0.20250705110245-9c1011567a97 h1:V8m1pyQOYVEJK5RBy1SLg/Y+hgXYFFiMZOd7NhWWLAE=
github.com/bluenviron/gortsplib/v4 v4.14.1/go.mod h1:3LaEcg0d47+kfXju5KSlsSxCiZ3IKBI/sqIrBPcsS64= github.com/bluenviron/gortsplib/v4 v4.14.2-0.20250705110245-9c1011567a97/go.mod h1:rur2QGh1wRU6KINZn8LwU8qTPFt1XafJGtsfs0KYzRo=
github.com/bluenviron/mediacommon/v2 v2.2.0 h1:fGXEX0OEvv5VhGHOv3Q2ABzOtSkIpl9UbwOHrnKWNTk= github.com/bluenviron/mediacommon/v2 v2.2.0 h1:fGXEX0OEvv5VhGHOv3Q2ABzOtSkIpl9UbwOHrnKWNTk=
github.com/bluenviron/mediacommon/v2 v2.2.0/go.mod h1:a6MbPmXtYda9mKibKVMZlW20GYLLrX2R7ZkUE+1pwV0= github.com/bluenviron/mediacommon/v2 v2.2.0/go.mod h1:a6MbPmXtYda9mKibKVMZlW20GYLLrX2R7ZkUE+1pwV0=
github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ= github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ=
@ -173,8 +173,8 @@ github.com/pion/sctp v1.8.36 h1:owNudmnz1xmhfYje5L/FCav3V9wpPRePHle3Zi+P+M0=
github.com/pion/sctp v1.8.36/go.mod h1:cNiLdchXra8fHQwmIoqw0MbLLMs+f7uQ+dGMG2gWebE= github.com/pion/sctp v1.8.36/go.mod h1:cNiLdchXra8fHQwmIoqw0MbLLMs+f7uQ+dGMG2gWebE=
github.com/pion/sdp/v3 v3.0.14 h1:1h7gBr9FhOWH5GjWWY5lcw/U85MtdcibTyt/o6RxRUI= github.com/pion/sdp/v3 v3.0.14 h1:1h7gBr9FhOWH5GjWWY5lcw/U85MtdcibTyt/o6RxRUI=
github.com/pion/sdp/v3 v3.0.14/go.mod h1:88GMahN5xnScv1hIMTqLdu/cOcUkj6a9ytbncwMCq2E= github.com/pion/sdp/v3 v3.0.14/go.mod h1:88GMahN5xnScv1hIMTqLdu/cOcUkj6a9ytbncwMCq2E=
github.com/pion/srtp/v3 v3.0.4 h1:2Z6vDVxzrX3UHEgrUyIGM4rRouoC7v+NiF1IHtp9B5M= github.com/pion/srtp/v3 v3.0.6 h1:E2gyj1f5X10sB/qILUGIkL4C2CqK269Xq167PbGCc/4=
github.com/pion/srtp/v3 v3.0.4/go.mod h1:1Jx3FwDoxpRaTh1oRV8A/6G1BnFL+QI82eK4ms8EEJQ= github.com/pion/srtp/v3 v3.0.6/go.mod h1:BxvziG3v/armJHAaJ87euvkhHqWe9I7iiOy50K2QkhY=
github.com/pion/stun/v3 v3.0.0 h1:4h1gwhWLWuZWOJIJR9s2ferRO+W3zA/b6ijOI6mKzUw= github.com/pion/stun/v3 v3.0.0 h1:4h1gwhWLWuZWOJIJR9s2ferRO+W3zA/b6ijOI6mKzUw=
github.com/pion/stun/v3 v3.0.0/go.mod h1:HvCN8txt8mwi4FBvS3EmDghW6aQJ24T+y+1TKjB5jyU= github.com/pion/stun/v3 v3.0.0/go.mod h1:HvCN8txt8mwi4FBvS3EmDghW6aQJ24T+y+1TKjB5jyU=
github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0= github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0=

View file

@ -220,25 +220,29 @@ type Conf struct {
PlaybackTrustedProxies IPNetworks `json:"playbackTrustedProxies"` PlaybackTrustedProxies IPNetworks `json:"playbackTrustedProxies"`
// RTSP server // RTSP server
RTSP bool `json:"rtsp"` RTSP bool `json:"rtsp"`
RTSPDisable *bool `json:"rtspDisable,omitempty"` // deprecated RTSPDisable *bool `json:"rtspDisable,omitempty"` // deprecated
Protocols *RTSPTransports `json:"protocols,omitempty"` // deprecated Protocols *RTSPTransports `json:"protocols,omitempty"` // deprecated
RTSPTransports RTSPTransports `json:"rtspTransports"` RTSPTransports RTSPTransports `json:"rtspTransports"`
Encryption *Encryption `json:"encryption,omitempty"` // deprecated Encryption *Encryption `json:"encryption,omitempty"` // deprecated
RTSPEncryption Encryption `json:"rtspEncryption"` RTSPEncryption Encryption `json:"rtspEncryption"`
RTSPAddress string `json:"rtspAddress"` RTSPAddress string `json:"rtspAddress"`
RTSPSAddress string `json:"rtspsAddress"` RTSPSAddress string `json:"rtspsAddress"`
RTPAddress string `json:"rtpAddress"` RTPAddress string `json:"rtpAddress"`
RTCPAddress string `json:"rtcpAddress"` RTCPAddress string `json:"rtcpAddress"`
MulticastIPRange string `json:"multicastIPRange"` MulticastIPRange string `json:"multicastIPRange"`
MulticastRTPPort int `json:"multicastRTPPort"` MulticastRTPPort int `json:"multicastRTPPort"`
MulticastRTCPPort int `json:"multicastRTCPPort"` MulticastRTCPPort int `json:"multicastRTCPPort"`
ServerKey *string `json:"serverKey,omitempty"` SRTPAddress string `json:"srtpAddress"`
ServerCert *string `json:"serverCert,omitempty"` SRTCPAddress string `json:"srtcpAddress"`
RTSPServerKey string `json:"rtspServerKey"` MulticastSRTPPort int `json:"multicastSRTPPort"`
RTSPServerCert string `json:"rtspServerCert"` MulticastSRTCPPort int `json:"multicastSRTCPPort"`
AuthMethods *RTSPAuthMethods `json:"authMethods,omitempty"` // deprecated ServerKey *string `json:"serverKey,omitempty"`
RTSPAuthMethods RTSPAuthMethods `json:"rtspAuthMethods"` ServerCert *string `json:"serverCert,omitempty"`
RTSPServerKey string `json:"rtspServerKey"`
RTSPServerCert string `json:"rtspServerCert"`
AuthMethods *RTSPAuthMethods `json:"authMethods,omitempty"` // deprecated
RTSPAuthMethods RTSPAuthMethods `json:"rtspAuthMethods"`
// RTMP server // RTMP server
RTMP bool `json:"rtmp"` RTMP bool `json:"rtmp"`
@ -376,6 +380,10 @@ func (conf *Conf) setDefaults() {
conf.MulticastIPRange = "224.1.0.0/16" conf.MulticastIPRange = "224.1.0.0/16"
conf.MulticastRTPPort = 8002 conf.MulticastRTPPort = 8002
conf.MulticastRTCPPort = 8003 conf.MulticastRTCPPort = 8003
conf.SRTPAddress = ":8004"
conf.SRTCPAddress = ":8005"
conf.MulticastSRTPPort = 8006
conf.MulticastSRTCPPort = 8007
conf.RTSPServerKey = "server.key" conf.RTSPServerKey = "server.key"
conf.RTSPServerCert = "server.crt" conf.RTSPServerCert = "server.crt"
conf.RTSPAuthMethods = RTSPAuthMethods{auth.VerifyMethodBasic} conf.RTSPAuthMethods = RTSPAuthMethods{auth.VerifyMethodBasic}
@ -619,14 +627,6 @@ func (conf *Conf) Validate(l logger.Writer) error {
l.Log(logger.Warn, "parameter 'encryption' is deprecated and has been replaced with 'rtspEncryption'") l.Log(logger.Warn, "parameter 'encryption' is deprecated and has been replaced with 'rtspEncryption'")
conf.RTSPEncryption = *conf.Encryption conf.RTSPEncryption = *conf.Encryption
} }
if conf.RTSPEncryption == EncryptionStrict {
if _, ok := conf.RTSPTransports[gortsplib.TransportUDP]; ok {
return fmt.Errorf("strict encryption cannot be used with the UDP transport protocol")
}
if _, ok := conf.RTSPTransports[gortsplib.TransportUDPMulticast]; ok {
return fmt.Errorf("strict encryption cannot be used with the UDP-multicast transport protocol")
}
}
if conf.AuthMethods != nil { if conf.AuthMethods != nil {
l.Log(logger.Warn, "parameter 'authMethods' is deprecated and has been replaced with 'rtspAuthMethods'") l.Log(logger.Warn, "parameter 'authMethods' is deprecated and has been replaced with 'rtspAuthMethods'")
conf.RTSPAuthMethods = *conf.AuthMethods conf.RTSPAuthMethods = *conf.AuthMethods

View file

@ -291,18 +291,6 @@ func TestConfErrors(t *testing.T) {
"udpMaxPayloadSize: 5000\n", "udpMaxPayloadSize: 5000\n",
"'udpMaxPayloadSize' must be less than 1472", "'udpMaxPayloadSize' must be less than 1472",
}, },
{
"invalid strict encryption 1",
"rtspEncryption: strict\n" +
"rtspTransports: [udp]\n",
"strict encryption cannot be used with the UDP transport protocol",
},
{
"invalid strict encryption 2",
"rtspEncryption: strict\n" +
"rtspTransports: [multicast]\n",
"strict encryption cannot be used with the UDP-multicast transport protocol",
},
{ {
"invalid ICE server", "invalid ICE server",
"webrtcICEServers: [testing]\n", "webrtcICEServers: [testing]\n",

View file

@ -410,19 +410,22 @@ func (p *Core) createResources(initial bool) error {
(p.conf.RTSPEncryption == conf.EncryptionStrict || (p.conf.RTSPEncryption == conf.EncryptionStrict ||
p.conf.RTSPEncryption == conf.EncryptionOptional) && p.conf.RTSPEncryption == conf.EncryptionOptional) &&
p.rtspsServer == nil { p.rtspsServer == nil {
_, useUDP := p.conf.RTSPTransports[gortsplib.TransportUDP]
_, useMulticast := p.conf.RTSPTransports[gortsplib.TransportUDPMulticast]
i := &rtsp.Server{ i := &rtsp.Server{
Address: p.conf.RTSPSAddress, Address: p.conf.RTSPSAddress,
AuthMethods: p.conf.RTSPAuthMethods, AuthMethods: p.conf.RTSPAuthMethods,
ReadTimeout: p.conf.ReadTimeout, ReadTimeout: p.conf.ReadTimeout,
WriteTimeout: p.conf.WriteTimeout, WriteTimeout: p.conf.WriteTimeout,
WriteQueueSize: p.conf.WriteQueueSize, WriteQueueSize: p.conf.WriteQueueSize,
UseUDP: false, UseUDP: useUDP,
UseMulticast: false, UseMulticast: useMulticast,
RTPAddress: "", RTPAddress: p.conf.SRTPAddress,
RTCPAddress: "", RTCPAddress: p.conf.SRTCPAddress,
MulticastIPRange: "", MulticastIPRange: p.conf.MulticastIPRange,
MulticastRTPPort: 0, MulticastRTPPort: p.conf.MulticastSRTPPort,
MulticastRTCPPort: 0, MulticastRTCPPort: p.conf.MulticastSRTCPPort,
IsTLS: true, IsTLS: true,
ServerCert: p.conf.RTSPServerCert, ServerCert: p.conf.RTSPServerCert,
ServerKey: p.conf.RTSPServerKey, ServerKey: p.conf.RTSPServerKey,

View file

@ -398,12 +398,15 @@ func TestPathRunOnRead(t *testing.T) {
switch ca { switch ca {
case "rtsp": case "rtsp":
reader := gortsplib.Client{}
u, err := base.ParseURL("rtsp://127.0.0.1:8554/test?query=value") u, err := base.ParseURL("rtsp://127.0.0.1:8554/test?query=value")
require.NoError(t, err) require.NoError(t, err)
err = reader.Start(u.Scheme, u.Host) reader := gortsplib.Client{
Scheme: u.Scheme,
Host: u.Host,
}
err = reader.Start2()
require.NoError(t, err) require.NoError(t, err)
defer reader.Close() defer reader.Close()
@ -417,12 +420,16 @@ func TestPathRunOnRead(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
case "rtsps": case "rtsps":
reader := gortsplib.Client{TLSConfig: &tls.Config{InsecureSkipVerify: true}}
u, err := base.ParseURL("rtsps://127.0.0.1:8322/test?query=value") u, err := base.ParseURL("rtsps://127.0.0.1:8322/test?query=value")
require.NoError(t, err) require.NoError(t, err)
err = reader.Start(u.Scheme, u.Host) reader := gortsplib.Client{
Scheme: u.Scheme,
Host: u.Host,
TLSConfig: &tls.Config{InsecureSkipVerify: true},
}
err = reader.Start2()
require.NoError(t, err) require.NoError(t, err)
defer reader.Close() defer reader.Close()
@ -649,12 +656,15 @@ func TestPathMaxReaders(t *testing.T) {
defer source.Close() defer source.Close()
for i := 0; i < 2; i++ { for i := 0; i < 2; i++ {
reader := gortsplib.Client{}
u, err := base.ParseURL("rtsp://127.0.0.1:8554/mystream") u, err := base.ParseURL("rtsp://127.0.0.1:8554/mystream")
require.NoError(t, err) require.NoError(t, err)
err = reader.Start(u.Scheme, u.Host) reader := gortsplib.Client{
Scheme: u.Scheme,
Host: u.Host,
}
err = reader.Start2()
require.NoError(t, err) require.NoError(t, err)
defer reader.Close() defer reader.Close()
@ -796,8 +806,12 @@ func TestPathFallback(t *testing.T) {
u, err := base.ParseURL("rtsp://localhost:8554/path1") u, err := base.ParseURL("rtsp://localhost:8554/path1")
require.NoError(t, err) require.NoError(t, err)
dest := gortsplib.Client{} dest := gortsplib.Client{
err = dest.Start(u.Scheme, u.Host) Scheme: u.Scheme,
Host: u.Host,
}
err = dest.Start2()
require.NoError(t, err) require.NoError(t, err)
defer dest.Close() defer dest.Close()
@ -856,12 +870,15 @@ func TestPathResolveSource(t *testing.T) {
require.Equal(t, true, ok) require.Equal(t, true, ok)
defer p.Close() defer p.Close()
reader := gortsplib.Client{}
u, err := base.ParseURL("rtsp://127.0.0.1:8554/test_a?key=val") u, err := base.ParseURL("rtsp://127.0.0.1:8554/test_a?key=val")
require.NoError(t, err) require.NoError(t, err)
err = reader.Start(u.Scheme, u.Host) reader := gortsplib.Client{
Scheme: u.Scheme,
Host: u.Host,
}
err = reader.Start2()
require.NoError(t, err) require.NoError(t, err)
defer reader.Close() defer reader.Close()
@ -909,12 +926,15 @@ func TestPathOverridePublisher(t *testing.T) {
frameRecv := make(chan struct{}) frameRecv := make(chan struct{})
c := gortsplib.Client{}
u, err := base.ParseURL("rtsp://localhost:8554/teststream") u, err := base.ParseURL("rtsp://localhost:8554/teststream")
require.NoError(t, err) require.NoError(t, err)
err = c.Start(u.Scheme, u.Host) c := gortsplib.Client{
Scheme: u.Scheme,
Host: u.Host,
}
err = c.Start2()
require.NoError(t, err) require.NoError(t, err)
defer c.Close() defer c.Close()

View file

@ -253,12 +253,15 @@ func TestServerRead(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
defer s.Close() defer s.Close()
reader := gortsplib.Client{}
u, err := base.ParseURL("rtsp://myuser:mypass@127.0.0.1:8557/teststream?param=value") u, err := base.ParseURL("rtsp://myuser:mypass@127.0.0.1:8557/teststream?param=value")
require.NoError(t, err) require.NoError(t, err)
err = reader.Start(u.Scheme, u.Host) reader := gortsplib.Client{
Scheme: u.Scheme,
Host: u.Host,
}
err = reader.Start2()
require.NoError(t, err) require.NoError(t, err)
defer reader.Close() defer reader.Close()
@ -370,12 +373,15 @@ func TestServerRedirect(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
defer s.Close() defer s.Close()
reader := gortsplib.Client{}
u, err := base.ParseURL("rtsp://myuser:mypass@127.0.0.1:8557/path1?param=value") u, err := base.ParseURL("rtsp://myuser:mypass@127.0.0.1:8557/path1?param=value")
require.NoError(t, err) require.NoError(t, err)
err = reader.Start(u.Scheme, u.Host) reader := gortsplib.Client{
Scheme: u.Scheme,
Host: u.Host,
}
err = reader.Start2()
require.NoError(t, err) require.NoError(t, err)
defer reader.Close() defer reader.Close()

View file

@ -110,7 +110,14 @@ func (s *Source) Run(params defs.StaticSourceRunParams) error {
decodeErrors.Start() decodeErrors.Start()
defer decodeErrors.Stop() defer decodeErrors.Stop()
u, err := base.ParseURL(params.ResolvedSource)
if err != nil {
return err
}
c := &gortsplib.Client{ c := &gortsplib.Client{
Scheme: u.Scheme,
Host: u.Host,
Transport: params.Conf.RTSPTransport.Transport, Transport: params.Conf.RTSPTransport.Transport,
TLSConfig: tls.ConfigForFingerprint(params.Conf.SourceFingerprint), TLSConfig: tls.ConfigForFingerprint(params.Conf.SourceFingerprint),
ReadTimeout: time.Duration(s.ReadTimeout), ReadTimeout: time.Duration(s.ReadTimeout),
@ -134,12 +141,7 @@ func (s *Source) Run(params defs.StaticSourceRunParams) error {
}, },
} }
u, err := base.ParseURL(params.ResolvedSource) err = c.Start2()
if err != nil {
return err
}
err = c.Start(u.Scheme, u.Host)
if err != nil { if err != nil {
return err return err
} }

View file

@ -237,12 +237,12 @@ playbackTrustedProxies: []
rtsp: yes rtsp: yes
# List of enabled RTSP transport protocols. # List of enabled RTSP transport protocols.
# UDP is the most performant, but doesn't work when there's a NAT/firewall between # UDP is the most performant, but doesn't work when there's a NAT/firewall between
# server and clients, and doesn't support encryption. # server and clients.
# UDP-multicast allows to save bandwidth when clients are all in the same LAN. # UDP-multicast allows to save bandwidth when clients are all in the same LAN.
# TCP is the most versatile, and does support encryption. # TCP is the most versatile.
# The handshake is always performed with TCP. # The handshake is always performed with TCP.
rtspTransports: [udp, multicast, tcp] rtspTransports: [udp, multicast, tcp]
# Encrypt handshakes and TCP streams with TLS (RTSPS). # Use secure protocol variants (RTSPS, TLS, SRTP).
# Available values are "no", "strict", "optional". # Available values are "no", "strict", "optional".
rtspEncryption: "no" rtspEncryption: "no"
# Address of the TCP/RTSP listener. This is needed only when encryption is "no" or "optional". # Address of the TCP/RTSP listener. This is needed only when encryption is "no" or "optional".
@ -259,6 +259,14 @@ multicastIPRange: 224.1.0.0/16
multicastRTPPort: 8002 multicastRTPPort: 8002
# Port of all UDP-multicast/RTCP listeners. This is needed only when "multicast" is in rtspTransports. # Port of all UDP-multicast/RTCP listeners. This is needed only when "multicast" is in rtspTransports.
multicastRTCPPort: 8003 multicastRTCPPort: 8003
# Address of the UDP/SRTP listener. This is needed only when "udp" is in rtspTransports and encryption is enabled.
srtpAddress: :8004
# Address of the UDP/SRTCP listener. This is needed only when "udp" is in rtspTransports and encryption is enabled.
srtcpAddress: :8005
# Port of all UDP-multicast/SRTP listeners. This is needed only when "multicast" is in rtspTransports and encryption is enabled.
multicastSRTPPort: 8006
# Port of all UDP-multicast/SRTCP listeners. This is needed only when "multicast" is in rtspTransports and encryption is enabled.
multicastSRTCPPort: 8007
# Path to the server key. This is needed only when encryption is "strict" or "optional". # Path to the server key. This is needed only when encryption is "strict" or "optional".
# This can be generated with: # This can be generated with:
# openssl genrsa -out server.key 2048 # openssl genrsa -out server.key 2048