Live video platform · 2026

TheFanPod

FanPod puts the audience on air. Fans scan a QR code in the stands and stream their phone's camera straight from the browser. The producer picks who goes live and pulls each feed into vMix, OBS or a hardware switcher over SRT.

Try it

Run the pod yourself

Scan the code with your phone, let it off the waitlist, and watch your own camera land in the player.

Live feed Offline Opening a room
Live feed Opening a room…

Peer-to-peer connection between your phone and this browser. Nothing is recorded. Demo feeds run for 90 seconds, then the room closes. If the two can't reach each other directly, the video is relayed through Cloudflare. Everything is encrypted end-to-end and never stored.

From the stands to the switcher

  1. Phone browser WebRTC, H.264
  2. Membrane Depayload, Opus to AAC, MPEG-TS
  3. SRT gateway One port, routed by stream ID
  4. Your switcher vMix, OBS, hardware

Phones send H.264 over WebRTC to a Membrane pipeline written in Elixir, which also runs the signaling. It repackages the video without transcoding, converts the audio from Opus to AAC and muxes MPEG-TS.

A Rust gateway built on libsrt serves every feed from a single SRT port and routes each consumer by stream ID. Producers get predictable URLs per event that they set up once, with no port pools. The hop from Membrane to the gateway runs over TCP, so frames that survived the fan's cellular connection aren't lost on the way out.

Admission control

Every phone that scans lands on a first-in, first-out waitlist with a low-frame-rate preview. The producer invites the angles they want, up to the event's slot limit, and cycles a slot to bring in the next fan. A Next.js control plane on Supabase handles admission, mints short-lived signaling tickets and tracks each session from waitlisted to live.

About the demo

The demo above runs the same loop on a smaller scale. Your phone streams peer-to-peer to this browser and a Cloudflare Durable Object relays the handshake. Cloudflare TURN covers the cellular networks where a direct connection fails. The Durable Object's alarm, not a timer in the browser, ends each feed after 90 seconds, which keeps relay usage bounded.

Built with

  • Elixir
  • Membrane
  • WebRTC
  • SRT
  • Rust
  • Next.js
  • Supabase
  • Cloudflare Workers