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:
TIANYAO ZHANGandClaude Opus 5.5 committed 2026-09-27 21:52:47 +08:00
1 parent 8ff51ea6e0
commit 07ad861ecf
6 files changed
+263 -8

No files matched your search

+8
View File
@@ -64,6 +64,14 @@ describe("buildFfmpegArgs", () => {
expect(ssIdx).toBeGreaterThan(iIdx);
});
it("seeks B站 streams input-side (before -i) so a resume jumps via Range instead of re-downloading (#161)", () => {
const args = buildFfmpegArgs("https://upos-sz-mirrorcos.bilivideo.com/audio.m4s", 3600);
const ssIdx = args.indexOf("-ss");
expect(args[ssIdx + 1]).toBe("3600");
expect(ssIdx).toBeLessThan(args.indexOf("-i"));
expect(args.lastIndexOf("-ss")).toBe(ssIdx); // only one -ss
});
it("does not insert -ss when seekSeconds is 0", () => {
const args = buildFfmpegArgs("https://example.com/song.mp3", 0);
expect(args).not.toContain("-ss");