Relay a live source at the source boundary, byte-exact - #128
Merged
Conversation
The source boundary was documented but unbuilt: a live channel could only be relayed as its post-ffmpeg output, and asking for the source bytes always answered SOURCE_BOUNDARY_UNAVAILABLE. Now, for the sources nixamp can read itself, it can. A Channel may read its own source and pipe it to ffmpeg rather than let ffmpeg dial it. Every chunk that goes down that pipe is first handed to whoever has tapped the source, so a tap sees exactly the bytes ffmpeg does -- the original transport stream, padding and all, not the re-muxed output that drops null packets. The tap is ended when the source starts over, so a new generation never follows the old middle, and the pipe is paced by ffmpeg's own reading through ordinary backpressure. Only the sources that can be read exactly are read this way: a transport stream from a plain http(s) URL or a local file, joined from its start, with no per-request headers and no separate audio file. Anything else stays ffmpeg's to dial, and a source-boundary relay of it is refused with the reason. The readability gate is one function, tested against each way a source can fail it. The relay encoder now carries its boundary in the envelope and the negotiation headers; a source relay taps the source, a channel relay listens to the output, and the two are different variants so a channel can serve both at once without one compressor doing the other's work. A receiver learns the boundary and the media codecs before the first byte, so a source-boundary receiver can hand the bytes to its own ffmpeg without a probe. Bringing a relay in now probes it first: a source-boundary upstream is read through this server too, so it plays here and can be relayed on again at either boundary. A source-boundary relay is a live join with no preface: the receiver's demuxer re-syncs on the next program table and keyframe, the same way a listener joining a live channel does. Tests: the readability gate; a deterministic byte-exact tap with a controlled source and a stub ffmpeg, including rollover ending the tap; an end-to-end source relay over HTTP that reassembles the original packets byte for byte from the start; and a real-ffmpeg tee reading a transport stream file. Full suite 509 pass; the one remaining failure is the pre-existing @profullstack/player web-test module resolution on this branch, unchanged from main. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MxNif5tsYq4LczgG7aE8Jp
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.
Follows #124 (merged), which shipped the relay compression baseline with the source boundary documented but unbuilt. A live channel could only be relayed as its post-ffmpeg output, and asking for the source bytes always answered
SOURCE_BOUNDARY_UNAVAILABLE. This builds the source boundary for the sources nixamp can read exactly.What it does
-probesize,-analyzeduration,-fflags, as Raw 1080p and 4K transport streams play, go live, and reach a browser #126 now passes for every TS) as fine, and rejects only real request-header flags.Tests (9, all passing)
Full suite: 545 pass, the one remaining failure is the pre-existing
@profullstack/playerweb-test module resolution, unchanged from main.Not here
Sources ffmpeg alone can reach — behind per-request headers (a yt-dlp link), a separate audio track, or a non-transport container — stay channel-boundary only, as documented.
docs/stream-compression.mdis updated for all of the above.🤖 Generated with Claude Code
https://claude.ai/code/session_01MxNif5tsYq4LczgG7aE8Jp