mirror of
https://github.com/ZHANGTIANYAO1/teamspeak-music-bot.git
synced 2026-10-10 17:02:49 +08:00
fix(bilibili): keep long videos playing when the CDN drops the stream (#161)
Long B站 videos (2-3 h) still stopped ~15-20 min in, the same symptom as #89. Reconnecting to the same URL is not enough once the CDN session is gone, so: - Prefer an upos/cos mirror from baseUrl + backupUrl over PCDN hosts (*.mcdn.bilivideo.cn, *.szbdyd.com), which are the ones that cut off. - When a B站 track ends more than 30 s before its known duration, fetch a fresh URL and resume at the current position instead of advancing. Up to 3 attempts without real progress, then advance as before; a track the user started meanwhile is never clobbered. - Seek B站 URLs input-side (-ss before -i). Their CDN serves Range, so a resume jumps to the byte offset instead of re-downloading everything before it (measured locally: 0.2 s vs a full-file download at 1.5 h into a 2 h fMP4), which would otherwise trip the 60 s stall watchdog. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
8ff51ea6e0
commit
07ad861ecf
6 files changed
+263
-8
No files matched your search
+32
-1
@@ -42,6 +42,37 @@ export interface BiliVideoPartsResult {
|
||||
parts: BiliVideoPart[];
|
||||
}
|
||||
|
||||
/**
|
||||
* PCDN / P2P edge hosts (xy*.mcdn.bilivideo.cn:<port>, *.szbdyd.com). Their
|
||||
* sessions get cut mid-file, which kills long streams partway (#89, #161),
|
||||
* and a reconnect to the same host rarely recovers.
|
||||
*/
|
||||
const BILI_PCDN_HOST = /\.mcdn\.bilivideo\.cn$|\.szbdyd\.com$/i;
|
||||
|
||||
/**
|
||||
* Pick the audio URL least likely to die mid-stream: the first upos/cos
|
||||
* mirror among baseUrl + backupUrl, else the baseUrl as before.
|
||||
*/
|
||||
export function pickStableAudioUrl(stream: {
|
||||
baseUrl?: string;
|
||||
base_url?: string;
|
||||
backupUrl?: string[];
|
||||
backup_url?: string[];
|
||||
}): string | undefined {
|
||||
const primary = stream.baseUrl ?? stream.base_url;
|
||||
const candidates = [primary, ...(stream.backupUrl ?? stream.backup_url ?? [])].filter(
|
||||
(u): u is string => typeof u === "string" && u.length > 0,
|
||||
);
|
||||
const stable = candidates.find((u) => {
|
||||
try {
|
||||
return !BILI_PCDN_HOST.test(new URL(u).hostname);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return stable ?? primary;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析带有分P信息的 B站 ID 或 URL。
|
||||
* 支持形如 "BVxxxx", "BVxxxx?p=2", "BVxxxx:p2" 以及完整 URL 等格式,默认 page 为 1。
|
||||
@@ -353,7 +384,7 @@ export class BiliBiliProvider implements MusicProvider {
|
||||
(b.bandwidth ?? 0) > (a.bandwidth ?? 0) ? b : a
|
||||
);
|
||||
|
||||
const biliUrl = best.baseUrl ?? best.base_url;
|
||||
const biliUrl = pickStableAudioUrl(best);
|
||||
return biliUrl ? { url: biliUrl } : null;
|
||||
} catch {
|
||||
return null;
|
||||
|
||||
Reference in new issue
Block a user