Files
MusicServer/sdk/apple/index.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

107 lines
3.4 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 平台模块(上游 music-lib/apple/apple.go 的 Node/TS 移植,平台 id: ap)
// 能力:搜索 / 歌词(TTML,匿名 developer token 通常拿不到,见 lyric.ts)/ 封面 /
// 专辑(搜索+详情+链接解析)/ 歌单(搜索+详情+分类+分类歌单+链接解析)/
// 链接解析(song/album/playlist)/ 取流(**仅 preview 试听片段**,见 sdk/apis/apple.ts)。
// 凭据:上游 New(cookie) → getCredentials('ap'),cookie 形如
// "media-user-token=xxx;storefront=cn;token=xxx",也支持 storefront/mediaUserToken/token 直填字段。
// 未实现(上游也没有):userPlaylist、榜单、热搜、歌手、评论、扫码登录。
import appleApi from '../apis/apple.ts'
import musicSearch from './musicSearch.ts'
import lyric from './lyric.ts'
import album from './album.ts'
import playlist from './playlist.ts'
import parse from './parse.ts'
import {
appleArtworkURL,
appleSongFromCatalog,
appleWebURL,
extractAppleID,
fetchAppleSongResource,
getAppleConfig,
getAppleToken,
} from './util.ts'
import { getCredentials } from '../auth/store.ts'
const songIdOf = (songInfo: any): string => (
extractAppleID(String(songInfo?.songmid ?? songInfo?.id ?? ''), 'song')
)
const apple = {
/** 预热 developer token(失败不阻塞启动,路由调用时会重试) */
init() {
return getAppleToken().then(() => true).catch(() => false)
},
musicSearch,
getMusicUrl(songInfo, type) {
return appleApi.getMusicUrl(songInfo, type)
},
getLyric(songInfo, ...rest) {
return lyric.getLyric(songInfo, ...rest)
},
/** 封面:搜索结果自带 img;缺失时回源歌曲详情(best-effort) */
async getPic(songInfo) {
if (songInfo?.img) return String(songInfo.img)
const id = songIdOf(songInfo)
if (!id) return null
try {
const res = await fetchAppleSongResource(id)
return res ? (appleArtworkURL(res.attributes?.artwork, 600) || null) : null
} catch {
return null
}
},
/** 歌曲详情(best-effort;等价上游 Parse(id)) */
async getMusicInfo(songInfo) {
const id = songIdOf(songInfo)
if (!id) return null
const res = await fetchAppleSongResource(id, 'lyrics,albums')
return res ? appleSongFromCatalog(res) : null
},
album: {
getAlbumDetail: album.getAlbumDetail,
getAlbumSongs: album.getAlbumSongs,
searchAlbum: album.searchAlbum,
parseAlbumLink: album.parseAlbumLink,
},
playlist,
// 契约别名:Apple 的歌单分类即 genre curators,挂到 songList 键供 /song-list/ap 复用
songList: {
sortList: [{ name: '热门', id: '1526756058' }],
getTags() {
return playlist.getCategories()
},
getList(sortId: string, tagId: string, page = 1, limit = 20) {
const cate = String(tagId || sortId || '').trim()
return playlist.getCategoryPlaylists(cate, page, limit)
},
},
parse,
getMusicDetailPageUrl(songInfo) {
if (songInfo?.link) return String(songInfo.link)
const id = songIdOf(songInfo)
if (!id) return 'https://music.apple.com/'
return appleWebURL('song', id, getAppleConfig().storefront)
},
}
/** 登录状态(media-user-token 存在性判断;无在线校验接口) */
export const status = () => {
const cred = getCredentials('ap') as any
const cfg = getAppleConfig()
return (cfg.mediaUserToken || cred?.cookie)
? { logged: true, updatedAt: cred?.updatedAt }
: { logged: false }
}
export default apple