refactor(ffmpeg): share the ffmpeg stdin write and cleanup between fetch paths - #170
Merged
Merged
Conversation
…tch paths The curl_cffi and aiohttp streaming paths each inlined their own chunk write to ffmpeg stdin and carried a byte-identical stdin close/wait_closed cleanup block. Extracted _write_to_ffmpeg() and _close_ffmpeg_stdin() and used them from both, removing the three duplicated blocks. The aiohttp path now also skips writes while stdin is closing, a guard the curl_cffi path already had. The two transports themselves are deliberately left separate: curl_cffi exists for TLS impersonation to get past Cloudflare, which aiohttp cannot do, so they are different capabilities rather than duplicated logic. Retry parity between them is tracked in #169, since doing it correctly needs Range-resume in the curl_cffi path and cannot be verified without a live voice server and a real Cloudflare-protected source. Bumps VERSION to 1.8.22. Closes #150 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Co-Authored-By: Dolly132 <109222243+Dolly132@users.noreply.github.com>
Rushaway
commented
Sep 5, 2026
Rushaway
left a comment
Member
Author
There was a problem hiding this comment.
Self-review: this is the PR where I deliberately did less than the issue asked. The full transport abstraction would be a big rewrite of the audio hot path that I cannot test here (no live voice server, no real Cloudflare source), and the retry parity needs Range-resume across a thread boundary to avoid restarting playback from byte 0. I extracted the part that is genuinely duplicated and verifiable, and split the rest to #169 with the reasoning written down. Push back if you would rather I attempt the full unification.
This was referenced Sep 5, 2026
Dolly132
approved these changes
Sep 6, 2026
Dolly132
left a comment
Collaborator
There was a problem hiding this comment.
Can't say no to reusable code, so LGTM
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
close()/wait_closed()cleanup block (three duplicated blocks in total)._write_to_ffmpeg()and_close_ffmpeg_stdin()and used them from both paths.What I deliberately did not do, and why
The issue asked to "unify into one fetch abstraction with a pluggable transport wrapped by a single shared retry policy." I don't think that's the right change to ship blind, and here's the reasoning:
The two transports aren't gratuitous duplication.
curl_cffiis there forimpersonate="chrome120"— TLS fingerprint impersonation, which is precisely what gets past Cloudflare and which aiohttp fundamentally cannot do.aiohttpgives async-native streaming plus retry/Rangeresume and SOCKS support. They're different capabilities that happen to both end in "write bytes to ffmpeg" — and that ending is exactly the part I extracted.The retry inconsistency is real, but fixing it properly is its own job. Naive retry on the curl_cffi path would restart the stream from byte 0 mid-playback (audible repetition); doing it right needs
Rangeresume tracking across a thread boundary. And none of it is verifiable here — no live voice server, no real Cloudflare-protected source. This is the audio hot path; an unverified rewrite of it fails in production rather than in review. Tracked in #169 with the specifics, for someone who can test it end to end.Happy to go further if you'd rather, but I didn't want to hand you a large, untested rewrite of streaming under a "refactor" label.
Closes #150
Test plan
Exercised both extracted helpers with stubs:
is_closing().ffmpeg_processisNone(both helpers)._close_ffmpeg_stdin()closes stdin; no crash with no process.🤖 Generated with Claude Code