feat(sdk): 新增咪咕/千千/JOOX/哔哩哔哩/5sing/Apple Music 六平台
平台注册表由 9 个扩到 15 个,同时补齐 sdk/types.ts 的类型与 OpenAPI 文档里的能力位声明。 - migu:命中 Z3D/I3D 加密候选时不返回直链,改由服务端解密代理出流, SDK 侧只负责登记票据,避免客户端拿到无法播放的密文 - apple:只提供 preview 试听片段(完整曲为 DRM),标 noAggregate 排除在跨平台精确匹配之外,防止用它顶掉其它平台的可播结果 - 其余平台按既有 PlatformModule 约定实现搜索/专辑/歌单/歌词 为什么合并成一次提交:六平台共用同一份注册表与能力位声明, 拆开会产生互相引用、单独无法通过类型检查的中间态。
This commit is contained in:
1 parent
47ce651f46
commit
33b96f92c4
54 files changed
+6161
-5
No files matched your search
@@ -0,0 +1,74 @@
|
||||
// Apple Music 搜索(上游 apple.go 的 Search / SearchAlbum / SearchPlaylist)
|
||||
// 通道:amp-api /v1/catalog/<storefront>/search(Bearer developer token,见 util.ts)
|
||||
// 单次请求上限 25 条,page/limit 用 offset 翻页;响应没有 total,
|
||||
// 因此 total = 已翻过的条数 + 本页条数(下一页是否存在由 next 决定,allPage=页码+1)。
|
||||
import {
|
||||
appleAmpGet,
|
||||
appleSongFromCatalog,
|
||||
appleAlbumToPlaylist,
|
||||
applePlaylistToPlaylist,
|
||||
getAppleConfig,
|
||||
} from './util.ts'
|
||||
|
||||
/** amp-api search 单页硬上限 */
|
||||
export const SEARCH_PAGE_MAX = 25
|
||||
|
||||
const catalogSearch = async(keyword: string, types: string, page: number, limit: number) => {
|
||||
const word = String(keyword ?? '').trim()
|
||||
const p = Math.max(1, Number(page) || 1)
|
||||
const l = Math.min(Math.max(1, Number(limit) || 20), 100)
|
||||
if (!word) return { body: null, page: p, limit: l }
|
||||
const cfg = getAppleConfig()
|
||||
const body: any = await appleAmpGet(`/v1/catalog/${cfg.storefront}/search`, {
|
||||
term: word,
|
||||
types,
|
||||
limit: Math.min(l, SEARCH_PAGE_MAX),
|
||||
offset: (p - 1) * l,
|
||||
})
|
||||
return { body, page: p, limit: l }
|
||||
}
|
||||
|
||||
/** 上游 Search:搜索歌曲 */
|
||||
export const search = async(keyword: string, page = 1, limit = 20) => {
|
||||
const { body, page: p, limit: l } = await catalogSearch(keyword, 'songs', page, limit)
|
||||
const bucket = body?.results?.songs ?? {}
|
||||
const list = (bucket.data ?? []).map((item: any) => appleSongFromCatalog(item))
|
||||
const hasNext = Boolean(bucket.next)
|
||||
return {
|
||||
list,
|
||||
allPage: hasNext ? p + 1 : p,
|
||||
total: (p - 1) * l + list.length,
|
||||
limit: l,
|
||||
source: 'apple' as const,
|
||||
}
|
||||
}
|
||||
|
||||
/** 上游 SearchAlbum:搜索专辑(返回歌单摘要形状) */
|
||||
export const searchAlbum = async(keyword: string, page = 1, limit = 20) => {
|
||||
const { body, page: p, limit: l } = await catalogSearch(keyword, 'albums', page, limit)
|
||||
const items = body?.results?.albums?.data ?? []
|
||||
const list = items.map((item: any) => appleAlbumToPlaylist(item))
|
||||
return {
|
||||
list,
|
||||
total: (p - 1) * l + list.length,
|
||||
page: p,
|
||||
limit: l,
|
||||
source: 'apple' as const,
|
||||
}
|
||||
}
|
||||
|
||||
/** 上游 SearchPlaylist:搜索歌单 */
|
||||
export const searchPlaylist = async(keyword: string, page = 1, limit = 20) => {
|
||||
const { body, page: p, limit: l } = await catalogSearch(keyword, 'playlists', page, limit)
|
||||
const items = body?.results?.playlists?.data ?? []
|
||||
const list = items.map((item: any) => applePlaylistToPlaylist(item))
|
||||
return {
|
||||
list,
|
||||
total: (p - 1) * l + list.length,
|
||||
page: p,
|
||||
limit: l,
|
||||
source: 'apple' as const,
|
||||
}
|
||||
}
|
||||
|
||||
export default { search, searchAlbum, searchPlaylist }
|
||||
Reference in new issue
Block a user