Livestreams
A self-hostable live-video platform — multi-protocol go-live, adaptive-quality playback, crash-safe recording, and one-click restreaming — that you own instead of renting from Mux or Livepeer.
The problem
Self-hosters and small teams want to own their live-streaming platform instead of paying a managed provider like Mux or Livepeer. Livestreams lets creators go live over RTMP, SRT, or straight from the browser, then automatically transcodes to adaptive quality, records every session, and restreams to third-party platforms — all self-hosted, driving a clean dashboard.
Challenges
Multi-protocol ingest without trusting the client
A dedicated media server accepts the incoming feed over RTMP, SRT, or browser WebRTC, but the decision of whether a given stream is allowed to publish belongs to the app, not the media server. The media server calls back into private, secret-guarded endpoints as a stream starts and stops, and those endpoints validate the stream's ingest key against the database. For browser publishing, the ingest key never reaches the client at all — it's injected by a same-origin server proxy.
Adaptive-bitrate transcoding
To keep playback smooth on any connection, each live feed is transcoded into a three-rung quality ladder (720p/480p/360p) whose segments are aligned so players can switch rungs seamlessly. The same transcode configuration drives both live playback and the seekable video-on-demand recording, and it adapts automatically to sources that carry no audio track.
Long-running media jobs vs a request/response API
A transcode runs for the entire length of a broadcast — completely at odds with a short-lived HTTP request. The system is split into an API service and a separate worker service, coordinated through a durable job queue. Live transcode jobs are allowed to run open-endedly until the broadcaster disconnects, with a read timeout that prevents a job from hanging forever on an input stream that never cleanly ends.
Recording that survives an abrupt kill
Because a live recording is often terminated mid-write when the broadcaster drops, a normal video file — which only becomes valid once its closing index is written — would be left corrupt. Recordings are instead written in a fragmented format that stays playable even if the process is killed at any moment. Truncated, content-free fragments are discarded rather than saved as broken files, and every valid recording is stored as an asset with a thumbnail and a scrubbing preview.
Implementation
API / worker split over a shared job queue
The API only ever enqueues work, behind an abstraction so request handlers never couple to the queue directly, while the worker service owns the actual executors: live transcode-and-record, restreaming, video-on-demand processing, clipping, auto-captioning, and webhook delivery. A restream job reports back its handle so toggling "go live off" can cancel the running relay cleanly.
Live progress telemetry
Processing jobs stream their progress — frames, speed, bitrate, percentage — and their logs to the dashboard in real time over a live event channel, with logs persisted so the activity timeline survives even after the job ends. Restreaming is a pure passthrough relay to an external target such as YouTube or Twitch, decrypting the destination credentials only in memory as it connects.
Adaptive playback and object storage
Workers write the quality-ladder output to an origin that a CDN sits in front of in production, and for protected streams every segment URL is rewritten on the fly to carry a signed access token. Recordings, clips, thumbnails, and captions all go to S3-compatible object storage behind a small interface, read back through pre-signed URLs so the media tools can stream directly from storage.
Versioned, layered API
The whole surface is versioned and wrapped in composable middleware for request tracing, recovery, CORS, and timeouts. It authenticates both session tokens and API keys, with a separate token-in-query path so the browser's live-event connections can authenticate too, and cleanly separates public and rate-limited auth routes from the authenticated surface.
Real-time events and geo analytics
Every step of the pipeline is recorded and published on a low-latency message bus, fanned out both to dashboards in real time and to dispatchers that deliver signed webhooks and notifications. Viewer quality-of-service beacons feed analytics, and location lookup degrades gracefully to a no-op when no geo database is configured, so the feature is optional rather than required.
Why this stack
- Go
- One codebase builds both the API and worker services, and its process control and concurrency tools are a natural fit for supervising long-lived transcode processes with clean cancellation.
- chi
- A lightweight HTTP router whose composable middleware lets session-auth, event-stream auth, rate-limited, and secret-guarded routes all coexist in one clear tree.
- PostgreSQL
- The single source of truth, with type-safe generated queries and managed schema migrations.
- River
- Durable background jobs living in the same database — no extra message broker to run — with open-ended timeouts for live work, retries for webhooks, and cancellation to stop live relays on demand.
- ffmpeg / SRS
- The media server handles multi-protocol ingest and browser-to-RTMP bridging with hooks for authorization; ffmpeg does the adaptive transcode, recording, clipping, and restreaming.
- Redis
- A low-latency message bus carrying stream and progress events, fanned out to live dashboard connections and to webhook and notification dispatchers.
What it does
- RTMP/SRT ingest with per-stream keys and publish hooks, plus browser go-live over WebRTC/WHIP
- Automatic adaptive HLS (720p/480p/360p) from a built-in, CDN-frontable origin with signed-token playback
- Crash-safe fragmented-MP4 recording, VOD upload/transcode, and clip cutting with thumbnails and storyboards
- Restream/simulcast to YouTube/Twitch/any RTMP target with OAuth account linking
- Live transcode progress and activity timeline over SSE, plus QoS and GeoIP analytics
- Multi-tenant orgs with roles, JWT + API keys, signed webhooks with redelivery, and Whisper auto-captions