Skip to content

Commit 772f655

Browse files
committed
🦄 refactor: 基础适配新格式
1 parent c9f3553 commit 772f655

12 files changed

Lines changed: 900 additions & 827 deletions

File tree

components.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,11 @@ declare module 'vue' {
100100
NP: typeof import('naive-ui')['NP']
101101
NPopconfirm: typeof import('naive-ui')['NPopconfirm']
102102
NPopover: typeof import('naive-ui')['NPopover']
103+
NProgress: typeof import('naive-ui')['NProgress']
103104
NQrCode: typeof import('naive-ui')['NQrCode']
104105
NRadio: typeof import('naive-ui')['NRadio']
105106
NRadioGroup: typeof import('naive-ui')['NRadioGroup']
107+
NResult: typeof import('naive-ui')['NResult']
106108
NScrollbar: typeof import('naive-ui')['NScrollbar']
107109
NSelect: typeof import('naive-ui')['NSelect']
108110
NSkeleton: typeof import('naive-ui')['NSkeleton']

src/components/Player/FullPlayer.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
'player-content',
3232
{
3333
pure: statusStore.pureLyricMode && musicStore.isHasLrc,
34-
'no-lrc': !musicStore.isHasLrc,
34+
'no-lrc': !musicStore.isHasLrc || (!musicStore.isHasLrc && !statusStore.lyricLoading),
3535
},
3636
]"
3737
@mousemove="playerMove"
@@ -114,7 +114,8 @@ const instantLyrics = computed(() => {
114114
const content = isYrc
115115
? musicStore.songLyric.yrcData[statusStore.lyricIndex]
116116
: musicStore.songLyric.lrcData[statusStore.lyricIndex];
117-
return { content: content?.content, tran: settingStore.showTran && content?.tran };
117+
const contentStr = content?.words?.map((v) => v.word).join("") || "";
118+
return { content: contentStr, tran: settingStore.showTran && content?.translatedLyric };
118119
});
119120
120121
// 隐藏播放元素

src/components/Player/MainAMLyric.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ const amLyricsData = computed<LyricLine[]>(() => {
7272
if (!songLyric) return [];
7373
7474
// 优先使用逐字歌词(YRC/TTML)
75-
const useYrc = songLyric.yrcAMData?.length && settingStore.showYrc;
76-
const lyrics = useYrc ? songLyric.yrcAMData : songLyric.lrcAMData;
75+
const useYrc = songLyric.yrcData?.length && settingStore.showYrc;
76+
const lyrics = useYrc ? songLyric.yrcData : songLyric.lrcData;
7777
7878
// 简单检查歌词有效性
7979
if (!Array.isArray(lyrics) || lyrics.length === 0) return [];

src/components/Player/MainLyric.vue

Lines changed: 54 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
>
2222
<Transition name="fade" mode="out-in">
2323
<div
24-
:key="musicStore.songLyric.lrcData?.[0]?.content"
24+
:key="musicStore.songLyric.lrcData?.[0]?.words?.[0]?.word"
2525
class="lyric-content"
2626
@after-enter="lyricsScroll(statusStore.lyricIndex)"
2727
@after-leave="lyricsScroll(statusStore.lyricIndex)"
@@ -34,7 +34,7 @@
3434
<!-- 倒计时 -->
3535
<CountDown
3636
:start="0"
37-
:duration="musicStore.songLyric.yrcData[0].time || 0"
37+
:duration="(musicStore.songLyric.yrcData[0].startTime || 0) / 1000"
3838
:seek="playSeek"
3939
:playing="statusStore.playStatus"
4040
/>
@@ -50,68 +50,73 @@
5050
// on: statusStore.lyricIndex === index,
5151
// 当播放时间大于等于当前歌词的开始时间
5252
on:
53-
(playSeek >= item.time && playSeek < item.endTime) ||
53+
(playSeek >= item.startTime / 1000 && playSeek < item.endTime / 1000) ||
5454
statusStore.lyricIndex === index,
5555
'is-bg': item.isBG,
5656
'is-duet': item.isDuet,
5757
},
5858
]"
5959
:style="{
6060
filter: settingStore.lyricsBlur
61-
? (playSeek >= item.time && playSeek < item.endTime) ||
61+
? (playSeek >= item.startTime / 1000 && playSeek < item.endTime / 1000) ||
6262
statusStore.lyricIndex === index
6363
? 'blur(0)'
6464
: `blur(${Math.min(Math.abs(statusStore.lyricIndex - index) * 1.8, 10)}px)`
6565
: 'blur(0)',
6666
}"
67-
@click="jumpSeek(item.time)"
67+
@click="jumpSeek(item.startTime)"
6868
>
6969
<!-- 歌词 -->
7070
<div class="content">
7171
<div
72-
v-for="(text, textIndex) in item.contents"
72+
v-for="(text, textIndex) in item.words"
7373
:key="textIndex"
7474
:class="{
7575
'content-text': true,
7676
'content-long':
7777
settingStore.showYrcLongEffect &&
78-
text.duration >= 1.5 &&
79-
playSeek <= text.endTime,
80-
'end-with-space': text.endsWithSpace,
78+
(text.endTime - item.startTime) / 1000 >= 1.5 &&
79+
playSeek <= text.endTime / 1000,
80+
'end-with-space': text.word.endsWith(' ') || text.startTime === 0,
8181
}"
8282
>
83-
<span class="word" :lang="getLyricLanguage(text.content)">
84-
{{ text.content }}
83+
<span class="word" :lang="getLyricLanguage(text.word)">
84+
{{ text.word }}
8585
</span>
8686
<span
8787
class="filler"
8888
:style="getYrcStyle(text, index)"
89-
:lang="getLyricLanguage(text.content)"
89+
:lang="getLyricLanguage(text.word)"
9090
>
91-
{{ text.content }}
91+
{{ text.word }}
9292
</span>
9393
</div>
9494
</div>
9595
<!-- 翻译 -->
96-
<span v-if="item.tran && settingStore.showTran" class="tran" lang="en">
97-
{{ item.tran }}
96+
<span v-if="item.translatedLyric && settingStore.showTran" class="tran" lang="en">
97+
{{ item.translatedLyric }}
9898
</span>
9999
<!-- 音译 -->
100-
<span v-if="item.roma && settingStore.showRoma" class="roma" lang="en">
101-
{{ item.roma }}
100+
<span v-if="item.romanLyric && settingStore.showRoma" class="roma" lang="en">
101+
{{ item.romanLyric }}
102102
</span>
103103
<!-- 间奏倒计时 -->
104104
<div
105105
v-if="
106106
settingStore.countDownShow &&
107-
item.time > 0 &&
108-
musicStore.songLyric.yrcData[index + 1]?.time - item.endTime >= 10
107+
item.startTime > 0 &&
108+
((musicStore.songLyric.yrcData[index + 1]?.startTime || 0) - item.endTime) /
109+
1000 >=
110+
10
109111
"
110112
class="count-down-content"
111113
>
112114
<CountDown
113-
:start="item.endTime"
114-
:duration="musicStore.songLyric.yrcData[index + 1]?.time - item.endTime || 0"
115+
:start="item.endTime / 1000"
116+
:duration="
117+
((musicStore.songLyric.yrcData[index + 1]?.startTime || 0) - item.endTime) /
118+
1000
119+
"
115120
:seek="playSeek"
116121
:playing="statusStore.playStatus"
117122
/>
@@ -125,7 +130,7 @@
125130
<!-- 倒计时 -->
126131
<CountDown
127132
:start="0"
128-
:duration="musicStore.songLyric.lrcData[0].time || 0"
133+
:duration="(musicStore.songLyric.lrcData[0].startTime || 0) / 1000"
129134
:seek="playSeek"
130135
:playing="statusStore.playStatus"
131136
/>
@@ -140,17 +145,19 @@
140145
? `blur(${Math.min(Math.abs(statusStore.lyricIndex - index) * 1.8, 10)}px)`
141146
: 'blur(0)',
142147
}"
143-
@click="jumpSeek(item.time)"
148+
@click="jumpSeek(item.startTime)"
144149
>
145150
<!-- 歌词 -->
146-
<span class="content" :lang="getLyricLanguage(item.content)">{{ item.content }}</span>
151+
<span class="content" :lang="getLyricLanguage(item.words?.[0]?.word)">
152+
{{ item.words?.[0]?.word }}
153+
</span>
147154
<!-- 翻译 -->
148-
<span v-if="item.tran && settingStore.showTran" class="tran" lang="en">
149-
{{ item.tran }}
155+
<span v-if="item.translatedLyric && settingStore.showTran" class="tran" lang="en">
156+
{{ item.translatedLyric }}
150157
</span>
151158
<!-- 音译 -->
152-
<span v-if="item.roma && settingStore.showRoma" class="roma" lang="en">
153-
{{ item.roma }}
159+
<span v-if="item.romanLyric && settingStore.showRoma" class="roma" lang="en">
160+
{{ item.romanLyric }}
154161
</span>
155162
</div>
156163
<div class="placeholder" />
@@ -164,7 +171,8 @@
164171
</template>
165172

166173
<script setup lang="ts">
167-
import type { LyricContentType } from "@/types/main";
174+
// import type { LyricContentType } from "@/types/main";
175+
import { LyricWord } from "@applemusic-like-lyrics/lyric";
168176
import { NScrollbar } from "naive-ui";
169177
import { useMusicStore, useSettingStore, useStatusStore } from "@/stores";
170178
import player from "@/utils/player";
@@ -222,22 +230,22 @@ const INACTIVE_NO_ANIMATION_STYLE = { opacity: 0 } as const;
222230
* @param lyricIndex 歌词索引
223231
* @returns 逐字歌词动画样式
224232
*/
225-
const getYrcStyle = (wordData: LyricContentType, lyricIndex: number) => {
233+
const getYrcStyle = (wordData: LyricWord, lyricIndex: number) => {
226234
// 获取当前歌词行数据
227235
const currentLine = musicStore.songLyric.yrcData[lyricIndex];
228236
// 缓存 playSeek 值,避免多次访问响应式变量
229237
const currentSeek = playSeek.value;
230238
231239
// 判断当前行是否处于激活状态
232240
const isLineActive =
233-
(currentSeek >= currentLine.time && currentSeek < currentLine.endTime) ||
241+
(currentSeek >= currentLine.startTime / 1000 && currentSeek < currentLine.endTime / 1000) ||
234242
statusStore.lyricIndex === lyricIndex;
235243
236244
// 如果当前歌词行不是激活状态,返回固定样式,避免不必要的计算
237245
if (!isLineActive) {
238246
if (settingStore.showYrcAnimation) {
239247
// 判断单词是否已经唱过:已唱过保持填充状态(0%),未唱到保持未填充状态(100%)
240-
const hasPlayed = currentSeek >= wordData.time + wordData.duration;
248+
const hasPlayed = currentSeek >= wordData.endTime / 1000;
241249
return {
242250
WebkitMaskPositionX: hasPlayed ? "0%" : "100%",
243251
};
@@ -249,24 +257,30 @@ const getYrcStyle = (wordData: LyricContentType, lyricIndex: number) => {
249257
// 激活状态的样式计算
250258
if (settingStore.showYrcAnimation) {
251259
// 如果播放状态不是加载中,且当前单词的时间加上持续时间减去播放进度大于 0
252-
if (statusStore.playLoading === false && wordData.time + wordData.duration - currentSeek > 0) {
260+
if (statusStore.playLoading === false && wordData.endTime / 1000 - currentSeek > 0) {
253261
return {
254262
transitionDuration: `0s, 0s, 0.35s`,
255263
transitionDelay: `0ms`,
256264
WebkitMaskPositionX: `${
257-
100 - Math.max(((currentSeek - wordData.time) / wordData.duration) * 100, 0)
265+
100 -
266+
Math.max(
267+
((currentSeek - wordData.startTime / 1000) /
268+
((wordData.endTime - wordData.startTime) / 1000)) *
269+
100,
270+
0,
271+
)
258272
}%`,
259273
};
260274
}
261275
// 预计算时间差,避免重复计算
262-
const timeDiff = wordData.time - currentSeek;
276+
const timeDiff = wordData.startTime - currentSeek * 1000;
263277
return {
264-
transitionDuration: `${wordData.duration}ms, ${wordData.duration * 0.8}ms, 0.35s`,
265-
transitionDelay: `${timeDiff}ms, ${timeDiff + wordData.duration * 0.5}ms, 0ms`,
278+
transitionDuration: `${wordData.endTime - wordData.startTime}ms, ${(wordData.endTime - wordData.startTime) * 0.8}ms, 0.35s`,
279+
transitionDelay: `${timeDiff}ms, ${timeDiff + (wordData.endTime - wordData.startTime) * 0.5}ms, 0ms`,
266280
};
267281
} else {
268282
// 无动画模式:根据单词时间判断透明度
269-
return statusStore.playLoading === false && wordData.time >= currentSeek
283+
return statusStore.playLoading === false && wordData.startTime / 1000 >= currentSeek
270284
? { opacity: 0 }
271285
: { opacity: 1 };
272286
}
@@ -277,7 +291,7 @@ const jumpSeek = (time: number) => {
277291
if (!time) return;
278292
lrcMouseStatus.value = false;
279293
const offsetSeconds = statusStore.getSongOffset(musicStore.playSong?.id);
280-
player.setSeek(time - offsetSeconds);
294+
player.setSeek(time / 1000 - offsetSeconds);
281295
player.play();
282296
};
283297
@@ -411,7 +425,7 @@ onBeforeUnmount(() => {
411425
opacity 0.3s,
412426
filter 0.3s,
413427
margin 0.3s,
414-
padding 0.3s !important;
428+
padding 0.3s;
415429
}
416430
&.end-with-space {
417431
margin-right: 12px;

src/components/Player/MainPlayer.vue

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -275,9 +275,10 @@ const instantLyrics = computed(() => {
275275
const content = isYrc
276276
? musicStore.songLyric.yrcData[statusStore.lyricIndex]
277277
: musicStore.songLyric.lrcData[statusStore.lyricIndex];
278-
return content?.tran && settingStore.showTran
279-
? `${content?.content}( ${content?.tran} )`
280-
: content?.content;
278+
const contentStr = content?.words?.map((v) => v.word).join("") || "";
279+
return content?.translatedLyric && settingStore.showTran
280+
? `${contentStr}( ${content?.translatedLyric} )`
281+
: contentStr || "";
281282
});
282283
</script>
283284

src/stores/music.ts

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
11
import { defineStore } from "pinia";
2-
import type { LyricLine } from "@applemusic-like-lyrics/core";
3-
import type { SongType, LyricType } from "@/types/main";
2+
import type { SongType } from "@/types/main";
43
import { isElectron } from "@/utils/env";
54
import { cloneDeep } from "lodash-es";
5+
import { SongLyric } from "@/types/lyric";
66

77
interface MusicState {
88
playSong: SongType;
99
playPlaylistId: number;
10-
songLyric: {
11-
lrcData: LyricType[];
12-
yrcData: LyricType[];
13-
lrcAMData: LyricLine[];
14-
yrcAMData: LyricLine[];
15-
};
10+
songLyric: SongLyric;
1611
personalFM: {
1712
playIndex: number;
1813
list: SongType[];
@@ -46,8 +41,6 @@ export const useMusicStore = defineStore("music", {
4641
songLyric: {
4742
lrcData: [], // 普通歌词
4843
yrcData: [], // 逐字歌词
49-
lrcAMData: [], // 普通歌词-AM
50-
yrcAMData: [], // 逐字歌词-AM
5144
},
5245
// 私人FM数据
5346
personalFM: {
@@ -88,32 +81,23 @@ export const useMusicStore = defineStore("music", {
8881
// 恢复默认音乐数据
8982
resetMusicData() {
9083
this.playSong = { ...defaultMusicData };
91-
this.songLyric = {
92-
lrcData: [],
93-
yrcData: [],
94-
lrcAMData: [],
95-
yrcAMData: [],
96-
};
84+
this.songLyric = { lrcData: [], yrcData: [] };
9785
},
9886
/**
9987
* 设置/更新歌曲歌词数据
10088
* @param updates 部分或完整歌词数据
10189
* @param replace 是否覆盖(true:用提供的数据覆盖并为缺省字段置空;false:合并更新)
10290
*/
103-
setSongLyric(updates: Partial<MusicState["songLyric"]>, replace: boolean = false) {
91+
setSongLyric(updates: Partial<SongLyric>, replace: boolean = false) {
10492
if (replace) {
10593
this.songLyric = {
10694
lrcData: updates.lrcData ?? [],
10795
yrcData: updates.yrcData ?? [],
108-
lrcAMData: updates.lrcAMData ?? [],
109-
yrcAMData: updates.yrcAMData ?? [],
11096
};
11197
} else {
11298
this.songLyric = {
11399
lrcData: updates.lrcData ?? this.songLyric.lrcData,
114100
yrcData: updates.yrcData ?? this.songLyric.yrcData,
115-
lrcAMData: updates.lrcAMData ?? this.songLyric.lrcAMData,
116-
yrcAMData: updates.yrcAMData ?? this.songLyric.yrcAMData,
117101
};
118102
}
119103
// 更新歌词窗口数据

src/types/desktop-lyric.d.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { LyricType } from "@/types/main";
1+
import { type LyricLine } from "@applemusic-like-lyrics/lyric";
22

33
/** 桌面歌词数据 */
44
export interface LyricData {
@@ -13,8 +13,8 @@ export interface LyricData {
1313
/** 当前歌曲的时间偏移(秒,正负均可) */
1414
songOffset?: number;
1515
/** 歌词数据 */
16-
lrcData?: LyricType[];
17-
yrcData?: LyricType[];
16+
lrcData?: LyricLine[];
17+
yrcData?: LyricLine[];
1818
/** 歌词播放索引 */
1919
lyricIndex?: number;
2020
}
@@ -52,7 +52,7 @@ export interface LyricConfig {
5252
*/
5353
export interface RenderLine {
5454
/** 当前整行歌词数据(用于逐字渲染) */
55-
line: LyricType;
55+
line: LyricLine;
5656
/** 当前行在歌词数组中的索引 */
5757
index: number;
5858
/** 唯一键 */

0 commit comments

Comments
 (0)