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 (未部署, 留主会话上卡)。
This commit is contained in:
1 parent
9d93f1b1ef
commit
2bfe1ed796
8 files changed
+261
-20
No files matched your search
@@ -538,7 +538,7 @@ void player_play_song(int idx)
|
||||
? s.al_pic : g_st.cover_url;
|
||||
player_manager_play(idx);
|
||||
appstate_set_playing_song(idx, NULL);
|
||||
cover_request(cover);
|
||||
cover_request(cover, s.id); /* 曲目专辑封面:带 id,死链时 song/detail 兜底(REPORT §NEW 任务1) */
|
||||
g_ppage = 0; /* 新曲 → 回封面页 */
|
||||
meow_view_page_push(ACT_PLAYER);
|
||||
}
|
||||
@@ -554,7 +554,7 @@ void player_play_search_song(int i)
|
||||
const char *cover = s.al_pic[0] ? s.al_pic : g_st.cover_url;
|
||||
player_manager_play(i);
|
||||
appstate_set_playing_song(i, NULL);
|
||||
cover_request(cover);
|
||||
cover_request(cover, s.id);
|
||||
g_ppage = 0;
|
||||
meow_view_page_push(ACT_PLAYER);
|
||||
}
|
||||
@@ -585,7 +585,7 @@ void player_tick(uint64_t now)
|
||||
ncm_song_t s2;
|
||||
if (sc >= 0 && cur_song_meta(&s2) == 0 && strcmp(s2.id, g_last_meta_id) != 0) {
|
||||
ncm_strlcpy(g_last_meta_id, s2.id, sizeof g_last_meta_id);
|
||||
cover_request(s2.al_pic[0] ? s2.al_pic : g_st.cover_url);
|
||||
cover_request(s2.al_pic[0] ? s2.al_pic : g_st.cover_url, s2.id);
|
||||
player_static_invalidate();
|
||||
player_dyn_invalidate();
|
||||
}
|
||||
|
||||
@@ -548,7 +548,7 @@ static void pl_page_enter(meow_view *v, void *ctx)
|
||||
* (旧版只在 playlist_open 里 cover_cache_reset 清掉,无人再请求 → 头块永远占位 ♪)。 */
|
||||
const ncm_playlist_t *pcur = pl_cur();
|
||||
if (pcur && pcur->cover[0])
|
||||
cover_request(pcur->cover);
|
||||
cover_request(pcur->cover, NULL); /* 歌单封面:无曲目 id,不走 song/detail 兜底 */
|
||||
playlist_refresh();
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user