diff --git a/app/src/main/java/com/kabouzeid/gramophone/model/lyrics/AbsSynchronizedLyrics.java b/app/src/main/java/com/kabouzeid/gramophone/model/lyrics/AbsSynchronizedLyrics.java index d3052045..93daf296 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/model/lyrics/AbsSynchronizedLyrics.java +++ b/app/src/main/java/com/kabouzeid/gramophone/model/lyrics/AbsSynchronizedLyrics.java @@ -4,25 +4,32 @@ import android.util.SparseArray; public abstract class AbsSynchronizedLyrics { public final SparseArray lines = new SparseArray<>(); + public boolean isValid = false; - public static AbsSynchronizedLyrics parse(String data) - { - return new SynchronizedLyricsLRC(data); // no another formats at the moment + public static AbsSynchronizedLyrics parse(String data, boolean justCheck) { + return new SynchronizedLyricsLRC(data, justCheck); // no another formats at the moment } - public String getLine(int time) - { + public static AbsSynchronizedLyrics parse(String data) { + return parse(data, false); + } + + public static boolean isSynchronized(String data) { + AbsSynchronizedLyrics lyrics = parse(data, true); + return lyrics.isValid; + } + + public String getLine(int time) { time += 500; // small time adjustment to display line before it actually starts int lastLineTime = lines.keyAt(0); - for(int i = 0; i < lines.size(); i++) { + for (int i = 0; i < lines.size(); i++) { int lineTime = lines.keyAt(i); - if(time >= lineTime) { + if (time >= lineTime) { lastLineTime = lineTime; - } - else { + } else { break; } } diff --git a/app/src/main/java/com/kabouzeid/gramophone/model/lyrics/SynchronizedLyricsLRC.java b/app/src/main/java/com/kabouzeid/gramophone/model/lyrics/SynchronizedLyricsLRC.java index e0b43eda..92a979aa 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/model/lyrics/SynchronizedLyricsLRC.java +++ b/app/src/main/java/com/kabouzeid/gramophone/model/lyrics/SynchronizedLyricsLRC.java @@ -5,38 +5,40 @@ import java.util.regex.Pattern; public class SynchronizedLyricsLRC extends AbsSynchronizedLyrics { private static Pattern LRC_LINE_PATTERN = Pattern.compile("((?:\\[.*?\\])+)(.*)"); - private static Pattern LRC_TIME_PATTERN = Pattern.compile("\\[(\\d\\d):(\\d\\d)(?:\\.(\\d\\d))\\]"); + private static Pattern LRC_TIME_PATTERN = Pattern.compile("\\[(\\d+):(\\d{2}(?:\\.\\d+)?)\\]"); - public SynchronizedLyricsLRC(String data) - { - if(data == null || data.isEmpty()) { + public SynchronizedLyricsLRC(String data, boolean justCheck) { + if (data == null || data.isEmpty()) { return; } String[] lines = data.split("\r?\n"); - for(String line : lines) { + for (String line : lines) { line = line.trim(); - if(line.isEmpty()) { + if (line.isEmpty()) { continue; } Matcher matcher = SynchronizedLyricsLRC.LRC_LINE_PATTERN.matcher(line); - if(matcher.find()) { + if (matcher.find()) { String time = matcher.group(1); String text = matcher.group(2); Matcher timeMatcher = SynchronizedLyricsLRC.LRC_TIME_PATTERN.matcher(time); - while(timeMatcher.find()) { - int m = 0, s = 0, x = 0; + while (timeMatcher.find()) { + int m = 0; + float s = 0f; try { m = Integer.parseInt(timeMatcher.group(1)); - s = Integer.parseInt(timeMatcher.group(2)); - x = Integer.parseInt(timeMatcher.group(3)); + s = Float.parseFloat(timeMatcher.group(2)); } catch (NumberFormatException ex) { ex.printStackTrace(); } - int ms = x*10 + s*1000 + m*60000; + int ms = (int) (s * 1000f) + m * 60000; + + this.isValid = true; + if (justCheck) return; this.lines.append(ms, text); } diff --git a/app/src/main/java/com/kabouzeid/gramophone/util/MusicUtil.java b/app/src/main/java/com/kabouzeid/gramophone/util/MusicUtil.java index db71af1c..656d6873 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/util/MusicUtil.java +++ b/app/src/main/java/com/kabouzeid/gramophone/util/MusicUtil.java @@ -24,6 +24,7 @@ import com.kabouzeid.gramophone.loader.SongLoader; import com.kabouzeid.gramophone.model.Artist; import com.kabouzeid.gramophone.model.Playlist; import com.kabouzeid.gramophone.model.Song; +import com.kabouzeid.gramophone.model.lyrics.AbsSynchronizedLyrics; import org.jaudiotagger.audio.AudioFileIO; import org.jaudiotagger.tag.FieldKey; @@ -274,13 +275,17 @@ public class MusicUtil { e.printStackTrace(); } - if (lyrics == null || lyrics.trim().isEmpty()) { + if (lyrics == null || lyrics.trim().isEmpty() || !AbsSynchronizedLyrics.isSynchronized(lyrics)) { File dir = file.getAbsoluteFile().getParentFile(); if (dir != null && dir.exists() && dir.isDirectory()) { + String format = ".*%s.*\\.(lrc|txt)"; + String filename = Pattern.quote(FileUtil.stripExtension(file.getName())); + String songtitle = Pattern.quote(song.title); + final ArrayList patterns = new ArrayList<>(); - patterns.add(Pattern.compile(String.format(".*%s.*\\.(lrc|txt)", FileUtil.stripExtension(file.getName())), Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE)); - patterns.add(Pattern.compile(String.format(".*%s.*\\.(lrc|txt)", song.title), Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE)); + patterns.add(Pattern.compile(String.format(format, filename), Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE)); + patterns.add(Pattern.compile(String.format(format, songtitle), Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE)); File[] files = dir.listFiles(new FileFilter() { @Override @@ -295,9 +300,12 @@ public class MusicUtil { if (files != null && files.length > 0) { for (File f : files) { try { - lyrics = FileUtil.read(f); - if (lyrics != null && !lyrics.trim().isEmpty()) { - return lyrics; + String newLyrics = FileUtil.read(f); + if (newLyrics != null && !newLyrics.trim().isEmpty()) { + if (AbsSynchronizedLyrics.isSynchronized(newLyrics)) { + return newLyrics; + } + lyrics = newLyrics; } } catch (Exception e) { e.printStackTrace();