fix: use curl pipe to bypass FFmpeg HTTP header buffer limit

The previous -max_alloc approach does not fix the 'overlong headers' error
because FFmpeg 5.1 (Debian bookworm) uses a compile-time stack-allocated
buffer (MAX_URL_SIZE=4096) for HTTP response headers, which -max_alloc
cannot change.

Instead, when the stream URL is HTTP/HTTPS, launch curl to handle the
HTTP connection and pipe its stdout to FFmpeg via stdin (pipe:0). Curl
does not have the 4096-byte header limit, so it handles oversized CDN
response headers from Douyin without error.

Additional changes:
- RequestStopAsync kills curl first (instead of sending 'q' to FFmpeg),
  causing the pipe to close and FFmpeg to exit gracefully on EOF.
- SessionProcessRuntime tracks the curl process for cleanup.
This commit is contained in:
2026-07-09 12:19:34 +08:00
parent 8a079b4698
commit ad86c080e3
3 changed files with 132 additions and 21 deletions
@@ -1905,6 +1905,7 @@ public sealed partial class FfmpegService
public bool HasRetriedWithRefreshedStream { get; }
public bool HasRetriedWithAlternateProtocol { get; set; }
public Process? Process { get; private set; }
public Process? CurlProcess { get; private set; }
public int ProcessId => Process?.Id ?? 0;
public bool CompletionRequested { get; private set; }
public bool StopRequested { get; private set; }
@@ -1977,6 +1978,7 @@ public sealed partial class FfmpegService
private bool RuntimeSourceFailureVerificationInProgress { get; set; }
public void AttachProcess(Process process) => Process = process;
public void AttachCurlProcess(Process curlProcess) => CurlProcess = curlProcess;
public void MarkStopRequested(bool markAsCompletedOnExit)
{
@@ -2094,6 +2096,11 @@ public sealed partial class FfmpegService
public void Dispose()
{
if (CurlProcess is not null)
{
try { if (!CurlProcess.HasExited) CurlProcess.Kill(true); } catch { }
CurlProcess.Dispose();
}
DanmakuCancellation.Dispose();
Gate.Dispose();
}