Skip to content

Commit 2268036

Browse files
authored
Merge pull request #1025 from MoYingJi/pr/up-amll
chore(deps): 升级 AMLL 有关的依赖
2 parents bea6f8f + a9355d0 commit 2268036

10 files changed

Lines changed: 82 additions & 96 deletions

File tree

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@
3939
"docs:preview": "vitepress preview docs"
4040
},
4141
"dependencies": {
42-
"@applemusic-like-lyrics/core": "^0.2.0",
43-
"@applemusic-like-lyrics/lyric": "^0.3.0",
42+
"@applemusic-like-lyrics/core": "^0.3.2",
43+
"@applemusic-like-lyrics/lyric": "^0.4.1",
4444
"@electron-toolkit/preload": "^3.0.2",
4545
"@electron-toolkit/utils": "^4.0.0",
4646
"@imsyy/color-utils": "^1.0.2",

pnpm-lock.yaml

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

src/components/AMLL/LyricPlayer.vue

Lines changed: 34 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -118,15 +118,6 @@ const props = defineProps({
118118
type: Number,
119119
default: 0.5,
120120
},
121-
/**
122-
* 设置所有歌词行在横坐标上的弹簧属性,包括重量、弹力和阻力。
123-
*
124-
* @param params 需要设置的弹簧属性,提供的属性将会覆盖原来的属性,未提供的属性将会保持原样
125-
*/
126-
linePosXSpringParams: {
127-
type: Object as PropType<Partial<spring.SpringParams>>,
128-
required: false,
129-
},
130121
/**
131122
* 设置所有歌词行在​纵坐标上的弹簧属性,包括重量、弹力和阻力。
132123
*
@@ -177,6 +168,30 @@ export interface LyricPlayerRef {
177168
* 将歌词播放实例的元素包裹起来的 DIV 元素实例
178169
*/
179170
wrapperEl: Readonly<ShallowRef<HTMLDivElement | null>>;
171+
/**
172+
* 设置当前播放进度
173+
*/
174+
setCurrentTime: (time: number, isSeek?: boolean) => void;
175+
/**
176+
* 获取当前 Player 内部使用的歌词行元素
177+
*/
178+
get currentLyricLineObjects(): LyricLineObject[] | undefined;
179+
}
180+
181+
/**
182+
* DomLyricPlayer 内部使用的歌词行元素(被称为 LyricLineEl)
183+
*
184+
* 用来进行一些神秘的 Hook(如根据歌词行内容设置语言属性)
185+
*/
186+
interface LyricLineObject {
187+
/**
188+
* 歌词行
189+
*/
190+
lyricLine: LyricLine;
191+
/**
192+
* 歌词行的 HTML 元素
193+
*/
194+
element: HTMLElement;
180195
}
181196
182197
// 模板引用
@@ -284,55 +299,13 @@ watchEffect(() => {
284299
});
285300
286301
// 当前播放时间
287-
watch(
288-
() => props.currentTime,
289-
(time, oldTime) => {
290-
if (time === undefined) return;
291-
const isSeek = oldTime !== undefined && Math.abs(time - oldTime) > 1000;
292-
293-
if (isSeek) {
294-
// 针对 v0.2.0 版本的临时修复:手动处理跳转逻辑
295-
// 因为 npm 版本的 Core 存在 seek 逻辑缺失,这里手动重置滚动状态
296-
const player = playerRef.value as any;
297-
if (player) {
298-
player.setCurrentTime(time, true);
299-
300-
// 强制重置缓冲行和滚动位置
301-
if (player.bufferedLines && player.hotLines && player.processedLines) {
302-
player.bufferedLines.clear();
303-
for (const v of player.hotLines) {
304-
player.bufferedLines.add(v);
305-
}
306-
307-
if (player.bufferedLines.size > 0) {
308-
player.scrollToIndex = Math.min(...player.bufferedLines);
309-
} else {
310-
const foundIndex = player.processedLines.findIndex(
311-
(line: any) => line.startTime >= time,
312-
);
313-
player.scrollToIndex = foundIndex === -1 ? player.processedLines.length : foundIndex;
314-
}
315-
316-
player.resetScroll?.();
317-
player.calcLayout?.();
318-
}
319-
}
320-
} else {
321-
playerRef.value?.setCurrentTime(time, false);
322-
}
323-
},
324-
{ immediate: true },
325-
);
326-
327-
// 渐变宽度
328302
watchEffect(() => {
329-
if (props.wordFadeWidth !== undefined) playerRef.value?.setWordFadeWidth(props.wordFadeWidth);
303+
if (props.currentTime !== undefined) playerRef.value?.setCurrentTime(props.currentTime);
330304
});
331305
332-
// X 轴弹簧参数
306+
// 渐变宽度
333307
watchEffect(() => {
334-
if (props.linePosXSpringParams !== undefined)
335-
playerRef.value?.setLinePosXSpringParams(props.linePosXSpringParams);
308+
if (props.wordFadeWidth !== undefined) playerRef.value?.setWordFadeWidth(props.wordFadeWidth);
336309
});
337310
338311
// Y 轴弹簧参数
@@ -351,6 +324,13 @@ watchEffect(() => {
351324
defineExpose<LyricPlayerRef>({
352325
lyricPlayer: playerRef,
353326
wrapperEl: wrapperRef,
327+
328+
setCurrentTime: (time: number, isSeek?: boolean) => {
329+
playerRef.value?.setCurrentTime(time, isSeek);
330+
},
331+
get currentLyricLineObjects() {
332+
return playerRef.value?.currentLyricLineObjects as LyricLineObject[] | undefined;
333+
},
354334
});
355335
</script>
356336

src/components/Player/PlayerLyric/AMLyric.vue

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656

5757
<script setup lang="ts">
5858
import { LyricLineMouseEvent, type LyricLine } from "@applemusic-like-lyrics/core";
59+
import { type LyricPlayerRef } from "@/components/AMLL/LyricPlayer.vue";
5960
import { useMusicStore, useSettingStore, useStatusStore } from "@/stores";
6061
import { getLyricLanguage } from "@/utils/format";
6162
import { usePlayerController } from "@/core/player/PlayerController";
@@ -75,7 +76,7 @@ const statusStore = useStatusStore();
7576
const settingStore = useSettingStore();
7677
const player = usePlayerController();
7778
78-
const lyricPlayerRef = ref<any | null>(null);
79+
const lyricPlayerRef = ref<LyricPlayerRef | null>(null);
7980
8081
// 当前歌词
8182
const amLyricsData = computed(() => {
@@ -94,7 +95,7 @@ const amLyricsData = computed(() => {
9495
// 处理显隐
9596
if (!showTran) line.translatedLyric = "";
9697
if (!showRoma) line.romanLyric = "";
97-
if (!showWordsRoma) line.words?.forEach((word) => (word.romanWord = ""));
98+
if (!showWordsRoma) line.words?.forEach((word) => delete word.romanWord);
9899
// 调换翻译与音译位置
99100
if (swapTranRoma) {
100101
const temp = line.translatedLyric;
@@ -115,29 +116,44 @@ const hasDuet = computed(() => amLyricsData.value?.some((line) => line.isDuet) ?
115116
// 进度跳转
116117
const jumpSeek = (line: LyricLineMouseEvent) => {
117118
const lineContent = line.line.getLine();
118-
if (!lineContent?.startTime) return;
119-
const time = lineContent.startTime;
119+
const lyricTargetTime = lineContent?.startTime;
120+
if (
121+
typeof lyricTargetTime !== "number" ||
122+
!Number.isFinite(lyricTargetTime) ||
123+
lyricTargetTime < 0
124+
) {
125+
return;
126+
}
127+
// 让 LyricPlayer 跳转到目标时间,第二个参数 isSeek = true 会重置滚动状态
128+
lyricPlayerRef.value?.setCurrentTime(lyricTargetTime, true);
129+
// 获取偏移时间,计算歌曲真实的目标时间,并跳转
120130
const offsetMs = statusStore.getSongOffset(musicStore.playSong?.id);
121-
player.setSeek(time - offsetMs);
131+
const musicTargetTime = lyricTargetTime - offsetMs;
132+
player.setSeek(musicTargetTime);
122133
player.play();
123134
};
124135
125136
// 处理歌词语言
126137
const processLyricLanguage = (player = lyricPlayerRef.value) => {
127-
const lyricLineObjects = player?.lyricPlayer?.currentLyricLineObjects;
138+
const lyricLineObjects = player?.currentLyricLineObjects;
128139
if (!Array.isArray(lyricLineObjects) || lyricLineObjects.length === 0) {
129140
return;
130141
}
131142
// 遍历歌词行
132143
for (let e of lyricLineObjects) {
133144
// 获取歌词行内容 (合并逐字歌词为一句)
134-
const content = e.lyricLine.words.map((word: any) => word.word).join("");
145+
const content = e.lyricLine.words.map((word) => word.word).join("");
135146
// 跳过空行
136147
if (!content) continue;
137148
// 获取歌词语言
138149
const lang = getLyricLanguage(content);
139150
// 为主歌词设置 lang 属性 (firstChild 获取主歌词 不为翻译和音译设置属性)
140-
e.element.firstChild.setAttribute("lang", lang);
151+
const lyricMainLineElement = e.element?.firstChild;
152+
if (lyricMainLineElement instanceof HTMLElement) {
153+
lyricMainLineElement.setAttribute("lang", lang);
154+
} else {
155+
console.warn("无法获取歌词行元素的主歌词部分,无法设置 lang 属性", e.element);
156+
}
141157
}
142158
};
143159

src/core/player/LyricManager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,7 @@ class LyricManager {
721721
word: line.words?.map((w) => w.word)?.join("") || "",
722722
startTime: line.startTime || 0,
723723
endTime: line.endTime || 0,
724-
romanWord: line.words?.map((w) => w.romanWord)?.join("") || "",
724+
romanWord: line.words?.map((w) => w.romanWord)?.join("") || undefined,
725725
},
726726
],
727727
}));

src/stores/status.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,8 @@ export const useStatusStore = defineStore("status", {
316316
},
317317
/**
318318
* 获取指定歌曲的偏移
319-
* 单位:毫秒
319+
* @param songId 歌曲 id
320+
* @returns 歌曲的偏移量(单位:毫秒,正值为歌词提前),默认为 0
320321
*/
321322
getSongOffset(songId?: number): number {
322323
if (!songId) return 0;
@@ -326,7 +327,7 @@ export const useStatusStore = defineStore("status", {
326327
/**
327328
* 设置指定歌曲的偏移
328329
* @param songId 歌曲 id
329-
* @param offset 偏移量(单位:毫秒)
330+
* @param offset 偏移量(单位:毫秒,正值为歌词提前
330331
*/
331332
setSongOffset(songId?: number, offset: number = 0) {
332333
if (!songId) return;
@@ -344,7 +345,7 @@ export const useStatusStore = defineStore("status", {
344345
/**
345346
* 调整指定歌曲的偏移(增量)
346347
* @param songId 歌曲 id
347-
* @param delta 偏移增量(单位:毫秒,默认 500ms)
348+
* @param delta 偏移增量(单位:毫秒,默认 500ms,正值为歌词提前
348349
*/
349350
incSongOffset(songId?: number, delta: number = 500) {
350351
if (!songId) return;

src/utils/lyric/lyricParser.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { LyricLine } from "@applemusic-like-lyrics/lyric";
1+
import type { LyricLine, LyricWord } from "@applemusic-like-lyrics/lyric";
22
import { cloneDeep } from "lodash-es";
33
import { parseLrc } from "./parseLrc";
44
import { extractLyricContent } from "./parseQrc";
@@ -15,9 +15,6 @@ export enum LrcFormat {
1515
Enhanced = "enhanced",
1616
}
1717

18-
/** LyricWord 类型 */
19-
type LyricWord = { word: string; startTime: number; endTime: number; romanWord: string };
20-
2118
// 预编译正则表达式
2219
const META_TAG_REGEX = /^\[[a-z]+:/i;
2320
const TIME_TAG_REGEX = /\[(\d{2}):(\d{2})\.(\d{1,})\]/g;
@@ -52,7 +49,6 @@ const createWord = (word: string, startTime: number, endTime: number = startTime
5249
word,
5350
startTime,
5451
endTime,
55-
romanWord: "",
5652
});
5753

5854
/**
@@ -465,10 +461,7 @@ export const parseQRCLyric = (qrcContent: string, trans?: string, roma?: string)
465461
const qrcLines = parseQRCContent(qrcContent);
466462
let result: LyricLine[] = qrcLines.map((qrcLine) => {
467463
return {
468-
words: qrcLine.words.map((word) => ({
469-
...word,
470-
romanWord: "",
471-
})),
464+
words: qrcLine.words,
472465
startTime: qrcLine.startTime,
473466
endTime: qrcLine.endTime,
474467
translatedLyric: "",
@@ -502,7 +495,6 @@ export const parseQRCLyric = (qrcContent: string, trans?: string, roma?: string)
502495
startTime: line.startTime,
503496
endTime: line.endTime,
504497
word: line.words.map((w) => w.word).join(""),
505-
romanWord: "",
506498
},
507499
],
508500
startTime: line.startTime,

src/utils/lyric/parseLrc.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,5 +117,4 @@ const newLyricWord = (): LyricWord => ({
117117
startTime: 0,
118118
endTime: 0,
119119
word: "",
120-
romanWord: "",
121120
});

src/utils/lyric/parseTTML.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ const createWord = (word: string, startTime: number, endTime: number): LyricWord
8888
word,
8989
startTime,
9090
endTime,
91-
romanWord: "",
9291
});
9392

9493
/**

0 commit comments

Comments
 (0)