SRS
A simple, high efficiency and real-time video server, supports RTMP,
SRS is a high-efficiency real-time video server supporting RTMP, WebRTC, HLS, HTTP-FLV and SRT ingest and playback. It targets developers building live streaming services with low latency. It is deployed via Docker or a compiled C++ binary.
Key features
- RTMP, WebRTC, HLS, SRT support
- Low-latency live streaming
- Recording and transcoding
- HTTP API and callbacks
Pros & cons
Strengths
- Many protocols supported
- Low latency streaming
- Efficient C++ core
Trade-offs
- Docs partly Chinese
- Configuration can be involved
Last reviewed Sep 13, 2026 · 832 words
Pick your output protocol by the delay you can tolerate, because that choice decides everything else about an SRS deployment. HLS gives you the widest playback compatibility at 5 to 15 seconds of latency. HTTP-FLV brings that down to 1 to 3 seconds in a browser with a small player library. WebRTC gets you under a second but needs a UDP port and a correctly advertised IP. SRT handles the contribution side across bad networks. SRS speaks all of them from one C++ binary, and once you know which one you need, the configuration stops looking complicated.
What it is for, and who runs it
SRS is a media origin server, not a streaming platform. It ingests a stream from OBS or a hardware encoder, optionally records or transcodes it, and serves it back out in whichever protocols you enabled. There is no channel page, no chat, no user accounts. The people who run it are building something: a low-latency camera feed for a workshop, a private event stream for a few hundred viewers, a classroom relay, an internal broadcast that must not touch a third-party CDN. If you want to press go and have a viewer-facing page with chat, Owncast does that in one container and you should read no further.
The port map is the whole install
services:
srs:
image: ossrs/srs:5
command: ./objs/srs -c conf/docker.conf
ports:
- "1935:1935" # RTMP ingest
- "1985:1985" # HTTP API
- "8080:8080" # HLS, HTTP-FLV, built-in console
- "8000:8000/udp" # WebRTC media
- "10080:10080/udp" # SRT
environment:
- CANDIDATE=203.0.113.10
restart: unless-stopped
Point OBS at rtmp://your-host/live with stream key demo, then open http://your-host:8080/live/demo.m3u8 in any HLS-capable player or http://your-host:8080/live/demo.flv for the lower-latency option. The console on port 8080 shows connected publishers, viewer counts, and bitrates without any setup. The default docker.conf enables RTMP, HLS, HTTP-FLV, and WebRTC, so the compose file above works as written; the 512 MB rating is generous for a handful of streams, and CPU only becomes interesting when you turn on transcoding.
CANDIDATE is the setting that breaks WebRTC
Nearly every "WebRTC plays black" issue comes down to one variable. WebRTC clients need to be told which IP to send media to, and inside a container SRS sees only its private address. CANDIDATE must be the IP the browser can actually reach: your public address for internet viewers, the LAN address for a local setup. Get it wrong and signalling succeeds on port 1985 while media on port 8000 goes nowhere. If viewers are behind strict NAT you will also need a TURN server, which SRS does not include. HLS and FLV have no such problem, which is why I tell people to get a stream working over FLV first and add WebRTC second.
Recording, callbacks, and the API
Enable DVR in the config and SRS writes each session to an MP4 or FLV file on a path you choose, with segmenting by time or size. The HTTP API on port 1985 lists streams and clients and lets you kick a publisher. HTTP callbacks fire on publish, unpublish, play, and DVR completion, which is how you build authentication: SRS posts the stream key to your endpoint and a non-200 response rejects the publisher. That callback is the only access control you get, so wire it up before you expose port 1935 to the internet, or anyone who guesses the URL can broadcast on your server.
The documentation is uneven
The project comes from a Chinese-speaking community and the English docs at ossrs.io are a translation that lags the original in places. Configuration reference pages are thorough; troubleshooting threads are often in Chinese. This is the main reason a comparable tool gets recommended more often: MediaMTX is a single Go binary with a flat YAML config, English-first documentation, and the same core protocols including RTSP, which SRS does not do. SRS holds its ground on WebRTC maturity, the built-in console, and transcoding hooks, and at 29,203 stars it is the larger project. For the rest of the media server category, most entries are libraries for stored video, not live origins, and do not compete here.
What I'd do
For a private live feed where sub-second latency does not matter, I would run MediaMTX because the config fits on one screen. Where WebRTC playback in a browser is the actual requirement, SRS is the tool I trust more: run the compose file above, set CANDIDATE to the reachable IP, prove the FLV URL plays, then enable WebRTC, then wire the publish callback to a 20-line auth endpoint. Keep transcoding off unless viewers need multiple bitrates, and record to a disk you have measured, because an unattended 6 Mbps stream fills 2.7 GB an hour.
Similar media servers apps
Jellyfin
Media ServersFree software media system for streaming your library
Replaces Plex, Emby
qBittorrent
Media ServersBittorrent client that aims to be a good alternative to all other
Replaces µTorrent
Navidrome
Media ServersModern music streaming server for your collection
Replaces Spotify
Kodi
Media ServersOpen-source home theater and media center
Replaces Plex
Koel
Media ServersPersonal music streaming server with an elegant interface
Replaces Spotify
Sonarr
Media ServersSeries collection manager for Usenet and BitTorrent users