您的位置:首页 > 其它

MP3 lrc文件的解析

2011-11-08 01:56 176 查看
今天在看Mars 的mp3播放器的视频时,看到lrc歌词文件的匹配, lrc文件的格式为

[00:01.00]第一次

[00:03.00]光良

[00:05.00]作词:张天成 作曲:光良 [00:08.00]当你看著我 我没有开口

[00:13.00]已被你猜透

[00:01.00]代表的是一个时间段, 可以表示为long time =00*1000*60 +01*1000+00*100

后面的内容代表的是需要显示的内容, 我们在匹配歌词的时候 可以通过在 mp3文件play 时 获得begin=System.currentTimeMillis() ,

从而通过 当前时间- System.currentTimeMillis()-begin>time 时 循环调用handle 来匹配歌词

因为下下来的歌词是

[02:14.00][00:42.00]不知不觉让视线开始闪烁

[03:09.00][02:23.00][00:51.00]喔 第一次我 说爱你的时候 

类型的,所以对歌词进行了下处理

//传入该src文件路径,如果是网络读取的话,直接修改成inputStream
//一般以第一次从网络读取后都会缓存到本地吧
public static Map<Long,String> getStr(String url) {
//此处定义为TreeMap 为了获得排列好的map
Map<Long, String> map = new TreeMap<Long, String>();
//匹配第一个[XXX]
String str = "\\[[^\\]]+\\]";
//匹配前面全部[XXX]
String s = "\\[.+\\]";
//定义时间
long time = 0l;

//定义内容
String content = "";
Pattern pattern = Pattern.compile(str);
Pattern pat = Pattern.compile(s);
try {
//读取文本,我在本地访问正常,放到sdcard后变成为了乱码,改成了gbk正常
//可能是模拟器原因吧
FileInputStream in = new FileInputStream(url);
BufferedReader br = new BufferedReader(new InputStreamReader(in,"gbk"));
String line = null;
while ((line = br.readLine()) != null) {
//匹配第一个[XXX]
Matcher m = pattern.matcher(line);
while (m.find()) {
Matcher mat = pat.matcher(line);
// 通过长度判断 ,可以跳过前面的[[ti:第一次] 标题
if (line.length() > m.group().length()&&mat.find()) {
//System.out.println("find===="+mat.group());
//歌词内容
content = line.substring(mat.group().length());
//从新获取第二个[XXX]到最后的对象
line = line.substring(m.group().length());
//[ti:第一次] 和[00:00.00]我也不知道该怎么处理好,暂且通过判断第二个是不是数字吧
if ( mat.group().charAt(1) >= '0'
&& mat.group().charAt(1) <='9') {
//获取当前毫秒数
time = parseTime(m.group().substring(1,
m.group().length() - 1));
}
}
//当不存在时间节点时,直接将节点加入到了Map
else
content=m.group().substring(1,m.group().length()-1);
if (map.containsKey(time)) {
map.put(time, map.get(time) + ",\n" + content);
} else
map.put(time, content);
}
}
System.out.println(map);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return map;

}

public static long parseTime(String str) {
// System.out.println(str);
long min = Long.parseLong(str.split("\\:")[0]);
long sec = Long.parseLong((str.split("\\:")[1]).split("\\.")[0]);
long mill = Long.parseLong(str.split("\\.")[1]);
// System.out.println(min+"  "+sec+" "+mill);
return min * 60 * 1000 + sec * 1000 + mill * 10;
}


返回得到的map通过

Queue<Long> times=new LinkedList<Long>(map.keySet());

Queue<String> contents=new LinkedList<String>(map.values());

转化为两个队列 然后通过 poll出栈就可以了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: