Skip to content

Commit 8830720

Browse files
lyrics: Add support for LRCLIB
Suggested in #1558 and easy to implement for plain lyrics. See also: https://lrclib.net/docs
1 parent 8b09c77 commit 8830720

File tree

10 files changed

+99
-1
lines changed

10 files changed

+99
-1
lines changed

src/lyrics-common/lrclib_provider.cc

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright (c) 2025 Thomas Lange <[email protected]>
3+
*
4+
* Permission to use, copy, modify, and/or distribute this software for any
5+
* purpose with or without fee is hereby granted, provided that the above
6+
* copyright notice and this permission notice appear in all copies.
7+
*
8+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
9+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11+
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
12+
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
14+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
15+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
16+
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
17+
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
18+
* POSSIBILITY OF SUCH DAMAGE.
19+
*/
20+
21+
#include "lyrics.h"
22+
23+
bool LrcLibProvider::match (LyricsState state)
24+
{
25+
fetch (state);
26+
return true;
27+
}
28+
29+
void LrcLibProvider::fetch (LyricsState state)
30+
{
31+
auto handle_result_cb = [=] (const char * uri, const Index<char> & buf) {
32+
if (! buf.len ())
33+
{
34+
update_lyrics_window_error (str_printf (_("Unable to fetch %s"), uri));
35+
return;
36+
}
37+
38+
String lyrics;
39+
if (! try_parse_json (buf, "plainLyrics", lyrics))
40+
{
41+
update_lyrics_window_error (str_printf (_("Unable to parse %s"), uri));
42+
return;
43+
}
44+
45+
LyricsState new_state = g_state;
46+
new_state.lyrics = lyrics;
47+
48+
if (! lyrics)
49+
{
50+
update_lyrics_window_notfound (new_state);
51+
return;
52+
}
53+
54+
new_state.source = LyricsState::Source::LrcLib;
55+
56+
update_lyrics_window (new_state.title, new_state.artist, new_state.lyrics);
57+
persist_state (new_state);
58+
};
59+
60+
auto artist = str_copy (state.artist);
61+
artist = str_encode_percent (state.artist, -1);
62+
63+
auto title = str_copy (state.title);
64+
title = str_encode_percent (state.title, -1);
65+
66+
auto fetch_uri = str_concat(
67+
{m_base_url, "/api/get?artist_name=", artist, "&track_name=", title});
68+
69+
vfs_async_file_get_contents (fetch_uri, handle_result_cb);
70+
update_lyrics_window_message (state, _("Looking for lyrics ..."));
71+
}

src/lyrics-common/lyrics.h

+18-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ struct LyricsState {
4343
Embedded,
4444
Local,
4545
LyricsOVH,
46-
ChartLyrics
46+
ChartLyrics,
47+
LrcLib
4748
} source = None;
4849

4950
bool error = false;
@@ -109,6 +110,21 @@ class ChartLyricsProvider : public LyricProvider
109110
};
110111

111112

113+
// LrcLibProvider provides a strategy for fetching lyrics using the LRCLIB API.
114+
class LrcLibProvider : public LyricProvider
115+
{
116+
public:
117+
LrcLibProvider () {};
118+
119+
bool match (LyricsState state) override;
120+
void fetch (LyricsState state) override;
121+
String edit_uri (LyricsState state) override { return String (); }
122+
123+
private:
124+
const char * m_base_url = "https://lrclib.net";
125+
};
126+
127+
112128
// LyricsOVHProvider provides a strategy for fetching lyrics using the
113129
// lyrics.ovh search engine.
114130
class LyricsOVHProvider : public LyricProvider
@@ -127,6 +143,7 @@ class LyricsOVHProvider : public LyricProvider
127143

128144
extern FileProvider file_provider;
129145
extern ChartLyricsProvider chart_lyrics_provider;
146+
extern LrcLibProvider lrclib_provider;
130147
extern LyricsOVHProvider lyrics_ovh_provider;
131148
LyricProvider * remote_source ();
132149

src/lyrics-common/preferences.h

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ static const char * const defaults[] = {
4242
static const ComboItem remote_sources[] = {
4343
ComboItem (N_("Nowhere"), "nowhere"),
4444
ComboItem ("chartlyrics.com", "chartlyrics.com"),
45+
ComboItem ("lrclib.net", "lrclib.net"),
4546
ComboItem ("lyrics.ovh", "lyrics.ovh")
4647
};
4748

src/lyrics-common/utils.cc

+3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ LyricProvider * remote_source ()
2929
if (! strcmp (source, "chartlyrics.com"))
3030
return & chart_lyrics_provider;
3131

32+
if (! strcmp (source, "lrclib.net"))
33+
return & lrclib_provider;
34+
3235
if (! strcmp (source, "lyrics.ovh"))
3336
return & lyrics_ovh_provider;
3437

src/lyrics-gtk/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ PLUGIN = lyrics-gtk${PLUGIN_SUFFIX}
22

33
SRCS = ../lyrics-common/chart_lyrics_provider.cc \
44
../lyrics-common/file_provider.cc \
5+
../lyrics-common/lrclib_provider.cc \
56
../lyrics-common/lyrics_ovh_provider.cc \
67
../lyrics-common/utils.cc \
78
lyrics-gtk.cc

src/lyrics-gtk/lyrics-gtk.cc

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ const PluginPreferences LyricsGtk::prefs = {{widgets}};
5353

5454
FileProvider file_provider;
5555
ChartLyricsProvider chart_lyrics_provider;
56+
LrcLibProvider lrclib_provider;
5657
LyricsOVHProvider lyrics_ovh_provider;
5758

5859
LyricsState g_state;

src/lyrics-gtk/meson.build

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ lyrics_deps = [audacious_dep, audgui_dep, gtk_dep, glib_dep, json_glib_dep, xml_
66
lyrics_src = [
77
'../lyrics-common/chart_lyrics_provider.cc',
88
'../lyrics-common/file_provider.cc',
9+
'../lyrics-common/lrclib_provider.cc',
910
'../lyrics-common/lyrics_ovh_provider.cc',
1011
'../lyrics-common/utils.cc',
1112
'lyrics-gtk.cc'

src/lyrics-qt/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ PLUGIN = lyrics-qt${PLUGIN_SUFFIX}
22

33
SRCS = ../lyrics-common/chart_lyrics_provider.cc \
44
../lyrics-common/file_provider.cc \
5+
../lyrics-common/lrclib_provider.cc \
56
../lyrics-common/lyrics_ovh_provider.cc \
67
../lyrics-common/utils.cc \
78
lyrics-qt.cc

src/lyrics-qt/lyrics-qt.cc

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ const PluginPreferences LyricsQt::prefs = {{widgets}};
6666

6767
FileProvider file_provider;
6868
ChartLyricsProvider chart_lyrics_provider;
69+
LrcLibProvider lrclib_provider;
6970
LyricsOVHProvider lyrics_ovh_provider;
7071

7172
LyricsState g_state;

src/lyrics-qt/meson.build

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ lyrics_deps = [audacious_dep, audqt_dep, glib_dep, qt_dep, xml_dep]
44
lyrics_src = [
55
'../lyrics-common/chart_lyrics_provider.cc',
66
'../lyrics-common/file_provider.cc',
7+
'../lyrics-common/lrclib_provider.cc',
78
'../lyrics-common/lyrics_ovh_provider.cc',
89
'../lyrics-common/utils.cc',
910
'lyrics-qt.cc'

0 commit comments

Comments
 (0)