lyrics-kit
v1.0.0
Published
Fetch and parse lyrics from various sources.
Downloads
2
Readme
lyrics-kit
Fetch and parse lyrics from various sources.
This project is ported and expanded from ddddxxx/LyricsKit, and is licenced under AGPL v3.
Install
$ npm install lyrics-kit
Install locally
npm install
Usage
Typescript (ES6 import)
import {
LyricsSearchRequest as Request,
LyricsProviderManager as Manager,
LyricsProviderSource as Source,
Lyrics,
} from "lyrics-kit";
async () => {
const request = Request.fromInfo(
"Song title",
"Artist name",
/* duration in seconds */ 320.1
);
// Get lyrics from all sources.
let manager = new Manager();
let lyrics: Lyrics[] = manager.getLyrics(request);
// Get lyrics from a set of sources
manager = new Manager([Source.netease, Source.kugou]);
lyrics = manager.getLyrics(request);
// Get lyrics from a single source
source = Source.qqMusic.build();
lyrics = source.getLyrics(request);
// Get LRCX text
for (const lyric of lyrics) {
console.log("========== BEGIN LRCX CONTENT ==========");
console.log(lyric.toString());
console.log("=========== END LRCX CONTENT ===========");
}
};
Appendix: LRCX specification
Taken from ddddxxx/LyricsKit.
<lrcx> ::= <line> (NEWLINE <line>)*
<line> ::= <id tag>
| <lyric line>
| <lyric attachment>
| ""
<id tag> ::= <tag>
<tag> ::= "[" <tag content> "]"
<tag content> ::= <tag key>
| <tag key> ":" <tag value>
<tag key> ::= [0-9a-zA-Z_-]+
<tag value> ::= <character except NEWLINE or "]">+
<lyric line> ::= <time tag> <character except NEWLINE>*
<lyric attachment> ::= <time tag> <attachment tag> <attachment body>
<time tag> ::= "[" (<minute> ":")* <second> ("." <millisecond>)* "]"
<attachment tag> ::= <tag>
<attachment body> ::= <plain text attachment>
| <index based attachment>
| <range based attachment>
<plain text attachment> ::= <character except NEWLINE>+
<index based attachment> ::= <index based segment>+
<range based attachment> ::= <range based segment>+
<index based segment> ::= "<" <segment value> "," <segment index> ">"
<range based segment> ::= "<" <segment value> "," <segment range> ">"
<segment value> ::= <characters except NEWLINE, "," or ">">
<segment index> ::= <number>
<segment range> ::= <lowerBound> "," <upperBound>
lrcx ::= [line (NEWLINE line)*]
line ::= id_tag | lyric_line | ""
// ID tags
id_tag ::= "[" text_tag_key ":" tag_text "]"
| "[length:" fixed_2_number "]"
| "[offset:" number "]"
id_tag_key ::= "ti" | "al" | "ar" | "au" | "by"
tag_text ::= < all printable characters except NEWLINE, ":" or "]">
// Lyric line
lyric_line ::= time_tag text [NEWLINE time_tag inline_time_tag] [NEWLINE time_tag translation] [NEWLINE time_tag ruby]
time_tag ::= ["-"] decimal decimal decimal* ":" decimal decimal ":" decimal decimal decimal
text ::= <all printable characters except NEWLINE, "[" or "]">
// Inline time tags
inline_time_tag ::= inline_time_tag_element inline_time_tag_element* [duration_tag]
inline_time_tag_element ::= "<" non_negative_integer "," non_negative_integer ">"
duration_tag ::= "<" non_negative_integer ">"
// Translation
translation ::= "[tr" [ ":" text ] "]" text
// Ruby (furigana / romaji for Japanese)
ruby ::= "[" ("fu" | "ro") "]" ruby_tags
ruby_tags ::= ruby_tag ruby_tag*
ruby_tag ::= "<" ruby_tag_text "," non_negative_integer "," non_negative_integer ">"
ruby_text_text ::= <all printable characters except NEWLINE, "<" or ">">
// Numbers
fixed_2_number ::= decimal decimal* "." decimal decimal
number ::= ["-"] integer ["." decimal decimal*]
decimal ::= "0".."9"
integer ::= negative_integer | zero | positive_integer
negative_integer ::= "-" positive_integer
zero ::= "0"
positive_integer ::= "1".."9" decimal*
non_negative_integer ::= zero | positive_integer
Known issue
- LRCX specs uses indexes of grapheme clusters when processing inline tags
concerning text offset. The ported
lyrics-kit
has not yet implemented this feature and counting by the default JavaScript string length (UTF-16 encoded length) instead for now. This may result in a discrepancy when rendering lyrics with LyricsX.
lyrics-kit: Fetch and parse lyrics from various sources.
Copyright (C) 2023 Eana Hufwe
Copyright (C) 2020 ddddxxx
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.