Template
fix: tighten lyric placeholder detection
This commit is contained in:
@@ -127,6 +127,7 @@ public class LyricsService {
|
||||
String normalized = lyrics.replace("\uFEFF", "").replace("\r", "");
|
||||
int lines = 0;
|
||||
int chars = 0;
|
||||
int timedLines = 0;
|
||||
for (String raw : normalized.split("\\n")) {
|
||||
String line = raw.trim();
|
||||
if (line.isEmpty() || line.matches("^\\[(?:ti|ar|al|by|re|ve|offset):.*$")) continue;
|
||||
@@ -134,8 +135,10 @@ public class LyricsService {
|
||||
String body = timed.matches() ? timed.group(1).trim() : line;
|
||||
if (body.isEmpty() || META_LINE.matcher(body).matches()) continue;
|
||||
lines++;
|
||||
if (timed.matches()) timedLines++;
|
||||
chars += body.replaceAll("\\s+", "").length();
|
||||
}
|
||||
if (timedLines > 0) return lines >= 3 && chars >= 12;
|
||||
return lines >= 2 && chars >= 8;
|
||||
}
|
||||
private static byte[] readLimited(InputStream in) throws Exception { try (InputStream x = in; ByteArrayOutputStream b = new ByteArrayOutputStream()) { byte[] buf = new byte[8192]; int n, total = 0; while ((n = x.read(buf)) >= 0) { total += n; if (total > MAX_BYTES) throw new IllegalArgumentException("歌词响应过大"); b.write(buf, 0, n); } return b.toByteArray(); } }
|
||||
|
||||
@@ -30,7 +30,7 @@ class LibraryHealthServiceTest {
|
||||
Path album = root.resolve("Artist").resolve("Album");
|
||||
Files.createDirectories(album);
|
||||
Files.write(album.resolve("01 - Song.mp3"), new byte[]{1, 2, 3});
|
||||
Files.write(album.resolve("01 - Song.lrc"), "[00:01]first line\n[00:02]second line".getBytes(StandardCharsets.UTF_8));
|
||||
Files.write(album.resolve("01 - Song.lrc"), "[00:01]first line\n[00:02]second line\n[00:03]third line".getBytes(StandardCharsets.UTF_8));
|
||||
Files.write(album.resolve("orphan.lrc"), "[00:01]orphan".getBytes(StandardCharsets.UTF_8));
|
||||
Files.write(album.resolve("cover.jpg"), new byte[]{(byte) 0xFF, (byte) 0xD8, (byte) 0xFF});
|
||||
return album;
|
||||
@@ -244,7 +244,7 @@ class LibraryHealthServiceTest {
|
||||
Files.createDirectories(album);
|
||||
// 大写 .LRC 侧车:既不应算缺歌词,也不应算孤立(与 orphan 判定保持一致)
|
||||
Files.write(album.resolve("01 - Song.mp3"), new byte[]{1, 2, 3});
|
||||
Files.write(album.resolve("01 - Song.LRC"), "[00:01]first line\n[00:02]second line".getBytes(StandardCharsets.UTF_8));
|
||||
Files.write(album.resolve("01 - Song.LRC"), "[00:01]first line\n[00:02]second line\n[00:03]third line".getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
LibraryHealthService svc = newService(root);
|
||||
LibraryHealthReport report = svc.scan(false);
|
||||
|
||||
@@ -22,8 +22,8 @@ class LyricsServiceTest {
|
||||
@Test
|
||||
void selectsExactArtistInsteadOfFirstCoverCandidate() throws Exception {
|
||||
String json = "["
|
||||
+ "{\"title\":\"夜曲 (网易云音乐)\",\"artist\":\"Xai小爱\",\"lyrics\":\"[00:01]翻唱第一句\\n[00:02]翻唱第二句\",\"type\":\"lrc\",\"source\":\"netease\"},"
|
||||
+ "{\"title\":\"夜曲 (酷狗音乐)\",\"artist\":\"周杰伦\",\"lyrics\":\"[00:01]一群嗜血的蚂蚁\\n[00:02]被腐肉所吸引\",\"type\":\"lrc\",\"source\":\"kugou\",\"isComplete\":true}]";
|
||||
+ "{\"title\":\"夜曲 (网易云音乐)\",\"artist\":\"Xai小爱\",\"lyrics\":\"[00:01]翻唱第一句\\n[00:02]翻唱第二句\\n[00:03]翻唱第三句\",\"type\":\"lrc\",\"source\":\"netease\"},"
|
||||
+ "{\"title\":\"夜曲 (酷狗音乐)\",\"artist\":\"周杰伦\",\"lyrics\":\"[00:01]一群嗜血的蚂蚁\\n[00:02]被腐肉所吸引\\n[00:03]我面无表情\",\"type\":\"lrc\",\"source\":\"kugou\",\"isComplete\":true}]";
|
||||
start(json, 200);
|
||||
LyricsService.Candidate result = new LyricsService().lookup("夜曲", "周杰伦");
|
||||
assertNotNull(result);
|
||||
@@ -45,7 +45,7 @@ class LyricsServiceTest {
|
||||
|
||||
@Test
|
||||
void acceptsTimestampedLyrics() {
|
||||
assertTrue(LyricsService.hasMeaningfulLyrics("[00:01.00]第一句歌词\n[00:03.00]第二句歌词\n"));
|
||||
assertTrue(LyricsService.hasMeaningfulLyrics("[00:01.00]第一句歌词\n[00:03.00]第二句歌词\n[00:05.00]第三句歌词\n"));
|
||||
}
|
||||
|
||||
private void start(String body, int status) throws Exception {
|
||||
|
||||
@@ -14,13 +14,15 @@ text=open(sys.argv[1],encoding='utf-8-sig',errors='replace').read().replace('\r'
|
||||
meta=re.compile(r'^\[(?:ti|ar|al|by|re|ve|offset):',re.I)
|
||||
timed=re.compile(r'^\s*\[(?:\d{1,2}:)?\d{1,2}:\d{2}(?:\.\d+)?\]\s*(.*)$')
|
||||
labels=re.compile(r'^(?:作词|作曲|词曲|编曲|制作人?|混音(?:师|助理)?|录音(?:师)?|工程师|弦乐|鼓和钢琴|电贝斯|额外编程|数字编辑|原唱|演唱|出品|发行|版权|produced|written|composer|arranged|lyrics?|music|artist|title)\s*[::\-].*$',re.I)
|
||||
body=[]
|
||||
body=[]; timed_lines=0
|
||||
for raw in text.split('\n'):
|
||||
line=raw.strip()
|
||||
if not line or meta.match(line): continue
|
||||
match=timed.match(line); line=(match.group(1).strip() if match else line)
|
||||
if line and not labels.match(line): body.append(line)
|
||||
sys.exit(0 if len(body)>=2 and len(''.join(body).replace(' ',''))>=8 else 1)
|
||||
if line and not labels.match(line):
|
||||
body.append(line); timed_lines += 1 if match else 0
|
||||
valid=(len(body)>=3 and len(''.join(body).replace(' ',''))>=12) if timed_lines else (len(body)>=2 and len(''.join(body).replace(' ',''))>=8)
|
||||
sys.exit(0 if valid else 1)
|
||||
PY
|
||||
then
|
||||
echo "SKIP $audio"
|
||||
@@ -42,13 +44,14 @@ def meaningful(text):
|
||||
meta=re.compile(r'^\[(?:ti|ar|al|by|re|ve|offset):',re.I)
|
||||
timed=re.compile(r'^\s*\[(?:\d{1,2}:)?\d{1,2}:\d{2}(?:\.\d+)?\]\s*(.*)$')
|
||||
labels=re.compile(r'^(?:作词|作曲|词曲|编曲|制作人?|混音(?:师|助理)?|录音(?:师)?|工程师|弦乐|鼓和钢琴|电贝斯|额外编程|数字编辑|原唱|演唱|出品|发行|版权|produced|written|composer|arranged|lyrics?|music|artist|title)\s*[::\-].*$',re.I)
|
||||
body=[]
|
||||
body=[]; timed_lines=0
|
||||
for raw in text.replace('\r','').split('\n'):
|
||||
line=raw.strip()
|
||||
if not line or meta.match(line): continue
|
||||
match=timed.match(line); line=(match.group(1).strip() if match else line)
|
||||
if line and not labels.match(line): body.append(line)
|
||||
return len(body)>=2 and len(''.join(body).replace(' ',''))>=8
|
||||
if line and not labels.match(line):
|
||||
body.append(line); timed_lines += 1 if match else 0
|
||||
return (len(body)>=3 and len(''.join(body).replace(' ',''))>=12) if timed_lines else (len(body)>=2 and len(''.join(body).replace(' ',''))>=8)
|
||||
best=None
|
||||
for x in rows if isinstance(rows,list) else []:
|
||||
l=x.get('lyrics','').strip(); ct=x.get('title',''); ca=x.get('artist','')
|
||||
|
||||
Reference in New Issue
Block a user