ESR
  • schedule
  • shows
  • archive
  • about

  • schedule
  • archive
  • shows
  • forum
  • about
  • mixcloud
  • instagram
  • youtube

© ill-pitched 🤝

tech

Streaming Server

OvenMediaEngine (OME)

OvenMediaEngine is the core streaming server that handles ingest, transcoding, and delivery for all live video and audio streams. It is an open-source media server built for low-latency live streaming, and it runs the show from the moment a broadcast signal leaves the studio.

The primary delivery protocol is LLHLS (Low-Latency HLS) using fragmented MP4 (fMP4) segments. This keeps the glass-to-glass delay at roughly 2 seconds behind live — tight enough for real-time interaction without the complexity of WebRTC. For clients or networks that cannot sustain LLHLS, the server falls back to standard HLS with MPEG-TS segments, which runs at a more traditional 6–10 second latency.

Adaptive Bitrate (ABR) is configured with three renditions to cover every connection quality:

  • High — 1280×720, 25 fps, 2500 kbps video, 192 kbps AAC
  • Low — 640×360, 25 fps, 800 kbps video, 128 kbps AAC
  • Audio-focus — 1280×720, 2 fps (blocky hint frames), 192 kbps AAC

For listeners who prefer a pure audio stream — no video overhead, maximum compatibility — we run an Icecast server alongside OME. It serves AAC-LC at 192 kbps encoded via libfdk_aac, with an MP3 fallback for legacy clients that cannot decode AAC in an Icecast stream.

Thumbnail / Keyframe Service

thumb.ether.esr.li

A dedicated keyframe extraction service runs at thumb.ether.esr.li. It connects to the live stream and extracts keyframes at approximately 1 frame per second, producing 1280×720 JPEG images.

These thumbnails serve two purposes on the website: they are used as poster frames for the video player before the user hits play, and they populate the MediaSession artworkso that browser media controls and mobile lock screens display the current show's visual identity.

Backoffice

ControlRoom

ControlRoomis the custom-built backoffice system that manages the entire station. It handles show scheduling, episode management, host profiles, and the live “right now” status that tells listeners what is currently on air.

Every piece of data you see on this website — the schedule grid, show pages, episode archives, and the live indicator — comes from the ControlRoom JSON API at controlroom.one/api/v1/stations/…. There is no local database; the website is a pure consumer of the API.

Frontend

Next.js 16 + Turbopack

The website you are reading this on is built with Next.js 16 using the App Router. Both development and production builds run on Turbopack, the Rust-based bundler that replaces webpack for significantly faster refresh and build times.

State management is handled entirely through React Context— no Redux, no Zustand, no external state library. The context providers are nested in a specific order (ScheduleContext > MediaContext > MenuContext > HeaderContext) to ensure data dependencies are satisfied without circular issues.

Video playback uses hls.js directly (not via react-player) for fine-grained control over the HLS stream, including ABR switching and low-latency mode. The styling layer is Tailwind CSS v3 with a fully custom design scale — font sizes, breakpoints, and colour palette are all bespoke, defined in the project's tailwind.config.js.

The entire frontend is deployed on Vercel, which provides edge caching, automatic HTTPS, and seamless preview deployments for every branch.

Analytics & Monitoring

Umami provides privacy-friendly web analytics. It runs without cookies and does not perform cross-site tracking — no GDPR banner needed, no user fingerprinting. It gives us just enough data (page views, referrers, visitor numbers) to understand how the site is used.

Sentry handles error tracking and performance monitoring. It captures unhandled exceptions, API failures, and front-end performance metrics, with source maps uploaded during the CI build for readable stack traces.

Related Pages

Audio stream endpoints and direct listeningVideo stream endpoints and rendition details