mirror of
https://github.com/imsyy/SPlayer.git
synced 2025-11-25 19:37:35 +08:00
✨ feat: 新增音源-gequbao
This commit is contained in:
107
electron/server/unblock/gequbao.ts
Normal file
107
electron/server/unblock/gequbao.ts
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
import { SongUrlResult } from "./unblock";
|
||||||
|
import { serverLog } from "../../main/logger";
|
||||||
|
import axios from "axios";
|
||||||
|
import { randomBytes } from "crypto";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索歌曲获取 ID
|
||||||
|
* @param keyword 搜索关键词
|
||||||
|
* @returns 歌曲 ID 或 null
|
||||||
|
*/
|
||||||
|
const search = async (keyword: string): Promise<string | null> => {
|
||||||
|
try {
|
||||||
|
const searchUrl = `https://www.gequbao.com/s/${encodeURIComponent(keyword)}`;
|
||||||
|
const { data } = await axios.get(searchUrl);
|
||||||
|
|
||||||
|
// 匹配第一个歌曲链接 /music/12345
|
||||||
|
// <a href="/music/17165" target="_blank" class="music-link d-block">
|
||||||
|
const match = data.match(
|
||||||
|
/<a href="\/music\/(\d+)" target="_blank" class="music-link d-block">/,
|
||||||
|
);
|
||||||
|
if (match && match[1]) {
|
||||||
|
return match[1];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
} catch (error) {
|
||||||
|
serverLog.error("❌ Get GequbaoSongId Error:", error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取播放 ID
|
||||||
|
* @param id 歌曲 ID
|
||||||
|
* @returns 播放 ID 或 null
|
||||||
|
*/
|
||||||
|
const getPlayId = async (id: string): Promise<string | null> => {
|
||||||
|
try {
|
||||||
|
const url = `https://www.gequbao.com/music/${id}`;
|
||||||
|
const { data } = await axios.get(url);
|
||||||
|
|
||||||
|
// 匹配 window.appData 中的 play_id
|
||||||
|
// "play_id":"EFwMVSQDBgsBQV5WBCUDAVkCSQ9WX3kFXV9XEl0KBSEaVldTR19NVndQVlhXRl5cUA=="
|
||||||
|
const match = data.match(/"play_id":"(.*?)"/);
|
||||||
|
if (match && match[1]) {
|
||||||
|
return match[1];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
} catch (error) {
|
||||||
|
serverLog.error("❌ Get GequbaoPlayId Error:", error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取歌曲 URL
|
||||||
|
* @param keyword 搜索关键词
|
||||||
|
* @returns 包含歌曲 URL 的结果对象
|
||||||
|
*/
|
||||||
|
const getGequbaoSongUrl = async (keyword: string): Promise<SongUrlResult> => {
|
||||||
|
try {
|
||||||
|
if (!keyword) return { code: 404, url: null };
|
||||||
|
|
||||||
|
// 1. 获取 ID
|
||||||
|
const id = await search(keyword);
|
||||||
|
if (!id) return { code: 404, url: null };
|
||||||
|
|
||||||
|
// 2. 获取 play_id
|
||||||
|
const playId = await getPlayId(id);
|
||||||
|
if (!playId) return { code: 404, url: null };
|
||||||
|
|
||||||
|
// 3. 获取播放链接
|
||||||
|
const url = "https://www.gequbao.com/api/play-url";
|
||||||
|
const headers = {
|
||||||
|
accept: "application/json, text/javascript, */*; q=0.01",
|
||||||
|
"accept-language": "zh-CN,zh;q=0.9",
|
||||||
|
"cache-control": "no-cache",
|
||||||
|
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
||||||
|
pragma: "no-cache",
|
||||||
|
priority: "u=1, i",
|
||||||
|
"sec-ch-ua": '"Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"',
|
||||||
|
"sec-ch-ua-mobile": "?0",
|
||||||
|
"sec-ch-ua-platform": '"Windows"',
|
||||||
|
"sec-fetch-dest": "empty",
|
||||||
|
"sec-fetch-mode": "cors",
|
||||||
|
"sec-fetch-site": "same-origin",
|
||||||
|
"x-requested-with": "XMLHttpRequest",
|
||||||
|
cookie: `server_name_session=${randomBytes(16).toString("hex")}`,
|
||||||
|
Referer: `https://www.gequbao.com/music/${id}`,
|
||||||
|
};
|
||||||
|
|
||||||
|
const body = `id=${encodeURIComponent(playId)}`;
|
||||||
|
|
||||||
|
const { data } = await axios.post(url, body, { headers });
|
||||||
|
|
||||||
|
if (data.code === 1 && data.data && data.data.url) {
|
||||||
|
serverLog.log("🔗 GequbaoSong URL:", data.data.url);
|
||||||
|
return { code: 200, url: data.data.url };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { code: 404, url: null };
|
||||||
|
} catch (error) {
|
||||||
|
serverLog.error("❌ Get GequbaoSong URL Error:", error);
|
||||||
|
return { code: 404, url: null };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default getGequbaoSongUrl;
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
import { FastifyInstance, FastifyRequest, FastifyReply } from "fastify";
|
import { FastifyInstance, FastifyRequest, FastifyReply } from "fastify";
|
||||||
import { SongUrlResult } from "./unblock";
|
import { SongUrlResult } from "./unblock";
|
||||||
import { serverLog } from "../../main/logger";
|
import { serverLog } from "../../main/logger";
|
||||||
import getKuwoSongUrl from "./kuwo";
|
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import getKuwoSongUrl from "./kuwo";
|
||||||
import getBodianSongUrl from "./bodian";
|
import getBodianSongUrl from "./bodian";
|
||||||
|
import getGequbaoSongUrl from "./gequbao";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 直接获取 网易云云盘 链接
|
* 直接获取 网易云云盘 链接
|
||||||
@@ -74,6 +75,18 @@ export const initUnblockAPI = async (fastify: FastifyInstance) => {
|
|||||||
return reply.send(result);
|
return reply.send(result);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
// gequbao
|
||||||
|
fastify.get(
|
||||||
|
"/unblock/gequbao",
|
||||||
|
async (
|
||||||
|
req: FastifyRequest<{ Querystring: { [key: string]: string } }>,
|
||||||
|
reply: FastifyReply,
|
||||||
|
) => {
|
||||||
|
const { keyword } = req.query;
|
||||||
|
const result = await getGequbaoSongUrl(keyword);
|
||||||
|
return reply.send(result);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
serverLog.info("🌐 Register UnblockAPI successfully");
|
serverLog.info("🌐 Register UnblockAPI successfully");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "splayer",
|
"name": "splayer",
|
||||||
"productName": "SPlayer",
|
"productName": "SPlayer",
|
||||||
"version": "3.0.0-beta.5",
|
"version": "3.0.0-beta.6",
|
||||||
"description": "A minimalist music player",
|
"description": "A minimalist music player",
|
||||||
"main": "./out/main/index.js",
|
"main": "./out/main/index.js",
|
||||||
"author": "imsyy",
|
"author": "imsyy",
|
||||||
|
|||||||
@@ -494,6 +494,7 @@ const instantLyrics = computed(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.play-menu {
|
.play-menu {
|
||||||
|
margin-left: auto;
|
||||||
max-width: 640px;
|
max-width: 640px;
|
||||||
.time-container {
|
.time-container {
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
|
|||||||
Reference in New Issue
Block a user