Skip to main content

Spotify in your terminal — a from-scratch TUI client with real audio visualizers

Project description

zpotify

Spotify, entirely in your terminal. The official Spotify app never opens.

A from-scratch TUI client: hand-rolled terminal engine (no curses, no TUI framework), its own OAuth PKCE flow, a raw stdlib Spotify Web API client, and a real audio visualizer driven by an FFT of the PCM actually playing through your speakers. Runtime dependencies: numpy and sounddevice. That's it.

 1 now playing  2 search  3 playlists  4 library  5 queue  6 devices  7 settings   ziedjohn

   Levels                                                                 █   ▀ ▄▀▀
   Avicii                                               ▀▀▀█▀ █▀▀▀▄ ▄▀▀▀▄ █▀▀ █ █▀▀ █   █
   Levels                                                ▄▀   █▄▄▄▀ █   █ █   █ █   ▀▄▄▄█
                                                        ▀▀▀▀▀ █      ▀▀▀   ▀▀ ▀ ▀       █
                                                              ▀                      ▀▀▀

        ─   ─           ─
                        ▂         ─           ┌─ UP NEXT ────────────────────────────────┐
            █         ▃ █                     │  1 Wake Me Up — Avicii                   │
        ▆   █         █ █ ▂       ▇           │  2 The Nights — Avicii                   │
        █   █ ▇       █ █ █     ▂ █           │  3 Hey Brother — Avicii                  │
        █ █ █ █     ▆ █ █ █ ▂   █ █           │  4 Waiting For Love — Avicii             │
      ▃ █ █ █ █ ▇   █ █ █ █ █   █ █ ▅         │  5 Red Lights — Tiësto                   │
      █ █ █ █ █ █   █ █ █ █ █ ▇ █ █ █         │  6 The Business — Tiësto                 │
    ▂ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ ▆       │  7 The Motto — Tiësto, Ava Max           │
    █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ ▃     │  8 Are You With Me — Lost Frequencies    │
  ▆ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ ▂   │  9 Reality — Lost Frequencies            │
  █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ ▃ │ 10 Where Are You Now — Lost Frequencies  │
  █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ └──────────────────────────────────────────┘

─██████████████████████████████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░─
  Levels  Avicii — Levels
 ⏮  ⏸  ⏭  [shuffle] [repeat:off]                                      1:24 / 3:19  vol  80%

How it works

zpotify runs librespot as a subprocess that registers on your account as a Spotify Connect device — used strictly as an audio faucet. Control (search, playlists, play/pause/seek) goes through the Web API with a hand-written PKCE OAuth flow; the raw PCM flows through zpotify, which plays it on your system output and FFTs it for the visualizer. Everything you see and interact with is this codebase.

Requirements

  • Spotify Premium (Spotify requirement for playback outside official apps)
  • macOS with Homebrew: brew install librespot
  • uv
  • A free Spotify developer app — the first-run wizard walks you through it

Install & run

Install once as a global command (an isolated venv plus a zpotify shim in ~/.local/bin):

uv tool install zpotify    # or: pipx install zpotify

Then from anywhere:

zpotify          # first run launches the setup wizard
zpotify doctor   # health check when something's off
zpotify auth     # redo the Spotify login

Or try it without installing: uvx zpotify.

From source / development: uv tool install --editable /path/to/zpotify (--editable links src/, so code changes apply without reinstalling; inside the repo, uv run zpotify works too).

→ Full setup walkthrough, key reference, and troubleshooting: docs/USER_GUIDE.md

Keys

space play/pause · n/b next/prev · ,/. seek ±10s · +/- volume · / floating search from anywhere (enter searches, / or esc closes) · 1-7 views (7 = settings) · tab/shift+tab cycle tabs · j/k/h/l vim navigation in views · enter play · a queue · s shuffle · r repeat · v visualizer · ? help · q quit — plus full mouse support (click rows/tabs/buttons, scroll wheel, click the progress bar to seek).

Themes

Settings (7) includes an accent theme — 12 colors (green default, plus cyan, blue, teal, lime, yellow, orange, red, pink, magenta, purple, white) that re-skin the tabs, bars, highlights, and visualizer live.

Project layout

src/zpotify/
  term/       terminal engine: raw mode, diff renderer, key/mouse decoding, widgets
  auth.py     OAuth 2.0 PKCE against accounts.spotify.com (stdlib only)
  api.py      Spotify Web API client (urllib), models in models.py
  player/     librespot subprocess, PCM ring buffer → sounddevice, FFT analysis
  ui/         event loop, seven views, player bar, overlays, theming
tests/        140+ unit tests: input decoding, rendering, API parsing, audio, FFT

Development

uv run pytest -q        # test suite

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

zpotify-0.2.0.tar.gz (54.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

zpotify-0.2.0-py3-none-any.whl (68.9 kB view details)

Uploaded Python 3

File details

Details for the file zpotify-0.2.0.tar.gz.

File metadata

  • Download URL: zpotify-0.2.0.tar.gz
  • Upload date:
  • Size: 54.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for zpotify-0.2.0.tar.gz
Algorithm Hash digest
SHA256 e878086f15a7793a5dc2caa6bc1f7c46014ffe17ef5c780316fefe6338510eb8
MD5 3becc883282dc520b22af3072de4cb06
BLAKE2b-256 4b9ff3439356e9faad25a20bef5f871e2eaaed22b5b48aabf7e40bf5449c0045

See more details on using hashes here.

File details

Details for the file zpotify-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: zpotify-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 68.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for zpotify-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8296bd47022cee75ce5fb3b309bb9b9456d8d5b8bdde6fe0278440145c94933b
MD5 8fc8382e57eaf3f62f147723c9b8f4d9
BLAKE2b-256 e5e407ebf912176116152fdc24ea067f0f44d8c6c1d30bc1cb771f5be45fcff1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page