Back to project page LyricHere.
The source code is released under:
Apache License
If you think the Android project LyricHere listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package cn.zhaiyifan.lyrichere.utils; /*from w w w. j a v a 2 s. c om*/ import android.text.TextUtils; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.util.Collections; import java.util.LinkedList; import java.util.List; import cn.zhaiyifan.lyrichere.Constants; import cn.zhaiyifan.lyrichere.model.Lyric; import cn.zhaiyifan.lyrichere.model.Lyric.Sentence; /** * Created by yifan on 5/13/14. */ public class LyricUtils { private static final String TAG = LyricUtils.class.getSimpleName(); public static Lyric parseLyric(File file, String Encoding) { Lyric lyric = new Lyric(); try { BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), Encoding)); Util.log(TAG, String.format("parseLyric(%s, %s)", file.getPath(), Encoding)); String line; while ((line = br.readLine()) != null) { parseLine(line, lyric); } Collections.sort(lyric.getSentenceList(), new Lyric.SentenceComparator()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } if (TextUtils.isEmpty(lyric.getTitle()) || TextUtils.isEmpty(lyric.getArtist())) { String title; String artist = null; String filename = file.getName(); filename = filename.substring(0, filename.length() - 4); int index = filename.indexOf('-'); if (index > 0) { artist = filename.substring(0, index).trim(); title = filename.substring(index + 1).trim(); } else { title = filename.trim(); } if (TextUtils.isEmpty(lyric.getTitle()) && !TextUtils.isEmpty(title)) { lyric.setTitle(title); } else if (!TextUtils.isEmpty(artist)) { lyric.setArtist(artist); } } return lyric; } /** * Save lyric to local app directory * * @return Saved destination. Null if failed. */ public static String saveLyric(Lyric lyric) { return ""; } /** * Get sentence according to timestamp. * * @param lyric * @param ts * @return */ public static Sentence getSentence(Lyric lyric, long ts) { return getSentence(lyric, ts, 0); } /** * Get sentence according to timestamp and current index. * * @param lyric * @param ts * @param index * @return */ public static Sentence getSentence(Lyric lyric, long ts, int index) { return getSentence(lyric, ts, index, 0); } /** * Get sentence according to timestamp, current index, offset. * * @param lyric * @param ts * @param index * @param offset * @return */ public static Sentence getSentence(Lyric lyric, long ts, int index, int offset) { int found = getSentenceIndex(lyric, ts, index, offset); if (found == -1) return null; return lyric.getSentenceList().get(found); } /** * Get current index of sentence list. * * @param lyric Lyric file. * @param ts Current timestamp. * @param index Current index. * @param offset Lyric offset. * @return current sentence index, -1 if before first, -2 if not found. */ public static int getSentenceIndex(Lyric lyric, long ts, int index, int offset) { if (lyric == null || ts < 0 || index < -1) return -1; List<Sentence> list = lyric.getSentenceList(); if (index >= list.size()) index = list.size() - 1; if (index == -1) index = 0; int found = -2; if (list.get(index).getFromTime() + offset > ts) { for (int i = index; i > -1; --i) { if (list.get(i).getFromTime() + offset <= ts) { found = i; break; } } // First line of lyric is bigger than starting time. if (found == -2) found = -1; } else { for (int i = index; i < list.size() - 1; ++i) { //Log.d(TAG, String.format("ts: %d, offset: %d, curr_ts: %d, next_ts: %d", ts, offset, list.get(i).getFromTime(), list.get(i + 1).getFromTime())); if (list.get(i + 1).getFromTime() + offset > ts) { found = i; break; } } // If not found, return last mLyricIndex if (found == -2) { found = list.size() - 1; } } return found; } private static boolean parseLine(String line, Lyric lyric) { int lineLength = line.length(); line = line.trim(); int openBracketIndex, closedBracketIndex; openBracketIndex = line.indexOf('[', 0); while (openBracketIndex != -1) { closedBracketIndex = line.indexOf(']', openBracketIndex); // (1) ']' does not exist, (2) is the first character if (closedBracketIndex < 1) return false; String closedTag = line.substring(openBracketIndex + 1, closedBracketIndex); String[] colonSplited = closedTag.split(":", 2); if (colonSplited.length < 2) return false; if (colonSplited[0].equalsIgnoreCase(Constants.ID_TAG_TITLE)) { lyric.setTitle(colonSplited[1].trim()); } else if (colonSplited[0].equalsIgnoreCase(Constants.ID_TAG_ARTIST)) { lyric.setArtist(colonSplited[1].trim()); } else if (colonSplited[0].equalsIgnoreCase(Constants.ID_TAG_ALBUM)) { lyric.setAlbum(colonSplited[1].trim()); } else if (colonSplited[0].equalsIgnoreCase(Constants.ID_TAG_CREATOR_LRCFILE)) { lyric.setBy(colonSplited[1].trim()); } else if (colonSplited[0].equalsIgnoreCase(Constants.ID_TAG_CREATOR_SONGTEXT)) { lyric.setAuthor(colonSplited[1].trim()); } else if (colonSplited[0].equalsIgnoreCase(Constants.ID_TAG_LENGTH)) { lyric.setLength(parseTime(colonSplited[1].trim(), lyric)); } else if (colonSplited[0].equalsIgnoreCase(Constants.ID_TAG_OFFSET)) { lyric.setOffset(parseOffset(colonSplited[1].trim())); } else { if (Character.isDigit(colonSplited[0].charAt(0))) { List<Long> timestampList = new LinkedList<Long>(); long time = parseTime(closedTag, lyric); if (time != -1) { timestampList.add(time); } //Log.d(TAG, line); // We may have line like [01:38.33][01:44.01][03:22.05]Test Test // [03:55.00] while ((lineLength > closedBracketIndex + 2) && (line.charAt(closedBracketIndex + 1) == '[')) { //Log.d(TAG, String.valueOf(closedBracketIndex)); int nextOpenBracketIndex = closedBracketIndex + 1; int nextClosedBracketIndex = line.indexOf(']', nextOpenBracketIndex + 1); time = parseTime(line.substring(nextOpenBracketIndex + 1, nextClosedBracketIndex), lyric); if (time != -1) { timestampList.add(time); } closedBracketIndex = nextClosedBracketIndex; } String content = line.substring(closedBracketIndex + 1, line.length()); for (long timestamp : timestampList) { lyric.addSentence(content, timestamp); } } else { // Ignore unknown tag return true; } } // We may have line like [00:53.60]On a dark [00:54.85]desert highway openBracketIndex = line.indexOf('[', closedBracketIndex + 1); } return true; } /** * ??00:00.00?????????? ????????? 01:10.34???????10?????340?? ?????70340?? * * @param time ?????? * @return ???????? */ private static long parseTime(String time, Lyric lyric) { String[] ss = time.split("\\:|\\."); // ?? ??????????????? if (ss.length < 2) { return -1; } else if (ss.length == 2) {// ???????????? try { // ???????????????????? if (lyric.getOffset() == 0 && ss[0].equalsIgnoreCase("offset")) { lyric.setOffset(Integer.parseInt(ss[1])); System.err.println("??????????" + lyric.getOffset()); return -1; } int min = Integer.parseInt(ss[0]); int sec = Integer.parseInt(ss[1]); if (min < 0 || sec < 0 || sec >= 60) { throw new RuntimeException("????????!"); } // System.out.println("time" + (min * 60 + sec) * 1000L); return (min * 60 + sec) * 1000L; } catch (Exception exe) { return -1; } } else if (ss.length == 3) {// ?????????????????? try { int min = Integer.parseInt(ss[0]); int sec = Integer.parseInt(ss[1]); int mm = Integer.parseInt(ss[2]); if (min < 0 || sec < 0 || sec >= 60 || mm < 0 || mm > 99) { throw new RuntimeException("????????!"); } // System.out.println("time" + (min * 60 + sec) * 1000L + mm * 10); return (min * 60 + sec) * 1000L + mm * 10; } catch (Exception exe) { return -1; } } else {// ????????? return -1; } } /** * ????????????? * * @param str ?????????? * @return ?????????????????????????? */ private static int parseOffset(String str) { if (str.equalsIgnoreCase("0")) return 0; String[] ss = str.split("\\:"); if (ss.length == 2) { if (ss[0].equalsIgnoreCase("offset")) { int os = Integer.parseInt(ss[1]); Util.log(TAG, "??????????" + os); return os; } else { return Integer.MAX_VALUE; } } else { return Integer.MAX_VALUE; } } }