About
Noctalia Lyrics 1.5.8
Synchronized lyrics for the Noctalia bar, with multiple MPRIS players, translation and romanization layers, configurable sources, karaoke highlighting, album artwork, and layout controls.
Plugin
| Field | Value |
|---|---|
| ID | h465855hgg/lyrics |
| Entries | Bar widget: lyrics; panel: selector; shortcut: open_selector; service: service |
Requirements
Install these commands on PATH:
playerctl: read and control MPRIS players.python3: run the unified lyric-source adapter and dynamic lyric parser.cp: preserve local MPRIS artwork in the plugin cache.chmod: secures the temporary request directory before credentials are written.timeout: bounds eachplayerctlmetadata poll during startup and runtime.
For a dependency table and package-manager install commands, see DEPENDENCIES.md.
Usage
Enable h465855hgg/lyrics, start its service entry, and add the lyrics bar
widget. The widget declares default pointer bindings that appear under Actions
in its bar settings:
| Gesture | Default command | Behavior |
|---|---|---|
| Left click | plugin h465855hgg/lyrics:lyrics all toggle-view |
Switch between lyrics and track information when display_mode is toggle |
| Right click | plugin h465855hgg/lyrics:service all toggle-playback |
Pause or resume the selected player |
| Scroll up | plugin h465855hgg/lyrics:service all next |
Next track on the selected player |
| Scroll down | plugin h465855hgg/lyrics:service all previous |
Previous track on the selected player |
Override or clear any binding per widget in the bar widget's Actions section.
The left-click command is broadcast to every lyrics widget, and only the
instance under the pointer changes its view. When LRCLIB returns multiple
matches, open the selector panel from the
open_selector control-center shortcut and apply another result. The widget no
longer opens the selector on hover; it can also be opened directly through IPC:
noctalia msg panel-toggle h465855hgg/lyrics:selector
Screenshots
Double-line widget with translated or romanized lyrics:

Plugin-wide settings:

Per-widget bar settings:

Local development
Add the parent directory of this checkout as a local Noctalia source:
noctalia msg plugins source add lyrics-dev path /path/to/plugin-parent
noctalia msg plugins enable h465855hgg/lyrics
noctalia msg config-reload
Run validation after every change:
python3 .github/workflows/scripts/validate-plugins.py
noctalia plugins lint lyrics
sh lyrics/scripts/setup-deps.sh --check
cd lyrics
python3 -m py_compile lyric_sources.py music_sources.py krc_decode.py lrclib_lyric.py
python3 -m unittest discover -v
Lyrics model
Every source is normalized to lines with independent original, translation, romanization, and character-timing fields:
{
"time": 1200,
"duration": 1800,
"text": "Original lyric",
"translation": "Translated lyric",
"romanization": "romanized lyric",
"chars": [1200, 1500, 1800]
}
Sources
auto tries the IDs listed in lyrics_sources from top to bottom. Supported
IDs are:
lrclib: public LRCLIB search with automatic synchronized-result ranking and manual result selection.netease: public NetEase cloud search and lyric endpoint with legacy fallback, synchronized lyrics, translations, and romanization when returned.splayer: SPlayer's complete current lyric data, including line and word timing, translations, romanization, background lines, and duet markers. SPlayer must be running; the default API URL ishttp://127.0.0.1:25884. Changing this URL sends current track metadata to the configured service.qqmusic: QQ Music desktop catalogue search and lyric endpoint with legacy endpoint fallback.kugou: public Kugou search and lyric download endpoint.qishui: user-configured HTTP endpoint supporting{title},{artist}, and{album}placeholders.apple_music: Apple Music catalog and lyrics request using manually supplied developer and optional user tokens.spotify: Spotify search and color-lyrics request using a manually supplied access token orsp_dc.musixmatch: Musixmatch subtitle request using a manually supplied usertoken.mpris: embeddedxesam:asTextlyrics from the selected player.custom: existing generic HTTP endpoint.external: lyrics pushed through Noctalia IPC.
Source APIs can change or reject requests by region or account. Failure of one source in automatic mode moves to the next source without logging credentials. Album artwork uses MPRIS first, then the matched lyric source when available. LRCLIB, Qishui, and Musixmatch matches use the public iTunes Search API as an artwork fallback. Cached covers retain their detected image format and the oldest files are removed after the cache reaches 80 covers.
Runtime cache files are stored in noctalia.pluginDataDir() .. "/cache", which
honors NOCTALIA_STATE_HOME and survives plugin source updates. Existing
source-local caches are not migrated; artwork is fetched again as needed.
Credential warning
Noctalia currently exposes these as normal string settings, not secret fields.
Spotify, Apple Music, Musixmatch, and Qishui credentials may therefore be stored
in plaintext in Noctalia's settings. The plugin never scans browser cookies,
never logs credential values, and deletes its temporary credential request file
as soon as the source adapter reads it. The service applies mode 0700 to the
request directory before writing any credential-bearing file.
Settings
The plugin settings control source selection and fallback order, translation language, lyric timing offset in milliseconds, MPRIS polling interval in milliseconds, player filters, and source credentials.
Per-widget settings control the fallback glyph, artist visibility, paused-state visibility, visibility when no lyrics are available, album-cover shape and size, primary, inactive, and secondary lyric colors, display mode, lyric layers, karaoke behavior, scrolling, fixed lyric width, transitions, typography, spacing, padding, intro/interlude cue visibility and text, and text alignment. The Actions section lists the default left-click, right-click, and scroll bindings described above. Credential and source-specific fields are shown only when their matching source is selected; source order, credentials, polling, marquee metrics, player filters, cue timing thresholds, and fine layout controls are under Advanced settings.
1.5 configuration change
Display settings are now stored per lyrics widget. After upgrading from 1.4, open each lyrics widget's settings and reapply its preferred display, animation, scrolling, typography, and layout options. Source, player, timing, and credential settings remain plugin-wide.
Feature test checklist
The normal settings view contains everyday source, lyric-layer, display, font, and animation controls. Open Advanced settings for credentials, source order, polling, marquee metrics, player filters, and fine padding.
- Language: change Noctalia's global language and reload the config. Plugin settings and runtime text follow the host language. Noctalia currently supports English and Simplified Chinese from the originally requested locale set; Japanese, Korean, and Traditional Chinese are not host language options. Close and reopen Settings, then disable and enable the plugin if the runtime tooltip still uses the previous language.
- Chinese translation: use NetEase/QQ/Musixmatch with
show_translation=trueandtranslation_language=zh-Hans. - Romanization: enable
show_romanizationand select a NetEase/QQ track that returns romanized lyrics. - Sources: select each
lyrics_sourcedirectly, then test custom fallback order throughlyrics_sources. - Delay: set
lyrics_offset_msto1000and-1000; positive values should show the next lyric one second earlier. - Polling: test
poll_interval_msat100,500, and2000. - Cover: test circle, rounded, square, and custom radius; change
cover_size. - Double line: enable
double_lineand switchsecondary_line_mode. On horizontal bars keepdouble_line_auto_fitenabled and lowerdouble_line_height_budgetif the bar clips the second line. - Karaoke: toggle
karaoke_enabled; line transitions must continue when off. - Hide layers: independently disable
show_translationandshow_romanization. - Track-only: select
display_mode=track; other lyrics widget instances still fetch and display lyrics normally. - Font and double-line sizing: test
font_family,primary_font_size,secondary_font_size,line_gap,font_weight, andfont_style. - Animations: test karaoke, cascade, wave, fade, typewriter, pulse, blink, and none.
- Layout: test
max_charsandtext_alignmentwith short and long lyrics, pluspadding_left,padding_right, andline_gapon horizontal and vertical bars. - LRCLIB selection: play a track with multiple results, open the selector from its shortcut or IPC, and switch between synchronized and plain entries without changing tracks.
- Cues: toggle
show_cuesand verify the widget hides cue text but keeps lyrics visible; adjust the cue thresholds under Advanced. - Actions: open the widget's Actions section and confirm the left, right, scroll-up, and scroll-down rows show the defaults above; rebind one, then clear it to restore the default.
External protocol
Address the singleton service with:
noctalia msg plugin h465855hgg/lyrics:service all <event> '<payload>'
Supported events:
push-lrc: synchronized or plain LRC text.push-json: JSON withlinesorlyrics.push-state: also updates track, position, playing, and cover.clear: clears current lyrics.
MPRIS track duration and playback position are microseconds. Lyric line, duration, and character timestamps are milliseconds.
Versions
| Version | Plugin API | Updated |
|---|---|---|
| v1.5.8 latest | 14 | Oct 21, 2026 |
| v1.5.7 | 3 | Oct 20, 2026 |
Older versions stay installable on a Noctalia release whose plugin API is below the latest version's.