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 <noreply@anthropic.com>
This commit is contained in:
XuVIIJayandClaude Opus 4.7 committed 2026-08-20 21:07:21 +08:00
1 parent af1dac848d
commit 9fd1b39092
2 files changed
+5 -3

No files matched your search

+2 -2
View File
@@ -55,13 +55,13 @@ describe("buildFfmpegArgs", () => {
expect(idx).toBeLessThan(args.indexOf("-i")); // input options must precede -i 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 args = buildFfmpegArgs("https://example.com/song.mp3", 42);
const ssIdx = args.indexOf("-ss"); const ssIdx = args.indexOf("-ss");
const iIdx = args.indexOf("-i"); const iIdx = args.indexOf("-i");
expect(ssIdx).toBeGreaterThan(-1); expect(ssIdx).toBeGreaterThan(-1);
expect(args[ssIdx + 1]).toBe("42"); expect(args[ssIdx + 1]).toBe("42");
expect(ssIdx).toBeLessThan(iIdx); expect(ssIdx).toBeGreaterThan(iIdx);
}); });
it("does not insert -ss when seekSeconds is 0", () => { it("does not insert -ss when seekSeconds is 0", () => {
+3 -1
View File
@@ -103,8 +103,10 @@ export function buildFfmpegArgs(url: string, seekSeconds: number): string[] {
"-reconnect_on_http_error", "4xx,5xx", "-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)); 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; return args;
} }