Chusko Blog · 2026-08-12
How Chusko casts video peer-to-peer
Chusko is browser-based P2P casting: a Projector streams local media straight to a Screen over WebRTC. Here's how pairing, the relay, and playback actually work.
Chusko is a browser-based casting tool built on a deliberately simple model: one device has the video, another device displays it, and nothing in between ever touches the media. This post walks through how it works, from the 6-character room code to the encrypted byte stream.
Two roles: Projector and Screen
Chusko splits the job into two roles, and the terms matter:
- Projector — the device that holds the local media files and controls playback. It picks the file and drives play, pause, seek, volume, and ±10 second skips.
- Screen — the device that displays the stream. It's passive: it receives the file bytes and plays them, but has no transport controls of its own.
One room has exactly one projector and as many screens as you like — handy when several displays should show the same thing.
Pairing: a room code and a QR deep link
A screen hosts a room, which produces a 6-character code drawn from an unambiguous alphabet (no confusingI/O or 0/1). The other device enters the code — or scans a QR code, whose deep link pre-fills the code so there's nothing to type. The code is the pairing: whoever holds it joins the room.
The relay only sets up the connection
The only server in Chusko is a small signaling relay. It does two things: it hands the peers a room to meet in, and it forwards one offer and one answer blob so the WebRTC connection can be established. That handshake is a few kilobytes. Once the peer connection opens, the relay is out of the path entirely — and it never carried media in the first place.
If the devices can't connect directly (both behind strict network address translation), the connection falls back to a TURN relay that forwards packets. Those packets are the WebRTC stream, which is encrypted end to end — the relay forwards bytes it cannot read.
Streaming: raw bytes, native playback, no remuxing
The video travels over a single WebRTC data channel as raw file bytes. The screen stores them in its browser's IndexedDB, keyed by file offset, and serves them to its own <video> element with standard HTTP Range semantics. The browser's native demuxer does the rest.
That design choice is what makes Chusko format-agnostic:
- MP4, MOV, WebM, MKV, Ogg — anything the browser plays natively.
- No fragmentation requirement. Files don't need to be "faststart" or fragmented; even MP4s with the moov atom at the end play correctly.
- Movies of any size, because received pieces are disk-backed blobs, not memory.
Playback control and seeking
The projector sends short control messages over the same channel: play, pause, seek, volume, end-of-stream. Seek is a plain byte-offset computation — no container alignment step — and the screen can answer from bytes it already holds, so skipping back is instant and skipping forward re-streams only the missing range.
Sessions are also resumable. A screen that reloads keeps the bytes it already received and continues instead of restarting the transfer, and the projector remembers its playhead across a reload. The philosophy throughout: the bytes live on the devices, so reconnects cost only what's missing.
What it adds up to
Pairing with a code, a handshake through a tiny relay, encrypted bytes straight between your devices, native playback of any format — that's the whole system, and that's why your media never touches a server. For the short version, see the FAQ.