mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-07-10 11:57:35 +08:00
refactor(download): 重构下载系统,支持暂停/恢复/取消,修复歌词加载
- 新建 DownloadManager 类(主进程),每个任务独立 AbortController 控制 - 新建 Pinia useDownloadStore 作为渲染进程单一数据源 - 支持暂停/恢复/取消下载,支持断点续传(Range header) - 批量下载全部完成后发送汇总系统通知,单首不重复通知 - 并发数可配置(1-5),队列持久化(重启后恢复) - 修复下载列表不全、封面加载失败、通知重复等 bug - 修复本地/下载歌曲歌词加载:优先从 ID3/FLAC 元数据提取,API 作为 fallback - 删除 useDownloadStatus.ts,统一状态管理 - DownloadDrawer/DownloadPage 全面重写,移除 @apply 违规 - 新增 5 语言 i18n 键值(暂停/恢复/取消/排队中等)
This commit is contained in:
@@ -188,10 +188,10 @@ const setupMusicWatchers = () => {
|
||||
if (playMusic.value.lyric && typeof playMusic.value.lyric === 'object') {
|
||||
playMusic.value.lyric.hasWordByWord = hasWordByWord;
|
||||
}
|
||||
} else {
|
||||
} else if (lyricData && typeof lyricData === 'object' && lyricData.lrcArray?.length > 0) {
|
||||
// 使用现有的歌词数据结构
|
||||
const rawLrc = lyricData?.lrcArray || [];
|
||||
lrcTimeArray.value = lyricData?.lrcTimeArray || [];
|
||||
const rawLrc = lyricData.lrcArray || [];
|
||||
lrcTimeArray.value = lyricData.lrcTimeArray || [];
|
||||
|
||||
try {
|
||||
const { translateLyrics } = await import('@/services/lyricTranslation');
|
||||
@@ -200,6 +200,53 @@ const setupMusicWatchers = () => {
|
||||
console.error('翻译歌词失败,使用原始歌词:', e);
|
||||
lrcArray.value = rawLrc as any;
|
||||
}
|
||||
} else if (isElectron && playMusic.value.playMusicUrl?.startsWith('local:///')) {
|
||||
// 从下载/本地文件的 ID3/FLAC 元数据中提取嵌入歌词
|
||||
try {
|
||||
let filePath = decodeURIComponent(
|
||||
playMusic.value.playMusicUrl.replace('local:///', '')
|
||||
);
|
||||
// 处理 Windows 路径:/C:/... → C:/...
|
||||
if (/^\/[a-zA-Z]:\//.test(filePath)) {
|
||||
filePath = filePath.slice(1);
|
||||
}
|
||||
const embeddedLyrics = await window.api.getEmbeddedLyrics(filePath);
|
||||
if (embeddedLyrics) {
|
||||
const {
|
||||
lrcArray: parsedLrcArray,
|
||||
lrcTimeArray: parsedTimeArray,
|
||||
hasWordByWord
|
||||
} = await parseLyricsString(embeddedLyrics);
|
||||
lrcArray.value = parsedLrcArray;
|
||||
lrcTimeArray.value = parsedTimeArray;
|
||||
if (playMusic.value.lyric && typeof playMusic.value.lyric === 'object') {
|
||||
(playMusic.value.lyric as any).hasWordByWord = hasWordByWord;
|
||||
}
|
||||
} else {
|
||||
// 无嵌入歌词 — 若有数字 ID,尝试 API 兜底
|
||||
const songId = playMusic.value.id;
|
||||
if (songId && typeof songId === 'number') {
|
||||
try {
|
||||
const { getMusicLrc } = await import('@/api/music');
|
||||
const res = await getMusicLrc(songId);
|
||||
if (res?.data?.lrc?.lyric) {
|
||||
const { lrcArray: apiLrcArray, lrcTimeArray: apiTimeArray } =
|
||||
await parseLyricsString(res.data.lrc.lyric);
|
||||
lrcArray.value = apiLrcArray;
|
||||
lrcTimeArray.value = apiTimeArray;
|
||||
}
|
||||
} catch (apiErr) {
|
||||
console.error('API lyrics fallback failed:', apiErr);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to extract embedded lyrics:', err);
|
||||
}
|
||||
} else {
|
||||
// 无歌词数据
|
||||
lrcArray.value = [];
|
||||
lrcTimeArray.value = [];
|
||||
}
|
||||
// 当歌词数据更新时,如果歌词窗口打开,则发送数据
|
||||
if (isElectron && isLyricWindowOpen.value) {
|
||||
|
||||
Reference in New Issue
Block a user