Files
MusicServer/sdk/apple/album.ts
T
snowy-yang 1b972ec4dd refactor(api)!: 平台 id 收尾统一——migu→mg、apple→ap
补上最后两个多字母 id,至此 15 个平台对外 id 全部为两字母:
kw kg tx wy qs xm me qt lr mg bd jx bl 5s ap

**破坏性变更**:id 出现在所有 URL、/sources 返回以及 data/auth.json 的
凭据键里,咪咕与 Apple Music 已存的登录态会失效,需重新登录。

- sdk/index.ts:id 与 supportQuality 映射键(展示名 `咪咕音乐` /
  `Apple Music` 保持不动)
- sdk/types.ts:Source 联合类型
- src/routes.ts:/stream 的 enum ['qs','migu'] → ['qs','mg'],以及
  /url/mg、/stream/mg 等路径与 schema 描述
- src/http/migu-stream.ts、src/routes-login.ts、src/server.ts
- test/smoke-test.ts、README.md、docs/API.md 同步

有意未改:域名与 API 路径(music.migu.cn、music.apple.com、
amp-api.music.apple.com、/v1/catalog/cn/apple-curators/…)、
标识符(registerMiguStream、appleAmpGet、APPLE_AMP_API_URL 等)、
sdk/migu 与 sdk/apple 的目录与文件名、错误文案里的平台名。

验证:typecheck ✓、pnpm test 112/112 ✓;另起临时实例实证 /sources
(15/15 平台 id 与展示名全对)与 /login/status,旧 id 零残留。
2026-10-03 11:07:21 +08:00

78 lines
2.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Apple Music 专辑(上游 apple.go 的 SearchAlbum / ParseAlbum / GetAlbumSongs)
// 详情:amp-api /v1/catalog/<sf>/albums/<id>?extend=extendedAssetUrls
// → data[0].relationships.tracks.data[](>300 首时分页,next 由 fetchAllTrackResources 跟进)
// 链接:extractAppleID(link, 'album'),支持裸数字 id 与 /us/album/<slug>/<id> 链接。
import {
appleAmpGet,
appleAlbumToPlaylist,
appleSongFromCatalog,
extractAppleID,
fetchAllTrackResources,
getAppleConfig,
} from './util.ts'
export { searchAlbum } from './musicSearch.ts'
import { searchAlbum } from './musicSearch.ts'
/** 专辑详情(page/limit 在完整曲目上切片,与其它平台 getAlbumDetail 契约一致) */
export const getAlbumDetail = async(rawId: string, page = 1, limit = 50) => {
const albumId = extractAppleID(String(rawId ?? ''), 'album')
if (!albumId) throw new Error(`invalid apple music album id/link: ${rawId}`)
const cfg = getAppleConfig()
const body: any = await appleAmpGet(`/v1/catalog/${cfg.storefront}/albums/${albumId}`, { extend: 'extendedAssetUrls' })
const album = (body?.data ?? [])[0]
if (!album) throw new Error(`apple album not found: ${albumId}`)
const tracks = await fetchAllTrackResources(album?.relationships?.tracks)
const songs = tracks.map((track: any) => appleSongFromCatalog(track, albumId))
const p = Math.max(1, Number(page) || 1)
const l = Math.max(1, Number(limit) || 50)
const summary = appleAlbumToPlaylist(album)
// 上游 fetchPlaylistDetail 的做法:接口未给 trackCount 时以实际曲目数补齐
if (!summary.trackCount || songs.length > summary.trackCount) summary.trackCount = songs.length
return {
source: 'ap' as const,
info: {
id: albumId,
name: summary.name,
img: summary.cover,
desc: summary.description,
author: summary.creator,
link: summary.link,
trackCount: summary.trackCount,
releaseDate: summary.extra?.release_date || '',
recordLabel: summary.extra?.record_label || '',
},
list: songs.slice((p - 1) * l, (p - 1) * l + l),
page: p,
limit: l,
total: songs.length,
}
}
/** 上游 GetAlbumSongs:只返回曲目数组 */
export const getAlbumSongs = async(id: string): Promise<any[]> => {
const { list } = await getAlbumDetail(id, 1, 100000)
return list
}
/** 上游 ParseAlbum:专辑链接 → 详情(曲目全量,不分页) */
export const parseAlbumLink = async(link: string) => {
const detail = await getAlbumDetail(link, 1, 100000)
return {
source: 'ap' as const,
id: detail.info.id,
info: detail.info,
list: detail.list,
page: 1,
limit: Math.max(detail.total, 1),
total: detail.total,
}
}
export default { getAlbumDetail, getAlbumSongs, searchAlbum, parseAlbumLink }