Files
omarchy-screencast/README.md
T
alan 1ed57291f9 Screencast: cast the desktop to Cast, DLNA and AirPlay receivers
An Omarchy shell plugin: a Python/asyncio daemon that discovers network
displays and serves an encoded screen capture for them to pull, plus a
Quickshell bar widget and panel to drive it.

The screen comes from the xdg-desktop-portal ScreenCast interface (asked
for every time, never remembered), goes through GStreamer, and is served
from a local HTTP port. Desktop audio is mixed in from the default
output's monitor. The container follows the receiver: WebM/VP8 for Cast,
MPEG-TS/H.264 for DLNA, HLS for AirPlay video.

The stream port has to be reachable from the LAN, and none of these
protocols can carry a credential, so the capability is the URL: a fresh
random path per session, refused to anything off the LAN, capped at four
concurrent readers.
2026-08-29 19:57:54 +01:00

88 lines
3.5 KiB
Markdown

# Screencast
An [Omarchy](https://omarchy.org) shell plugin that finds the displays on your
network and casts this desktop to them, with the controls in the bar.
Google Cast (Chromecast, Google TV, Nest), DLNA/UPnP TVs, and AirPlay video.
The screen is captured through the `xdg-desktop-portal` ScreenCast interface,
encoded with GStreamer, and served from a local HTTP port that the receiver
pulls from. Desktop audio is mixed in from the default output's monitor.
> **Status: early. Looking for testers.** It works here on Cast; DLNA and
> AirPlay have had far less exercise. Bug reports welcome.
## Install
```bash
omarchy plugin add https://github.com/alanfortlink/omarchy-screencast --enable
```
On first run the plugin builds a private virtualenv under
`~/.local/lib/screencast` for its daemon. That needs no password. It does need
these Arch packages, and it will tell you in the panel if any are missing:
```
gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugin-pipewire
gst-libav xdg-desktop-portal xdg-desktop-portal-hyprland
```
Remove with `omarchy plugin remove io.github.alanfortlink.screencast`.
## Using it
Click the cast icon (󰄘), click a display. The portal asks which screen to
share every time — the choice is deliberately never remembered. While casting
you get stop, pause, change-screen, a live preview and the receiver's volume.
Quality, bitrate, desktop audio and pointer visibility are at the bottom of the
panel.
Keys while the panel is open: `↑`/`↓` and `Enter` to cast, `r` rescan, `s` stop,
`p` pause, `Esc` close.
For a keybinding:
```
bind = SUPER SHIFT, C, exec, omarchy-shell io.github.alanfortlink.screencast cast "TV name"
bind = SUPER SHIFT, X, exec, omarchy-shell io.github.alanfortlink.screencast stop
```
The same from a terminal: `screencast-server devices | cast "TV name" | status |
stop | pair "TV name"`.
Settings live in `~/.config/screencast/config.json` (`fps`, `maxHeight`,
`bitrate`, `encoder`, `audio`, `cursor`, `port`, `autoReconnect`) and the panel
writes the same file.
## Two things to know
**It is not low latency.** Cast, DLNA and AirPlay video are *pull* protocols:
you hand the device a URL and it buffers. Expect one to three seconds, same as
casting a tab from a phone. Fine for a film, a talk or a dashboard; wrong for
playing a game on the TV. Low-latency mirroring means Miracast or real AirPlay
mirroring, neither of which has a working Linux sender.
**The receiver connects to you**, so a default-deny inbound firewall — which
Omarchy sets up — silently drops it. The panel notices and offers a button that
opens the port for your subnet only, through one polkit password dialog.
Nothing to type.
AirPlay here is AirPlay *video*, not mirroring (mirroring needs Apple's
FairPlay handshake). Apple TVs and most AirPlay 2 TVs accept it; some want
pairing first, via the **Pair** button on the row. Support comes from `pyatv`,
which is installed best-effort — if it fails, Cast and DLNA carry on.
## Troubleshooting
* **Nothing found.** mDNS and SSDP do not cross subnets, VPNs, or the client
isolation some routers apply to Wi-Fi. Compare with
`avahi-browse -rt _googlecast._tcp`.
* **The TV spins forever.** Almost always the firewall above.
* **Stutter.** Lower the bitrate or resolution; Wi-Fi is usually the limit.
Cast is the one path that encodes VP8 on the CPU.
* **Logs.** `~/.local/state/screencast/daemon.log`, and
`~/.cache/screencast/install.log` for the install.
## Licence
MIT — see [LICENSE](LICENSE).