Files
MusicServer/sdk/apis/wy.ts
T
snowy-yang 354df2e739 refactor: 架构整固——分层单向化、全量 TypeScript、直接运行
- 移除 bd/mg 两平台及磁盘残留产物;清理 api-test 死脚本、musicSdk/message+options 死模块、infSign vendor
- musicSdk/ 改名 sdk/;src/common、src/auth、src/apis 整体移入 sdk/,依赖方向定为 src → sdk 严格单向
- src/ 手写 JS 全量转 .ts,删除 JS 类型垫片 modules.d.ts;源码 import 统一 .ts 后缀
- Node 原生类型剥离直接运行 .ts(engines >=22.18),取消 tsc 发射产物,tsc 仅类型检查(pnpm typecheck)
- 删除 kwdes 备用实现与 src/index.ts 转发垫片;测试移至 test/smoke-test.ts
- common/request.ts 补显式导出类型;修复 set-cookie 单值形态、ApiError 类字段等隐患

验证:tsc 零错误,smoke-test 41/41
2026-09-25 23:06:23 +08:00

49 lines
1.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.
// 网易云音乐 URL 获取(直连)
// 接口: https://interface3.music.163.com/eapi/song/enhance/player/url/v1(eapi 加密请求,响应为明文 JSON)
// 音质: 128k → standard, 320k → exhigh, flac → lossless
// 统一接口约定:apis('wy').getMusicUrl(songInfo, type) → { promise, cancelHttp }
// promise resolve → { type, url }
import { httpFetch } from '../common/request.ts'
// crypto.js 为 tsc 就地发射产物(源 sdk/wy/utils/crypto.ts);统一走 .js,避免同进程出现 .ts/.js 双实例
import { eapi } from '../wy/utils/crypto.ts'
import { getWyCookie } from '../auth/store.ts'
const levelMap = {
'128k': 'standard',
'320k': 'exhigh',
flac: 'lossless',
flac24bit: 'hires',
}
export const getMusicUrl = (songInfo, type) => {
const requestObj = { cancelHttp() {}, promise: null as any }
const data = {
ids: `[${songInfo.songmid}]`,
level: levelMap[type] || 'standard',
encodeType: 'flac',
}
const cookie = getWyCookie()
const request = httpFetch('https://interface3.music.163.com/eapi/song/enhance/player/url/v1', {
method: 'post',
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
origin: 'https://music.163.com',
...(cookie ? { cookie } : {}),
},
form: eapi('/api/song/enhance/player/url/v1', data),
timeout: 15000,
})
requestObj.promise = request.promise.then(({ statusCode, body }) => {
if (statusCode != 200 || body.code != 200) {
return Promise.reject(new Error('获取失败'))
}
const item = body.data?.[0]
if (!item?.url) return Promise.reject(new Error('获取失败'))
return { type, url: item.url }
})
return requestObj
}
export default { getMusicUrl }