Fix loading LRC files with regex control characters in name

Fix non-standart LRC timestamps
This commit is contained in:
tkashkin 2017-06-14 18:49:11 +03:00
commit 1a71950930
3 changed files with 44 additions and 27 deletions

View file

@ -4,14 +4,22 @@ import android.util.SparseArray;
public abstract class AbsSynchronizedLyrics { public abstract class AbsSynchronizedLyrics {
public final SparseArray<String> lines = new SparseArray<>(); public final SparseArray<String> lines = new SparseArray<>();
public boolean isValid = false;
public static AbsSynchronizedLyrics parse(String data) public static AbsSynchronizedLyrics parse(String data, boolean justCheck) {
{ return new SynchronizedLyricsLRC(data, justCheck); // no another formats at the moment
return new SynchronizedLyricsLRC(data); // 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 time += 500; // small time adjustment to display line before it actually starts
int lastLineTime = lines.keyAt(0); int lastLineTime = lines.keyAt(0);
@ -21,8 +29,7 @@ public abstract class AbsSynchronizedLyrics {
if (time >= lineTime) { if (time >= lineTime) {
lastLineTime = lineTime; lastLineTime = lineTime;
} } else {
else {
break; break;
} }
} }

View file

@ -5,10 +5,9 @@ import java.util.regex.Pattern;
public class SynchronizedLyricsLRC extends AbsSynchronizedLyrics { public class SynchronizedLyricsLRC extends AbsSynchronizedLyrics {
private static Pattern LRC_LINE_PATTERN = Pattern.compile("((?:\\[.*?\\])+)(.*)"); 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) public SynchronizedLyricsLRC(String data, boolean justCheck) {
{
if (data == null || data.isEmpty()) { if (data == null || data.isEmpty()) {
return; return;
} }
@ -28,15 +27,18 @@ public class SynchronizedLyricsLRC extends AbsSynchronizedLyrics {
Matcher timeMatcher = SynchronizedLyricsLRC.LRC_TIME_PATTERN.matcher(time); Matcher timeMatcher = SynchronizedLyricsLRC.LRC_TIME_PATTERN.matcher(time);
while (timeMatcher.find()) { while (timeMatcher.find()) {
int m = 0, s = 0, x = 0; int m = 0;
float s = 0f;
try { try {
m = Integer.parseInt(timeMatcher.group(1)); m = Integer.parseInt(timeMatcher.group(1));
s = Integer.parseInt(timeMatcher.group(2)); s = Float.parseFloat(timeMatcher.group(2));
x = Integer.parseInt(timeMatcher.group(3));
} catch (NumberFormatException ex) { } catch (NumberFormatException ex) {
ex.printStackTrace(); 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); this.lines.append(ms, text);
} }

View file

@ -24,6 +24,7 @@ import com.kabouzeid.gramophone.loader.SongLoader;
import com.kabouzeid.gramophone.model.Artist; import com.kabouzeid.gramophone.model.Artist;
import com.kabouzeid.gramophone.model.Playlist; import com.kabouzeid.gramophone.model.Playlist;
import com.kabouzeid.gramophone.model.Song; import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.model.lyrics.AbsSynchronizedLyrics;
import org.jaudiotagger.audio.AudioFileIO; import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.tag.FieldKey; import org.jaudiotagger.tag.FieldKey;
@ -274,13 +275,17 @@ public class MusicUtil {
e.printStackTrace(); e.printStackTrace();
} }
if (lyrics == null || lyrics.trim().isEmpty()) { if (lyrics == null || lyrics.trim().isEmpty() || !AbsSynchronizedLyrics.isSynchronized(lyrics)) {
File dir = file.getAbsoluteFile().getParentFile(); File dir = file.getAbsoluteFile().getParentFile();
if (dir != null && dir.exists() && dir.isDirectory()) { 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<Pattern> patterns = new ArrayList<>(); final ArrayList<Pattern> 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(format, filename), 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, songtitle), Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE));
File[] files = dir.listFiles(new FileFilter() { File[] files = dir.listFiles(new FileFilter() {
@Override @Override
@ -295,9 +300,12 @@ public class MusicUtil {
if (files != null && files.length > 0) { if (files != null && files.length > 0) {
for (File f : files) { for (File f : files) {
try { try {
lyrics = FileUtil.read(f); String newLyrics = FileUtil.read(f);
if (lyrics != null && !lyrics.trim().isEmpty()) { if (newLyrics != null && !newLyrics.trim().isEmpty()) {
return lyrics; if (AbsSynchronizedLyrics.isSynchronized(newLyrics)) {
return newLyrics;
}
lyrics = newLyrics;
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();