mirror of
https://github.com/bluenviron/mediamtx.git
synced 2025-12-20 02:00:05 -08:00
rtsp: support encrypting UDP and UDP-multicast streams (#4690)
This commit is contained in:
parent
81af4075f0
commit
c475f84e5d
11 changed files with 131 additions and 90 deletions
18
README.md
18
README.md
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
4
go.mod
|
|
@ -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
8
go.sum
|
|
@ -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=
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
14
mediamtx.yml
14
mediamtx.yml
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue