Skip to content

Commit

Permalink
Fix some problems with local matching lyrics and display more informa…
Browse files Browse the repository at this point in the history
…tion in the lyrics type
  • Loading branch information
chenmozhijin committed Mar 7, 2024
1 parent 34dcb3c commit 096d576
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 35 deletions.
6 changes: 6 additions & 0 deletions ui/search.ui
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,12 @@
</item>
<item>
<widget class="QLineEdit" name="lyric_types_lineEdit">
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
<property name="text">
<string/>
</property>
Expand Down
12 changes: 10 additions & 2 deletions ui/search_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,15 @@
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################

from PySide6.QtCore import QCoreApplication, QMetaObject, QSize, Qt
from PySide6.QtGui import QFont
from PySide6.QtCore import (
QCoreApplication,
QMetaObject,
QSize,
Qt,
)
from PySide6.QtGui import (
QFont,
)
from PySide6.QtWidgets import (
QAbstractItemView,
QAbstractScrollArea,
Expand Down Expand Up @@ -177,6 +184,7 @@ def setupUi(self, search):

self.lyric_types_lineEdit = QLineEdit(self.layoutWidget_3)
self.lyric_types_lineEdit.setObjectName(u"lyric_types_lineEdit")
self.lyric_types_lineEdit.setMinimumSize(QSize(300, 0))
self.lyric_types_lineEdit.setReadOnly(True)

self.horizontalLayout_5.addWidget(self.lyric_types_lineEdit)
Expand Down
39 changes: 23 additions & 16 deletions utils/lyrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@

class LyricType(Enum):
PlainText = 0
LRC = 1
QRC = 2
KRC = 3
YRC = 4
JSONVERBATIM = 1
JSONLINE = 2
LRC = 3
QRC = 4
KRC = 5
YRC = 6


class LyricProcessingError(Enum):
Expand Down Expand Up @@ -414,7 +416,7 @@ def __init__(self, info: dict | None = None) -> None:
self.mid = info.get("mid", None)
self.accesskey = info.get("accesskey", None)

self.orig_type = None
self.lrc_types = {}
self.tags = {}

def download_and_decrypt(self) -> tuple[str | None, LyricProcessingError | None]:
Expand Down Expand Up @@ -447,20 +449,15 @@ def download_and_decrypt(self) -> tuple[str | None, LyricProcessingError | None]
lyric, error = qrc_decrypt(encrypted_lyric, QrcType.CLOUD)

if lyric is not None:
type_ = judge_lyric_type(lyric)
if type_ == LyricType.QRC:
lrc_type = judge_lyric_type(lyric)
if lrc_type == LyricType.QRC:
tags, lyric = qrc2list(lyric)
if key == "orig":
self.orig_type = LyricType.QRC
elif LyricType.LRC:
tags, lyric = lrc2list(lyric)
if key == "orig":
self.orig_type = LyricType.LRC
elif LyricType.PlainText:
tags = {}
lyric = plaintext2list(lyric)
if key == "orig":
self.orig_type = LyricType.PlainText
self.lrc_types[key] = lrc_type

if key == "orig":
self.tags = tags
Expand All @@ -481,7 +478,12 @@ def download_and_decrypt(self) -> tuple[str | None, LyricProcessingError | None]
return f"解密krc歌词失败,错误:{error}", LyricProcessingError.DECRYPT
self.tags, lyric = krc2dict(krc)
self.update(lyric)
self.orig_type = LyricType.KRC
if 'orig' in lyric:
self.lrc_types['orig'] = LyricType.KRC
if 'ts' in lyric:
self.lrc_types['ts'] = LyricType.JSONLINE
if 'roma' in lyric:
self.lrc_types['roma'] = LyricType.JSONVERBATIM

case Source.NE:
lyrics = ne_get_lyric(self.id)
Expand All @@ -508,7 +510,6 @@ def download_and_decrypt(self) -> tuple[str | None, LyricProcessingError | None]
("ts", 'tlyric'),
("roma", 'romalrc'),
("orig_lrc", 'lrc')]
self.orig_type = LyricType.YRC
else:
mapping_table = [("orig", 'lrc'),
("ts", 'tlyric'),
Expand All @@ -520,10 +521,13 @@ def download_and_decrypt(self) -> tuple[str | None, LyricProcessingError | None]
lyric_type = judge_lyric_type(lyrics[value]['lyric'])
if value == 'yrc':
self[key] = yrc2list(lyrics[value]['lyric'])
self.lrc_types[key] = LyricType.YRC
elif lyric_type == LyricType.LRC:
self[key] = lrc2list(lyrics[value]['lyric'])[1]
self.lrc_types[key] = LyricType.LRC
elif lyric_type == LyricType.PlainText:
self[key] = plaintext2list(lyrics[value]['lyric'])
self.lrc_types[key] = LyricType.PlainText

if "orig" not in self or self["orig"] is None:
logging.error("没有获取到的歌词(orig=None)")
Expand All @@ -538,14 +542,17 @@ def download_normal_lyrics(self) -> tuple[str | None, LyricProcessingError | Non
if orig is not None:
if judge_lyric_type(orig) == LyricType.LRC:
self.tags, self["orig"] = lrc2list(orig)
self.lrc_types["orig"] = LyricType.LRC
else:
self["orig"] = plaintext2list(orig)
self.orig_type = LyricType.LRC
self.lrc_types["orig"] = LyricType.PlainText
if ts is not None:
if judge_lyric_type(ts) == LyricType.LRC:
tags, self["ts"] = lrc2list(ts)
self.lrc_types["ts"] = LyricType.LRC
else:
self["ts"] = plaintext2list(ts)
self.lrc_types["ts"] = LyricType.PlainText
if not self.tags:
self.tags = tags
if self["orig"] is None and self["ts"] is None:
Expand Down
37 changes: 27 additions & 10 deletions utils/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ def get_merged_lyric(self, song_info: dict, lyric_type: list) -> bool:
return from_cache

if self.task["type"] == "get_merged_lyric":
self.signals.result.emit(self.taskid, {'info': song_info, 'available_types': list(lyrics.keys()), 'merged_lyric': merged_lyric})
self.signals.result.emit(self.taskid, {'info': song_info, 'lrc_types': lyrics.lrc_types, 'merged_lyric': merged_lyric})

elif self.task["type"] == "get_list_lyrics":
save_folder, file_name = get_save_path(self.task["save_folder"], self.task["lyrics_file_name_format"] + ".lrc", song_info, lyrics_order)
Expand Down Expand Up @@ -382,10 +382,10 @@ def search_and_get(self, info: dict) -> list:
keywords = [info["title"]]
else:
keywords = [f"{info['artist']} - {info['title']}", info["title"]]
from_cache = False
min_title = re.sub(self.min_title_pattern1, "", info["title"].strip())
min_title = re.sub(self.min_title_pattern2, "", min_title.strip())
for source in self.sources:
from_cache = False
if not self.is_running:
return None, None
match source:
Expand Down Expand Up @@ -423,6 +423,7 @@ def search_and_get(self, info: dict) -> list:
if (info["artist"] is not None and
keyword == f"{info['artist']} - {info['title']}" and
(info['duration'] is None or abs(int(search_return[0]['duration']) - info['duration']) < 5)):
logging.debug(f"本地: {info}\n搜索结果:{search_return[0]}\n分数:1000")
scores.append((search_return[0], 1000))

for song_info in search_return:
Expand Down Expand Up @@ -458,9 +459,9 @@ def search_and_get(self, info: dict) -> list:
return None, None
if self.skip_inst_lyrics and scores[0][0]['source'] == Source.KG and scores[0][0]['language'] in ["纯音乐", '伴奏']:
if 'artist' in info:
msg = f"[{self.current_index}/{self.total_index}]本地: {info['artist']} - {info['title']} 搜索结果:{song_info['artist']} - {song_info['title']} 跳过纯音乐"
msg = f"[{self.current_index}/{self.total_index}]本地: {info['artist']} - {info['title']} 搜索结果:{scores[0][0]['artist']} - {scores[0][0]['title']} 跳过纯音乐"
else:
msg = f"[{self.current_index}/{self.total_index}]本地: {info['title']} 搜索结果:{song_info['artist']} - {song_info['title']} 跳过纯音乐"
msg = f"[{self.current_index}/{self.total_index}]本地: {info['title']} 搜索结果:{scores[0][0]['artist']} - {scores[0][0]['title']} 跳过纯音乐"
self.signals.massage.emit(msg)
return None, None

Expand Down Expand Up @@ -497,6 +498,7 @@ def search_and_get(self, info: dict) -> list:

# Step 3 获取歌词
from_cache = False
inst = False
obtained_sources = []
lyrics: list[tuple[Lyrics, int, dict]] = []
for song_info, score in scores:
Expand All @@ -507,36 +509,51 @@ def search_and_get(self, info: dict) -> list:
lyric = None
lyric, from_cache = self.LyricProcessingWorker.get_lyrics(song_info)
if lyric is not None:
obtained_sources.append(song_info['source'])
logging.debug(f"lyric['orig']:{lyric['orig']}")
if self.skip_inst_lyrics and len(lyric["orig"]) != 0 and (lyric["orig"][0][2][0][2] == "此歌曲为没有填词的纯音乐,请您欣赏" or lyric["orig"][0][2][0][2] == "纯音乐,请欣赏"):
inst = True
continue
lyrics.append((lyric, score, song_info))
obtained_sources.append(song_info['source'])
inst = False
if not from_cache:
time.sleep(0.5)

verbatim_lyrics_formats = [LyricType.QRC, LyricType.KRC, LyricType.YRC]
verbatim_lyrics_formats = [LyricType.QRC, LyricType.KRC, LyricType.YRC, LyricType.JSONVERBATIM]
if len(lyrics) == 1:
song_info = lyrics[0][2]
lyrics = lyrics[0][0]
elif len(lyrics) > 1:
if lyrics[0][0].orig_type in verbatim_lyrics_formats:
if lyrics[0][0].lrc_types['orig'] in verbatim_lyrics_formats:
song_info = lyrics[0][2]
lyrics = lyrics[0][0]
elif lyrics[1][0].orig_type in verbatim_lyrics_formats and abs(lyrics[0][1] - lyrics[1][1]) < 15:
elif lyrics[1][0].lrc_types['orig'] in verbatim_lyrics_formats and abs(lyrics[0][1] - lyrics[1][1]) < 15:
song_info = lyrics[1][2]
lyrics = lyrics[1][0]
elif len(lyrics) > 2 and lyrics[2][0].orig_type in verbatim_lyrics_formats and abs(lyrics[0][1] - lyrics[2][1]) < 15:
elif len(lyrics) > 2 and lyrics[2][0].lrc_types['orig'] in verbatim_lyrics_formats and abs(lyrics[0][1] - lyrics[2][1]) < 15:
song_info = lyrics[2][2]
lyrics = lyrics[2][0]
else:
song_info = lyrics[0][2]
lyrics = lyrics[0][0]
# Step 4 合并歌词
if isinstance(lyrics, Lyrics):
merged_lyric = lyrics.merge(self.lyrics_order)
return merged_lyric, song_info
if 'artist' in info:
msg = f"[{self.current_index}/{self.total_index}]本地: {info['artist']} - {info['title']} 搜索结果:{song_info['artist']} - {song_info['title']} 歌词获取失败"
if inst:
msg = f"[{self.current_index}/{self.total_index}]本地: {info['artist']} - {info['title']} 搜索结果:{scores[0][0]['artist']} - {scores[0][0]['title']} 跳过纯音乐"
else:
msg = f"[{self.current_index}/{self.total_index}]本地: {info['artist']} - {info['title']} 搜索结果:{song_info['artist']} - {song_info['title']} 歌词获取失败"
elif inst:
msg = f"[{self.current_index}/{self.total_index}]本地: {info['title']} 搜索结果:{scores[0][0]['artist']} - {scores[0][0]['title']} 跳过纯音乐"
else:
msg = f"[{self.current_index}/{self.total_index}]本地: {info['title']} 搜索结果:{song_info['artist']} - {song_info['title']} 歌词获取失败"
self.signals.massage.emit(msg)
return None, None

def run(self) -> None:
logging.info(f"开始本地匹配歌词,源:{self.sources}")
try:
start_time = time.time()
# Setp 1 处理cue 与 遍历歌曲文件
Expand Down
23 changes: 16 additions & 7 deletions view/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
Source,
)
from utils.data import Data
from utils.lyrics import LyricType
from utils.utils import get_save_path, ms2formattime
from utils.worker import GetSongListWorker, LyricProcessingWorker, SearchWorker
from view.get_list_lyrics import GetListLyrics
Expand Down Expand Up @@ -284,16 +285,24 @@ def update_preview_lyric_error_slot(self, error: str) -> None:
@Slot(int, dict)
def update_preview_lyric_result_slot(self, taskid: int, result: dict) -> None:
"""更新预览歌词结果时调用"""
def lrc_type2text(lrc_type: LyricType) -> str:
if lrc_type in [LyricType.QRC, LyricType.KRC, LyricType.YRC, LyricType.JSONVERBATIM]:
return "逐字"
if lrc_type in [LyricType.LRC, LyricType.JSONLINE]:
return "逐行"
if lrc_type == LyricType.PlainText:
return "纯文本"
return "未知"
if taskid != self.taskid["update_preview_lyric"]:
return
self.preview_info = {"info": result["info"], 'available_types': result['available_types']}
self.preview_info = {"info": result["info"], 'lrc_types': result['lrc_types']}
lyric_types_text = ""
if "orig" in result['available_types']:
lyric_types_text += "原文"
if "ts" in result['available_types']:
lyric_types_text += "、译文"
if "roma" in result['available_types']:
lyric_types_text += "、罗马音"
if "orig" in result['lrc_types']:
lyric_types_text += "原文" + f"({lrc_type2text(result['lrc_types']['orig'])})"
if "ts" in result['lrc_types']:
lyric_types_text += "、译文" + f"({lrc_type2text(result['lrc_types']['ts'])})"
if "roma" in result['lrc_types']:
lyric_types_text += "、罗马音" + f"({lrc_type2text(result['lrc_types']['roma'])})"
self.lyric_types_lineEdit.setText(lyric_types_text)
self.songid_lineEdit.setText(str(result['info']['id']))

Expand Down

0 comments on commit 096d576

Please sign in to comment.