You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit d6c50b8
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: docs/selkies/components/baseimages.md
+4-3Lines changed: 4 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -24,13 +24,14 @@ There is deliberately **no `latest` tag** for base images. Downstream images pin
24
24
## What is inside
25
25
26
26
-**The LSIO foundation**: each tag builds on the corresponding LinuxServer.io distro baseimage, inheriting s6-overlay init, the `abc` user with PUID and PGID remapping, `TZ`, Docker mods, and the `/custom-cont-init.d` and `/custom-services.d` hooks.
27
-
-**Selkies** (pinned commit) installed into the `/lsiopy` virtualenv, with pixelflux 2.x and pcmflux 2.x, plus [Pelorus](pelorus.md) preinstalled.
27
+
-**Selkies** (pinned release) installed into the `/lsiopy` virtualenv, with pixelflux 2.x and pcmflux 2.x, plus [Pelorus](pelorus.md) preinstalled.
28
28
-**The web client**: prebuilt dashboards under `/usr/share/selkies/`, selected at runtime by the `DASHBOARD` variable.
29
-
-**Display servers for both stacks**: labwc (built from source with a small IPC patch that adds the window query socket Pelorus uses) for Wayland, and an XLibre Xvfb built with glamor and DRI3 plus Openbox for X11. The Xvfb carries a LinuxServer patch that keeps the screen pixmap on the GPU and lets the framebuffer follow RandR resizes, which is what makes zero copy capture possible on X11. Both are prebuilt per distro in [selkies-layers](https://github.com/linuxserver/selkies-layers) and copied into the image. A patched wlroots build makes the compositor survive pixman rendering faults instead of crashing.
29
+
-**Display servers for both stacks**: labwc (built from source with two small patches: the IPC socket Pelorus queries windows over, and a control socket Selkies asks for a second screen over) for Wayland, and an XLibre Xvfb built with glamor and DRI3 plus Openbox for X11. The Xvfb carries four LinuxServer patches: the screen pixmap lives on the GPU and the framebuffer follows RandR resizes, which is what makes zero copy capture possible on X11; it starts with spare outputs a second display is plugged into as a real monitor; DRI3 presents synchronize explicitly through timeline syncobjs where the driver supports them; and its fake vblank runs at the rate the session is captured at. Both are prebuilt per distro in [selkies-layers](https://github.com/linuxserver/selkies-layers) and copied into the image, along with wlroots 0.19.3 on distros that do not package it.
30
30
-**[Selkies Desktop](selkies-desktop.md)** at `/usr/bin/selkies-desktop`, activated by env var.
31
-
-**Nginx**with the fancyindex module, serving the client, proxying the WebSocket, handling basic auth, subfolder support, and the `/files` download index.
31
+
-**Nginx**serving the client, proxying everything under `/api` (the WebSocket, WebRTC signaling, files, printing, and the operator API) to Selkies, handling basic auth, the subfolder prefix, and the `/pelorus/` proxy.
32
32
-**PulseAudio** with null sinks (`output` and `input`) wired for stream audio and microphone return.
33
33
-**Gamepad plumbing**: the input interposer and fake udev libraries, preloaded globally, with device nodes created at init.
34
+
-**Printing**: `cups-daemon` and `cups-filters`, which Selkies runs as the session user so a printed document reaches the browser.
34
35
-**Quality of life**: passwordless sudo for the desktop user, all system locales prebuilt for `LC_ALL`, `proot-apps` synced into the user home for persistent app installs, Docker in Docker support for privileged containers, and notification support.
Copy file name to clipboardExpand all lines: docs/selkies/components/pelorus.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -19,7 +19,7 @@ docker run --rm -it \
19
19
`PELORUS=true` in Wayland mode does all of this automatically:
20
20
21
21
- Starts the Pelorus FastAPI server (port 5100 internally, proxied by the container's Nginx at `/pelorus/`)
22
-
- Enables the pixelflux **Computer Use API** on port 5000 internally (`PIXELFLUX_CU=5000`), the raw input injection and screenshot layer
22
+
- Enables the pixelflux **Computer Use API** on port 5000 internally (`PIXELFLUX_CU=5000`), the raw input injection and screenshot layer. That server binds loopback and expects a bearer token (`PIXELFLUX_CU_TOKEN`) on every request
23
23
- Starts the AT-SPI accessibility registry and forces the accessibility bridge on for GTK and Qt applications so their UI trees are readable
24
24
- On labwc, starts the compositor with its IPC socket (`labwc -i`) so windows can be enumerated; on KDE, window data comes from KWin over D-Bus
Copy file name to clipboardExpand all lines: docs/selkies/components/pixelflux.md
+11-8Lines changed: 11 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,11 +8,11 @@ Pcmflux is its audio sibling: it captures PulseAudio output and encodes Opus fra
8
8
9
9
## What it actually is
10
10
11
-
As of the 2.0.0 release, pixelflux is a **Rust** library exposed to Python through PyO3 (earlier versions were C++ with ctypes). One extension module contains:
11
+
pixelflux is a **Rust** library exposed to Python through PyO3. One extension module contains:
12
12
13
13
- An **X11 backend**: DRI3 capture that blits the GPU resident screen into DMA-BUFs the encoder imports in place, and XShm capture with XFixes cursor tracking where that does not apply.
14
14
- A **Wayland backend**: a full headless Wayland compositor built on [Smithay](https://github.com/Smithay/smithay), running in process. This is the key architectural point of the Wayland stack: **pixelflux does not capture a Wayland compositor, it is the compositor.** It synthesizes the output, seat, and clipboard itself, which is why the framebuffer can live directly on a GPU and why input is injected through its API rather than tools like xdotool.
15
-
- Six codecs across software and hardware encoders, and the damage tracking, paint over, and rate control logic shared between them.
15
+
- Six codecs across software and hardware encoders, and the damage tracking, paint over, and rate control logic shared between them. Beyond NVENC and VA-API the hardware side also drives a Jetson's Tegra encoder through the vendor's V4L2 libraries and stateful V4L2 memory to memory encoders on other boards.
16
16
17
17
## Encoders
18
18
@@ -27,7 +27,7 @@ Every codec is selected by name (`codec = "h264"` and so on) and pixelflux resol
27
27
| VP9 | libvpx | No | Yes | Full frame | Profile 1 on libvpx and VA-API |
28
28
| AV1 | SVT-AV1 | Ada and newer | Where the GPU has an engine | Full frame | No |
29
29
30
-
Hardware encoders are loaded at runtime: NVENC through the driver's `libnvidia-encode` and `libcuda` with no CUDA toolkit, VA-API and the software H.265, VP8, VP9, and AV1 encoders through the system FFmpeg's `libavcodec`. The official wheels are GPL builds with x264 and x265; a `PIXELFLUX_ENABLE_GPL=0` source build swaps in OpenH264 and kvazaar and keeps everything else.
30
+
Hardware encoders are loaded at runtime: NVENC through the driver's `libnvidia-encode` and `libcuda` with no CUDA toolkit, VA-API through the host's `libva` with the session writing the codec headers itself. The software encoders are linked directly, libvpx, x265, and SVT-AV1 built into the wheel, so nothing links or loads FFmpeg. The official wheels are GPL builds with x264 and x265; a `PIXELFLUX_ENABLE_GPL=0` source build swaps in OpenH264 and kvazaar and keeps everything else. Every encoder also reports which formats it codes (`420-8`, `444-8`, `420-10`, `444-10`), which is how Selkies knows where FullColor and 10-bit reach the stream.
31
31
32
32
### Striped encoding
33
33
@@ -47,8 +47,9 @@ The signature quality feature. After a region has been static for a configurable
47
47
48
48
### Rate control
49
49
50
-
-**CRF/CQP mode** (default): constant quality, bits go wherever needed.
51
-
- Infinite GOP by default: keyframes are only sent on demand (client join, recovery, or an optional periodic interval). Bitrate, framerate, and quality are all adjustable live without restarting the capture.
50
+
-**CRF/CQP mode**, the containers' default: constant quality on one quality index mapped onto each codec's quantizer, bits go wherever needed.
51
+
-**CBR mode**, upstream's default: a bitrate target with a one and a half frame VBV, which Selkies' congestion control steers down to what the link carries. A still screen is still refined to the paint over quality, through the rate control rather than a burst.
52
+
- Infinite GOP by default: keyframes are only sent on demand (client join, recovery, or an optional periodic interval), and a frame a client lost is predicted past rather than answered with a keyframe on every encoder that lets the session name its references. Bitrate, framerate, and quality are all adjustable live without restarting the capture.
52
53
53
54
## Zero copy
54
55
@@ -81,14 +82,16 @@ capture = ScreenCapture()
81
82
capture.start_capture(on_frame, settings)
82
83
```
83
84
84
-
Each encoded stripe arrives with a compact binary header (6 bytes for JPEG, 10 for the video codecs carrying frame type and codec id, frame number, stripe offset, and dimensions) that the web client parses to place stripes on the canvas. Headers can be omitted for embedding in your own protocol.
85
+
Each encoded stripe arrives with a compact binary header (6 bytes for JPEG, 12 for the video codecs carrying frame kind and codec id, frame number, stripe offset, dimensions, and the id of the frame it predicts from) that the web client parses to place stripes on the canvas. Headers can be omitted for embedding in your own protocol.
85
86
86
87
The Wayland backend additionally exposes input injection (keyboard by scancode with a hot swappable XKB keymap, absolute and relative pointer, buttons, scroll), clipboard get and set, cursor callbacks delivering PNG cursor images out of band, and live rate updates. `example/screen_to_browser.py` in the repository is a complete working WebSocket streaming server in one file, with a matching browser client in `example/index.html`.
87
88
88
89
## Extras worth knowing about
89
90
90
-
-**Computer Use API**: setting the `PIXELFLUX_CU=<port>` environment variable starts a small HTTP server with a `POST /computer-use` endpoint accepting JSON actions (`screenshot`, `left_click`, `type`, `key`, `scroll`, `zoom`, and friends). This is the raw input and vision layer that [Pelorus](pelorus.md) builds on.
91
+
-**Computer Use API**: setting the `PIXELFLUX_CU=<port>` environment variable starts a small HTTP server with a `POST /computer-use` endpoint accepting JSON actions (`screenshot`, `left_click`, `type`, `key`, `scroll`, `zoom`, and friends). A bare port binds loopback only, and every request has to carry the bearer token `PIXELFLUX_CU_TOKEN` names. This is the raw input and vision layer that [Pelorus](pelorus.md) builds on.
91
92
-**Recording sink**: point `recording_socket` (or `PIXELFLUX_RECORDING_SOCKET`) at a Unix socket path and pixelflux serves the raw elementary stream to any connected client, forcing a keyframe when someone connects: Annex B for H.264 and H.265, an OBU stream for AV1, IVF for VP8 and VP9. Requires a full frame codec, striped H.264 and JPEG are not served.
93
+
-**MP4 recorder**: a crash safe fragmented MP4 recorder of its own, H.264 with the session's audio muxed in from pcmflux's Ogg Opus socket, which the Selkies operator API starts and stops.
94
+
-**Virtual camera**: decodes a browser's webcam uplink into the V4L2 device the [web client](../user-guide/web-client.md#webcam) feature rides on.
92
95
-**Watermarking**: composite a PNG over the stream at any corner, centered, or animated (it bounces). On the GPU path the watermark is composited before encode with no readback penalty.
93
96
-**Fractional scaling**, HiDPI support, and cursor theme control on the Wayland backend.
94
97
@@ -98,4 +101,4 @@ The library itself is configured purely through `CaptureSettings`. The familiar
98
101
99
102
## Building from source
100
103
101
-
`pip install .` drives a `setuptools-rust` build. On Debian or Ubuntu the build dependencies are roughly: `python3-dev cmake nasm libclang-dev libavcodec-dev libavutil-dev libx264-dev libturbojpeg0-dev libgbm-dev libdrm-dev libwayland-dev libinput-dev libxkbcommon-dev libva-dev` plus a Rust toolchain. Any system FFmpeg from 6.0 through 9.0 works, it supplies the VA-API encoders and the software H.265, VP8, VP9, and AV1 encoders, so a codec whose encoder that FFmpeg lacks has no software path. Most users should just take the prebuilt wheels.
104
+
`pip install .` drives a `setuptools-rust` build. On Debian or Ubuntu the build dependencies are roughly: `python3-dev cmake nasm libclang-dev libx264-dev libx265-dev libvpx-dev libsvtav1enc-dev libdav1d-dev libde265-dev libgbm-dev libdrm-dev libwayland-dev libinput-dev libudev-dev libxkbcommon-dev libpixman-1-dev` plus a Rust toolchain of 1.89 or newer. No FFmpeg and no libva development package is needed: the codec libraries are linked directly and libva is opened at runtime. libjpeg-turbo is vendored. Most users should just take the prebuilt wheels.
Copy file name to clipboardExpand all lines: docs/selkies/components/sealskin-apps.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -72,6 +72,8 @@ Scripts can also do first run setup, seeding emulator configs, installing deskto
72
72
73
73
Stores are cached server side with ETag revalidation and refreshed hourly, so updates propagate automatically. Custom store apps can point at any image, including your own images built with the [Developer Guide](../developer-guide/building-images.md), which makes the registry the natural distribution channel for in house apps on a SealSkin deployment.
74
74
75
+
A second kind of catalog sits beside the app stores: **PRoot Apps catalogs**, folders of portable applications built with `proot-apps localrepo`, which SealSkin fetches on every node, assigns to users and groups, and mounts into sessions as `PA_REPO_FOLDER`, so the sidebar's apps section installs from your catalog rather than the public one. See [Installing Applications](../user-guide/installing-apps.md).
76
+
75
77
## Related lists
76
78
77
79
The website app showcase at [sealskin.app](https://sealskin.app) maintains a compact JavaScript list of the fleet (`apps.js`) for display purposes; the YAML manifest in this repository is the operational source of truth that servers actually consume.
0 commit comments