From 9fd1b39092ec3c12ae2d53751071f2a7ecd49b09 Mon Sep 17 00:00:00 2001 From: XuVIIJay <2454233651@qq.com> Date: Thu, 20 Aug 2026 21:07:21 +0800 Subject: [PATCH] fix(audio): seek after -i (output-side) so drag-seek works on non-seekable HTTP CDNs Input-side fast seek (-ss before -i) requires the HTTP server to support Range/keyframe seeking. NetEase's CDN (music.126.net signed streams) doesn't, so dragging the progress bar hung FFmpeg and the player force-killed it (SIGKILL) with no audio. Moving -ss after -i decodes from the start and discards to the target, which works on any HTTP stream; FFmpeg still fast-seeks when the CDN supports it, so QQ keeps its instant resume. Co-Authored-By: Claude Opus 4.7 --- src/audio/player.test.ts | 4 ++-- src/audio/player.ts | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/audio/player.test.ts b/src/audio/player.test.ts index 9c85d31..e3aca27 100644 --- a/src/audio/player.test.ts +++ b/src/audio/player.test.ts @@ -55,13 +55,13 @@ describe("buildFfmpegArgs", () => { expect(idx).toBeLessThan(args.indexOf("-i")); // input options must precede -i }); - it("inserts -ss before -i when seekSeconds > 0", () => { + it("inserts -ss after -i when seekSeconds > 0", () => { const args = buildFfmpegArgs("https://example.com/song.mp3", 42); const ssIdx = args.indexOf("-ss"); const iIdx = args.indexOf("-i"); expect(ssIdx).toBeGreaterThan(-1); expect(args[ssIdx + 1]).toBe("42"); - expect(ssIdx).toBeLessThan(iIdx); + expect(ssIdx).toBeGreaterThan(iIdx); }); it("does not insert -ss when seekSeconds is 0", () => { diff --git a/src/audio/player.ts b/src/audio/player.ts index 888bd11..a47c722 100644 --- a/src/audio/player.ts +++ b/src/audio/player.ts @@ -103,8 +103,10 @@ export function buildFfmpegArgs(url: string, seekSeconds: number): string[] { "-reconnect_on_http_error", "4xx,5xx", ); } + args.push("-i", url); + // Output-side seek (after -i): works on CDNs that reject Range/keyframe seeks (NetEase music.126.net). if (seekSeconds > 0) args.push("-ss", String(seekSeconds)); - args.push("-i", url, "-f", "s16le", "-ar", "48000", "-ac", "2", "-acodec", "pcm_s16le", "-"); + args.push("-f", "s16le", "-ar", "48000", "-ac", "2", "-acodec", "pcm_s16le", "-"); return args; }