Skip to content

Commit

Permalink
support publishing, reading, proxying with SRT
Browse files Browse the repository at this point in the history
  • Loading branch information
aler9 committed Jul 17, 2023
1 parent 9b84daa commit 64ee16a
Show file tree
Hide file tree
Showing 19 changed files with 827 additions and 352 deletions.
39 changes: 32 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ Live streams can be published to the server with:

|protocol|variants|video codecs|audio codecs|
|--------|--------|------------|------------|
|[WebRTC](#webrtc)|Browser-based, WHIP|AV1, VP9, VP8, H264|Opus, G722, G711|
|[SRT clients](#srt-clients)||H265, H264|Opus, MPEG-4 Audio (AAC)|
|[SRT servers](#srt-servers)||H265, H264|Opus, MPEG-4 Audio (AAC)|
|[WebRTC clients](#webrtc-clients)|Browser-based, WHIP|AV1, VP9, VP8, H264|Opus, G722, G711|
|[RTSP clients](#rtsp-clients)|UDP, TCP, RTSPS|AV1, VP9, VP8, H265, H264, MPEG-4 Video (H263, Xvid), MPEG-1/2 Video, M-JPEG and any RTP-compatible codec|Opus, MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3), G722, G711, LPCM and any RTP-compatible codec|
|[RTSP cameras and servers](#rtsp-cameras-and-servers)|UDP, UDP-Multicast, TCP, RTSPS|AV1, VP9, VP8, H265, H264, MPEG-4 Video (H263, Xvid), MPEG-1/2 Video, M-JPEG and any RTP-compatible codec|Opus, MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3), G722, G711, LPCM and any RTP-compatible codec|
|[RTMP clients](#rtmp-clients)|RTMP, RTMPS, Enhanced RTMP|AV1, H265, H264|MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3)|
Expand All @@ -33,7 +35,8 @@ And can be read from the server with:

|protocol|variants|video codecs|audio codecs|
|--------|--------|------------|------------|
|[WebRTC](#webrtc-1)|Browser-based, WHEP|AV1, VP9, VP8, H264|Opus, G722, G711|
|[SRT](#srt)||H265, H264|Opus, MPEG-4 Audio (AAC)|
|[WebRTC](#webrtc)|Browser-based, WHEP|AV1, VP9, VP8, H264|Opus, G722, G711|
|[RTSP](#rtsp)|UDP, UDP-Multicast, TCP, RTSPS|AV1, VP9, VP8, H265, H264, MPEG-4 Video (H263, Xvid), MPEG-1/2 Video, M-JPEG and any RTP-compatible codec|Opus, MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3), G722, G711, LPCM and any RTP-compatible codec|
|[RTMP](#rtmp)|RTMP, RTMPS, Enhanced RTMP|H264|MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3)|
|[HLS](#hls)|Low-Latency HLS, MP4-based HLS, legacy HLS|H265, H264|Opus, MPEG-4 Audio (AAC)|
Expand Down Expand Up @@ -76,7 +79,9 @@ _rtsp-simple-server_ has been rebranded as _MediaMTX_. The reason is pretty obvi
* [Generic webcam](#generic-webcam)
* [Raspberry Pi Cameras](#raspberry-pi-cameras)
* [By protocol](#by-protocol)
* [WebRTC](#webrtc)
* [SRT clients](#srt-clients)
* [SRT servers](#srt-servers)
* [WebRTC clients](#webrtc-clients)
* [RTSP clients](#rtsp-clients)
* [RTSP cameras and servers](#rtsp-cameras-and-servers)
* [RTMP clients](#rtmp-clients)
Expand All @@ -90,7 +95,8 @@ _rtsp-simple-server_ has been rebranded as _MediaMTX_. The reason is pretty obvi
* [VLC](#vlc)
* [Web browsers](#web-browsers-1)
* [By protocol](#by-protocol-1)
* [WebRTC](#webrtc-1)
* [SRT](#srt)
* [WebRTC](#webrtc)
* [RTSP](#rtsp)
* [RTMP](#rtmp)
* [HLS](#hls)
Expand Down Expand Up @@ -242,7 +248,7 @@ makepkg -si

#### FFmpeg

FFmpeg can publish a stream to the server in multiple ways (RTSP client, RTMP client, UDP/MPEG-TS, WebRTC with WHIP). The recommended one consists in publishing as a [RTSP client](#rtsp-clients):
FFmpeg can publish a stream to the server in multiple ways (SRT client, SRT server, RTSP client, RTMP client, UDP/MPEG-TS, WebRTC with WHIP). The recommended one consists in publishing as a [RTSP client](#rtsp-clients):

```
ffmpeg -re -stream_loop -1 -i file.ts -c copy -f rtsp rtsp://localhost:8554/mystream
Expand All @@ -258,7 +264,7 @@ The resulting stream will be available in path `/mystream`.

#### GStreamer

GStreamer can publish a stream to the server in multiple ways (RTSP client, RTMP client, UDP/MPEG-TS, WebRTC with WHIP). The recommended one consists in publishing as a [RTSP client](#rtsp-clients):
GStreamer can publish a stream to the server in multiple ways (SRT client, SRT server, RTSP client, RTMP client, UDP/MPEG-TS, WebRTC with WHIP). The recommended one consists in publishing as a [RTSP client](#rtsp-clients):

```sh
gst-launch-1.0 rtspclientsink name=s location=rtsp://localhost:8554/mystream \
Expand All @@ -285,7 +291,7 @@ The resulting stream will be available in path `/mystream`.

#### OBS Studio

OBS Studio can publish to the server as a [RTMP client](#rtmp-clients). In `Settings -> Stream` (or in the Auto-configuration Wizard), use the following parameters:
OBS Studio can publish to the server in multiple ways (SRT client, RTMP client, WebRTC client). The recommended one consists in publishing as a [RTMP client](#rtmp-clients). In `Settings -> Stream` (or in the Auto-configuration Wizard), use the following parameters:

* Service: `Custom...`
* Server: `rtmp://localhost`
Expand Down Expand Up @@ -534,6 +540,14 @@ The resulting stream will be available in path `/cam_with_audio`.
### By protocol
#### SRT clients
TODO
#### SRT servers
TODO
#### WebRTC
WebRTC is an API that makes use of a set of protocols and methods to connect two clients together and allow them to exchange real-time media or data streams. You can publish a stream with WebRTC and a web browser by visiting:
Expand Down Expand Up @@ -755,6 +769,10 @@ This web page can be embedded into another web page by using an iframe:
### By protocol
#### SRT
TODO
#### WebRTC
WebRTC is an API that makes use of a set of protocols and methods to connect two clients together and allow them to exchange real-time media or data streams. You can read a stream with WebRTC and a web browser by visiting:
Expand Down Expand Up @@ -1401,31 +1419,38 @@ The command will produce tarballs in folder `binaries/`.
## Standards
* RTSP
* [RTSP / RTP / RTCP standards](https://github.com/bluenviron/gortsplib#standards)
* HLS
* [HLS standards](https://github.com/bluenviron/gohlslib#standards)
* RTMP
* [RTMP](https://rtmp.veriskope.com/pdf/rtmp_specification_1.0.pdf)
* [Enhanced RTMP](https://raw.githubusercontent.com/veovera/enhanced-rtmp/main/enhanced-rtmp-v1.pdf)
* WebRTC
* [WebRTC: Real-Time Communication in Browsers](https://www.w3.org/TR/webrtc/)
* [WebRTC HTTP Ingestion Protocol (WHIP)](https://datatracker.ietf.org/doc/draft-ietf-wish-whip/)
* [WebRTC HTTP Egress Protocol (WHEP)](https://datatracker.ietf.org/doc/draft-murillo-whep/)
* Video and audio codecs
* [Codec standards](https://github.com/bluenviron/mediacommon#standards)
* Other
* [Golang project layout](https://github.com/golang-standards/project-layout)
## Related projects
* [gortsplib (RTSP library used internally)](https://github.com/bluenviron/gortsplib)
* [gohlslib (HLS library used internally)](https://github.com/bluenviron/gohlslib)
* [mediacommon (codecs and formats library used internally)](https://github.com/bluenviron/mediacommon)
* [datarhei/gosrt (SRT library used internally)](https://github.com/datarhei/gosrt)
* [pion/webrtc (WebRTC library used internally)](https://github.com/pion/webrtc)
* [pion/sdp (SDP library used internally)](https://github.com/pion/sdp)
* [pion/rtp (RTP library used internally)](https://github.com/pion/rtp)
Expand Down
4 changes: 2 additions & 2 deletions internal/conf/conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ type Conf struct {
WebRTCICETCPMuxAddress string `json:"webrtcICETCPMuxAddress"`

// SRT
SRTDisable bool `json:"srtDisable"`
SRTAddress string `json:"srtAddress`
SRTDisable bool `json:"srtDisable"`
SRTAddress string `json:"srtAddress"`

// paths
Paths map[string]*PathConf `json:"paths"`
Expand Down
41 changes: 21 additions & 20 deletions internal/core/authentication.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const (
authProtocolRTMP authProtocol = "rtmp"
authProtocolHLS authProtocol = "hls"
authProtocolWebRTC authProtocol = "webrtc"
authProtocolSRT authProtocol = "srt"
)

func externalAuth(
Expand Down Expand Up @@ -95,7 +96,7 @@ func externalAuth(
return nil
}

type authCredentials struct {
type authParameters struct {
query string
ip net.IP
user string
Expand All @@ -113,28 +114,28 @@ func authenticate(
pathName string,
pathConf *conf.PathConf,
publish bool,
credentials authCredentials,
params authParameters,
) error {
var rtspAuth headers.Authorization
if credentials.rtspRequest != nil {
err := rtspAuth.Unmarshal(credentials.rtspRequest.Header["Authorization"])
if params.rtspRequest != nil {
err := rtspAuth.Unmarshal(params.rtspRequest.Header["Authorization"])
if err == nil && rtspAuth.Method == headers.AuthBasic {
credentials.user = rtspAuth.BasicUser
credentials.pass = rtspAuth.BasicPass
params.user = rtspAuth.BasicUser
params.pass = rtspAuth.BasicPass
}
}

if externalAuthenticationURL != "" {
err := externalAuth(
externalAuthenticationURL,
credentials.ip.String(),
credentials.user,
credentials.pass,
params.ip.String(),
params.user,
params.pass,
pathName,
credentials.proto,
credentials.id,
params.proto,
params.id,
publish,
credentials.query,
params.query,
)
if err != nil {
return fmt.Errorf("external authentication failed: %s", err)
Expand All @@ -156,26 +157,26 @@ func authenticate(
}

if pathIPs != nil {
if !ipEqualOrInRange(credentials.ip, pathIPs) {
return fmt.Errorf("IP '%s' not allowed", credentials.ip)
if !ipEqualOrInRange(params.ip, pathIPs) {
return fmt.Errorf("IP '%s' not allowed", params.ip)
}
}

if pathUser != "" {
if credentials.rtspRequest != nil && rtspAuth.Method == headers.AuthDigest {
if params.rtspRequest != nil && rtspAuth.Method == headers.AuthDigest {
err := auth.Validate(
credentials.rtspRequest,
params.rtspRequest,
pathUser,
pathPass,
credentials.rtspBaseURL,
params.rtspBaseURL,
rtspAuthMethods,
"IPCAM",
credentials.rtspNonce)
params.rtspNonce)
if err != nil {
return err
}
} else if !checkCredential(pathUser, credentials.user) ||
!checkCredential(pathPass, credentials.pass) {
} else if !checkCredential(pathUser, params.user) ||
!checkCredential(pathPass, params.pass) {
return fmt.Errorf("invalid credentials")
}
}
Expand Down
5 changes: 4 additions & 1 deletion internal/core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ type Core struct {
rtmpsServer *rtmpServer
hlsManager *hlsManager
webRTCManager *webRTCManager
srtServer *srtServer
srtServer *srtServer
api *api
confWatcher *confwatcher.ConfWatcher

Expand Down Expand Up @@ -437,6 +437,9 @@ func (p *Core) createResources(initial bool) error {
if !p.conf.SRTDisable {
p.srtServer, err = newSRTServer(
p.conf.SRTAddress,
p.conf.ReadTimeout,
p.pathManager,
p,
)
if err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion internal/core/hls_http_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ func (s *hlsHTTPServer) onRequest(ctx *gin.Context) {
res := s.pathManager.getPathConf(pathGetPathConfReq{
name: dir,
publish: false,
credentials: authCredentials{
authParameters: authParameters{
query: ctx.Request.URL.RawQuery,
ip: net.ParseIP(ctx.ClientIP()),
user: user,
Expand Down
Loading

0 comments on commit 64ee16a

Please sign in to comment.