Skip to content

Local test sink destination: rehearse the whole pipeline with zero risk#34

Merged
Soulhackzlol merged 2 commits into
mainfrom
feat/local-test-sink-destination
Jul 5, 2026
Merged

Local test sink destination: rehearse the whole pipeline with zero risk#34
Soulhackzlol merged 2 commits into
mainfrom
feat/local-test-sink-destination

Conversation

@Soulhackzlol

Copy link
Copy Markdown
Owner

Stacked on #33 - merge that first; GitHub retargets this one to main automatically.

What

The in-binary RTMP sink (instantclone sink) becomes a destination type. Pick Local test sink in the Destinations tab and InstantClone spawns its own tiny receiver on this PC and streams to it. No platform account, no stream key, nothing leaves the machine - test arm/activate/cut (and vertical) end to end before touching a real key.

How

  • Managed child process. The egress supervisor owns one instantclone sink child for all sink destinations: spawned when one is enabled (before the pump dials, so the receiver is listening first), killed when the last is disabled or removed, reaped and respawned (10 s throttle) if it dies, kill_on_drop so app exit takes it down, CREATE_NO_WINDOW so nothing flashes.
  • Fixed high ports (rtmp :19350, player :19351) so manual sink runs on the documented :1936/:1937 defaults and the e2e script never collide with the managed instance.
  • Feedback where you can see it. The sink's [sink] log lines (publish accepted, the 1 Hz stat windows) are forwarded into the dashboard's Logs tab, and the destination card gets a ▶ Watch output link to the sink's built-in live player - watch exactly what a platform would receive, delay and cuts included.
  • Form UX. The stream-key field hides for sink (any key works), and an open-by-default disclosure explains the feature inline. The first-run wizard deliberately does not offer it: the wizard writes the legacy single-destination config and its job is wiring your real platform.

Verification

  • cargo fmt --check, clippy --all-targets -- -D warnings, cargo test --release: 235 passed (new config test: sink destination is self-contained - fixed URL, well-formed and valid with no key).
  • Verified live end to end: app started with an enabled sink destination -> child spawned and both ports answered; a real ffmpeg publish flowed proxy -> sink with "publish accepted" landing in the dashboard log; the card reported alive + bitrate; the built-in player served on :19351; disabling the destination killed the child and freed the ports, with the stop logged.

@Soulhackzlol Soulhackzlol added the enhancement New feature or request label Jul 4, 2026
The in-binary RTMP sink existed only as a CLI tool, so "just try the
app" still meant either a real stream key or a second terminal. Now
"Local test sink" is a destination type: pick it in the Destinations
tab and InstantClone spawns its own receiver on this PC and streams to
it. No platform, no key, nothing leaves the machine - arm/activate/cut
(and vertical) can be tested end to end before touching a real key.

Details:

- config: platform "sink" resolves to a fixed local URL on new high
  ports (rtmp :19350, player :19351) so manual sink runs on the
  documented :1936/:1937 defaults never collide with the managed one.
  Validation treats it as self-contained (no key required).
- main: the egress supervisor owns one child process for all sink
  destinations - spawned on enable (before the pump dials, so the
  receiver is listening first), killed on disable/remove, reaped and
  respawned (10s throttle) if it dies, kill_on_drop so app exit takes
  it down, CREATE_NO_WINDOW so no console flashes. Its "[sink]" log
  lines are forwarded into the dashboard's Logs tab.
- web: /platforms gains the sink entry with an inline explainer
  (open-by-default disclosure in the destination form).
- UI: the form hides the stream-key field for sink; the card gets a
  "Watch output" link to the sink's built-in live player, its own
  stripe color, and a house icon. The first-run wizard deliberately
  does not offer sink - it writes the legacy single-destination config
  and its job is wiring the real platform.

Verified live: app spawns the child with the destination, ffmpeg
publish flows proxy -> sink ("publish accepted" in the dashboard log),
the card reports alive + bitrate, the player answers on :19351, and
disabling the destination kills the child and frees the ports.
235 tests green; fmt + clippy -D warnings clean.
@Soulhackzlol
Soulhackzlol force-pushed the feat/local-test-sink-destination branch from 1f39ac1 to fcb2892 Compare July 4, 2026 22:48
@Soulhackzlol
Soulhackzlol changed the base branch from feat/cut-after-this-airs to main July 5, 2026 12:32
@Soulhackzlol
Soulhackzlol merged commit f8cf741 into main Jul 5, 2026
4 checks passed
@Soulhackzlol
Soulhackzlol deleted the feat/local-test-sink-destination branch July 5, 2026 12:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant