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.
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
# 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).
|
||||
Reference in New Issue
Block a user