81 lines
2.6 KiB
TypeScript
81 lines
2.6 KiB
TypeScript
import { getQuery, createError } from 'h3'
|
|
import axios from 'axios'
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const query = getQuery(event)
|
|
const url = query.url as string
|
|
|
|
if (!url || !url.includes('kugou.com')) {
|
|
throw createError({
|
|
statusCode: 400,
|
|
message: 'Invalid Kugou URL'
|
|
})
|
|
}
|
|
|
|
try {
|
|
// 1. 获取重定向后的最终URL或HTML内容
|
|
const response = await axios.get(url, {
|
|
headers: {
|
|
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1'
|
|
}
|
|
})
|
|
|
|
// 很多时候链接会跳转,或者HTML里面有 hash 变量
|
|
const html = response.data
|
|
// 尝试正则匹配 "hash":"xxx" 或者 hash: 'xxx'
|
|
const hashMatch = html.match(/"hash"\s*:\s*"([a-zA-Z0-9]+)"/i) || html.match(/hash\s*=\s*"([a-zA-Z0-9]+)"/i) || html.match(/"320hash"\s*:\s*"([a-zA-Z0-9]+)"/i)
|
|
const albumMatch = html.match(/"album_id"\s*:\s*(\d+)/i)
|
|
|
|
if (hashMatch && hashMatch[1]) {
|
|
const hash = hashMatch[1]
|
|
// 用 hash 再次查询歌曲详情或者直接返回
|
|
// 我们可以调用移动端 track info API
|
|
const infoUrl = `http://m.kugou.com/app/i/getSongInfo.php?cmd=playInfo&hash=${hash}`
|
|
const infoRes = await axios.get(infoUrl, { validateStatus: () => true })
|
|
|
|
if (infoRes.data && infoRes.data.songName) {
|
|
return {
|
|
id: hash,
|
|
title: infoRes.data.songName,
|
|
artist: infoRes.data.singerName,
|
|
cover: infoRes.data.imgUrl ? infoRes.data.imgUrl.replace('{size}', '150') : '',
|
|
duration: infoRes.data.timeLength * 1000,
|
|
musicPlatform: 'kugou',
|
|
musicId: hash,
|
|
hasUrl: true,
|
|
isVip: infoRes.data.privilege >= 10,
|
|
sourceInfo: {
|
|
source: 'kugou',
|
|
originalId: hash,
|
|
fetchedAt: new Date()
|
|
}
|
|
}
|
|
}
|
|
|
|
// 如果 getSongInfo 失败,我们只返回 hash
|
|
return {
|
|
id: hash,
|
|
title: "解析成功,请点击投稿",
|
|
artist: "未知歌手",
|
|
musicPlatform: 'kugou',
|
|
musicId: hash,
|
|
hasUrl: true,
|
|
sourceInfo: {
|
|
source: 'kugou',
|
|
originalId: hash,
|
|
fetchedAt: new Date()
|
|
}
|
|
}
|
|
}
|
|
|
|
throw createError({
|
|
statusCode: 404,
|
|
message: 'Cannot find song hash in the provided link'
|
|
})
|
|
} catch (error: any) {
|
|
throw createError({
|
|
statusCode: 500,
|
|
message: error.message || 'Failed to parse link'
|
|
})
|
|
}
|
|
}) |