Multi-Tier Lyrics Caching¶
Lyrics retrieval in Cantus is designed for instantaneous local response times and resilient fallback handling across large, diverse music catalogs.
Retrieval Resolution Strategy¶
When a track starts playing, Cantus traverses a multi-tiered caching pipeline, then an ordered chain of lyric providers:
flowchart TD
Start[Track Changed / New Track ID] --> QueryLocal{1. Query SQLite Cache}
QueryLocal -->|Found Positive LRC| ReturnLyrics[Return Parsed Lyric Lines]
QueryLocal -->|Found Negative Cache| ReturnInstrumental[Flag as Instrumental / No Lyrics]
QueryLocal -->|Cache Miss| QueryLRCLIB[2. Query LRCLIB Synced API]
QueryLRCLIB -->|Match Found| SavePositive[4. Save to SQLite Positive Cache]
QueryLRCLIB -->|Miss| QueryNetease[3. Query NetEase Fallback]
QueryNetease -->|Match Found| SavePositive
QueryNetease -->|All Providers Answered: Not Found| SaveNegative[5. Save Negative Cache]
QueryNetease -->|Any Provider Unreachable| SkipCache[No Cache Entry: Retry Next Poll]
SavePositive --> ReturnLyrics
SaveNegative --> ReturnInstrumental
Provider Fallback Chain¶
Lyric sources implement ILyricsFetchProvider and run in a configured order (CachedLyricsService walks the list):
- LRCLIB (always first): community-driven, key-free synced and plain lyrics.
- NetEase Cloud Music (optional fallback,
Netease:Enabledinappsettings.json, on by default): unofficial web API with strong catalog coverage; synced lyrics only. CJK credit lines (lyricist/composer metadata) are stripped before parsing, and payload-level error codes (rate limits, anti-scraping challenges) are treated as transient failures.
Every provider classifies its result as found, authoritative miss, or transiently unavailable. The negative cache is only written when every provider authoritatively missed — an unreachable provider (network error, 5xx, or NetEase payload error code) leaves the cache untouched so the next playback poll retries.
Multi-Tier Cache Features¶
1. SQLite Local Positive Cache¶
- Duration: Persistent local storage (auto-renewing on access).
- Storage: Raw LRC string and normalized JSON parsed line objects indexed by Spotify Track ID and Artist/Title hash.
- Latency:
< 1msretrieval from local disk.
2. Negative Caching for Instrumental Tracks¶
- Problem: Many classical, jazz, EDM, and post-rock tracks have no lyrics. Without caching this absence, the server would query LRCLIB on every track transition.
- Solution: Cantus records a Negative Cache entry with a configurable 30-day TTL (configured via
LyricsCache:NegativeCacheDaysinappsettings.json; the setting is provider-agnostic and applies to the whole fallback chain). When the track plays again, Cantus immediately recognizes it as instrumental without network queries. A negative entry is only written when every provider in the chain authoritatively reported "not found" — transient provider failures are never cached.
3. LRCLIB Integration & Fuzzy Matching¶
- Primary Query: Exact search by Track Name, Artist Name, Album Name, and Duration.
- Fuzzy Fallback: If exact matching fails (common for remastered titles, "feat." artist tags, or deluxe editions), Cantus strips noise keywords (e.g.
(Remastered 2021),[Deluxe Edition]) and queries LRCLIB's fuzzy search endpoint.
LRC Parsing & Timestamp Normalization¶
Cantus implements a zero-allocation LRC parser (LrcParser) that translates standard LRC text formats into typed timestamp objects:
[00:12.45]First line of synchronized lyrics
[00:15.80]Second line of synchronized lyrics
[00:22.10]Third line after a brief break
Parser Features:¶
- Handles both 2-digit (
[mm:ss.xx]) and 3-digit ([mm:ss.xxx]) millisecond precision. - Normalizes out-of-order lyric lines.
- Computes start and end durations for each line to trigger smooth visual highlighting and transition states.