Files
netris-nestri/apps/neshub
DatCaptainHorseandClaude Opus 5.5 471d08d20f fix(neshub): pick a codec every connected client can decode
Each client states what it decodes when it connects, and the hub passed
each statement to the encoder as it arrived. The newest client decided, so
a client that only decodes H.264 lost its picture as soon as one that
decodes AV1 or H.265 joined.

The hub now keeps every client's statement and gives the encoder their
intersection, recomputed when a client joins, when one leaves, and when the
controller returns to automatic. A room settles on the best codec all of
its clients share, and moves up again once the client holding it back has
left. Manual mode still leaves the encoder alone; the change is applied
when the mode goes back to automatic.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 12:55:08 +03:00
..
2026-08-26 18:54:09 +03:00

neshub

One connection out of the box.

Everything inside the guest that produces or consumes a stream talks to neshub over a Unix socket. neshub muxes it all into a single iroh QUIC endpoint and fans client input back the other way. A client dials that endpoint with a ticket and gets video, audio, cursor and stats on it.

The sockets

socket default direction carries
--video-ipc /tmp/nestri-video.sock nescapture → neshub encoded video frames
--audio-ipc /tmp/nestri-audio.sock neswire → neshub Opus packets
--input-ipc /tmp/nestri-input.sock neshub ↔ nescope input out, cursor and stats back
--stats-ipc /tmp/nestri-stats.sock nescapture → neshub encoder stats
--screenshot-ipc /tmp/nestri-screenshot.sock neshub → nescope a picture of the screen, on request
--ticket-ipc /tmp/nestri-ticket.sock neshub → nesinit the ticket, once
— /tmp/nescapture-cmd.sock neshub → nescapture IDR requests, encode settings

neshub is the listener on every one of them and the other side dials in. That is deliberate: it removes the startup ordering problem entirely, since a producer that is not running yet simply has not connected yet.

The ticket

nestri:<base64 of {endpoint_addr, stream_name}>

Generated once per boot, when the endpoint binds. It is served on a socket rather than printed because stdout here is a log file inside a virtual machine and the person who needs it is outside one — nesinit reads it and carries it to the host.

What it does not do

neshub does not start the payload, know its name, or decide when the box is finished — nesinit owns all three, and shuts the VM down around this process. The same neshub binary serves a game, a desktop, or anything else that draws to nescope, because it never learns which one it is looking at.

Running it

cargo run --bin neshub                    # every socket at its default
cargo run --bin neshub -- --relay none    # direct connections only
RUST_LOG=neshub=debug cargo run --bin neshub