Selkies
Developer Reference

selkies

WebSockets-mode streaming server: the main Selkies application module.

Owns the data WebSocket plane for the websockets transport: per-client connection handling (auth/roles, input dispatch, settings), the per-display pixelflux video captures with their bounded per-client relays, the shared pcmflux Opus audio fan-out (with the all-clients Opus+RED gate), microphone forwarding, clipboard/cursor delivery, stats collection, and the display layout/reconfiguration engine shared conceptually with the WebRTC transport (parity between the two transports, and between X11 and Wayland, is a design requirement).

Threading model: one asyncio event loop runs everything control-plane. pixelflux/pcmflux deliver frames from their own native threads; those callbacks never touch asyncio state directly — they hand zero-copy items to the loop via call_soon_threadsafe. Per-client video delivery is bounded by _VideoRelay (drop-and-resync past a byte budget) and audio by a fixed queue, so one slow client can never back pressure the shared pipeline. Blocking native calls (capture start/stop, geometry reads) run on executor threads. The Wayland path is subprocess-free by design: compositor output management, DPI-as-output-scale, and cursor sizing all go through the in-process pixelflux handle, never through forked tools.

Wire framing: text frames carry the control verbs; binary frames are typed by their first byte — 0x01 Opus audio (pcmflux's native header, sent as-is), 0x03 JPEG and 0x04 H.264 video stripes from pixelflux, 0x02 client mic PCM, WS_OPCODE_WEBCAM a webcam frame for the virtual camera, and 0x05 a gzip wrapped control text. A client that sends _gz,1 can inflate gzip: control text at or above WS_GZIP_MIN_BYTES then goes out as 0x05 frames (small, latency-critical messages such as input stay raw), and the server echoes the verb so the client gzips its own large sends, which the handler inflates back into text before dispatch. Video chunks carry a uint16 frame id that the display's owning client acknowledges (CLIENT_FRAME_ACK); the ack cadence sizes that display's backpressure window and the matched send stamps feed its smoothed RTT.

attributeBACKPRESSURE_ALLOWED_DESYNC_MS
= 2000
attributeBACKPRESSURE_LATENCY_THRESHOLD_MS
= 50
attributeBACKPRESSURE_LATENCY_FORGIVENESS_MAX_MS
= 1000
attributeRTT_SAMPLE_SANE_MAX_MS
= 10000
attributeBACKPRESSURE_CHECK_INTERVAL_S
= 0.5
attributeMAX_UINT16_FRAME_ID
= 65535
attributeFRAME_ID_SUSPICIOUS_GAP_THRESHOLD
= MAX_UINT16_FRAME_ID // 2
attributeSTALLED_CLIENT_TIMEOUT_SECONDS
= 4.0
attributeSHARED_STREAM_SEND_TIMEOUT_SECONDS
= 1.0
attributeVIDEO_RELAY_BUDGET_SECONDS
= 2.0
attributeVIDEO_RELAY_BUDGET_MIN_BYTES
= 4 * 1024 * 1024
attributeVIDEO_RELAY_SYNC_FLOOR_SECONDS
= 1.0
attributeRTT_SMOOTHING_SAMPLES
= 20
attributeAUDIO_RED_DISTANCE
= 2
attributePCMFLUX_HEALTH_INTERVAL_SECONDS
= 2.0
attributePCMFLUX_RESTART_FLOOR_SECONDS
= 30.0
attributeSENT_FRAME_TIMESTAMP_HISTORY_SIZE
= 1000
attributeVIEWER_RESUME_MIN_INTERVAL_S
= 1.0
attributeTARGET_FRAMERATE
= 60
attributeUINPUT_MOUSE_SOCKET
= settings.uinput_mouse_socket
attributeENABLE_CURSORS
= bool(settings.enable_cursors[0])
attributeDEBUG_CURSORS
= bool(settings.debug_cursors[0])
attributeENABLE_RESIZE
= bool(settings.enable_resize[0])
attributeAUDIO_CHANNELS_DEFAULT
= 2
attributeAUDIO_BITRATE_DEFAULT
= int(float(settings.audio_bitrate))
attributePIXELFLUX_VIDEO_ENCODERS
= ['jpeg', 'h264enc', 'h264enc-striped']
attributeLOGLEVEL
= logging.INFO
attributelogger_selkies_gamepad
= logging.getLogger('selkies_gamepad')
attributelogger_app
= logging.getLogger('app')
attributelogger_app_resize
= logging.getLogger('app_resize')
attributelogger_input_handler
= logging.getLogger('input_handler')
attributelogger
= logging.getLogger('main')
attributedata_logger
= logging.getLogger('data_websocket')
attributeX11_CAPTURE_AVAILABLE
= True
attributePCMFLUX_AVAILABLE
= True
attributePCMFLUX_PLAYBACK_AVAILABLE
= True
attributeIS_WAYLAND
= bool(settings.wayland[0])
attributeCURSOR_SIZEOptional[int]
= settings.cursor_size if settings.cursor_size > 0 else None
attributeGPU_ID_DEFAULT
= _EXPLICIT_GPU_ID if _EXPLICIT_GPU_ID is not None and _EXPLICIT_GPU_ID >= 0 else 0
attributeupload_pathstr
= str(getattr(settings, 'file_manager_path', '') or '~/Desktop')
attributeupload_dir_pathOptional[str]
= os.path.expanduser(upload_path)
attributeuser_tokensdict[str, dict]
= {}
attributeclient_permissionsdict[Any, dict]
= {}
attributeactive_mk_tokenOptional[str]
= None
attributewebrtc_reconcile_hookOptional[Callable[[], Awaitable[None]]]
= None
attributeWS_GZIP_MIN_BYTES
= 512
attributeWS_GZIP_OFFLOAD_BYTES
= 512 * 1024

On this page

No Headings
Edit on GitHub