mirror of
https://github.com/datarhei/core.git
synced 2025-10-03 23:26:39 +08:00
Allow RTMP server if RTMPS server is enabled
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#### Core v16.8.0 > ?
|
#### Core v16.8.0 > ?
|
||||||
|
|
||||||
|
- Allow RTMP server if RTMPS server is enabled
|
||||||
- Add optional escape character to process placeholder
|
- Add optional escape character to process placeholder
|
||||||
- Fix output address validation for tee outputs
|
- Fix output address validation for tee outputs
|
||||||
- Fix updating process config
|
- Fix updating process config
|
||||||
|
@@ -127,6 +127,7 @@ The currently known environment variables (but not all will be respected) are:
|
|||||||
| CORE_RTMP_ENABLE | `false` | Enable RTMP server. |
|
| CORE_RTMP_ENABLE | `false` | Enable RTMP server. |
|
||||||
| CORE_RTMP_ENABLE_TLS | `false` | Enable RTMP over TLS (RTMPS). Requires `CORE_TLS_ENABLE` to be `true`. |
|
| CORE_RTMP_ENABLE_TLS | `false` | Enable RTMP over TLS (RTMPS). Requires `CORE_TLS_ENABLE` to be `true`. |
|
||||||
| CORE_RTMP_ADDRESS | `:1935` | RTMP server listen address. |
|
| CORE_RTMP_ADDRESS | `:1935` | RTMP server listen address. |
|
||||||
|
| CORE_RTMP_ADDRESS_TLS | `:1936` | RTMPS server listen address. |
|
||||||
| CORE_RTMP_APP | `/` | RTMP app for publishing. |
|
| CORE_RTMP_APP | `/` | RTMP app for publishing. |
|
||||||
| CORE_RTMP_TOKEN | (not set) | RTMP token for publishing and playing. The token is the value of the URL query parameter `token`. |
|
| CORE_RTMP_TOKEN | (not set) | RTMP token for publishing and playing. The token is the value of the URL query parameter `token`. |
|
||||||
| CORE_SRT_ENABLE | `false` | Enable SRT server. |
|
| CORE_SRT_ENABLE | `false` | Enable SRT server. |
|
||||||
@@ -257,6 +258,7 @@ All other values will be filled with default values and persisted on disk. The e
|
|||||||
"enable": false,
|
"enable": false,
|
||||||
"enable_tls": false,
|
"enable_tls": false,
|
||||||
"address": ":1935",
|
"address": ":1935",
|
||||||
|
"address_tls": ":1936",
|
||||||
"app": "/",
|
"app": "/",
|
||||||
"token": ""
|
"token": ""
|
||||||
},
|
},
|
||||||
@@ -386,6 +388,8 @@ If you set a value for `CORE_STORAGE_DISK_CACHE_MAXSIZEMBYTES`, which is larger
|
|||||||
|
|
||||||
The datarhei Core includes a simple RTMP server for publishing and playing streams. Set the environment variable `CORE_RTMP_ENABLE` to `true` to enable the RTMP server. It is listening on `CORE_RTMP_ADDRESS`. Use `CORE_RTMP_APP` to limit the app a stream can be published on, e.g. `/live` to require URLs to start with `/live`. To prevent anybody can publish streams, set `CORE_RTMP_TOKEN` to a secret only known to the publishers and subscribers. The token has to be put in the query of the stream URL, e.g. `/live/stream?token=...`.
|
The datarhei Core includes a simple RTMP server for publishing and playing streams. Set the environment variable `CORE_RTMP_ENABLE` to `true` to enable the RTMP server. It is listening on `CORE_RTMP_ADDRESS`. Use `CORE_RTMP_APP` to limit the app a stream can be published on, e.g. `/live` to require URLs to start with `/live`. To prevent anybody can publish streams, set `CORE_RTMP_TOKEN` to a secret only known to the publishers and subscribers. The token has to be put in the query of the stream URL, e.g. `/live/stream?token=...`.
|
||||||
|
|
||||||
|
For additionaly enabling the RTMPS server, set the config variable `rtmp.enable_tls` or environment variable `CORE_RTMP_ENABLE_TLS` to `true`. This requires `tls.enable` or `CORE_TLS_ENABLE` to be set to to `true`. Use `rtmp.address_tls` or `CORE_RTMP_ADDRESS_TLS` to set the listen address for the RTMPS server.
|
||||||
|
|
||||||
| Method | Path | Description |
|
| Method | Path | Description |
|
||||||
| ------ | ------------ | ------------------------------------- |
|
| ------ | ------------ | ------------------------------------- |
|
||||||
| GET | /api/v3/rtmp | List all currently published streams. |
|
| GET | /api/v3/rtmp | List all currently published streams. |
|
||||||
|
@@ -88,6 +88,7 @@ type api struct {
|
|||||||
main log.Logger
|
main log.Logger
|
||||||
sidecar log.Logger
|
sidecar log.Logger
|
||||||
rtmp log.Logger
|
rtmp log.Logger
|
||||||
|
rtmps log.Logger
|
||||||
srt log.Logger
|
srt log.Logger
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -669,11 +670,14 @@ func (a *api) start() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if cfg.RTMP.Enable {
|
if cfg.RTMP.Enable {
|
||||||
|
a.log.logger.rtmp = a.log.logger.core.WithComponent("RTMP").WithField("address", cfg.RTMP.Address)
|
||||||
|
|
||||||
config := rtmp.Config{
|
config := rtmp.Config{
|
||||||
Addr: cfg.RTMP.Address,
|
Addr: cfg.RTMP.Address,
|
||||||
|
TLSAddr: cfg.RTMP.AddressTLS,
|
||||||
App: cfg.RTMP.App,
|
App: cfg.RTMP.App,
|
||||||
Token: cfg.RTMP.Token,
|
Token: cfg.RTMP.Token,
|
||||||
Logger: a.log.logger.core.WithComponent("RTMP").WithField("address", cfg.RTMP.Address),
|
Logger: a.log.logger.rtmp,
|
||||||
Collector: a.sessions.Collector("rtmp"),
|
Collector: a.sessions.Collector("rtmp"),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -682,7 +686,9 @@ func (a *api) start() error {
|
|||||||
GetCertificate: autocertManager.GetCertificate,
|
GetCertificate: autocertManager.GetCertificate,
|
||||||
}
|
}
|
||||||
|
|
||||||
config.Logger = config.Logger.WithComponent("RTMPS")
|
config.Logger = config.Logger.WithComponent("RTMP/S")
|
||||||
|
|
||||||
|
a.log.logger.rtmps = a.log.logger.core.WithComponent("RTMPS").WithField("address", cfg.RTMP.AddressTLS)
|
||||||
}
|
}
|
||||||
|
|
||||||
rtmpserver, err := rtmp.New(config)
|
rtmpserver, err := rtmp.New(config)
|
||||||
@@ -690,7 +696,6 @@ func (a *api) start() error {
|
|||||||
return fmt.Errorf("unable to create RMTP server: %w", err)
|
return fmt.Errorf("unable to create RMTP server: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
a.log.logger.rtmp = config.Logger
|
|
||||||
a.rtmpserver = rtmpserver
|
a.rtmpserver = rtmpserver
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -901,15 +906,6 @@ func (a *api) start() error {
|
|||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if cfg.TLS.Enable && cfg.RTMP.EnableTLS {
|
|
||||||
logger.Info().Log("Server started")
|
|
||||||
err = a.rtmpserver.ListenAndServeTLS(cfg.TLS.CertFile, cfg.TLS.KeyFile)
|
|
||||||
if err != nil && err != rtmp.ErrServerClosed {
|
|
||||||
err = fmt.Errorf("RTMPS server: %w", err)
|
|
||||||
} else {
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.Info().Log("Server started")
|
logger.Info().Log("Server started")
|
||||||
err = a.rtmpserver.ListenAndServe()
|
err = a.rtmpserver.ListenAndServe()
|
||||||
if err != nil && err != rtmp.ErrServerClosed {
|
if err != nil && err != rtmp.ErrServerClosed {
|
||||||
@@ -917,10 +913,35 @@ func (a *api) start() error {
|
|||||||
} else {
|
} else {
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
sendError(err)
|
sendError(err)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
if cfg.TLS.Enable && cfg.RTMP.EnableTLS {
|
||||||
|
wgStart.Add(1)
|
||||||
|
a.wgStop.Add(1)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
logger := a.log.logger.rtmps
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
logger.Info().Log("Server exited")
|
||||||
|
a.wgStop.Done()
|
||||||
|
}()
|
||||||
|
|
||||||
|
wgStart.Done()
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
logger.Info().Log("Server started")
|
||||||
|
err = a.rtmpserver.ListenAndServeTLS(cfg.TLS.CertFile, cfg.TLS.KeyFile)
|
||||||
|
if err != nil && err != rtmp.ErrServerClosed {
|
||||||
|
err = fmt.Errorf("RTMPS server: %w", err)
|
||||||
|
} else {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.srtserver != nil {
|
if a.srtserver != nil {
|
||||||
@@ -1106,6 +1127,10 @@ func (a *api) stop() {
|
|||||||
if a.rtmpserver != nil {
|
if a.rtmpserver != nil {
|
||||||
a.log.logger.rtmp.Info().Log("Stopping ...")
|
a.log.logger.rtmp.Info().Log("Stopping ...")
|
||||||
|
|
||||||
|
if a.log.logger.rtmps != nil {
|
||||||
|
a.log.logger.rtmps.Info().Log("Stopping ...")
|
||||||
|
}
|
||||||
|
|
||||||
a.rtmpserver.Close()
|
a.rtmpserver.Close()
|
||||||
a.rtmpserver = nil
|
a.rtmpserver = nil
|
||||||
}
|
}
|
||||||
|
@@ -568,6 +568,14 @@ func (d *Config) Validate(resetLogs bool) {
|
|||||||
if !d.TLS.Enable {
|
if !d.TLS.Enable {
|
||||||
d.log("error", d.findVariable("rtmp.enable_tls"), "RTMPS server can only be enabled if TLS is enabled")
|
d.log("error", d.findVariable("rtmp.enable_tls"), "RTMPS server can only be enabled if TLS is enabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(d.RTMP.AddressTLS) == 0 {
|
||||||
|
d.log("error", d.findVariable("rtmp.address_tls"), "RTMPS server address must be set")
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.RTMP.Address == d.RTMP.AddressTLS {
|
||||||
|
d.log("error", d.findVariable("rtmp.address"), "The RTMP and RTMPS server can't listen on the same address")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If CORE_MEMFS_USERNAME and CORE_MEMFS_PASSWORD are set, automatically active/deactivate Basic-Auth for memfs
|
// If CORE_MEMFS_USERNAME and CORE_MEMFS_PASSWORD are set, automatically active/deactivate Basic-Auth for memfs
|
||||||
|
25
rtmp/rtmp.go
25
rtmp/rtmp.go
@@ -4,6 +4,7 @@ package rtmp
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -175,6 +176,9 @@ type Config struct {
|
|||||||
// The address the RTMP server should listen on, e.g. ":1935"
|
// The address the RTMP server should listen on, e.g. ":1935"
|
||||||
Addr string
|
Addr string
|
||||||
|
|
||||||
|
// The address the RTMPS server should listen on, e.g. ":1936"
|
||||||
|
TLSAddr string
|
||||||
|
|
||||||
// The app path for the streams, e.g. "/live". Optional. Defaults
|
// The app path for the streams, e.g. "/live". Optional. Defaults
|
||||||
// to "/".
|
// to "/".
|
||||||
App string
|
App string
|
||||||
@@ -217,6 +221,7 @@ type server struct {
|
|||||||
|
|
||||||
// A joy4 RTMP server instance
|
// A joy4 RTMP server instance
|
||||||
server *rtmp.Server
|
server *rtmp.Server
|
||||||
|
tlsServer *rtmp.Server
|
||||||
|
|
||||||
// Map of publishing channels and a lock to serialize
|
// Map of publishing channels and a lock to serialize
|
||||||
// access to the map.
|
// access to the map.
|
||||||
@@ -231,7 +236,7 @@ func New(config Config) (Server, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if config.Logger == nil {
|
if config.Logger == nil {
|
||||||
config.Logger = log.New("RTMP")
|
config.Logger = log.New("")
|
||||||
}
|
}
|
||||||
|
|
||||||
s := &server{
|
s := &server{
|
||||||
@@ -247,10 +252,18 @@ func New(config Config) (Server, error) {
|
|||||||
|
|
||||||
s.server = &rtmp.Server{
|
s.server = &rtmp.Server{
|
||||||
Addr: config.Addr,
|
Addr: config.Addr,
|
||||||
|
HandlePlay: s.handlePlay,
|
||||||
|
HandlePublish: s.handlePublish,
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(config.TLSAddr) != 0 {
|
||||||
|
s.tlsServer = &rtmp.Server{
|
||||||
|
Addr: config.TLSAddr,
|
||||||
TLSConfig: config.TLSConfig.Clone(),
|
TLSConfig: config.TLSConfig.Clone(),
|
||||||
HandlePlay: s.handlePlay,
|
HandlePlay: s.handlePlay,
|
||||||
HandlePublish: s.handlePublish,
|
HandlePublish: s.handlePublish,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
s.channels = make(map[string]*channel)
|
s.channels = make(map[string]*channel)
|
||||||
|
|
||||||
@@ -265,13 +278,21 @@ func (s *server) ListenAndServe() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *server) ListenAndServeTLS(certFile, keyFile string) error {
|
func (s *server) ListenAndServeTLS(certFile, keyFile string) error {
|
||||||
return s.server.ListenAndServeTLS(certFile, keyFile)
|
if s.tlsServer == nil {
|
||||||
|
return fmt.Errorf("RTMPS server is not configured")
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.tlsServer.ListenAndServeTLS(certFile, keyFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *server) Close() {
|
func (s *server) Close() {
|
||||||
// Stop listening
|
// Stop listening
|
||||||
s.server.Close()
|
s.server.Close()
|
||||||
|
|
||||||
|
if s.tlsServer != nil {
|
||||||
|
s.tlsServer.Close()
|
||||||
|
}
|
||||||
|
|
||||||
s.lock.Lock()
|
s.lock.Lock()
|
||||||
defer s.lock.Unlock()
|
defer s.lock.Unlock()
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user