File file=new File(FileUril.SDPATH + str);
Public SDPATH=Environment.getExternalStorageDirectory()+"/";
public LrcParser(String str){
index=0;
musicDate=new ArrayList();
map=new HashMap();
String s="";
File file=new File(FileUril.SDPATH+str);
try {
FileInputStream in=new FileInputStream(file);
BufferedReader b=new BufferedReader(new InputStreamReader(in,"utf-8"));while((s=b.readLine())!=null){
parser(s);
}
treeMap=new TreeMap(map);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
二、解析歌词lrc文件
在读取lrc数据时,通过调用parser(s)方法,实现歌词文件的读取,由于歌词信息不仅仅包含歌词,还有歌曲的一些作者信息,所以我们单独用字符判断就可以了。
在滤除了前面的信息后,设置正则表达式,由于歌词文件信息头为”[59:59.99]“,所以设置正则表达式String p="\\[([0-9]+:[0-9]+.[0-9]+)\\]";在正则表达式里有些标点字符用“\\”加该标点符号表示,如“[”,表示成“\\]”,因为“[、]、-”等是正则表达式的关键字。
“[0-9]”表示0到9中的一个数字,这样就可以匹配歌词信息。构造Pattern,这样就可以通过Pattern实例调用matcher匹配字符串了,返回的是Matcher对象,再通过该对象的find()方法就可以查询是否匹配了。
在find()函数返回的布尔类型,当为true时就表示查询的到。查询成功的话,利用pattern.split(str);将要解析的字符串以匹配字符为分割点,将字符串拆分,返回数组数据。
由于“[59:59.99][59:59.99]”找到的就是空格+空格+再加我们的歌词,我们需要的是最后面的数据,map.put(num,lrcContent[lrcContent.length-1]);知道我为什么len-1了吧。数据0开始,最后一个当然就是len-1了。将我们的数据保存。
但如何记录对应的时间呢,Matcher的group(int i)返回匹配字符,并前后剔除i个字符。String t=m.group(1);所以得到的字符数据位"59:59.99",再通过split将“59”,“59”,“99”分离出来,然后将字符串转换为整型,这样一来,我们的歌词时间点也记录了,这样一个个歌词信息通过map哈希表记录下来了。还有一个问题,由于有些歌词时间点几个都在一行,就是复歌部分,所以此map记录的数据歌词对应的时间就没有按一定的排序。所以我们还用到TreeMap,可以把map直接按键值排列。(另一种方法就是实现Comparable借口来实现排序,这样就更灵活)。
实现代码如下:
public void parser(String str){
if(str.startsWith("[ti:")){
musicDate.add(str.substring(4,str.length()-1));
}if(str.startsWith("[ar:")){
musicDate.add(str.substring(4,str.length()-1));
}if(str.startsWith("[al:")){
musicDate.add(str.substring(4,str.length()-1));
}
String p="\\[([0-9]+:[0-9]+.[0-9]+)\\]";
Pattern pattern=Pattern.compile(p);
Matcher m=pattern.matcher(str);
while(m.find()){
String t=m.group(1);
long num=ChartoLong(t);
String lrcContent[]=pattern.split(str);
if(lrcContent.length>1){
map.put(num,lrcContent[lrcContent.length-1]);
}else{
map.put(num,"");
}
}
}
Shader shader = new LinearGradient(0,0,lrcLen + paint.getTextSize() * 5,0,new int[] { Color.RED, Color.GREEN },new float[] {deltax* (play.getCurrentPosition() - startTime)+ 0.1f,deltax* (play.getCurrentPosition() - startTime)+ 0.3f }, TileMode.CLAMP);
paint.setShader(shader);