✳ tty.fm

Internet radio in your terminal.

One file, no dependencies, and a grudge against silence.

ttyfm plays live radio through mpv and wraps it in a fast TUI: what is on now, an equalizer that moves with the audio, favorites, history and yearly stats.

$npm install -g ttyfm

Needs Node 18 or newer and mpv. macOS, Linux and Windows.

  ✳ tty.fm                                                   live
  ────────────────────────────────────────────────────────────────

  ⏺ Better Times - Robin Schulz / Barbz
  ⏺ Laweta - Kizo / Julia Wieniawa 

 Dai Dai - Shakira / Burna Boy
━━━━━━━━━━━━━━━━━━━━━━──────────────  1:34 / 2:28

  ○ Fly High - Toby Romeo (up next)

  ────────────────────────────────────────────────────────────────
  [RMF MAXX · RS202-KRK]                            ▂▃▅▇▆▃▂▁▂▄▆▅▃▂
  ⏵⏵ during breaks: hop stations (shift+tab to cycle)      vol 80

Failover you never hear

When a stream dies or stalls, ttyfm starts a second muted mpv on the next best mirror, waits until audio is really flowing, jumps it to the live edge, then crossfades over about 300ms and kills the old one.

It leaves when the ads start

Breaks can fade the volume down, mute, or hop to another station that is currently playing music and crossfade back after. Your radio goes for a walk.

The equalizer is real

mpv reports loudness and tone over IPC, so the bars follow the actual signal. Bass lights up the left side, treble the right.

Wrapped, for radio

Top songs, top artists, streaks, hours per month, your peak listening hour, and a vibe like evening loyalist or night owl explorer. Built from local history, never uploaded.

50,000 stations to dig through

Discovery searches radio-browser.org with no key and no account. Same-name results collapse into one station whose URLs become its mirrors.

Your data stays yours

Stations, favorites, history and settings live in ~/.ttyfm as plain JSON. No cloud, no account, no telemetry. Delete a file to reset that part.