Real-time capture and encode
ScreenCaptureKit captures at a configured 60 fps cap. VideoToolbox uses real-time mode, zero maximum frame delay, and no frame reordering.
Performance
Screen Ferry delivers 60 fps desktop video and less than 30 ms interactive audio latency by removing delay at every stage and refusing to accumulate stale work.
ScreenCaptureKit captures at a configured 60 fps cap. VideoToolbox uses real-time mode, zero maximum frame delay, and no frame reordering.
The Client presents the newest useful complete frame. Old queued frames and incomplete assemblies expire instead of playing late.
Decoded NV12 buffers remain GPU-friendly through BT.709 conversion in the Metal fragment shader, avoiding an extra CPU conversion and copy.
The Client communicates its viewport and the Host selects an appropriate display mode so macOS lays out a legible desktop before it is captured.
The cursor gets its own path
The Host sends cursor position, visibility, and shape independently. The Client draws the pointer locally and predicts movement immediately, then reconciles against authoritative Host state.
This avoids waiting for capture, encode, transport, decode, and presentation just to move a pointer across the screen.
flowchart LR INPUT["Local pointer movement"] --> PREDICT["Client predicts and draws"] PREDICT --> NOW["Immediate visible motion"] INPUT --> HOST["Input sent to Host"] HOST --> AUTH["Authoritative macOS cursor state"] AUTH --> RECON["Client reconciliation"] RECON --> NOW
Less than 30 ms interactive audio
Screen Ferry uses AAC-ELD at 48 kHz. Its 512-sample frames represent roughly 10.67 ms of audio. An adaptive jitter buffer reacts quickly to arrival variation and returns conservatively to its low-latency operating point.
In-band redundancy can carry up to two previous audio blocks for burst-loss recovery. The Core Audio render callback reads a prefilled ring buffer without decoding, allocating, logging, actor calls, or locks.
flowchart LR CAP["ScreenCaptureKit audio"] --> AAC["AAC-ELD · 512 samples · 10.67 ms"] AAC --> QUEUE["Bounded real-time queue"] QUEUE --> NET["Prioritized sealed datagrams"] NET --> JITTER["Adaptive jitter + redundancy"] JITTER --> RING["Prefilled lock-free ring"] RING --> OUTPUT["Core Audio output"]
Adapt without interruption
Receiver reports carry RTT, loss, decode time, render-queue depth, freezes, and delivered bitrate. The Host combines them with measured relay egress and congestion feedback.
The running VideoToolbox session adjusts bitrate and its hard one-second cap without restarting. Audio quality follows a tiered link budget rather than simply disappearing under pressure.
Turn on P2P mode to let Screen Ferry qualify a shorter direct route when it is faster.