Repository navigation
Architecture and Ports
flowchart LR
I[iPhone / Moblin] -->|Authenticated SRT or RTMP over Tailscale| M[MediaMTX]
M -->|SRT or RTSP| O[OBS / VLC / FFmpeg]
M -->|LL-HLS or WebRTC| B[Browser preview]
M -->|Optional segments| R[Private recording directory]
D[Dashboard] -->|Local API 127.0.0.1:9997| M
D --> H[Connection history]
D --> S[Aggregate storage telemetry]
Provides encrypted device-to-device reachability. The software obtains the active IPv4 address from Tailscale and validates membership in 100.64.0.0/10 before starting.
Receives the publisher, enforces role-based authentication, exposes receiver protocols, remuxes LL-HLS/WebRTC and optionally writes recording segments. It does not perform video transcoding.
A dependency-free Python HTTP service that:
- Builds device-specific authenticated URLs
- Generates the Moblin import profile
- Reads MediaMTX status from localhost
- Calculates browser-side bitrate
- Persists state transitions
- Reports aggregate disk/recording usage
- macOS: two per-user LaunchAgents
- Linux: two hardened systemd services
| Component | Bind address | Protocol | Port | Exposure |
|---|---|---|---|---|
| SRT | Tailscale IPv4 | UDP | 8890 | Tailnet |
| RTSP | Tailscale IPv4 | TCP | 8554 | Tailnet |
| RTMP | Tailscale IPv4 | TCP | 1935 | Tailnet |
| LL-HLS | Tailscale IPv4 | TCP | 8888 | Tailnet |
| WebRTC signaling/HTTP | Tailscale IPv4 | TCP | 8889 | Tailnet |
| WebRTC media | Tailscale IPv4 | UDP | 8189 | Tailnet |
| Dashboard | Tailscale IPv4 | TCP | 8090 | Tailnet |
| MediaMTX API | 127.0.0.1 |
TCP | 9997 | Server localhost only |
| MediaMTX metrics | 127.0.0.1 |
TCP | 9998 | Server localhost only |
RTSP is restricted to TCP transport. Media over these ports should never be exposed through public router forwarding or tunnels.
| Identity | Permission | Path |
|---|---|---|
mobile |
Publish | live |
studio |
Read + playback | live |
| Localhost pseudo-user | API + metrics | Local control endpoints |
Random publisher and reader passwords are generated independently. The rendered MediaMTX configuration receives SHA-256 hashes rather than plaintext passwords.
| Data | Purpose | Contains secrets? |
|---|---|---|
credentials.env |
Publisher/reader passwords | Yes |
profile.env |
Moblin import settings | No |
recording.env |
Recording settings | No |
connection-history.json |
Event types, timestamps, durations | No |
recordings/ |
Optional media segments | Media content |
mediamtx.yml |
Rendered runtime configuration | Password hashes |
- Direct Tailscale binding: prevents accidental all-interface exposure.
- Separate publisher/reader secrets: limits the effect of a leaked receiver URL.
- Local control API: remote users cannot invoke MediaMTX administrative endpoints.
- Native services: fewer moving parts than a container runtime for a small relay.
- No transcoding: lower CPU use and latency; sender codec is preserved.
- Bounded history and cached storage scans: operational visibility without a database or constant disk traversal.
- Public ingest or playback
- Video mixing, graphics or transcoding
- SRTLA/multi-interface bonding
- Multiple independent stream paths
- Automatic cloud upload
- User accounts for the dashboard
Home · Quick start · Troubleshooting · Repository · Releases · License
Tailnet IRL Server · Developed by Nik Pottbecker