mirror of
https://github.com/bluenviron/mediamtx
synced 2024-12-13 10:14:58 +00:00
enable rtmp by default; add parameters to disable rtsp and rtmp
This commit is contained in:
parent
09cbeae60f
commit
f19e23eaa5
10
README.md
10
README.md
@ -282,13 +282,11 @@ paths:
|
||||
|
||||
### RTMP protocol
|
||||
|
||||
RTMP is a protocol that is used to read and publish streams, but is less versatile and less efficient than RTSP (doesn't support UDP, encryption, most RTSP codecs, feedback mechanism). If there is need of publishing or reading streams from a software that supports only RTMP (for instance, OBS Studio and DJI drones), it's possible to turn on a RTMP listener:
|
||||
RTMP is a protocol that is used to read and publish streams, but is less versatile and less efficient than RTSP (doesn't support UDP, encryption, doesn't support most RTSP codecs, doesn't support feedback mechanism). It is used when there's need of publishing or reading streams from a software that supports only RTMP (for instance, OBS Studio and DJI drones).
|
||||
|
||||
```yml
|
||||
rtmpEnable: yes
|
||||
```
|
||||
At the moment, only the H264 and AAC codecs can be used with the RTMP listener.
|
||||
|
||||
Streams can then be published or read with the RTMP protocol, for instance with _FFmpeg_:
|
||||
Streams can be published or read with the RTMP protocol, for instance with _FFmpeg_:
|
||||
|
||||
```
|
||||
ffmpeg -re -stream_loop -1 -i file.ts -c copy -f flv rtmp://localhost/mystream
|
||||
@ -306,8 +304,6 @@ Credentials can be provided by appending to the URL the `user` and `pass` parame
|
||||
ffmpeg -re -stream_loop -1 -i file.ts -c copy -f flv rtmp://localhost:8554/mystream?user=myuser&pass=mypass
|
||||
```
|
||||
|
||||
At the moment the RTMP listener supports only the H264 and AAC codecs.
|
||||
|
||||
### Publish a webcam
|
||||
|
||||
Edit `rtsp-simple-server.yml` and replace everything inside section `paths` with the following content:
|
||||
|
@ -63,6 +63,7 @@ type Conf struct {
|
||||
RunOnConnectRestart bool `yaml:"runOnConnectRestart"`
|
||||
|
||||
// rtsp
|
||||
RTSPDisable bool `yaml:"rtspDisable"`
|
||||
Protocols []string `yaml:"protocols"`
|
||||
ProtocolsParsed map[gortsplib.StreamProtocol]struct{} `yaml:"-" json:"-"`
|
||||
Encryption string `yaml:"encryption"`
|
||||
@ -78,8 +79,8 @@ type Conf struct {
|
||||
ReadBufferSize int `yaml:"readBufferSize"`
|
||||
|
||||
// rtmp
|
||||
RTMPEnable bool `yaml:"rtmpEnable"`
|
||||
RTMPPort int `yaml:"rtmpPort"`
|
||||
RTMPDisable bool `yaml:"rtmpDisable"`
|
||||
RTMPPort int `yaml:"rtmpPort"`
|
||||
|
||||
// path
|
||||
Paths map[string]*PathConf `yaml:"paths"`
|
||||
|
16
main.go
16
main.go
@ -183,8 +183,9 @@ func (p *program) createResources(initial bool) error {
|
||||
}
|
||||
}
|
||||
|
||||
if p.conf.EncryptionParsed == conf.EncryptionNo ||
|
||||
p.conf.EncryptionParsed == conf.EncryptionOptional {
|
||||
if !p.conf.RTSPDisable &&
|
||||
(p.conf.EncryptionParsed == conf.EncryptionNo ||
|
||||
p.conf.EncryptionParsed == conf.EncryptionOptional) {
|
||||
if p.serverRTSPPlain == nil {
|
||||
_, useUDP := p.conf.ProtocolsParsed[gortsplib.StreamProtocolUDP]
|
||||
p.serverRTSPPlain, err = serverrtsp.New(
|
||||
@ -207,8 +208,9 @@ func (p *program) createResources(initial bool) error {
|
||||
}
|
||||
}
|
||||
|
||||
if p.conf.EncryptionParsed == conf.EncryptionStrict ||
|
||||
p.conf.EncryptionParsed == conf.EncryptionOptional {
|
||||
if !p.conf.RTSPDisable &&
|
||||
(p.conf.EncryptionParsed == conf.EncryptionStrict ||
|
||||
p.conf.EncryptionParsed == conf.EncryptionOptional) {
|
||||
if p.serverRTSPTLS == nil {
|
||||
p.serverRTSPTLS, err = serverrtsp.New(
|
||||
p.conf.ListenIP,
|
||||
@ -230,7 +232,7 @@ func (p *program) createResources(initial bool) error {
|
||||
}
|
||||
}
|
||||
|
||||
if p.conf.RTMPEnable {
|
||||
if !p.conf.RTMPDisable {
|
||||
if p.serverRTMP == nil {
|
||||
p.serverRTMP, err = serverrtmp.New(
|
||||
p.conf.ListenIP,
|
||||
@ -299,6 +301,7 @@ func (p *program) closeResources(newConf *conf.Conf) {
|
||||
|
||||
closeServerPlain := false
|
||||
if newConf == nil ||
|
||||
newConf.RTSPDisable != p.conf.RTSPDisable ||
|
||||
newConf.EncryptionParsed != p.conf.EncryptionParsed ||
|
||||
newConf.ListenIP != p.conf.ListenIP ||
|
||||
newConf.RTSPPort != p.conf.RTSPPort ||
|
||||
@ -313,6 +316,7 @@ func (p *program) closeResources(newConf *conf.Conf) {
|
||||
|
||||
closeServerTLS := false
|
||||
if newConf == nil ||
|
||||
newConf.RTSPDisable != p.conf.RTSPDisable ||
|
||||
newConf.EncryptionParsed != p.conf.EncryptionParsed ||
|
||||
newConf.ListenIP != p.conf.ListenIP ||
|
||||
newConf.RTSPSPort != p.conf.RTSPSPort ||
|
||||
@ -326,7 +330,7 @@ func (p *program) closeResources(newConf *conf.Conf) {
|
||||
|
||||
closeServerRTMP := false
|
||||
if newConf == nil ||
|
||||
newConf.EncryptionParsed != p.conf.EncryptionParsed ||
|
||||
newConf.RTMPDisable != p.conf.RTMPDisable ||
|
||||
newConf.ListenIP != p.conf.ListenIP ||
|
||||
newConf.RTMPPort != p.conf.RTMPPort ||
|
||||
newConf.ReadTimeout != p.conf.ReadTimeout {
|
||||
|
93
main_test.go
93
main_test.go
@ -223,7 +223,8 @@ func TestRTSPPublishRead(t *testing.T) {
|
||||
proto = "rtsp"
|
||||
port = "8554"
|
||||
|
||||
p, ok := testProgram("readTimeout: 20s")
|
||||
p, ok := testProgram("rtmpDisable: yes\n" +
|
||||
"readTimeout: 20s\n")
|
||||
require.Equal(t, true, ok)
|
||||
defer p.close()
|
||||
|
||||
@ -239,7 +240,8 @@ func TestRTSPPublishRead(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
defer os.Remove(serverKeyFpath)
|
||||
|
||||
p, ok := testProgram("readTimeout: 20s\n" +
|
||||
p, ok := testProgram("rtmpDisable: yes\n" +
|
||||
"readTimeout: 20s\n" +
|
||||
"protocols: [tcp]\n" +
|
||||
"encryption: yes\n" +
|
||||
"serverCert: " + serverCertFpath + "\n" +
|
||||
@ -317,7 +319,8 @@ func TestRTSPPublishRead(t *testing.T) {
|
||||
|
||||
func TestRTSPAuth(t *testing.T) {
|
||||
t.Run("publish", func(t *testing.T) {
|
||||
p, ok := testProgram("paths:\n" +
|
||||
p, ok := testProgram("rtmpDisable: yes\n" +
|
||||
"paths:\n" +
|
||||
" all:\n" +
|
||||
" publishUser: testuser\n" +
|
||||
" publishPass: test!$()*+.;<=>[]^_-{}\n" +
|
||||
@ -356,7 +359,8 @@ func TestRTSPAuth(t *testing.T) {
|
||||
"vlc",
|
||||
} {
|
||||
t.Run("read_"+soft, func(t *testing.T) {
|
||||
p, ok := testProgram("paths:\n" +
|
||||
p, ok := testProgram("rtmpDisable: yes\n" +
|
||||
"paths:\n" +
|
||||
" all:\n" +
|
||||
" readUser: testuser\n" +
|
||||
" readPass: test!$()*+.;<=>[]^_-{}\n" +
|
||||
@ -402,7 +406,8 @@ func TestRTSPAuth(t *testing.T) {
|
||||
}
|
||||
|
||||
t.Run("hashed", func(t *testing.T) {
|
||||
p, ok := testProgram("paths:\n" +
|
||||
p, ok := testProgram("rtmpDisable: yes\n" +
|
||||
"paths:\n" +
|
||||
" all:\n" +
|
||||
" readUser: sha256:rl3rgi4NcZkpAEcacZnQ2VuOfJ0FxAqCRaKB/SwdZoQ=\n" +
|
||||
" readPass: sha256:E9JJ8stBJ7QM+nV4ZoUCeHk/gU3tPFh/5YieiJp6n2w=\n")
|
||||
@ -457,10 +462,12 @@ func TestRTSPAuthFail(t *testing.T) {
|
||||
},
|
||||
} {
|
||||
t.Run(ca.name, func(t *testing.T) {
|
||||
p, ok := testProgram("paths:\n" +
|
||||
" all:\n" +
|
||||
" publishUser: testuser\n" +
|
||||
" publishPass: testpass\n")
|
||||
p, ok := testProgram(
|
||||
"rtmpDisable: yes\n" +
|
||||
"paths:\n" +
|
||||
" all:\n" +
|
||||
" publishUser: testuser\n" +
|
||||
" publishPass: testpass\n")
|
||||
require.Equal(t, true, ok)
|
||||
defer p.close()
|
||||
|
||||
@ -513,10 +520,12 @@ func TestRTSPAuthFail(t *testing.T) {
|
||||
},
|
||||
} {
|
||||
t.Run(ca.name, func(t *testing.T) {
|
||||
p, ok := testProgram("paths:\n" +
|
||||
" all:\n" +
|
||||
" readUser: testuser\n" +
|
||||
" readPass: testpass\n")
|
||||
p, ok := testProgram(
|
||||
"rtmpDisable: yes\n" +
|
||||
"paths:\n" +
|
||||
" all:\n" +
|
||||
" readUser: testuser\n" +
|
||||
" readPass: testpass\n")
|
||||
require.Equal(t, true, ok)
|
||||
defer p.close()
|
||||
|
||||
@ -549,7 +558,8 @@ func TestRTSPAuthFail(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRTSPAuthIpFail(t *testing.T) {
|
||||
p, ok := testProgram("paths:\n" +
|
||||
p, ok := testProgram("rtmpDisable: yes\n" +
|
||||
"paths:\n" +
|
||||
" all:\n" +
|
||||
" publishIps: [127.0.0.1/32]\n")
|
||||
require.Equal(t, true, ok)
|
||||
@ -574,7 +584,8 @@ func TestRTSPAutomaticProtocol(t *testing.T) {
|
||||
"ffmpeg",
|
||||
} {
|
||||
t.Run(source, func(t *testing.T) {
|
||||
p, ok := testProgram("protocols: [tcp]\n")
|
||||
p, ok := testProgram("rtmpDisable: yes\n" +
|
||||
"protocols: [tcp]\n")
|
||||
require.Equal(t, true, ok)
|
||||
defer p.close()
|
||||
|
||||
@ -606,7 +617,7 @@ func TestRTSPAutomaticProtocol(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRTSPPublisherOverride(t *testing.T) {
|
||||
p, ok := testProgram("")
|
||||
p, ok := testProgram("rtmpDisable: yes\n")
|
||||
require.Equal(t, true, ok)
|
||||
defer p.close()
|
||||
|
||||
@ -662,7 +673,7 @@ func TestRTSPPath(t *testing.T) {
|
||||
},
|
||||
} {
|
||||
t.Run(ca.name, func(t *testing.T) {
|
||||
p, ok := testProgram("")
|
||||
p, ok := testProgram("rtmpDisable: yes\n")
|
||||
require.Equal(t, true, ok)
|
||||
defer p.close()
|
||||
|
||||
@ -694,7 +705,8 @@ func TestRTSPPath(t *testing.T) {
|
||||
|
||||
func TestRTSPNonCompliantFrameSize(t *testing.T) {
|
||||
t.Run("publish", func(t *testing.T) {
|
||||
p, ok := testProgram("readBufferSize: 4500\n")
|
||||
p, ok := testProgram("rtmpDisable: yes\n" +
|
||||
"readBufferSize: 4500\n")
|
||||
require.Equal(t, true, ok)
|
||||
defer p.close()
|
||||
|
||||
@ -724,7 +736,8 @@ func TestRTSPNonCompliantFrameSize(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("proxy", func(t *testing.T) {
|
||||
p1, ok := testProgram("protocols: [tcp]\n" +
|
||||
p1, ok := testProgram("rtmpDisable: yes\n" +
|
||||
"protocols: [tcp]\n" +
|
||||
"readBufferSize: 4500\n")
|
||||
require.Equal(t, true, ok)
|
||||
defer p1.close()
|
||||
@ -745,7 +758,8 @@ func TestRTSPNonCompliantFrameSize(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
defer source.Close()
|
||||
|
||||
p2, ok := testProgram("protocols: [tcp]\n" +
|
||||
p2, ok := testProgram("rtmpDisable: yes\n" +
|
||||
"protocols: [tcp]\n" +
|
||||
"readBufferSize: 4500\n" +
|
||||
"rtspPort: 8555\n" +
|
||||
"paths:\n" +
|
||||
@ -780,7 +794,8 @@ func TestRTSPNonCompliantFrameSize(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRTSPRedirect(t *testing.T) {
|
||||
p1, ok := testProgram("paths:\n" +
|
||||
p1, ok := testProgram("rtmpDisable: yes\n" +
|
||||
"paths:\n" +
|
||||
" path1:\n" +
|
||||
" source: redirect\n" +
|
||||
" sourceRedirect: rtsp://" + ownDockerIP + ":8554/path2\n" +
|
||||
@ -827,7 +842,8 @@ func TestRTSPFallback(t *testing.T) {
|
||||
return "/path2"
|
||||
}()
|
||||
|
||||
p1, ok := testProgram("paths:\n" +
|
||||
p1, ok := testProgram("rtmpDisable: yes\n" +
|
||||
"paths:\n" +
|
||||
" path1:\n" +
|
||||
" fallback: " + val + "\n" +
|
||||
" path2:\n")
|
||||
@ -878,7 +894,8 @@ wait
|
||||
t.Run("describe", func(t *testing.T) {
|
||||
defer os.Remove(doneFile)
|
||||
|
||||
p1, ok := testProgram(fmt.Sprintf("paths:\n"+
|
||||
p1, ok := testProgram(fmt.Sprintf("rtmpDisable: yes\n"+
|
||||
"paths:\n"+
|
||||
" all:\n"+
|
||||
" runOnDemand: %s\n"+
|
||||
" runOnDemandCloseAfter: 2s\n", onDemandFile))
|
||||
@ -918,7 +935,8 @@ wait
|
||||
t.Run("describe and setup", func(t *testing.T) {
|
||||
defer os.Remove(doneFile)
|
||||
|
||||
p1, ok := testProgram(fmt.Sprintf("paths:\n"+
|
||||
p1, ok := testProgram(fmt.Sprintf("rtmpDisable: yes\n"+
|
||||
"paths:\n"+
|
||||
" all:\n"+
|
||||
" runOnDemand: %s\n"+
|
||||
" runOnDemandCloseAfter: 2s\n", onDemandFile))
|
||||
@ -983,7 +1001,8 @@ wait
|
||||
t.Run("setup", func(t *testing.T) {
|
||||
defer os.Remove(doneFile)
|
||||
|
||||
p1, ok := testProgram(fmt.Sprintf("paths:\n"+
|
||||
p1, ok := testProgram(fmt.Sprintf("rtmpDisable: yes\n"+
|
||||
"paths:\n"+
|
||||
" all:\n"+
|
||||
" runOnDemand: %s\n"+
|
||||
" runOnDemandCloseAfter: 2s\n", onDemandFile))
|
||||
@ -1034,7 +1053,7 @@ wait
|
||||
}
|
||||
|
||||
func TestRTMPPublish(t *testing.T) {
|
||||
p, ok := testProgram("rtmpEnable: yes\n")
|
||||
p, ok := testProgram("")
|
||||
require.Equal(t, true, ok)
|
||||
defer p.close()
|
||||
|
||||
@ -1064,7 +1083,7 @@ func TestRTMPPublish(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRTMPRead(t *testing.T) {
|
||||
p, ok := testProgram("rtmpEnable: yes\n")
|
||||
p, ok := testProgram("")
|
||||
require.Equal(t, true, ok)
|
||||
defer p.close()
|
||||
|
||||
@ -1094,7 +1113,7 @@ func TestRTMPRead(t *testing.T) {
|
||||
|
||||
func TestRTMPAuth(t *testing.T) {
|
||||
t.Run("publish", func(t *testing.T) {
|
||||
p, ok := testProgram("rtmpEnable: yes\n" +
|
||||
p, ok := testProgram("rtspDisable: yes\n" +
|
||||
"paths:\n" +
|
||||
" all:\n" +
|
||||
" publishUser: testuser\n" +
|
||||
@ -1127,7 +1146,7 @@ func TestRTMPAuth(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("read", func(t *testing.T) {
|
||||
p, ok := testProgram("rtmpEnable: yes\n" +
|
||||
p, ok := testProgram("rtspDisable: yes\n" +
|
||||
"paths:\n" +
|
||||
" all:\n" +
|
||||
" readUser: testuser\n" +
|
||||
@ -1162,7 +1181,7 @@ func TestRTMPAuth(t *testing.T) {
|
||||
|
||||
func TestRTMPAuthFail(t *testing.T) {
|
||||
t.Run("publish", func(t *testing.T) {
|
||||
p, ok := testProgram("rtmpEnable: yes\n" +
|
||||
p, ok := testProgram("rtspDisable: yes\n" +
|
||||
"paths:\n" +
|
||||
" all:\n" +
|
||||
" publishUser: testuser2\n" +
|
||||
@ -1195,7 +1214,7 @@ func TestRTMPAuthFail(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("read", func(t *testing.T) {
|
||||
p, ok := testProgram("rtmpEnable: yes\n" +
|
||||
p, ok := testProgram("rtspDisable: yes\n" +
|
||||
"paths:\n" +
|
||||
" all:\n" +
|
||||
" readUser: testuser2\n" +
|
||||
@ -1239,7 +1258,8 @@ func TestSource(t *testing.T) {
|
||||
t.Run(source, func(t *testing.T) {
|
||||
switch source {
|
||||
case "rtsp_udp", "rtsp_tcp":
|
||||
p1, ok := testProgram("rtspPort: 8555\n" +
|
||||
p1, ok := testProgram("rtmpDisable: yes\n" +
|
||||
"rtspPort: 8555\n" +
|
||||
"rtpPort: 8100\n" +
|
||||
"rtcpPort: 8101\n" +
|
||||
"paths:\n" +
|
||||
@ -1261,7 +1281,8 @@ func TestSource(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
defer cnt1.close()
|
||||
|
||||
p2, ok := testProgram("paths:\n" +
|
||||
p2, ok := testProgram("rtmpDisable: yes\n" +
|
||||
"paths:\n" +
|
||||
" proxied:\n" +
|
||||
" source: rtsp://testuser:testpass@localhost:8555/teststream\n" +
|
||||
" sourceProtocol: " + source[len("rtsp_"):] + "\n" +
|
||||
@ -1278,7 +1299,8 @@ func TestSource(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
defer os.Remove(serverKeyFpath)
|
||||
|
||||
p, ok := testProgram("rtspPort: 8555\n" +
|
||||
p, ok := testProgram("rtmpDisable: yes\n" +
|
||||
"rtspPort: 8555\n" +
|
||||
"rtpPort: 8100\n" +
|
||||
"rtcpPort: 8101\n" +
|
||||
"readTimeout: 20s\n" +
|
||||
@ -1306,7 +1328,8 @@ func TestSource(t *testing.T) {
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
p2, ok := testProgram("paths:\n" +
|
||||
p2, ok := testProgram("rtmpDisable: yes\n" +
|
||||
"paths:\n" +
|
||||
" proxied:\n" +
|
||||
" source: rtsps://testuser:testpass@localhost:8555/teststream\n" +
|
||||
" sourceOnDemand: yes\n")
|
||||
|
@ -35,6 +35,8 @@ runOnConnectRestart: no
|
||||
###############################################
|
||||
# RTSP options
|
||||
|
||||
# disable support for the RTSP protocol.
|
||||
rtspDisable: no
|
||||
# supported RTSP stream protocols.
|
||||
# UDP is the most performant, but can cause problems if there's a NAT between
|
||||
# server and clients, and doesn't support encryption.
|
||||
@ -66,8 +68,8 @@ readBufferSize: 2048
|
||||
###############################################
|
||||
# RTMP options
|
||||
|
||||
# enable a RTMP listener that allows to receive streams with RTMP.
|
||||
rtmpEnable: no
|
||||
# disable support for the RTMP protocol.
|
||||
rtmpDisable: no
|
||||
# port of the RTMP listener.
|
||||
rtmpPort: 1935
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user