lmlrc
v2.0.0
Published
A stateless and extensible parser and serializer for LRC, LMLRC, NRC, and QRC lyrics.
Maintainers
Readme
LMLRC
A lyric codec library for LMusic. It parses and serializes LRC, LMLRC, NRC, and QRC lyrics in browsers and TypeScript projects.
Usage
Install and import the package:
pnpm add lmlrcimport { lmlrcCodec, lrcCodec } from "lmlrc";Or import the ESM bundle directly in a browser:
- UNPKG: https://unpkg.com/lmlrc
- jsDelivr: https://cdn.jsdelivr.net/npm/lmlrc
- Skypack: https://cdn.skypack.dev/lmlrc
- Statically: https://cdn.statically.io/npm/lmlrc
- JSDMirror: https://cdn.jsdmirror.com/npm/lmlrc/dist/index.js
import { lmlrcCodec, lrcCodec } from "https://unpkg.com/lmlrc";Each codec provides synchronous parse() and stringify() methods. The same
usage works with either import:
const path = "./磨瀬_初音未来 (初音ミク) - icicles.lmlrc";
const source = await fetch(path).then((response) => response.text());
const info = lmlrcCodec.parse(source);
const lrc = lrcCodec.stringify(info);The built-in codecs are lrcCodec, nrcCodec, qrcCodec and lmlrcCodec.
Lyric Model
interface LyricSegment {
text: string;
start: number;
duration: number;
}
interface LyricLine {
start: number;
end?: number;
text: string;
translation?: string;
segments?: LyricSegment[];
}
interface LyricInfo {
title?: string;
artist?: string;
album?: string;
offset?: number;
lines: LyricLine[];
}Times are expressed in milliseconds. segments contains word-level or
character-level timing when the source format supports it.
Codec Registry
Use a registry when the format is selected dynamically:
import { builtInCodecs, createCodecRegistry } from "lmlrc";
const registry = createCodecRegistry(builtInCodecs);
const source = await fetch("./磨瀬_初音未来 (初音ミク) - icicles.lmlrc").then(
(response) => response.text(),
);
const info = registry.parse("lmlrc", source);
const lrc = registry.stringify("lrc", info);Custom codecs implement LyricsCodec and are added with register():
import {
builtInCodecs,
createCodecRegistry,
lmlrcCodec,
} from "lmlrc";
import type { LyricsCodec } from "lmlrc";
interface TrimmedLmlrcOptions {
trim?: boolean;
}
const trimmedLmlrcCodec: LyricsCodec<
TrimmedLmlrcOptions,
Record<string, never>,
"trimmed-lmlrc"
> = {
format: "trimmed-lmlrc",
parse(text, options) {
return lmlrcCodec.parse(options?.trim ? text.trim() : text);
},
stringify(info) {
return lmlrcCodec.stringify(info);
},
};
const registry = createCodecRegistry(builtInCodecs);
registry.register(trimmedLmlrcCodec);
const source = await fetch(
"./磨瀬_初音未来 (初音ミク) - icicles.lmlrc",
).then((response) => response.text());
const info = registry.parse(trimmedLmlrcCodec, source, { trim: true });
const lrc = registry.stringify("lrc", info);