Android中解析lrc歌词


Android中解析lrc歌词

1.定义歌词实体类

  1. import java.util.HashMap;  
  2. import java.util.Map;  
  3. /*  
  4.  * 用于封装歌词的类  
  5.  * @author  
  6.  *   
  7.  * */  
  8. public class LrcInfo {  
  9.     private String title;//music title  
  10.     private String artist;//artist name  
  11.     private String album;//album name  
  12.     private String bySomeBody;//the lrc maker  
  13.     private String offset;//the time delay or bring forward  
  14.     private Map<Long,String> infos;//保存歌词信息和时间点一一对应的Map  
  15.     public String getTitle() {  
  16.         return title;  
  17.     }  
  18.     public void setTitle(String title) {  
  19.         this.title = title;  
  20.     }  
  21.     public String getArtist() {  
  22.         return artist;  
  23.     }  
  24.     public void setArtist(String artist) {  
  25.         this.artist = artist;  
  26.     }  
  27.     public String getAlbum() {  
  28.         return album;  
  29.     }  
  30.     public void setAlbum(String album) {  
  31.         this.album = album;  
  32.     }  
  33.     public String getBySomeBody() {  
  34.         return bySomeBody;  
  35.     }  
  36.     public void setBySomeBody(String bySomeBody) {  
  37.         this.bySomeBody = bySomeBody;  
  38.     }  
  39.     public String getOffset() {  
  40.         return offset;  
  41.     }  
  42.     public void setOffset(String offset) {  
  43.         this.offset = offset;  
  44.     }  
  45.     public Map<Long, String> getInfos() {  
  46.         return infos;  
  47.     }  
  48.     public void setInfos(Map<Long, String> infos) {  
  49.         this.infos = infos;  
  50.     }  
  51.       
  52. }  
2.定义解析类
  1. import java.io.BufferedReader;  
  2. import java.io.File;  
  3. import java.io.FileInputStream;  
  4. import java.io.FileNotFoundException;  
  5. import java.io.IOException;  
  6. import java.io.InputStream;  
  7. import java.io.InputStreamReader;  
  8. import java.util.Iterator;  
  9. import java.util.Map;  
  10. import java.util.Map.Entry;  
  11. import java.util.TreeMap;  
  12. import java.util.regex.Matcher;  
  13. import java.util.regex.Pattern;  
  14.   
  15. import android.util.Log;  
  16.   
  17. /*  
  18.  * 此类用来解析LRC文件  
  19.  *   
  20.  */  
  21. public class LrcParser {  
  22.     private LrcInfo lrcinfonew LrcInfo();   
  23.     //存放临时时间  
  24.     private long currentTime = 0 ;  
  25.     //存放临时歌词  
  26.     private String currentContent=null;  
  27.     //用于保存时间点和歌词之间的对应关系  
  28.     //private Map<Long,String> maps =new HashMap<Long,String>();  
  29.     private Map<Long,String> maps=new TreeMap<Long,String>();  
  30.       
  31.     /*  
  32.      * 根据文件路径,读取文件,返回一个输入流  
  33.      * @param   path    文件路径  
  34.      * @return InputStream 文件输入流  
  35.      * @throws FileNotFoundException  
  36.      * */  
  37.     private InputStream readLrcFile(String path) throws FileNotFoundException{  
  38.         File fnew File(path);  
  39.         InputStream ins = new FileInputStream(f);  
  40.         return ins;  
  41.     }  
  42.       
  43.     public LrcInfo parser(String path)throws Exception{  
  44.         InputStream in = readLrcFile(path);  
  45.         lrcinfo = parser(in);  
  46.         return lrcinfo;  
  47.     }  
  48.       
  49.     /**  
  50.      * @param inputStream 输入流  
  51.      * @return   
  52.      *   
  53.      * */  
  54.     public LrcInfo parser(InputStream inputStream) throws IOException{  
  55.         //包装对象  
  56.         InputStreamReader inr = new InputStreamReader(inputStream);  
  57.         BufferedReader reader =new BufferedReader(inr);  
  58.         //一行一行的读,每读一行解析一行  
  59.         String line =null;  
  60.         while((line=reader.readLine())!=null){  
  61.             parserLine(line);  
  62.         }  
  63.         //全部解析完后,设置info  
  64.         lrcinfo.setInfos(maps);  
  65.         Iterator<Entry<Long, String>> iter = maps.entrySet().iterator();  
  66.         while (iter.hasNext()) {  
  67.             Entry<Long,String> entry = (Entry<Long,String>)iter.next();  
  68.             Long key = entry.getKey();  
  69.             String val = entry.getValue();  
  70.             Log.e("---", "key="+key+"   val="+val);  
  71.         }   
  72.         return lrcinfo;  
  73.     }  
  74.     /**  
  75.      * 利用正则表达式解析每行具体语句  
  76.      * 并将解析完的信息保存到LrcInfo对象中  
  77.      * @param line  
  78.      */  
  79.     private void parserLine(String line) {  
  80.         //获取歌曲名信息  
  81.         if(line.startsWith("[ti:")){  
  82.             String title =line.substring(4,line.length()-1);  
  83.             Log.i("","title-->"+title);  
  84.             lrcinfo.setTitle(title);  
  85.         }  
  86.         //取得歌手信息  
  87.         else if(line.startsWith("[ar:")){  
  88.             String artist = line.substring(4, line.length()-1);  
  89.             Log.i("","artist-->"+artist);  
  90.             lrcinfo.setArtist(artist);  
  91.         }  
  92.         //取得专辑信息  
  93.         else if(line.startsWith("[al:")){  
  94.             String album =line.substring(4, line.length()-1);  
  95.             Log.i("","album-->"+album);  
  96.             lrcinfo.setAlbum(album);  
  97.         }  
  98.         //取得歌词制作者  
  99.         else if(line.startsWith("[by:")){  
  100.             String bysomebody=line.substring(4, line.length()-1);  
  101.             Log.i("","by-->"+bysomebody);  
  102.             lrcinfo.setBySomeBody(bysomebody);  
  103.         }  
  104.         //通过正则表达式取得每句歌词信息  
  105.         else{  
  106.             //设置正则表达式   
  107.             String reg ="\\[(\\d{1,2}:\\d{1,2}\\.\\d{1,2})\\]|\\[(\\d{1,2}:\\d{1,2})\\]";  
  108.             Pattern pattern = Pattern.compile(reg);  
  109.             Matcher matcher=pattern.matcher(line);  
  110.             //如果存在匹配项则执行如下操作  
  111.             while(matcher.find()){  
  112.                 //得到匹配的内容  
  113.                 String msg=matcher.group();  
  114.                 //得到这个匹配项开始的索引  
  115.                 int start = matcher.start();  
  116.                 //得到这个匹配项结束的索引  
  117.                 int end = matcher.end();  
  118.                 //得到这个匹配项中的数组  
  119.                 int groupCount = matcher.groupCount();  
  120.                 for(int index =0;index<groupCount;index++){  
  121.                     String timeStr = matcher.group(index);  
  122.                     Log.i("","time["+index+"]="+timeStr);  
  123.                     if(index==0){  
  124.                         //将第二组中的内容设置为当前的一个时间点  
  125.                         currentTime=str2Long(timeStr.substring(1, timeStr.length()-1));  
  126.                     }  
  127.                 }  
  128.                 //得到时间点后的内容  
  129.                 String[] content = pattern.split(line);  
  130.                 //for(int index =0; index<content.length; index++){  
  131.                     Log.i("","content="+content[content.length-1]);  
  132.                     //if(index==content.length-1){  
  133.                         //将内容设置魏当前内容  
  134.                         currentContent = content[content.length-1];  
  135.                     //}  
  136.                 //}  
  137.                 //设置时间点和内容的映射  
  138.                 maps.put(currentTime, currentContent);  
  139.                 Log.i("","currentTime--->"+currentTime+"   currentContent--->"+currentContent);  
  140.                 //遍历map  
  141.             }  
  142.         }  
  143.     }  
  144.     private long str2Long(String timeStr){  
  145.         //将时间格式为xx:xx.xx,返回的long要求以毫秒为单位  
  146.         Log.i("","timeStr="+timeStr);  
  147.         String[] s = timeStr.split("\\:");  
  148.         int min = Integer.parseInt(s[0]);  
  149.         int sec=0;  
  150.         int mill=0;  
  151.         if(s[1].contains(".")){  
  152.             String[] ss=s[1].split("\\.");  
  153.             sec =Integer.parseInt(ss[0]);  
  154.             mill=Integer.parseInt(ss[1]);  
  155.             Log.i("","s[0]="+s[0]+"s[1]"+s[1]+"ss[0]="+ss[0]+"ss[1]="+ss[1]);  
  156.         }else{  
  157.             sec=Integer.parseInt(s[1]);  
  158.             Log.i("","s[0]="+s[0]+"s[1]"+s[1]);  
  159.         }  
  160.         return min*60*1000+sec*1000+mill*10;  
  161.     }  
  162. }  
3.解析调用
  1.   
  2. import android.app.Activity;  
  3. import android.os.Bundle;  
  4. import android.util.Log;  
  5.   
  6. public class Lyric extends Activity {  
  7.     /** Called when the activity is first created. */  
  8.     @Override  
  9.     public void onCreate(Bundle savedInstanceState) {  
  10.         super.onCreate(savedInstanceState);  
  11.         setContentView(R.layout.main);  
  12.         LrcParser lp =new LrcParser();  
  13.         String path="/sdcard/Hotel California";  
  14.         try{  
  15.             Log.i("____Lyric___", "--begin--");  
  16.             lp.parser(path);  
  17.         }catch(Exception e){  
  18.               
  19.         }  
  20.     }  
  21. }  

相关内容