Skip to content

适配 xeapi ,补充部分 VIP 图标显示 - #1754

Open
ITManCHINA wants to merge 4 commits into
UnblockNeteaseMusic:enhancedfrom
ITManCHINA:feat/adapt-xeapi
Open

适配 xeapi ,补充部分 VIP 图标显示#1754
ITManCHINA wants to merge 4 commits into
UnblockNeteaseMusic:enhancedfrom
ITManCHINA:feat/adapt-xeapi

Conversation

@ITManCHINA

@ITManCHINA ITManCHINA commented Aug 24, 2026

Copy link
Copy Markdown

Note

根据 NeteaseCloudMusicApiEnhanced/api-enhanced 引入部分改动。
改动由 Claude Opus 5 总结。

按照 #1751 完善了一部分。


适配网易云 xeapi 以恢复音源替换,并补充部分 VIP 徽标显示。

背景:新版客户端改用 xeapi 加密(POST /xeapi/<path>,体为 B/S/R),而 hook.js 只识别 /eapi/linux/forward,请求完全未进入拦截,音源替换与本地 VIP 一并失效;另外本地 VIP 自 2021 年起只补了会员权益接口,未碰账号接口的 profile.vipType,导致界面不显示会员标识。

改动

  • crypto.js:新增 xeapi 加解密(decryptSession/decryptRequest/encryptRequest);eapi 与 xeapi 共用的响应编解码抽为 decryptResponse/encryptResponse,自动识别并保留内层 gzip;AES 密钥长度按实际长度推导以支持 32 字节会话密钥(既有密钥仍为 aes-128-ecb)。
  • 请求参数可解密:服务器经明文响应头 x-encr-sskey 下发会话密钥、客户端后续请求复用,记住即可反解 B;已对真实上游验证还原参数与发送值逐字节相同。
  • hook.js:拦截 /xeapi/;补全替换后的 level/encodeType/time(灰响应留 null/0 会让播放器拒绝 FLAC);风控码 -460/-462 时合成占位条目回落音源、成功后回写顶层 codeinject 守卫空条目并在 url 缺失时也触发;响应头剥离提前到解析前;applyLocalVip 拆为权益与账号两个补丁,后者设 profile.vipType;端点协议改为 PACKAGE_SCHEME/PLAIN_ENDPOINT_OS 配置驱动;新增大小写不敏感 setHeaderNETEASE_USER_AGENT/NETEASE_MCONFIG_INFO 覆盖。
  • provider/find.jsmatch.js:歌曲详情改用 /api/v3/song/detail、保留旧接口兜底、兼容新旧字段名;match() 附带 duration
  • provider/bilivideo.js:安全处理 WBI key、set-cookie、搜索结果及 DASH 音频字段缺失;Bilibili 返回限流/风控错误体时按音源未命中处理,不再因 data.result.map 抛错;音频缺少 base_url 时回退到 backup_url
  • provider/bilivideo.test.js:完整保留原有 5 首真实歌曲的上游可用性测试,并在同一文件中新增请求 mock 测试,覆盖正常匹配、搜索错误体和备用音频 URL。

向后兼容:所有改动均为新增,未替换或移除任何旧路径。补齐老/新不成对端点:song detail v1/v2/api/album、recommend v2/v3、VIP front/vip/info、账号接口两变体、/api/radio/likeNETEASE_COOKIE 保持合并语义(整体替换会丢掉客户端 os/appver,破坏平台识别)。

验证:回归 17 项 + 风控 7 项全过;真实上游验证了 xeapi 请求构造、会话解封与响应往返;某专辑 10 首灰歌 10/10 替换成功。yarn jest 与 prettier 状态与改动前一致(spawn.test.js 为既有平台差异,request.test.js/bilivideo.test.js 为联网 flake,已 git stash 对照确认)。

已知限制:xeapi 下载接口不做 pretendPlay(重加密需会话密钥,未建立时直接匹配响应);md5 仍为 URL 的 md5(既有行为);profile.vipType 取值 11/100、登录态 VIP 补丁与真实客户端播放已实测可用,但在 3.1.X 客户端中,VIP 图标状态很快会消失。

Comment thread src/crypto.js
for (let index = 0; index < buffer.length; index++)
masked[index] = buffer[index] ^ pad[index & 0x0f];
const encoded = Buffer.from(masked.toString('base64'));
const rotation = encoded.length ? (pad[0] & 0x0f) % encoded.length : 0;
@ITManCHINA

Copy link
Copy Markdown
Author

Oh,看来还要修一修小问题😋

@ITManCHINA
ITManCHINA marked this pull request as draft August 26, 2026 17:26
Signed-off-by: ITManCHINA <1678812512@qq.com>
@ITManCHINA
ITManCHINA marked this pull request as ready for review August 26, 2026 18:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants