Skip to content

Commit e00bdf5

Browse files
committed
🎈 perf: 优化流体背景及歌词效果
1 parent f683b58 commit e00bdf5

13 files changed

Lines changed: 318 additions & 489 deletions

File tree

auto-eslint.mjs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ export default {
5959
"isRef": true,
6060
"isShallow": true,
6161
"makeDestructurable": true,
62-
"manualResetRef": true,
6362
"markRaw": true,
6463
"nextTick": true,
6564
"onActivated": true,
@@ -97,11 +96,11 @@ export default {
9796
"refAutoReset": true,
9897
"refDebounced": true,
9998
"refDefault": true,
100-
"refManualReset": true,
10199
"refThrottled": true,
102100
"refWithControl": true,
103101
"resolveComponent": true,
104102
"resolveRef": true,
103+
"resolveUnref": true,
105104
"shallowReactive": true,
106105
"shallowReadonly": true,
107106
"shallowRef": true,

components.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ declare module 'vue' {
1515
ArtistList: typeof import('./src/components/List/ArtistList.vue')['default']
1616
AutoClose: typeof import('./src/components/Modal/AutoClose.vue')['default']
1717
Background: typeof import('./src/components/Other/background.vue')['default']
18+
BackgroundRender: typeof import('./src/components/Special/BackgroundRender.vue')['default']
1819
BatchList: typeof import('./src/components/Modal/BatchList.vue')['default']
1920
ChangeRate: typeof import('./src/components/Modal/ChangeRate.vue')['default']
2021
CloudMatch: typeof import('./src/components/Modal/CloudMatch.vue')['default']

electron/main/index.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { app, BrowserWindow } from "electron";
22
import { electronApp } from "@electron-toolkit/utils";
3-
import { release, type } from "os";
43
import { isMac } from "./utils/config";
54
import { initSingleLock } from "./utils/single-lock";
65
import { unregisterShortcuts } from "./shortcut";
@@ -40,8 +39,6 @@ class MainProcess {
4039
processLog.info("🚀 Main process startup");
4140
// 程序单例锁
4241
initSingleLock();
43-
// 禁用 Windows 7 的 GPU 加速功能
44-
if (release().startsWith("6.1") && type() == "Windows_NT") app.disableHardwareAcceleration();
4542
// 监听应用事件
4643
this.handleAppEvents();
4744
// Electron 初始化完成后

electron/main/ipc/ipc-file.ts

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { app, BrowserWindow, dialog, ipcMain, shell } from "electron";
2-
import { basename, isAbsolute, join, relative, resolve } from "path";
3-
import { access, readFile, stat, unlink, writeFile } from "fs/promises";
2+
import { basename, dirname, extname, isAbsolute, join, relative, resolve } from "path";
3+
import { access, readdir, readFile, stat, unlink, writeFile } from "fs/promises";
44
import { parseFile } from "music-metadata";
55
import { getFileID, getFileMD5, metaDataLyricsArrayToLrc } from "../utils/helper";
66
import { File, Picture, Id3v2Settings } from "node-taglib-sharp";
@@ -130,40 +130,61 @@ const initFileIpc = (): void => {
130130
"get-music-lyric",
131131
async (
132132
_,
133-
path: string,
133+
musicPath: string, // 参数名改为 musicPath 以示区分
134134
): Promise<{
135135
lyric: string;
136136
format: "lrc" | "ttml";
137137
}> => {
138138
try {
139-
const filePath = resolve(path).replace(/\\/g, "/");
140-
141-
// 尝试获取同名的歌词文件
142-
const filePathWithoutExt = filePath.replace(/\.[^.]+$/, "");
143-
for (const ext of ["ttml", "lrc"] as const) {
144-
const lyricPath = `${filePathWithoutExt}.${ext}`;
145-
const matches = await FastGlob(lyricPath, globOpt());
146-
ipcLog.info("lyric matches", matches);
147-
if (matches.length > 0) {
139+
// 获取文件基本信息
140+
const absPath = resolve(musicPath);
141+
const dir = dirname(absPath);
142+
const ext = extname(absPath);
143+
const baseName = basename(absPath, ext);
144+
// 读取目录下所有文件
145+
let files: string[] = [];
146+
try {
147+
files = await readdir(dir);
148+
} catch (error) {
149+
ipcLog.error("❌ Failed to read directory:", dir);
150+
throw error;
151+
}
152+
// 遍历优先级
153+
for (const format of ["lrc", "ttml"] as const) {
154+
// 构造期望目标文件名
155+
const targetNameLower = `${baseName}.${format}`.toLowerCase();
156+
// 在文件列表中查找是否存在匹配项(忽略大小写)
157+
const matchedFileName = files.find((file) => file.toLowerCase() === targetNameLower);
158+
if (matchedFileName) {
148159
try {
149-
const lyric = await readFile(matches[0], "utf-8");
150-
if (lyric && lyric !== "") return { lyric, format: ext };
160+
const lyricPath = join(dir, matchedFileName);
161+
const lyric = await readFile(lyricPath, "utf-8");
162+
// 若不为空
163+
if (lyric && lyric.trim() !== "") {
164+
ipcLog.info(`✅ Local lyric found (${format}): ${lyricPath}`);
165+
return { lyric, format };
166+
}
151167
} catch {
152-
/* empty */
168+
// 读取失败则尝试下一种格式
169+
continue;
153170
}
154171
}
155172
}
156-
157-
// 尝试获取元数据
158-
const { common } = await parseFile(filePath);
159-
const lyric = common?.lyrics?.[0]?.syncText;
160-
if (lyric && lyric.length > 0) {
161-
return { lyric: metaDataLyricsArrayToLrc(lyric), format: "lrc" };
173+
// 如果本地文件没找到,尝试读取内置元数据 (ID3 Tags)
174+
const { common } = await parseFile(absPath);
175+
const syncedLyric = common?.lyrics?.[0]?.syncText;
176+
if (syncedLyric && syncedLyric.length > 0) {
177+
return {
178+
lyric: metaDataLyricsArrayToLrc(syncedLyric),
179+
format: "lrc",
180+
};
162181
} else if (common?.lyrics?.[0]?.text) {
163-
return { lyric: common?.lyrics?.[0]?.text, format: "lrc" };
182+
return {
183+
lyric: common?.lyrics?.[0]?.text,
184+
format: "lrc",
185+
};
164186
}
165-
166-
// 没有歌词
187+
// 都没有找到
167188
return { lyric: "", format: "lrc" };
168189
} catch (error) {
169190
ipcLog.error("❌ Error fetching music lyric:", error);

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"build:linux": "npm run build && electron-builder --linux --config electron-builder.config.ts"
3434
},
3535
"dependencies": {
36-
"@applemusic-like-lyrics/core": "^0.1.3",
36+
"@applemusic-like-lyrics/core": "^0.2.0",
3737
"@applemusic-like-lyrics/lyric": "^0.3.0",
3838
"@applemusic-like-lyrics/vue": "^0.1.5",
3939
"@electron-toolkit/preload": "^3.0.2",

pnpm-lock.yaml

Lines changed: 42 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/Player/MainLyric.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
'content-text': true,
7676
'content-long':
7777
settingStore.showYrcLongEffect &&
78-
text.endTime - item.startTime >= 1500 &&
78+
text.endTime - text.startTime >= 1500 &&
7979
playSeek <= text.endTime,
8080
'end-with-space': text.word.endsWith(' ') || text.startTime === 0,
8181
}"
@@ -400,8 +400,8 @@ onBeforeUnmount(() => {
400400
top: 0;
401401
transform: none;
402402
will-change: -webkit-mask-position-x, transform, opacity;
403-
padding: 0.3em 0;
404-
margin: -0.3em 0;
403+
// padding: 0.3em 0;
404+
// margin: -0.3em 0;
405405
mask-image: linear-gradient(
406406
to right,
407407
rgb(0, 0, 0) 45.4545454545%,
@@ -420,7 +420,7 @@ onBeforeUnmount(() => {
420420
opacity 0.3s,
421421
filter 0.3s,
422422
margin 0.3s,
423-
padding 0.3s;
423+
padding 0.3s !important;
424424
}
425425
&.end-with-space {
426426
margin-right: 12px;

src/components/Player/PlayerBackground.vue

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,19 @@
1919
alt="cover"
2020
/>
2121
<!-- 流体效果 -->
22-
<FluidBackground
22+
<BackgroundRender
2323
v-else-if="settingStore.playerBackgroundType === 'animation'"
24-
:key="musicStore.songCover"
25-
:src="musicStore.songCover"
26-
:speed="0.8"
27-
:brightness="0.1"
24+
:album="musicStore.songCover"
25+
:fps="settingStore.playerBackgroundFps ?? 60"
26+
:flowSpeed="settingStore.playerBackgroundFlowSpeed ?? 4"
2827
/>
2928
</Transition>
3029
</div>
3130
</template>
3231

3332
<script setup lang="ts">
3433
import { useMusicStore, useSettingStore, useStatusStore } from "@/stores";
34+
import BackgroundRender from "../Special/BackgroundRender.vue";
3535
3636
const musicStore = useMusicStore();
3737
const statusStore = useStatusStore();

src/components/Setting/PlaySetting.vue

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,36 @@
155155
class="set"
156156
/>
157157
</n-card>
158+
<n-collapse-transition :show="settingStore.playerBackgroundType === 'animation'">
159+
<n-card class="set-item">
160+
<div class="label">
161+
<n-text class="name">背景动画帧率</n-text>
162+
<n-text class="tip" :depth="3">单位 fps,最小 24,最大 240</n-text>
163+
</div>
164+
<n-input-number
165+
v-model:value="settingStore.playerBackgroundFps"
166+
:min="24"
167+
:max="256"
168+
:show-button="false"
169+
class="set"
170+
placeholder="请输入背景动画帧率"
171+
/>
172+
</n-card>
173+
<n-card class="set-item">
174+
<div class="label">
175+
<n-text class="name">背景动画流动速度</n-text>
176+
<n-text class="tip" :depth="3">单位 倍数,最小 0.1,最大 10</n-text>
177+
</div>
178+
<n-input-number
179+
v-model:value="settingStore.playerBackgroundFlowSpeed"
180+
:min="0.1"
181+
:max="10"
182+
:show-button="false"
183+
class="set"
184+
placeholder="请输入背景动画流动速度"
185+
/>
186+
</n-card>
187+
</n-collapse-transition>
158188
<n-card class="set-item">
159189
<div class="label">
160190
<n-text class="name">全屏播放器留存</n-text>

0 commit comments

Comments
 (0)