Lyric fallback order: lrclib, dumb, genius, lastfm

This commit is contained in:
iamdoubz committed 2026-07-30 15:11:39 -05:00
1 parent 0bd54f7e3f
commit 09bf468fcf
5 files changed
+152 -34

No files matched your search

+31 -5
View File
@@ -165,11 +165,33 @@ function dumb_search($artist, $title, $timeout) {
return html_entity_decode($m[1], ENT_QUOTES | ENT_HTML5, 'UTF-8');
}
/**
* Extract Genius annotation ("referent") links out of a raw lyrics HTML
* fragment. Returns an ordered list of ['text' => plain annotated lyric
* text, 'path' => dumb path to fetch the annotation JSON from]. Matched
* structurally — href = "/{id}/{song-slug}/{verse-slug}" — rather than by
* CSS class, since Genius's class names are build-hashed (styled-components)
* and change on their end without notice.
*/
function dumb_extract_annotations($fragment) {
$out = [];
if (!preg_match_all('#<a\s+href="(/\d+/[^"/]+/[^"/]+)"[^>]*>(.*?)</a>#is', $fragment, $matches, PREG_SET_ORDER)) {
return $out;
}
foreach ($matches as $m) {
$text = trim(container_to_text($m[2]));
if ($text === '') continue;
$out[] = ['text' => $text, 'path' => $m[1] . '/annotations'];
}
return $out;
}
/**
* Fetch + parse a dumb song page ($path from dumb_search()). Returns
* ['lyrics' => plain text, 'album' => name, 'art' => absolute album art url,
* 'song_art' => absolute song thumbnail url] (any field may be ''), or null
* if the page couldn't be fetched.
* ['lyrics' => plain text, 'annotations' => [{text, path}, …] (see
* dumb_extract_annotations), 'album' => name, 'art' => absolute album art
* url, 'song_art' => absolute song thumbnail url] (any field may be ''/[]),
* or null if the page couldn't be fetched.
*/
function dumb_song($path, $timeout) {
$base = cfg('dumb.url');
@@ -177,14 +199,18 @@ function dumb_song($path, $timeout) {
$html = http_get($base . $path, $timeout);
if ($html === null) return null;
$out = ['lyrics' => '', 'album' => '', 'art' => '', 'song_art' => ''];
$out = ['lyrics' => '', 'annotations' => [], 'album' => '', 'art' => '', 'song_art' => ''];
// <div id="lyrics"> wraps the raw Genius lyrics HTML that dumb already
// extracted server-side (no data-lyrics-container markers left in it).
$idPos = strpos($html, 'id="lyrics"');
if ($idPos !== false) {
$lt = strrpos(substr($html, 0, $idPos), '<div');
if ($lt !== false) $out['lyrics'] = trim(container_to_text(inner_balanced_div($html, $lt)));
if ($lt !== false) {
$fragment = inner_balanced_div($html, $lt);
$out['annotations'] = dumb_extract_annotations($fragment);
$out['lyrics'] = trim(container_to_text($fragment));
}
}
// Two <img id="album-artwork"> tags can appear: the song thumbnail