Andromeda: a public TV channel with a schedule and a chat
A livestream page over my media library. Anyone with the link can watch what is on, see what is next, and talk about it. One process, one container.
ErsatzTV turns a media library into a television channel. It decides what plays next and loops forever, so at any moment there is something on. I liked that enough to want other people watching it with me, and watching together needs two things a raw stream does not have: a schedule, so you know whether to stay, and a chat, so you can react.
Andromeda is that page. Open the URL and the channel is already playing. Below it is what is on now and what is coming up. Beside it is the chat.
One process serves everything
The whole app is a single Node process on a single origin:
/ the page
/api/chat/* chat, with a server-sent-events stream for live messages
/api/schedule the schedule, normalized
/iptv/* a reverse proxy to ErsatzTVThat layout is most of the reason the project exists. The player, the schedule, the chat, and the stream proxy fit in one container, so deploying it is one compose service and the routing is something you can read in a file.
The schedule comes from the Jellyfin library that feeds ErsatzTV, and the server cleans it up before the browser sees it. The IPTV proxy rewrites the playlist it passes through so the stream resolves correctly behind whatever public hostname it lives at.
The chat is ephemeral on purpose
Accounts are a nickname and a password. Messages are capped at 500 characters and the server keeps only the last 100. That fits the medium. Television does not have a scrollback, and neither should the chat under it.
The frontend is React and TypeScript with Vite and Tailwind. The backend is a small Express app with SQLite and its own tests. Bun runs development, Node 24 runs production. It has been on for months now, and people I know drop in when something good is scheduled.
