mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-05-18 03:17:29 +08:00
✨ feat: 添加歌词缓存功能
This commit is contained in:
@@ -103,6 +103,7 @@ module.exports = {
|
|||||||
{
|
{
|
||||||
files: ['*.ts', '*.tsx'],
|
files: ['*.ts', '*.tsx'],
|
||||||
rules: {
|
rules: {
|
||||||
|
'max-classes-per-file': 'off',
|
||||||
'no-await-in-loop': 'off',
|
'no-await-in-loop': 'off',
|
||||||
'dot-notation': 'off',
|
'dot-notation': 'off',
|
||||||
'constructor-super': 'off',
|
'constructor-super': 'off',
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { app, globalShortcut, ipcMain, nativeImage } from 'electron';
|
|||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
import { loadLyricWindow } from './lyric';
|
import { loadLyricWindow } from './lyric';
|
||||||
|
import { initializeCacheManager } from './modules/cache';
|
||||||
import { initializeConfig } from './modules/config';
|
import { initializeConfig } from './modules/config';
|
||||||
import { initializeFileManager } from './modules/fileManager';
|
import { initializeFileManager } from './modules/fileManager';
|
||||||
import { initializeTray } from './modules/tray';
|
import { initializeTray } from './modules/tray';
|
||||||
@@ -26,6 +27,7 @@ function initialize() {
|
|||||||
// 初始化各个模块
|
// 初始化各个模块
|
||||||
initializeConfig();
|
initializeConfig();
|
||||||
initializeFileManager();
|
initializeFileManager();
|
||||||
|
initializeCacheManager();
|
||||||
|
|
||||||
// 创建主窗口
|
// 创建主窗口
|
||||||
mainWindow = createMainWindow(icon);
|
mainWindow = createMainWindow(icon);
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
import { ipcMain } from 'electron';
|
||||||
|
import Store from 'electron-store';
|
||||||
|
|
||||||
|
interface LyricData {
|
||||||
|
id: number;
|
||||||
|
data: any;
|
||||||
|
timestamp: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface StoreSchema {
|
||||||
|
lyrics: Record<number, LyricData>;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CacheManager {
|
||||||
|
private store: Store<StoreSchema>;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.store = new Store<StoreSchema>({
|
||||||
|
name: 'lyrics',
|
||||||
|
defaults: {
|
||||||
|
lyrics: {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async cacheLyric(id: number, data: any) {
|
||||||
|
try {
|
||||||
|
const lyrics = this.store.get('lyrics');
|
||||||
|
lyrics[id] = {
|
||||||
|
id,
|
||||||
|
data,
|
||||||
|
timestamp: Date.now()
|
||||||
|
};
|
||||||
|
this.store.set('lyrics', lyrics);
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error caching lyric:', error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getCachedLyric(id: number) {
|
||||||
|
try {
|
||||||
|
const lyrics = this.store.get('lyrics');
|
||||||
|
const result = lyrics[id];
|
||||||
|
|
||||||
|
if (!result) return undefined;
|
||||||
|
|
||||||
|
// 检查缓存是否过期(24小时)
|
||||||
|
if (Date.now() - result.timestamp > 24 * 60 * 60 * 1000) {
|
||||||
|
delete lyrics[id];
|
||||||
|
this.store.set('lyrics', lyrics);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error getting cached lyric:', error);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async clearLyricCache() {
|
||||||
|
try {
|
||||||
|
this.store.set('lyrics', {});
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error clearing lyric cache:', error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const cacheManager = new CacheManager();
|
||||||
|
|
||||||
|
export function initializeCacheManager() {
|
||||||
|
// 添加歌词缓存相关的 IPC 处理
|
||||||
|
ipcMain.handle('cache-lyric', async (_, id: number, lyricData: any) => {
|
||||||
|
return await cacheManager.cacheLyric(id, lyricData);
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.handle('get-cached-lyric', async (_, id: number) => {
|
||||||
|
return await cacheManager.getCachedLyric(id);
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.handle('clear-lyric-cache', async () => {
|
||||||
|
return await cacheManager.clearLyricCache();
|
||||||
|
});
|
||||||
|
}
|
||||||
Vendored
+1
@@ -13,6 +13,7 @@ declare global {
|
|||||||
miniTray: () => void;
|
miniTray: () => void;
|
||||||
restart: () => void;
|
restart: () => void;
|
||||||
unblockMusic: (id: number, data: any) => Promise<any>;
|
unblockMusic: (id: number, data: any) => Promise<any>;
|
||||||
|
invoke: (channel: string, ...args: any[]) => Promise<any>;
|
||||||
};
|
};
|
||||||
$message: any;
|
$message: any;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,15 @@ const api = {
|
|||||||
restart: () => ipcRenderer.send('restart'),
|
restart: () => ipcRenderer.send('restart'),
|
||||||
openLyric: () => ipcRenderer.send('open-lyric'),
|
openLyric: () => ipcRenderer.send('open-lyric'),
|
||||||
sendLyric: (data) => ipcRenderer.send('send-lyric', data),
|
sendLyric: (data) => ipcRenderer.send('send-lyric', data),
|
||||||
unblockMusic: (id) => ipcRenderer.invoke('unblock-music', id)
|
unblockMusic: (id) => ipcRenderer.invoke('unblock-music', id),
|
||||||
|
// 歌词缓存相关
|
||||||
|
invoke: (channel: string, ...args: any[]) => {
|
||||||
|
const validChannels = ['get-cached-lyric', 'cache-lyric', 'clear-lyric-cache'];
|
||||||
|
if (validChannels.includes(channel)) {
|
||||||
|
return ipcRenderer.invoke(channel, ...args);
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(`Invalid channel: ${channel}`));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Use `contextBridge` APIs to expose Electron APIs to
|
// Use `contextBridge` APIs to expose Electron APIs to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import store from '@/store';
|
import store from '@/store';
|
||||||
import { ILyric } from '@/type/lyric';
|
import type { ILyric } from '@/type/lyric';
|
||||||
import { isElectron } from '@/utils';
|
import { isElectron } from '@/utils';
|
||||||
import request from '@/utils/request';
|
import request from '@/utils/request';
|
||||||
import requestMusic from '@/utils/request_music';
|
import requestMusic from '@/utils/request_music';
|
||||||
@@ -36,8 +36,25 @@ export const getMusicDetail = (ids: Array<number>) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 根据音乐Id获取音乐歌词
|
// 根据音乐Id获取音乐歌词
|
||||||
export const getMusicLrc = (id: number) => {
|
export const getMusicLrc = async (id: number) => {
|
||||||
return request.get<ILyric>('/lyric', { params: { id } });
|
if (isElectron) {
|
||||||
|
// 先尝试从缓存获取
|
||||||
|
const cachedLyric = await window.api.invoke('get-cached-lyric', id);
|
||||||
|
console.log('cachedLyric', cachedLyric);
|
||||||
|
if (cachedLyric) {
|
||||||
|
return { data: cachedLyric };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果缓存中没有,则从服务器获取
|
||||||
|
const res = await request.get<ILyric>('/lyric', { params: { id } });
|
||||||
|
|
||||||
|
// 缓存完整的响应数据
|
||||||
|
if (isElectron && res) {
|
||||||
|
await window.api.invoke('cache-lyric', id, res.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getParsingMusicUrl = (id: number, data: any) => {
|
export const getParsingMusicUrl = (id: number, data: any) => {
|
||||||
|
|||||||
@@ -13,13 +13,11 @@ const musicHistory = useMusicHistory();
|
|||||||
// 获取歌曲url
|
// 获取歌曲url
|
||||||
export const getSongUrl = async (id: number, songData: any, isDownloaded: boolean = false) => {
|
export const getSongUrl = async (id: number, songData: any, isDownloaded: boolean = false) => {
|
||||||
const { data } = await getMusicUrl(id);
|
const { data } = await getMusicUrl(id);
|
||||||
console.log('data', data);
|
|
||||||
let url = '';
|
let url = '';
|
||||||
let songDetail = null;
|
let songDetail = null;
|
||||||
try {
|
try {
|
||||||
if (data.data[0].freeTrialInfo || !data.data[0].url) {
|
if (data.data[0].freeTrialInfo || !data.data[0].url) {
|
||||||
const res = await getParsingMusicUrl(id, songData);
|
const res = await getParsingMusicUrl(id, songData);
|
||||||
console.log('res', res);
|
|
||||||
url = res.data.data.url;
|
url = res.data.data.url;
|
||||||
songDetail = res.data.data;
|
songDetail = res.data.data;
|
||||||
} else {
|
} else {
|
||||||
@@ -52,7 +50,6 @@ const getSongDetail = async (playMusic: SongResult) => {
|
|||||||
export const useMusicListHook = () => {
|
export const useMusicListHook = () => {
|
||||||
const handlePlayMusic = async (state: any, playMusic: SongResult) => {
|
const handlePlayMusic = async (state: any, playMusic: SongResult) => {
|
||||||
const updatedPlayMusic = await getSongDetail(playMusic);
|
const updatedPlayMusic = await getSongDetail(playMusic);
|
||||||
console.log('updatedPlayMusic', updatedPlayMusic);
|
|
||||||
state.playMusic = updatedPlayMusic;
|
state.playMusic = updatedPlayMusic;
|
||||||
state.playMusicUrl = updatedPlayMusic.playMusicUrl;
|
state.playMusicUrl = updatedPlayMusic.playMusicUrl;
|
||||||
state.play = true;
|
state.play = true;
|
||||||
|
|||||||
@@ -552,7 +552,8 @@ const clearCacheOptions = ref([
|
|||||||
{ label: '用户数据', key: 'user', description: '清除登录信息和用户相关数据' },
|
{ label: '用户数据', key: 'user', description: '清除登录信息和用户相关数据' },
|
||||||
{ label: '应用设置', key: 'settings', description: '清除应用的所有自定义设置' },
|
{ label: '应用设置', key: 'settings', description: '清除应用的所有自定义设置' },
|
||||||
{ label: '下载记录', key: 'downloads', description: '清除下载历史记录(不会删除已下载的文件)' },
|
{ label: '下载记录', key: 'downloads', description: '清除下载历史记录(不会删除已下载的文件)' },
|
||||||
{ label: '音乐资源', key: 'resources', description: '清除已加载的音乐文件、歌词等资源缓存' }
|
{ label: '音乐资源', key: 'resources', description: '清除已加载的音乐文件、歌词等资源缓存' },
|
||||||
|
{ label: '歌词资源', key: 'lyrics', description: '清除已加载的歌词资源缓存' }
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const selectedCacheTypes = ref<string[]>([]);
|
const selectedCacheTypes = ref<string[]>([]);
|
||||||
@@ -609,6 +610,9 @@ const clearCache = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'lyrics':
|
||||||
|
window.api.invoke('clear-lyrics-cache');
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user