Skip to content

Commit fc52c79

Browse files
authored
Merge pull request #9 from chenmozhijin/dev
v0.7.1
2 parents be7b7d9 + bd3c948 commit fc52c79

24 files changed

+1165
-2546
lines changed

.github/workflows/build-nuitka.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ jobs:
6161
- name: Install create-dmg/upx
6262
if: ${{ runner.os == 'macOS' }}
6363
run: |
64-
brew install create-dmg upx
64+
brew install create-dmg
6565
6666
- name: Install upx/7zip
6767
if: ${{ runner.os == 'Windows' }}
@@ -88,14 +88,15 @@ jobs:
8888
echo "version=$(python build_helper.py --task get_version)" >> $GITHUB_OUTPUT
8989
cat $GITHUB_OUTPUT
9090
91-
- name: Build Executable
91+
- name: Build Executable(Linux/macOS)
9292
uses: Nuitka/Nuitka-Action@main
9393
if : ${{ runner.os == 'Linux' || runner.os == 'macOS'}}
9494
with:
9595
nuitka-version: main
9696
script-name: LDDC.py
9797
standalone: true
9898
onefile: false
99+
report: nuitka-report.xml
99100
enable-plugins: pyside6
100101
product-name: "LDDC"
101102
file-version: ${{ steps.info.outputs.version }}
@@ -109,14 +110,15 @@ jobs:
109110
macos-create-app-bundle: true
110111
macos-target-arch: ${{ steps.arch.outputs.nuitka_arch }}
111112

112-
- name: Build Executable
113+
- name: Build Executable(Windows)
113114
uses: Nuitka/Nuitka-Action@main
114115
if : ${{ runner.os == 'Windows' }}
115116
with:
116117
nuitka-version: main
117118
script-name: LDDC.py
118119
standalone: true
119120
onefile: false
121+
report: nuitka-report.xml
120122
enable-plugins: pyside6
121123
product-name: "LDDC"
122124
file-version: ${{ steps.info.outputs.version }}
@@ -134,7 +136,7 @@ jobs:
134136
name: ${{ runner.os }} - ${{ matrix.arch }} report
135137
path: |
136138
nuitka-crash-report.xml
137-
report.xml
139+
nuitka-report.xml
138140
139141
- name: create dmg
140142
if: ${{ runner.os == 'macOS' }}

LDDC.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@
3737

3838
exit_manager.close_signal.connect(service.stop_service, Qt.ConnectionType.BlockingQueuedConnection)
3939

40-
from view.main_window import main_window
4140
load_translation(False)
4241
if show:
42+
from view.main_window import main_window
4343
main_window.show()
4444
from utils.data import cfg
4545
if cfg["auto_check_update"]:

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
## 功能
1414

1515
- [x] 搜索QQ音乐、酷狗音乐、网易云音乐的单曲、专辑、歌单
16+
- [x] 拖动歌曲到搜索界面自动搜索并匹配歌词
1617
- [x] 一键下载整个 专辑、歌单 的歌词
1718
- [x] 一键为本地歌曲文件匹配歌词
1819
- [x] 支持保存为多种格式(逐字lrc、逐行lrc、增强型lrc、srt、ass)
@@ -32,9 +33,21 @@
3233

3334
## 预览
3435

36+
### 拖拽歌曲快速匹配歌词
37+
38+
![gif](img/drop.gif)
39+
40+
### 搜索界面
41+
3542
![image](img/zh_1.jpg)
43+
44+
### 打开歌词/本地匹配/设置界面
45+
3646
![image](img/zh_2.jpg)
3747

48+
### 桌面歌词
49+
50+
![image](img/zh_3.jpg)
3851
![gif](img/desktop_lyrics.gif)
3952

4053
## 使用方法
@@ -49,7 +62,6 @@
4962

5063
[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=WXRIW&repo=QQMusicDecoder)](https://github.com/WXRIW/QQMusicDecoder)
5164
[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=jixunmoe&repo=qmc-decode)](https://github.com/jixunmoe/qmc-decode)
52-
[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=parakeet-rs&repo=libparakeet)](https://github.com/parakeet-rs/libparakeet)
5365

5466
### 音乐平台api
5567

README_en.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
## Features
1414

1515
- [x] Search for singles, albums, and playlists on QQ Music, Kugou Music, and NetEase Cloud Music
16+
- [x] Drag the song to the search interface to automatically search and match the lyrics
1617
- [x] One-click download of lyrics for entire albums and playlists
1718
- [x] One-click match lyrics for local song files
1819
- [x] Support for saving in multiple formats (verbatim lrc,line by line lrc,Enhanced LRC, srt, ass)
@@ -32,9 +33,21 @@
3233

3334
## Preview
3435

36+
### Drag songs to quickly match lyrics
37+
38+
![gif](img/drop.gif)
39+
40+
### Search interface
41+
3542
![image](img/en_1.jpg)
43+
44+
### Open the lyrics/local matching/settings interface
45+
3646
![image](img/en_2.jpg)
3747

48+
### Desktop Lyrics
49+
50+
![image](img/en_3.jpg)
3851
![gif](img/desktop_lyrics.gif)
3952

4053
## Usage
@@ -49,7 +62,6 @@ Some functionalities are implemented with reference to the following projects:
4962

5063
[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=WXRIW&repo=QQMusicDecoder)](https://github.com/WXRIW/QQMusicDecoder)
5164
[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=jixunmoe&repo=qmc-decode)](https://github.com/jixunmoe/qmc-decode)
52-
[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=parakeet-rs&repo=libparakeet)](https://github.com/parakeet-rs/libparakeet)
5365

5466
### Music Platform APIs
5567

backend/converter/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ def convert2(lyrics: Lyrics,
4040
if key == "source":
4141
value: Source
4242
json_dict["info"][key] = value.name
43-
else:
43+
elif value is not None:
4444
json_dict["info"][key] = value
4545

46-
return json.dumps(json_dict, ensure_ascii=False)
46+
return json.dumps(json_dict, ensure_ascii=False)
4747

4848
if not langs:
4949
return ""

backend/fetcher/local.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,19 @@ def json2lyrics(json_data: dict, lyrics: Lyrics) -> None:
3737
for key, value in json_data["info"].items():
3838
key: str
3939
value: str | int
40-
if key in ("source", "title", "artist", "album", "mid", "accesskey") and not isinstance(value, str):
41-
msg = f"JSON歌词数据中包含值类型不正确的键: {key}"
42-
raise LyricsProcessingError(msg)
43-
if key in ("id", "duration") and not isinstance(value, int):
44-
msg = f"JSON歌词数据中包含值类型不正确的键: {key}"
4540

4641
if key == "source" and isinstance(value, str):
4742
lyrics.source = Source.__members__.get(value)
4843
if lyrics.source is None:
4944
msg = f"JSON歌词数据中包含不正确的值: {value}"
5045
raise LyricsProcessingError(msg)
5146

47+
elif ((key in ("source", "title", "album", "mid", "accesskey") and not isinstance(value, str)) or
48+
(key == "duration" and not isinstance(value, int)) or
49+
(key == "artist" and not isinstance(value, str | list)) or
50+
(key == "id" and not isinstance(value, str | int))):
51+
msg = f"JSON歌词数据中包含值类型不正确的键: {key}"
52+
raise LyricsProcessingError(msg)
5253
else:
5354
setattr(lyrics, key, value)
5455

backend/searcher.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def search(keyword: str,
4545
case Source.KG:
4646
if search_type == SearchType.LYRICS and info:
4747
results = kg_search(keyword=keyword, info=info, search_type=SearchType.LYRICS)
48-
results = [{**info, **item} for item in results]
48+
results = [{**info, **item, "duration": info["duration"]} for item in results]
4949
elif search_type != SearchType.LYRICS:
5050
results = kg_search(keyword=keyword, search_type=search_type, page=page)
5151
else:

backend/service.py

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,7 @@
1313
from random import SystemRandom
1414
from typing import Literal
1515

16-
try:
17-
import psutil
18-
except ImportError:
19-
psutil = None
16+
import psutil
2017
from PySide6.QtCore import (
2118
QCoreApplication,
2219
QEventLoop,
@@ -76,6 +73,10 @@ def __init__(self, service: "LDDCService", instance_id: int, client_id: int, pid
7673
def handle_task(self, task: dict) -> None:
7774
...
7875

76+
@abstractmethod
77+
def init(self) -> None:
78+
...
79+
7980
def stop(self) -> None:
8081
self.loop.quit()
8182
logger.info("Service instance %s stopped", self.instance_id)
@@ -87,6 +88,7 @@ def run(self) -> None:
8788
logger.info("Service instance %s started", self.instance_id)
8889
self.signals.handle_task.connect(self.handle_task)
8990
self.loop = QEventLoop()
91+
self.init()
9092
self.loop.exec()
9193

9294

@@ -95,8 +97,6 @@ def run(self) -> None:
9597

9698

9799
def clean_dead_instance() -> bool:
98-
if not psutil:
99-
return False
100100
to_stop = []
101101
instance_dict_mutex.lock()
102102
for instance_id, instance in instance_dict.items():
@@ -238,8 +238,10 @@ def q_server_read_client(self) -> None:
238238
client_connection.flush()
239239
client_connection.disconnectFromServer()
240240
case "show":
241-
from view.main_window import main_window
242-
in_main_thread(main_window.show_window)
241+
def show_main_window() -> None:
242+
from view.main_window import main_window
243+
main_window.show_window()
244+
in_main_thread(show_main_window)
243245
client_connection.write(b"message_received")
244246
client_connection.flush()
245247
client_connection.disconnectFromServer()
@@ -337,7 +339,7 @@ def __init__(self, service: LDDCService, instance_id: int, json_data: dict, clie
337339
# 任务ID 用于防止旧任务的结果覆盖新任务的结果
338340
self.taskid = 0
339341

340-
def run(self) -> None:
342+
def init(self) -> None:
341343
# 初始化界面
342344
in_main_thread(self.init_widget)
343345
if "name" in self.client_info and "repo" in self.client_info and "ver" in self.client_info:
@@ -366,7 +368,6 @@ def run(self) -> None:
366368
self.widget.menu.action_unlink_lyrics.triggered.connect(self.unlink_lyrics)
367369

368370
cfg.desktop_lyrics_changed.connect(self.cfg_changed_slot)
369-
super().run()
370371

371372
def init_widget(self) -> None:
372373
"""初始化界面(主线程)"""
@@ -426,9 +427,8 @@ def handle_task(self, task: dict) -> None:
426427
case "start":
427428
# 开始播放
428429
logger.debug("start")
429-
playback_time = self.get_playback_time(task)
430-
if playback_time is not None:
431-
self.start_time = int(time.time() * 1000)
430+
if (playback_time := self.get_playback_time(task)) is not None:
431+
self.start_time = int(time.time() * 1000) - playback_time
432432
else:
433433
self.start_time = int(time.time() * 1000) - self.current_time
434434
if not self.timer.isActive():
@@ -458,6 +458,9 @@ def handle_task(self, task: dict) -> None:
458458
logger.error("task:chang_music, invalid data")
459459
return
460460

461+
if (playback_time := self.get_playback_time(task)) is not None:
462+
self.start_time = int(time.time() * 1000) - playback_time
463+
461464
self.song_info = {"title": title, "artist": artist, "album": album, "duration": duration, "song_path": song_path,
462465
"track_number": str(track) if isinstance(track, int) else track}
463466
# 先在关联数据库中查找
@@ -625,20 +628,20 @@ def set_inst(self) -> None:
625628
if self.song_info:
626629
self.config["inst"] = True
627630
self.widget.new_lyrics.emit({"inst": True})
628-
self.show_artist_title(QCoreApplication.translate("DesktopLyrics", "纯音乐,请欣赏"))
629-
self.unlink_lyrics()
631+
self.unlink_lyrics(QCoreApplication.translate("DesktopLyrics", "纯音乐,请欣赏"))
630632

631633
def set_auto_search(self, is_disable: bool | None = None) -> None:
632634
if self.song_info:
633635
self.config["disable_auto_search"] = is_disable if is_disable is not None else bool(not self.config.get("disable_auto_search"))
634636
self.update_db_data()
635637

636-
def unlink_lyrics(self) -> None:
638+
def unlink_lyrics(self, msg: str = "") -> None:
637639
if self.song_info:
638640
self.lyrics_path = None
639641
self.lyrics = None
640642
self.offseted_lyrics = None
641643
self.update_db_data()
644+
self.show_artist_title(msg)
642645

643646
def update_db_data(self) -> None:
644647
local_song_lyrics.set_song(**self.song_info, lyrics_path=self.lyrics_path, config={k: v for k, v in self.config.items()

0 commit comments

Comments
 (0)