Browse Source

enable rtmp by default; add parameters to disable rtsp and rtmp

pull/235/head v0.15.0
aler9 4 years ago
parent
commit
f19e23eaa5
  1. 10
      README.md
  2. 5
      internal/conf/conf.go
  3. 16
      main.go
  4. 93
      main_test.go
  5. 6
      rtsp-simple-server.yml

10
README.md

@ -282,13 +282,11 @@ paths: @@ -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 @@ -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:

5
internal/conf/conf.go

@ -63,6 +63,7 @@ type Conf struct { @@ -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 { @@ -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

@ -183,8 +183,9 @@ func (p *program) createResources(initial bool) error { @@ -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 { @@ -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 { @@ -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) { @@ -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) { @@ -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) { @@ -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

@ -223,7 +223,8 @@ func TestRTSPPublishRead(t *testing.T) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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 @@ -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 @@ -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 @@ -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 @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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")

6
rtsp-simple-server.yml

@ -35,6 +35,8 @@ runOnConnectRestart: no @@ -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 @@ -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…
Cancel
Save