Lrc歌词的一般歌词格式如下:
[ti:歌曲名]
[ar:歌手名]
[al:专辑名]
[by:编辑者]
[offset:时间补偿值]
[00:00.00]或[00:00.000]
[ti:歌曲名]-title题目,标题,曲目
[ar:歌手名]-artist艺术家、演唱者
[al:专辑名]-album唱片集、专辑
[by:编辑者]-一般指lrc歌词的制作人
[offset:时间补偿值]-其单位是毫秒,正值表示延迟,负值表示提前。用于整体调整歌词显示慢(快)于音乐播放。
解析效果图
输出格式:
SimpleDateFormat format =
new SimpleDateFormat("mm:ss:SSS");
System.out.println(
format.format(lyrBean.getLongtime()) +
"----" + lyrBean.getText());
话就不多说,直接上代码
PraseLrc.java
/*
*
* 解析Lrc歌词
*
*/
public class PraseLrc {
public static void main(String[] args) {
//获取歌词文本
String lyr = getLrc();
//[ti:歌曲名]-title题目,标题,曲目
String tiText = getCenterText("[ti", "]", lyr);
//[ar:歌手名]-artist艺术家、演唱者
String arText = getCenterText("[ar", "]", lyr);
//[al:专辑名]-album唱片集、专辑
String alText = getCenterText("[al", "]", lyr);
//[by:编辑者](一般指lrc歌词的制作人)
String byText = getCenterText("[by", "]", lyr);
//[offset:时间补偿值]其单位是毫秒,正值表示延迟,负值表示提前。用于整体调整歌词显示慢(快)于音乐播放。
String offsetText = getCenterText("[offset", "]", lyr);
System.out.println("歌曲名:" + tiText);
System.out.println("歌手名:" + arText);
System.out.println("专辑名:" + alText);
System.out.println("编辑者:" + byText);
System.out.println("歌曲偏移:" + offsetText);
//解析歌词
List<LrcBean> lrcBeans = new ArrayList<>();//存放歌词
String[] split = lyr.split("\\n");//分割
if (split.length == 1) split = lyr.split("\\\\n");
for (String s : split) {
List<LrcBean> list = parseLine(s);
if (list != null && !list.isEmpty()) {
lrcBeans.addAll(list);
}
}
//按照时间排序
Collections.sort(lrcBeans, (lyrBean, t1) -> (int)
(lyrBean.getLongtime() - t1.getLongtime()));
//输出看看歌词效果
System.out.println("解析出的歌词如下:");
for (LrcBean lyrBean : lrcBeans) {
SimpleDateFormat format = new SimpleDateFormat("mm:ss:SSS");
System.out.println(format.format(lyrBean.getLongtime()) + "----"
+ lyrBean.getText());
}
}
//解析每一行的歌词
private static List<LrcBean> parseLine(String s) {
if (s.isEmpty()) {
return null;
}
// 去除空格
s = s.trim();
// 正则表达式,判断s中是否有[00:00.60]或[00:00.600]格式的片段
Matcher lineMatcher = Pattern.
compile("((\\[\\d{2}:\\d{2}\\.\\d{2,3}\\])+)(.+)").matcher(s);
// 如果没有,返回null
if (!lineMatcher.matches()) {
return null;
}
// 得到时间标签
String times = lineMatcher.group(1);
// 得到歌词文本内容
String text = lineMatcher.group(3);
List<LrcBean> entryList = new ArrayList<>();
Matcher timeMatcher = Pattern.compile("\\[(\\d\\d):(\\d\\d)\\.(\\d{2,3})\\]").matcher(times);
while (timeMatcher.find()) {
long min = Long.parseLong(timeMatcher.group(1));// 分
long sec = Long.parseLong(timeMatcher.group(2));// 秒
long mil = Long.parseLong(timeMatcher.group(3));// 毫秒
// 转换为long型时间
int scale_mil=mil>100?1:10;//如果毫秒是3位数则乘以1,反正则乘以10
// 转换为long型时间
long time =
min * 60000 +
sec * 1000 +
mil * scale_mil;
// 最终解析得到一个list
entryList.add(new LrcBean(time, times, text));
}
return entryList;
}
//获取中间文本,主要是获取歌词中的歌名专辑名这些
private static String getCenterText(String start, String end, String s) {
if (start.isEmpty() || end.isEmpty() || s.isEmpty()) {
return "";
}
int i = s.indexOf(start);
int i1 = s.indexOf(end, i);
if (i == -1 || i1 == -1) return "";
String s1 = s.substring(i + start.length(), i1);
return s1;
}
//歌词文本
public static String getLrc() {
return "[00:00.000] 作曲 : Skot Suyama 陶山\\n[00:01.000] 作词 : 陈忻玥\\n[00:14.325]不愿再低头懦弱\\n[00:18.810]泪水不停滑落\\n[00:20.958]不会再依循遵守\\n[00:25.829]心思不停躇踌\\n[00:27.743]\\n[00:28.149]我有我的心\\n[00:29.457]我有我的命\\n[00:31.123]要自己决定\\n[00:32.464]要对得起自己\\n[00:34.244]\\n[00:34.630]独自站在这路口\\n[00:39.529]Don’t know where to go\\n[00:41.159]\\n[00:41.442]But I ain’t gonna cry again.\\n[00:47.578]I’ll stand my ground, I’ll fight.\\n[00:53.552]\\n[00:56.202]挣开这世界的綑绑\\n[01:02.633]却看不清自己的模样\\n[01:08.124]Ignite the fire within me\\n[01:11.112]keeps burning till the day I’m underground\\n[01:15.891]冲破这世界的高墙\\n[01:21.451]Till I’m underground\\n[01:25.295]Imma get my crown\\n[01:28.345]Till I’m underground\\n[01:32.010]I will get my crown\\n[01:35.198]\\n[01:36.543]独自站在这路口\\n[01:41.076]我知道该往哪走\\n[01:43.243]不需要任何理由\\n[01:47.830]来忠于我的美梦\\n[01:49.575]\\n[01:50.094]我有我的心\\n[01:51.534]我有我的命\\n[01:53.193]要自己决定\\n[01:54.767]要对得起自己\\n[01:56.528]\\n[01:56.942]独自站在这路口\\n[02:01.531]I know where to go And I ain’t gonna cry again.\\n[02:09.795]I’ll stand my ground. I’ll fight.\\n[02:15.862]\\n[02:18.360]挣开这世界的綑绑\\n[02:24.880]却看不清自己的模样\\n[02:30.032]Ignite the fire within me\\n[02:33.444]keeps burning till the day I’m underground\\n[02:38.559]冲破这世界的高墙\\n[02:43.657]Till I’m underground\\n[02:47.207]Imma get my crown\\n[02:50.461]Till I’m underground\\n[02:53.891]I will get my crown\\n[02:55.311]\\n[03:13.129]All I wanna do is follow my heart\\n[03:15.835]All I know is that I don’t give a ****\\n[03:19.264]All I wanna do is stand on my ground\\n[03:22.667]All I know is that I’ll never give up\\n[03:26.096]\\n[03:27.130]挣开这世界的綑绑\\n[03:32.963]却看不清自己的模样\\n[03:38.533]Ignite the fire within me\\n[03:42.132]keeps burning till the day I’m underground\\n[03:47.312]冲破这世界的高墙\\n[03:52.277]Till I’m underground\\n[03:56.084]Imma get my crown\\n[03:59.080]Till I’m underground\\n[04:02.527]I will get my crown\\n";
}
}
LrcBean.java
public class LyrBean {
long longtime;//long类型时间
String time, text;//时间文本与歌词文本
public long getLongtime() {
return longtime;
}
public void setLongtime(long longtime) {
this.longtime = longtime;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public LrcBean(long longtime, String time, String text) {
this.longtime = longtime;
this.time = time;
this.text = text;
}
}