LRC歌词是一种应用广泛的歌词文件,各主流播放器都支持。
lrc歌词文本中含有两类标签:
1、标识标签(ID-tags)
[ar:艺人名]
[ti:曲名]
[al:专辑名]
[by:编者(指编辑LRC歌词的人)]
[offset:时间补偿值] 其单位是毫秒,正值表示整体提前,负值相反
2、 时间标签(Time-tag)
标准格式: [分钟:秒.毫秒] 歌词
例:[01:15.62]
在这里为了简便我只是解析了时间标签,对其进行解析时使用到了正则表达式:
正则表达式语法参考:
示例歌词:
[ar:胡彦斌]
[ti:月光]
[00:00.86]月光(秦时明月主题曲)
[00:06.31]歌手 胡彦斌
[00:08.68]作词 林文炫
[00:10.49]作曲 胡彦斌
[00:20.11]月光色
[00:22.30]女子香
[00:24.51]泪断剑
[00:26.70]情多长
[00:28.95]有多痛
[00:30.97]无字想
[00:33.35]忘了你
[00:39.43]孤单魂
[00:41.51]随风荡
[00:43.57]谁去笑
[00:45.87]痴情郎
[00:48.03]这红尘的战场
[00:52.95]千军万马有谁能称王
[01:01.69]过情关
[01:06.00]谁敢闯
[01:10.42]望明月
[01:15.62]心悲凉
[01:19.13]千古恨
[01:23.45]轮回尝
[01:27.76]眼一闭
[01:32.71]谁最狂
[01:38.90]这世道的无常
[01:43.23]注定敢爱的人一生伤
[02:07.33]月光色
[02:09.20]女子香
[02:11.49]泪断剑
[02:13.58]情多长
[02:15.80]有多痛
[02:17.87]无字想
[02:20.23]忘了你
[02:26.21]孤单魂
[02:28.20]随风荡
[02:30.56]谁去笑
[02:32.64]痴情郎
[02:34.94]这红尘的战场
[02:39.70]千军万马有谁能称王
[02:48.65]过情关
[02:52.66]谁敢闯
[02:57.34]望明月
[03:02.44]心悲凉
[03:05.97]千古恨
[03:09.99]轮回尝
[03:14.67]眼一闭
[03:19.95]谁最狂
[03:30.06]过情关
[03:34.34]谁敢闯
[03:38.78]望明月
[03:43.92]心悲凉
[03:47.58]千古恨
[03:51.50]轮回尝
[03:55.96]眼一闭
[04:01.51]谁最狂
[04:07.21]这世道的无常
[04:21.34]注定敢爱的人一生伤
View Lyric
Java源代码:
1 import java.io.BufferedReader;
2 import java.io.File;
3 import java.io.FileInputStream;
4 import java.io.InputStreamReader;
5 import java.util.ArrayList;
6 import java.util.HashMap;
7 import java.util.List;
8 import java.util.Map;
9 import java.util.Map.Entry;
10 import java.util.regex.Matcher;
11 import java.util.regex.Pattern;
12
13 public class TestLRC {
14
15 public static void main(String[] args) {
16 String path = "D:\\a.lrc"; // 歌词文件路径
17 TestLRC lrc = new TestLRC();
18 List<Map<Long, String>> list = lrc.parse(path);
19 lrc.printLrc(list);
20 }
21
22 /**
23 * 解析LRC歌词文件
24 *
25 * @param path
26 * lrc文件路径
27 * @return
28 */
29 private List<Map<Long, String>> parse(String path) {
30 // 存储所有歌词信息的容器
31 List<Map<Long, String>> list = new ArrayList<Map<Long, String>>();
32 try {
33 // String encoding = "utf-8"; // 字符编码,若与歌词文件编码不符将会出现乱码
34 String encoding = "GBK";
35 File file = new File(path);
36 if (file.isFile() && file.exists()) { // 判断文件是否存在
37 InputStreamReader read = new InputStreamReader(
38 new FileInputStream(file), encoding);
39 BufferedReader bufferedReader = new BufferedReader(read);
40 String regex = "\\[(\\d{1,2}):(\\d{1,2}).(\\d{1,2})\\]"; // 正则表达式
41 Pattern pattern = Pattern.compile(regex); // 创建 Pattern 对象
42 String lineStr = null; // 每次读取一行字符串
43 while ((lineStr = bufferedReader.readLine()) != null) {
44 Matcher matcher = pattern.matcher(lineStr);
45 while (matcher.find()) {
46 // 用于存储当前时间和文字信息的容器
47 Map<Long, String> map = new HashMap<Long, String>();
48 // System.out.println(m.group(0)); // 例:[02:34.94]
49 // [02:34.94] ----对应---> [分钟:秒.毫秒]
50 String min = matcher.group(1); // 分钟
51 String sec = matcher.group(2); // 秒
52 String mill = matcher.group(3); // 毫秒,注意这里其实还要乘以10
53 long time = getLongTime(min, sec, mill + "0");
54 // 获取当前时间的歌词信息
55 String text = lineStr.substring(matcher.end());
56 map.put(time, text); // 添加到容器中
57 list.add(map);
58 }
59 }
60 read.close();
61 return list;
62 } else {
63 System.out.println("找不到指定的文件:" + path);
64 }
65 } catch (Exception e) {
66 System.out.println("读取文件出错!");
67 e.printStackTrace();
68 }
69 return null;
70 }
71
72 /**
73 * 将以字符串形式给定的分钟、秒钟、毫秒转换成一个以毫秒为单位的long型数
74 *
75 * @param min
76 * 分钟
77 * @param sec
78 * 秒钟
79 * @param mill
80 * 毫秒
81 * @return
82 */
83 private long getLongTime(String min, String sec, String mill) {
84 // 转成整型
85 int m = Integer.parseInt(min);
86 int s = Integer.parseInt(sec);
87 int ms = Integer.parseInt(mill);
88
89 if (s >= 60) {
90 System.out.println("警告: 出现了一个时间不正确的项 --> [" + min + ":" + sec + "."
91 + mill.substring(0, 2) + "]");
92 }
93 // 组合成一个长整型表示的以毫秒为单位的时间
94 long time = m * 60 * 1000 + s * 1000 + ms;
95 return time;
96 }
97
98 /**
99 * 打印歌词信息
100 */
101 private void printLrc(List<Map<Long, String>> list) {
102 if (list == null || list.isEmpty()) {
103 System.out.println("没有任何歌词信息!");
104 } else {
105 for (Map<Long, String> map : list) {
106 for (Entry<Long, String> entry : map.entrySet()) {
107 System.out.println("时间:" + entry.getKey() + " \t歌词:"
108 + entry.getValue());
109 }
110 }
111 }
112 }
113 }
114
解析结果: