Synchronized lyrics in your terminal for the currently playing Spotify track
Project description
spotty
Synchronized lyrics in your terminal for the currently playing Spotify track.
- Line-by-line sync using LRC timestamps from lrclib.net
- Falls back to plain lyrics via lyrics.ovh if no synced lyrics found
- Smooth display — progress interpolated between API polls (no jumping)
- Auto-refreshes when track changes
- Handles instrumental sections, multi-artist tracks, featured artists
Requirements
- Python 3.11+
- A Spotify Developer App
Installation
pip install spotty-cli
Or from source:
git clone https://github.com/Arideno/spotty
cd spotty
pip install -e .
Setup
1. Create a Spotify App
- Go to Spotify Developer Dashboard
- Click Create app
- Set Redirect URI to
http://127.0.0.1:8888/callback - Copy your Client ID
2. Configure credentials
spotty init
You will be prompted for:
Spotify Client ID: <paste your client ID>
Redirect URI [http://127.0.0.1:8888/callback]: <Enter to keep default>
Config is saved to ~/.config/spotty/config.json.
On first run after init, a browser window opens for Spotify authorization. Tokens are saved to ~/.config/spotty/tokens.json and refreshed automatically.
Usage
# Synchronized mode (default) — live updating display
spotty
# Plain lyrics — print and exit
spotty --plain
# Adjust timing if lyrics feel early or late
spotty --offset 300 # shift 300ms later
spotty --offset -200 # shift 200ms earlier
# Version
spotty --version
# Help
spotty --help
Options
| Option | Default | Description |
|---|---|---|
--plain |
off | Show plain (non-synced) lyrics and exit |
--offset MS |
0 |
Shift lyrics by MS milliseconds. Positive = later, negative = earlier |
--version |
— | Show version and exit |
--help |
— | Show help and exit |
Configuration
Credentials are stored in ~/.config/spotty/config.json after running spotty init.
| Key | Required | Default | Description |
|---|---|---|---|
client_id |
Yes | — | Spotify app client ID |
client_secret |
Yes | — | Spotify app client secret |
redirect_uri |
No | http://127.0.0.1:8888/callback |
OAuth callback URI — must match your Spotify app settings |
To update any value, re-run spotty init.
File locations
| File | Purpose |
|---|---|
~/.config/spotty/config.json |
Credentials |
~/.config/spotty/tokens.json |
OAuth tokens (auto-managed) |
Delete tokens.json to force re-authentication.
How it works
- Auth — OAuth2 PKCE flow, no client secret needed in the token exchange
- Now playing — polls
GET /me/player/currently-playingevery 500ms - Lyrics — fetches LRC-timed lyrics from lrclib.net; falls back to lyrics.ovh for plain text
- Display — interpolates playback position between polls using the local clock for smooth highlighting
Development
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run directly
python -m spotty.cli
Contributing
- Fork the repo
- Create a branch:
git checkout -b my-feature - Make changes and add tests
- Run
pytest— all tests must pass - Open a pull request
License
MIT — see LICENSE
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file spotty_cli-0.0.5.tar.gz.
File metadata
- Download URL: spotty_cli-0.0.5.tar.gz
- Upload date:
- Size: 133.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2424cf31bbca94678884c8b427e0ccba3eb2e1b0664ddc116788f202a3b4cffa
|
|
| MD5 |
8dff48f121c6473f23dfeaaa55548913
|
|
| BLAKE2b-256 |
3e93a582916227ef66c8a3f32d95bd8b654fb2b5fc2b1bb812c8ed58dff0392a
|
File details
Details for the file spotty_cli-0.0.5-py3-none-any.whl.
File metadata
- Download URL: spotty_cli-0.0.5-py3-none-any.whl
- Upload date:
- Size: 12.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
71f03acd2778e40b68eeea7c43e32c6afae45a0b1ee80980ce36da0462917b2f
|
|
| MD5 |
b86e905b0c8c855b5d894946aa3a23db
|
|
| BLAKE2b-256 |
19252f25367c38cbc8d51700a390e35d947790be3fd174cbf509d3e017ef6ead
|