Files
MeowOS-For-R3P2/patch_v2/ncm_app/app/ui
AskaEth 2bfe1ed796 feat(ncm): 封面死链兜底链 —— 原 picUrl 失败→web 端 song/detail 重取活链→歌单封面兜底
用户调研: 官方旧版 GET music.163.com/api/song/detail/?id=<id>&ids=[<id>] 免登录出
songs[0].album.picUrl/blurPicUrl。本批宿主实锤: 登录态 eapi 给的死链封面, 该 web 接口给不同活链
(死链 yR2VGt7.../10995116862531 -> album.picUrl p2.../6y-UleORIT.../...jpg 活 PNG 146KB)。

实现 (patch_v2/ncm_app/):
- cover_request(url, song_id): 新增第二参曲目 id; g_tgt_song 记录; 新目标重置 g_fb_done。
  player.c 三处传 s.id(专辑封面), playlist.c 传 NULL(歌单封面无兜底)。
- cover_song_detail_pic(song_id): web song/detail 重取 album.picUrl(缺 blurPicUrl);
  ids=[<id>] 的 [ ] URL 编码 %5B/%5D(裸[ ] curl 报 bad range); 带 Referer+桌面UA; ncm_http_request
  (头进 resp->headers, 体进 16KB 栈缓冲) + ncm_json 解析; 只读一次。
- cover_try_fallback(url, song_id): 仅原链确定性失败时触发; g_tgt_url 仍==url(未被换走) + 曲目非空 +
  未兜底 + 同曲 5 分钟冷却(ncm_monotonic_ms) 才下探; 拿到不同新图->记冷却/置 g_fb_done/换目标返 1
  (worker 重试新图); 无新图/冷却中/已兜底/目标被换走->返 0 走歌单封面兜底; 每步日志写清级别。
- worker: kind=1(webp)/kind=2(非图)/确定性4xx 死链分支清目标前先
  if(song[0]&&!fb_done&&cover_try_fallback(url,song)) continue; 瞬时错误仍指数退避不触发。
- 风控: 只在原链失败触发(不新增常规请求); 单曲目最多一次(g_fb_done)+5分钟冷却。

验证 (宿主+qemu, 0 新增真实 CDN 业务请求):
- cover_chain_sim T1-T12 ALL PASS(新增 T11 原链死->song/detail活链->出图+恰1次+song-detail fallback日志;
  T12 兜底也死->留歌单封面+同曲再请求 song/detail 0次(冷却)+cooldown日志)。
- cache_evict/player_flow/window/search/stream sim 全 PASS; core host+mipsel(qemu) PASS;
  build_ncm.sh 0 warning(text 1022210/bss 1362564,+64B); ncm_host UI dump exit=0。
  新 ncm md5 e1f4b7ade834b18c7910b9c3e64bc858 (未部署, 留主会话上卡)。
2026-09-02 11:41:54 +08:00
..