Skip to content

Repository files navigation

Solstice Lyrics

Multi-provider lyrics fetching library.
Standalone lyrics modules powering Solstice — a high-performance, privacy-focused YouTube Music client for Android.

Solstice (2026)
© Stark — github.com/urstark

Based on ArchiveTune
© Rukamori — github.com/rukamori

6 Lyrics SourcesLicenseKotlinJVMStars

Star History Chart

Overview

This repository contains the standalone lyrics provider modules extracted from Solstice. Each module is a self-contained Ktor-based HTTP client for a different lyrics source, designed as pure JVM libraries with no Android dependencies — the same approach as the core submodule.

Modules

ModuleSourceDescription
kugouKuGou MusicFetches LRC lyrics from KuGou's mobile API (mobileservice.kugou.com). Searches by title+artist keyword, matches by duration tolerance, downloads base64-encoded LRC.
lrclibLRC LibFetches synced + plain lyrics from lrclib.net. Uses Levenshtein distance for similarity matching.
simpmusicSimpMusicFetches crowd-sourced lyrics from api-lyrics.simpmusic.org. Indexed by YouTube video ID.
paxsenixPaxsenixMulti-backend proxy client for lyrics.paxsenix.org. Wraps Apple Music, NetEase, Spotify, Musixmatch, and YouTube lyrics endpoints.
betterlyricsBetterLyricsFetches TTML (Apple Music format) lyrics from lyrics-api.boidu.dev. Includes a full XML DOM-based TTML parser with word-by-word timing, CJK support, and transliteration.
unisonUnisonFetches lyrics from unison.boidu.dev. Supports lookup by video ID or metadata (title, artist, album, duration).

Features

  • Six independent providers — each module is a separate Gradle subproject with no cross-dependencies
  • Pure JVM — no Android SDK required, testable on any JVM
  • Ktor Client — built on Ktor with content negotiation and JSON serialization
  • Kotlinx Serialization — all API responses parsed into typed data classes
  • Multiple lyrics formats — plain text, LRC (synced), TTML (word-by-word), karaoke-style
  • Duration-aware matching — providers use Levenshtein distance and duration tolerance for accurate results

Architecture

The diagram below shows how these lyrics modules integrate into the Solstice app.

flowchart TB
subgraph Android["Solstice App (Android)"]
UI["Jetpack Compose UI<br/>LyricsScreen, LyricsMenu"]
VM["LyricsMenuViewModel"]
LH["LyricsHelper<br/>Orchestrator & Cache"]
LP["LyricsProvider interface<br/>App-layer wrappers"]
end
subgraph Lyrics["lyrics (this repository)"]
subgraph Kugou["kugou"]
KG["KuGou.kt<br/>KuGou mobile API"]
end
subgraph Lrclib["lrclib"]
LL["LrcLib.kt<br/>lrclib.net API"]
end
subgraph Simpmusic["simpmusic"]
SM["SimpMusicLyrics.kt<br/>SimpMusic API"]
end
subgraph Paxsenix["paxsenix"]
PX["PaxsenixLyrics.kt<br/>Multi-backend proxy"]
PXAM["Apple Music"]
PXNE["NetEase"]
PXSP["Spotify"]
PXMX["Musixmatch"]
PXYT["YouTube"]
end
subgraph Betterlyrics["betterlyrics"]
BL["BetterLyrics.kt<br/>TTML API"]
TTP["TTMLParser.kt<br/>XML word-by-word parser"]
end
subgraph Unison["unison"]
UN["Unison.kt<br/>Unison API"]
end
end
subgraph External["External APIs"]
EXKG["mobileservice.kugou.com"]
EXLL["lrclib.net"]
EXSM["api-lyrics.simpmusic.org"]
EXPX["lyrics.paxsenix.org"]
EXBL["lyrics-api.boidu.dev"]
EXUN["unison.boidu.dev"]
end
UI --> VM --> LH
LH --> LP
LP --> KG & LL & SM & PX & BL & UN
KG --> EXKG
LL --> EXLL
SM --> EXSM
PX --> EXPX
PXAM & PXNE & PXSP & PXMX & PXYT --> PX
BL --> EXBL
UN --> EXUN
Loading

Data flow:

  1. LyricsHelper receives a playback request with track metadata
  2. It iterates through configured providers in user-defined priority order
  3. Each app-layer LyricsProvider delegates to its corresponding library module
  4. The library module makes an HTTP request via Ktor to the external API
  5. Raw JSON responses are deserialized via Kotlinx Serialization
  6. Results are cached and returned to the UI

Package Structure

urstark.solstice/
├── kugou/ # kugou module
│ └── KuGou.kt — KuGou API client
├── lrclib/ # lrclib module
│ └── LrcLib.kt — LRC Lib API client
├── simpmusic/ # simpmusic module
│ └── SimpMusicLyrics.kt — SimpMusic lyrics client
├── paxsenix/ # paxsenix module
│ └── PaxsenixLyrics.kt — Multi-backend proxy client
├── betterlyrics/ # betterlyrics module
│ ├── BetterLyrics.kt — BetterLyrics API client
│ └── TTMLParser.kt — TTML XML parser
└── unison/ # unison module
└── Unison.kt — Unison API client

Dependencies

All modules share a common dependency set:

  • Ktor Client — HTTP client core, OkHttp/CIO engines, content negotiation, JSON serialization, encoding, logging
  • Kotlinx Serialization — JSON deserialization of API responses
  • JUnit — unit testing

Usage

Each module exposes a singleton object with a getLyrics() method. Below are examples for each provider.

KuGou

val lyrics =KuGou.getLyrics(
query ="Never Gonna Give You Up",
artist ="Rick Astley",
duration =213,
)

LRC Lib

val lyrics =LrcLib.getLyrics(
title ="Never Gonna Give You Up",
artist ="Rick Astley",
duration =213,
)

SimpMusic

val lyrics =SimpMusicLyrics.getLyrics(
videoId ="dQw4w9WgXcQ",
duration =213,
)

Paxsenix

// Auto-select (chains Apple Music -> NetEase -> Spotify -> Musixmatch)val lyrics =PaxsenixLyrics.getLyrics(
title ="Never Gonna Give You Up",
artist ="Rick Astley",
duration =213,
)
// Specific backendval appleMusic =PaxsenixLyrics.getAppleMusicLyrics(title, artist, duration)
val netease =PaxsenixLyrics.getNeteaseLyrics(title, artist, duration)
val spotify =PaxsenixLyrics.getSpotifyLyrics(title, artist, duration)
val musixmatch =PaxsenixLyrics.getMusixmatchLyrics(title, artist, duration)
val youtube =PaxsenixLyrics.getYouTubeLyrics(title, artist, duration)

BetterLyrics

val lyrics =BetterLyrics.getLyrics(
title ="Never Gonna Give You Up",
artist ="Rick Astley",
album ="Whenever You Need Somebody",
duration =213,
)

Unison

val lyrics =Unison.getLyrics(
videoId ="dQw4w9WgXcQ",
title ="Never Gonna Give You Up",
artist ="Rick Astley",
album ="Whenever You Need Somebody",
durationSeconds =213,
)

License

GNU General Public License v3.0

About

Lyrics library for ArchiveTune

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages