mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-04-26 01:07:22 +08:00
feat:优化lx音源问题
This commit is contained in:
@@ -17,6 +17,7 @@ import { setupUpdateHandlers } from './modules/update';
|
||||
import { createMainWindow, initializeWindowManager, setAppQuitting } from './modules/window';
|
||||
import { initWindowSizeManager } from './modules/window-size';
|
||||
import { startMusicApi } from './server';
|
||||
import { initLxMusicHttp } from './modules/lxMusicHttp';
|
||||
|
||||
// 导入所有图标
|
||||
const iconPath = join(__dirname, '../../resources');
|
||||
@@ -57,6 +58,9 @@ function initialize(configStore: any) {
|
||||
// 启动音乐API
|
||||
startMusicApi();
|
||||
|
||||
// 初始化落雪音乐 HTTP 请求处理
|
||||
initLxMusicHttp();
|
||||
|
||||
// 加载歌词窗口
|
||||
loadLyricWindow(ipcMain, mainWindow);
|
||||
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* 落雪音乐 HTTP 请求处理(主进程)
|
||||
* 绕过渲染进程的 CORS 限制
|
||||
*/
|
||||
|
||||
import { ipcMain } from 'electron';
|
||||
import fetch, { type RequestInit } from 'node-fetch';
|
||||
|
||||
interface LxHttpRequest {
|
||||
url: string;
|
||||
options: {
|
||||
method?: string;
|
||||
headers?: Record<string, string>;
|
||||
body?: string;
|
||||
form?: Record<string, string>;
|
||||
formData?: Record<string, string>;
|
||||
timeout?: number;
|
||||
};
|
||||
requestId: string;
|
||||
}
|
||||
|
||||
interface LxHttpResponse {
|
||||
statusCode: number;
|
||||
headers: Record<string, string | string[]>;
|
||||
body: any;
|
||||
}
|
||||
|
||||
// 取消控制器映射
|
||||
const abortControllers = new Map<string, AbortController>();
|
||||
|
||||
/**
|
||||
* 初始化 HTTP 请求处理
|
||||
*/
|
||||
export const initLxMusicHttp = () => {
|
||||
// 处理 HTTP 请求
|
||||
ipcMain.handle(
|
||||
'lx-music-http-request',
|
||||
async (_, request: LxHttpRequest): Promise<LxHttpResponse> => {
|
||||
const { url, options, requestId } = request;
|
||||
const controller = new AbortController();
|
||||
|
||||
// 保存取消控制器
|
||||
abortControllers.set(requestId, controller);
|
||||
|
||||
try {
|
||||
console.log(`[LxMusicHttp] 请求: ${options.method || 'GET'} ${url}`);
|
||||
|
||||
const fetchOptions: RequestInit = {
|
||||
method: options.method || 'GET',
|
||||
headers: {
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
|
||||
...(options.headers || {})
|
||||
},
|
||||
signal: controller.signal
|
||||
};
|
||||
|
||||
// 处理请求体
|
||||
if (options.body) {
|
||||
fetchOptions.body = options.body;
|
||||
} else if (options.form) {
|
||||
const formData = new URLSearchParams(options.form);
|
||||
fetchOptions.body = formData.toString();
|
||||
fetchOptions.headers = {
|
||||
...fetchOptions.headers,
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
};
|
||||
} else if (options.formData) {
|
||||
// node-fetch 的 FormData 需要特殊处理
|
||||
const FormData = (await import('form-data')).default;
|
||||
const formData = new FormData();
|
||||
for (const [key, value] of Object.entries(options.formData)) {
|
||||
formData.append(key, value);
|
||||
}
|
||||
fetchOptions.body = formData as any;
|
||||
// FormData 会自动设置 Content-Type
|
||||
}
|
||||
|
||||
// 设置超时
|
||||
const timeout = options.timeout || 30000;
|
||||
const timeoutId = setTimeout(() => {
|
||||
console.warn(`[LxMusicHttp] 请求超时: ${url}`);
|
||||
controller.abort();
|
||||
}, timeout);
|
||||
|
||||
const response = await fetch(url, fetchOptions);
|
||||
clearTimeout(timeoutId);
|
||||
|
||||
console.log(`[LxMusicHttp] 响应: ${response.status} ${url}`);
|
||||
|
||||
// 读取响应体
|
||||
const rawBody = await response.text();
|
||||
|
||||
// 尝试解析 JSON
|
||||
let parsedBody: any = rawBody;
|
||||
const contentType = response.headers.get('content-type') || '';
|
||||
if (
|
||||
contentType.includes('application/json') ||
|
||||
rawBody.startsWith('{') ||
|
||||
rawBody.startsWith('[')
|
||||
) {
|
||||
try {
|
||||
parsedBody = JSON.parse(rawBody);
|
||||
} catch {
|
||||
// 解析失败则使用原始字符串
|
||||
}
|
||||
}
|
||||
|
||||
// 转换 headers 为普通对象
|
||||
const headers: Record<string, string | string[]> = {};
|
||||
response.headers.forEach((value, key) => {
|
||||
headers[key] = value;
|
||||
});
|
||||
|
||||
const result: LxHttpResponse = {
|
||||
statusCode: response.status,
|
||||
headers,
|
||||
body: parsedBody
|
||||
};
|
||||
|
||||
return result;
|
||||
} catch (error: any) {
|
||||
console.error(`[LxMusicHttp] 请求失败: ${url}`, error.message);
|
||||
throw error;
|
||||
} finally {
|
||||
// 清理取消控制器
|
||||
abortControllers.delete(requestId);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 处理请求取消
|
||||
ipcMain.handle('lx-music-http-cancel', (_, requestId: string) => {
|
||||
const controller = abortControllers.get(requestId);
|
||||
if (controller) {
|
||||
console.log(`[LxMusicHttp] 取消请求: ${requestId}`);
|
||||
controller.abort();
|
||||
abortControllers.delete(requestId);
|
||||
}
|
||||
});
|
||||
|
||||
console.log('[LxMusicHttp] HTTP 请求处理已初始化');
|
||||
};
|
||||
|
||||
/**
|
||||
* 清理所有正在进行的请求
|
||||
*/
|
||||
export const cleanupLxMusicHttp = () => {
|
||||
for (const [requestId, controller] of abortControllers.entries()) {
|
||||
console.log(`[LxMusicHttp] 清理请求: ${requestId}`);
|
||||
controller.abort();
|
||||
}
|
||||
abortControllers.clear();
|
||||
};
|
||||
Reference in New Issue
Block a user