- Rust 96.9%
- CSS 2.3%
- Shell 0.5%
- Makefile 0.3%
|
|
||
|---|---|---|
| build-aux | ||
| data | ||
| src | ||
| tests | ||
| .gitignore | ||
| .set_theater(!w.theater.get()));|&\n act("mute", \|w\| w.toggle_mute());| | ||
| build.rs | ||
| Cargo.lock | ||
| Cargo.toml | ||
| LICENSE | ||
| Makefile | ||
| README.md | ||
Watchplace
A native GNOME client for watching Streamplace — the livestreaming service built on the AT Protocol. Watching only: no streaming features, just a fast, clean way to find and enjoy streams.
Built with Rust, GTK 4, libadwaita and GStreamer. Talks to the Streamplace node and the public Bluesky AppView directly, using the place.stream.* lexicons — no extra servers.
Features
- Following — sign in and see who you follow the moment they go live, with the most-watched one featured up top. Offline streamers get a bell for go-live notifications, Continue watching brings back broadcasts you started, and Catch up shows recent ones. Works offline from a cache and starts instantly.
- Live — everything live, with search, sort, language and category filters tucked away in a popover. Optional shelves (Just started, Picked for you, Small and cozy) can be switched off for a minimal grid.
- Watch — low-latency playback with an optional ambient glow, auto-hiding controls, theater mode (
T), fullscreen (F), screenshots (S), a stream statistics overlay (D), the delay behind live next to the viewer count, the streamer's content warnings, and live chat with badges, name colors, replies (click to jump to the original), links, mentions, pinned messages and@/://completion. Click a name for a user card with their banner, or hide someone's messages. Chat follows new messages unless you scroll up, and can float over the video in theater mode. - Audio only — just listen (with a fraction of the bandwidth and power), from the watch menu.
- Mini player (
I) — pop the stream into a small borderless window and keep browsing. - Sign in with ATProto OAuth — one login through your browser (Watchplace never sees your password) powers Following, chat, replies, mentions and following or unfollowing streamers. Watching never needs an account.
- Live previews — hover a card for a moment to see the stream, muted.
- Quick switcher (
Ctrl+K) — jump to any live stream or streamer by typing a few letters. - Past broadcasts — streamer pages with VODs and clips, played with a seek bar (
←/→to skip), at 0.75–2× speed (</>), resuming where you left off. - Surf — lean-back channel flipping. Scroll, swipe or use the arrow keys; optional auto-advance.
- Multiview — up to four streams at once in the largest grid that fits, or a focus layout; click to choose whose audio you hear, and the chat follows along. Drag any stream card onto Multiview to add it. It comes back as you left it.
- Notifications — when someone you follow goes live, optionally running in the background and starting at login.
- Customization — light/dark style, accent color, card size, accent glow, live previews, featured banner, chat position, width, text size, timestamps, badges, name colors, latency buffer, start muted, start in theater mode, and more.
- Adaptive and accessible — works down to phone width (chat moves under the video), with a compact sidebar option, keyboard navigation throughout and named controls for screen readers.
Building
Requirements: Rust (2024 edition), GTK ≥ 4.20, libadwaita ≥ 1.8, libsoup 3, GStreamer ≥ 1.24 with gst-plugins-good/-bad, an H.264 decoder (gst-libav or VA-API) and the GTK 4 paintable sink (gstreamer1-plugin-gtk4 / gst-plugin-gtk4).
On Fedora:
sudo dnf install gtk4-devel libadwaita-devel libsoup3-devel gstreamer1-devel gstreamer1-plugins-base-devel gstreamer1-plugin-gtk4 gstreamer1-plugin-libav
Then:
cargo run # development build
make install # release build into ~/.local (PREFIX=… to change)
make flatpak # build and install the Flatpak (GNOME 51 runtime)
Keyboard shortcuts
| Keys | Action |
|---|---|
Ctrl+1 … Ctrl+4 |
Following, Live, Surf, Multiview |
Ctrl+F |
Search live streams |
Ctrl+K |
Go to a stream or streamer |
Ctrl+R |
Refresh |
Space / K |
Play / pause (live streams resume at the live edge) |
T |
Theater mode |
I |
Mini player |
S |
Save screenshot (to Pictures/Watchplace) |
D |
Stream statistics overlay |
↑ / ↓ |
Volume (watch page) |
F / double-click |
Fullscreen |
C |
Toggle chat |
M |
Mute |
R |
Jump to live |
← / → |
Seek 10 s (past broadcasts) |
< / > |
Slower / faster (past broadcasts) |
↑ / ↓ / scroll |
Previous / next stream (Surf) |
Esc |
Leave fullscreen / theater / page |
How it works
| What | Where it comes from |
|---|---|
| Who is live | place.stream.live.getLiveUsers |
| Your follows | app.bsky.graph.getFollows (public AppView) |
| Profiles | app.bsky.actor.getProfiles |
| Categories | place.stream.livestream activity and tags (lang:xx for language) |
| Recommendations | place.stream.live.getRecommendations |
| Live video | WebRTC via place.stream.playback.whep (like Streamplace's own player), falling back to HLS place.stream.playback.getLivePlaylist |
| Chat, viewers, pins, teleports, bans | the node's websocket, /api/websocket/<did> |
| Content warnings | the streamer's place.stream.metadata.configuration record on their PDS |
| Past broadcasts | place.stream.media.getVideoList, place.stream.playback.getVideoPlaylist |
| Sign-in | OAuth via the node's oatproxy: PAR + PKCE + DPoP (ES256) with its downstream client; the code returns through /api/app-return to the tv.aquareum: URI scheme Watchplace registers |
| Sending chat, following | com.atproto.repo.createRecord/deleteRecord through the node (DPoP-bound token), which forwards to your PDS |
Live streams play over WebRTC: the server pushes media continuously, which stays smooth even on long round trips, about half a second behind live. If WebRTC can't connect, Watchplace falls back to HLS, where Streamplace's ~1 s CMAF segments are re-anchored on the sink pads with an adaptive buffer (see src/player.rs). WebRTC needs GStreamer's libnice plugin (included in the Flatpak; libnice-gstreamer1 on Fedora).
Settings live in ~/.config/watchplace/settings.json, written with 0600 permissions; that includes the sign-in tokens and the DPoP key.
For the browser to hand the login back, the tv.aquareum: scheme must be registered: the Flatpak and make install do that through the desktop file. If your browser doesn't return to Watchplace, paste the address of the “Complete Login” page into the waiting dialog.
Testing
cargo test runs the unit tests. tests/ui-smoke.sh drives the main flows of a debug build in a private headless GNOME session with playwaita — signed out, with WATCHPLACE_SILENT=1 so nothing reaches a sound device.
License
GPL-3.0-or-later. Watchplace is an independent client and not affiliated with Streamplace.