LRCファイルは、音楽プレイヤーで歌詞を同期表示するために使われるテキスト形式です。各行にはタイムスタンプと対応する歌詞が含まれており、JavaScriptで解析することで、Webアプリケーションに歌詞同期機能を実装できます。
以下は、LRCファイルの内容を解析し、構造化されたデータに変換する実装例です。
const lrcContent = `
[00:01.59]不再犹豫
[00:03.91]作词:小美 作曲:黄家驹
[00:06.46]演唱:Beyond
[00:08.55]
[00:29.48]无聊望见了犹豫
[00:32.87]达到理想不太易
[00:36.44]即使有信心
[00:38.58]斗志却抑止
[00:43.61]谁人定我去或留
[00:47.31]定我心中的宇宙
[00:50.83]只想靠两手向理想挥手
[00:56.88]
[00:58.15]问句天几高心中志比天更高
[01:05.11]自信打不死的心态活到老
[01:11.37]
[01:11.90]OH… 我有我心底故事
[01:19.41]亲手写上每段
[01:21.57]得失乐与悲与梦儿
[01:26.18]OH… 纵有创伤不退避
[01:33.77]梦想有日达成
[01:35.90]找到心底梦想的世界
[01:40.01]终可见
[01:43.83]
[02:09.64]谁人没试过犹豫
[02:13.28]达到理想不太易
[02:16.85]即使有信心
[02:18.91]斗志却抑止
[02:23.96]谁人定我去或留
[02:27.68]定我心中的宇宙
[02:31.28]只想靠两手向理想挥手
[02:36.83]
[02:38.41]问句天几高
[02:40.06]心中志比天更高
[02:45.57]自信打不死的心态活到老
[02:51.53]
[02:52.34]OH… 我有我心底故事
[02:59.91]亲手写上每段
[03:02.05]得失乐与悲与梦儿
[03:06.66]OH… 纵有创伤不退避
[03:14.07]梦想有日达成
[03:16.35]找到心底梦想的世界
[03:20.45]终可见
[03:24.04]
[03:25.06]OH… 亲手写上每段
[03:30.64]得失乐与悲与梦儿
[03:36.31]
[03:39.07]OH… 梦想有日达成
[03:45.05]找到心底梦想的世界
[03:49.60]终可见
[03:52.99]`;
解析関数は、LRCのメタデータ(曲名、アーティストなど)と歌詞行を分離して、時間情報とテキストをペアで整理します。
function extractLyrics(lrcText) {
const metadata = {
title: "",
artist: "",
album: "",
creator: "",
};
const lyrics = [];
const lines = lrcText.split("\n").map(line => line.trim()).filter(line => line.length > 0);
lines.forEach(line => {
// メタデータ行のマッチ([ti:曲名]形式)
const metaMatch = line.match(/^\[(\w+):(.+)\]$/);
if (metaMatch) {
const key = metaMatch[1].toLowerCase();
if (key in metadata) {
metadata[key] = metaMatch[2];
}
return;
}
// 歌詞行のマッチ([mm:ss.xx]テキスト形式)
const lyricMatch = line.match(/^\[(\d{2}):(\d{2})\.(\d{2})\](.+)$/);
if (lyricMatch) {
const minutes = lyricMatch[1];
const seconds = lyricMatch[2];
const milliseconds = lyricMatch[3];
const text = lyricMatch[4].trim();
lyrics.push({
time: {
min: minutes,
sec: seconds,
ms: milliseconds,
},
text: text,
});
}
});
return {
metadata,
lyrics,
};
}
この関数を実行すると、以下のような構造化された出力が得られます。
const parsed = extractLyrics(lrcContent);
console.log(parsed.metadata);
// { title: "", artist: "", album: "", creator: "" }
console.log(parsed.lyrics[0]);
// {
// time: { min: "00", sec: "01", ms: "59" },
// text: "不再犹豫"
// }
このデータ構造は、音楽再生中のタイムラインと連動して歌詞を表示するための基盤として活用できます。たとえば、Audio APIと連携し、現在の再生位置に応じて対応する歌詞行を高亮表示することが可能です。