feat(xm): 喜马拉雅平台接入——匿名搜索/专辑/免费曲直链(hdaa xm-sign+AES-ECB 解密)、cookie 绑定解锁付费
This commit is contained in:
1 parent
44852864e2
commit
5a9915b74c
8 files changed
+717
No files matched your search
@@ -0,0 +1,56 @@
|
||||
// 喜马拉雅搜索(web 通道)
|
||||
// 接口: https://www.ximalaya.com/revision/search?core=track&kw=&page=&rows=&spellchecker=true&condition=relation&device=web
|
||||
// 实测(2026-10-02)匿名可用(注意:同参数的 /revision/search/main 与 /search/main 会命中
|
||||
// risk invalid 风控,本端点 + condition=relation&device=web 不受影响)
|
||||
// 返回 data.result.response.docs[],字段 id/title/duration(秒)/nickname/album_id/album_title/
|
||||
// album_cover_path/is_paid/is_trailer
|
||||
import { httpFetch } from '../request.ts'
|
||||
import { formatPlayTime } from '../index.ts'
|
||||
import { XM_UA } from './sign.ts'
|
||||
|
||||
const SEARCH_URL = 'https://www.ximalaya.com/revision/search'
|
||||
|
||||
const normalizeCover = (path: unknown): string | null => {
|
||||
if (!path) return null
|
||||
const s = String(path)
|
||||
return s.startsWith('http') ? s : `https://imagev2.xmcdn.com/${s}`
|
||||
}
|
||||
|
||||
export const search = (keyword: string, page = 1, limit = 20) => {
|
||||
const params = new URLSearchParams({
|
||||
core: 'track', kw: keyword, page: String(page), rows: String(limit),
|
||||
spellchecker: 'true', condition: 'relation', device: 'web',
|
||||
})
|
||||
return httpFetch(`${SEARCH_URL}?${params.toString()}`, {
|
||||
headers: { 'User-Agent': XM_UA, Accept: 'application/json, text/plain, */*', Referer: 'https://www.ximalaya.com/' },
|
||||
timeout: 15000,
|
||||
}).promise.then(({ statusCode, body }: any) => {
|
||||
if (statusCode != 200 || body?.ret != 200) throw new Error(body?.msg || '搜索失败')
|
||||
const docs = body?.data?.result?.response?.docs ?? []
|
||||
const total = Number(body?.data?.result?.response?.numFound ?? docs.length)
|
||||
const allPage = Math.ceil(total / limit) || page
|
||||
return {
|
||||
allPage,
|
||||
total,
|
||||
limit,
|
||||
source: 'xm' as const,
|
||||
list: docs.map((item: any) => ({
|
||||
songmid: String(item.id),
|
||||
name: item.title || '',
|
||||
singer: item.nickname || '',
|
||||
albumId: item.album_id ? String(item.album_id) : '',
|
||||
albumName: item.album_title || '',
|
||||
interval: item.duration ? formatPlayTime(Number(item.duration)) : 0,
|
||||
payPlay: Boolean(item.is_paid),
|
||||
img: normalizeCover(item.album_cover_path),
|
||||
lrc: '',
|
||||
lrcx: '',
|
||||
types: [],
|
||||
_types: {},
|
||||
disabled: false,
|
||||
})),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export default { search }
|
||||
Reference in new issue
Block a user