mirror of
https://github.com/ZHANGTIANYAO1/teamspeak-music-bot.git
synced 2026-10-02 04:52:50 +08:00
Merge pull request #124 from Slldyd2077/fix/qq-song-detail-empty-name
fix(qq): 按 ID 播放时回填歌曲元数据,修复 TS 显示空歌名
This commit is contained in:
1 file changed
+47
-1
+47
-1
@@ -364,8 +364,18 @@ export class QQMusicProvider implements MusicProvider {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// fall through to stub
|
// fall through to musicu.fcg fallback
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fallback: fetch metadata via u.y.qq.com/cgi-bin/musicu.fcg. The bundled
|
||||||
|
// library's /getSongInfo route is broken (upstream code 500001), so the
|
||||||
|
// primary try above almost always falls through here for QQ. Without this,
|
||||||
|
// play-by-id songs carry an empty name → the TS nickname / now-playing
|
||||||
|
// message renders as "♪ 正在播放: - []". This endpoint (same host/shape
|
||||||
|
// as search) reliably returns full track_info without requiring login.
|
||||||
|
const detail = await this.fetchSongDetailViaMusicu(songId);
|
||||||
|
if (detail) return detail;
|
||||||
|
|
||||||
// Minimal stub — resolveAndPlay only needs id + platform to fetch a
|
// Minimal stub — resolveAndPlay only needs id + platform to fetch a
|
||||||
// play URL. Name/artist/album will be empty in play history, but the
|
// play URL. Name/artist/album will be empty in play history, but the
|
||||||
// song will actually play, which is the important part.
|
// song will actually play, which is the important part.
|
||||||
@@ -380,6 +390,42 @@ export class QQMusicProvider implements MusicProvider {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Fetch a single song's metadata via u.y.qq.com/cgi-bin/musicu.fcg
|
||||||
|
* (module music.pf_song_detail_svr / get_song_detail_yqq). This mirrors the
|
||||||
|
* search path's host + request shape and, unlike the library's /getSongInfo,
|
||||||
|
* actually works against QQ's current API. Returns null on any failure so the
|
||||||
|
* caller can fall back to the minimal stub. */
|
||||||
|
private async fetchSongDetailViaMusicu(songId: string): Promise<Song | null> {
|
||||||
|
try {
|
||||||
|
const reqData = JSON.stringify({
|
||||||
|
req_0: {
|
||||||
|
module: "music.pf_song_detail_svr",
|
||||||
|
method: "get_song_detail_yqq",
|
||||||
|
param: { song_mid: songId, song_type: 0 },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const res = await qqMusicuApi.get("/cgi-bin/musicu.fcg", {
|
||||||
|
params: { format: "json", data: reqData },
|
||||||
|
});
|
||||||
|
const t = res.data?.req_0?.data?.track_info;
|
||||||
|
if (!t) return null;
|
||||||
|
const albumMid = t.album?.mid ?? t.album?.pmid ?? "";
|
||||||
|
return {
|
||||||
|
id: String(t.mid ?? t.id ?? songId),
|
||||||
|
name: t.name ?? t.title ?? "",
|
||||||
|
artist: (t.singer ?? []).map((a: any) => a.name ?? a.title ?? "").filter(Boolean).join(" / "),
|
||||||
|
album: t.album?.name ?? t.album?.title ?? "",
|
||||||
|
duration: t.interval ?? 0,
|
||||||
|
coverUrl: albumMid
|
||||||
|
? `https://y.gtimg.cn/music/photo_new/T002R300x300M000${albumMid}.jpg`
|
||||||
|
: "",
|
||||||
|
platform: "qq",
|
||||||
|
};
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async getPlaylistSongs(playlistId: string): Promise<Song[]> {
|
async getPlaylistSongs(playlistId: string): Promise<Song[]> {
|
||||||
const res = await this.api.get("/getSongListDetail", {
|
const res = await this.api.get("/getSongListDetail", {
|
||||||
params: { disstid: playlistId, ...this.cookieParams },
|
params: { disstid: playlistId, ...this.cookieParams },
|
||||||
|
|||||||
Reference in new issue
Block a user