LRX-CLI

Warning

This project is primarily provided for educational and experimental purposes. It is yet not ready for production or commercial use and may violate the terms of service (ToS) of thirdparty music platforms. Use of this software is at your own risk; the authors provide no warranties and accept no liability for any consequences arising from its use.

A CLI tool for fetching LRC lyrics on Linux. Automatically detects the currently playing track via MPRIS/DBus and retrieves the best-matching lyrics from multiple sources, ranked by confidence scoring.

Sources

Sources are queried in order. High-confidence results (exact match or manual insert) terminate the pipeline early; otherwise all sources are tried and the highest-confidence result wins.

  1. Local — sidecar .lrc files or embedded audio metadata (FLAC, MP3)
  2. Cache Search — fuzzy cross-album lookup in local cache
  3. Spotify — synced lyrics via Spotify's API (requires credentials.spotify_sp_dc and Spotify trackid)
  4. LRCLIB — exact match from lrclib.net (requires full metadata)
  5. Musixmatch (Spotify) — Musixmatch API with Spotify trackid (requires Spotify trackid)
  6. LRCLIB Search — fuzzy search from lrclib.net (requires at least a title)
  7. Musixmatch — Musixmatch API with metadata search (requires at least a title)
  8. Netease — Netease Cloud Music public API
  9. QQ Music — QQ Music via self-hosted API proxy (requires credentials.qq_music_api_url; compatible with tooplick/qq-music-api)

I'm aware that Spotify's lyrics are provided by Musixmatch, but the fact is that Musixmatch's own search will yield different (and more) results than Spotify's, so I treat them as separate sources.

Usage

See lrx --help for full command reference. Common use cases:

  • Fetch lyrics for the currently playing track:

    lrx fetch
    

    targeting a specific player and source:

    lrx fetch --player mpd --method lrclib-search
    
  • Search by metadata (bypasses MPRIS):

    lrx search -t "My Love" -a "Westlife"
    lrx search --trackid "5p0ietGkLNEqx1Z7ijkw5g"
    

    or by path to a local audio file:

    lrx search --path "/path/to/Westlife - My Love.flac"
    
  • Export to sidecar .lrc file (or .txt with --plain):

    lrx export
    lrx export --plain
    lrx export --output /path/to/lyrics.lrc
    
  • Watch active player and stream lyrics continuously to stdout:

    lrx watch pipe
    lrx watch pipe --before 1 --after 2   # show context lines
    

    Control a running watch session:

    lrx watch ctl status                  # print session status as JSON
    lrx watch ctl offset +200             # shift lyrics forward 200 ms
    lrx watch ctl offset -150
    
  • Cache management:

    lrx cache stats                       # statistics
    lrx cache query                       # inspect cache entries for current track
    lrx cache clear                       # clear cache of current track
    lrx cache clear --all                 # clear entire cache
    lrx cache confidence spotify 100      # manually set confidence for a source
    

Shell completion (zsh/fish/bash):

lrx --install-completion

Configuration

Configuration is read from ~/.config/lrx-cli/config.toml. The file is optional; all values have defaults. Unknown keys are rejected with an error.

[general]
preferred_player  = "spotify"       # preferred MPRIS player when multiple are active
player_blacklist  = ["firefox", "zen", "chrome", "chromium", "vivaldi", "edge", "opera", "mpv"]
http_timeout      = 10.0            # seconds

[credentials]
spotify_sp_dc         = ""          # required for Spotify source
musixmatch_usertoken  = ""          # optional; anonymous token fetched if empty
qq_music_api_url      = ""          # required for QQ Music source

[watch]
debounce_ms             = 400       # ms to wait after a track change before fetching
calibration_interval_s  = 3.0       # seconds between full MPRIS position recalibrations
position_tick_ms        = 50        # ms between local position ticks
socket_path             = ""        # Unix socket path; defaults to <cache_dir>/watch.sock

Credentials:

  • spotify_sp_dcSP_DC cookie from a logged-in Spotify web session. Required for the Spotify source; leave empty to disable it.
  • musixmatch_usertoken — found at Curators Settings Page → Login → "Copy debug info". If empty, an anonymous token will be fetched at runtime, which could be more likely to hit the rate limits.
  • qq_music_api_url — base URL of a self-hosted qq-music-api (compatible) instance. Required for the QQ Music source; leave empty to disable it.

Development

Clone this repository:

git clone https://github.com/Uyanide/lrx-cli.git
cd lrx-cli

Create a virtual environment and install dependencies (for example, using uv):

uv venv .venv
uv sync

Run tests without network calls:

uv run pytest -m "not network"

or run full tests. The REAL API calls will be made and some of them will be skipped if the required credentials are not configured as above. This might be useful to verify that the lyric sources are still valid and working as expected:

uv run pytest

Run the CLI:

uv run lrx --help

Install to user-level (optional):

uv tool install .

Credits

S
Description
Fetch line-synced lyrics for your music player
Readme BSD-3-Clause 2.1 MiB
Languages
Python 100%