# Ocula
A small Rust screen recorder designed to fail safely. The GUI binary is `ocula`; the CLI binary is `oculo`.
It records through the desktop screencast portal on Wayland and can use direct X11 capture on X11. Output is written to a temporary file in the same directory, finalized with EOS on stop, synced, then atomically renamed to the final `.mp4`, `.mkv`, or `.gif` file.
## Why This Is Harder To Break
- Uses `xdg-desktop-portal` and PipeWire instead of brittle screenshot loops.
- Defaults to MP4/H.264 for compatibility, while keeping MKV/MJPEG available as the safest high-throughput option.
- Handles Ctrl-C and SIGTERM by sending EOS before stopping, so muxers can finalize.
- Writes to `*.part` first, then renames into place only after GStreamer has stopped.
- Creates the output directory automatically and avoids overwriting existing recordings unless asked.
- Probes existing output directories or their nearest existing parents for writability before capture setup.
- Can fall back to X11 capture when running under X11.
- Supports selected-region recording with `--area` or X11/XWayland on-screen selection.
- Includes opt-in GLSL styles with refined neon edge, glass refraction, prism, aurora, glitch, and kaleidoscope math, with matching effect-aware area selection visuals.
- Downscales large full-screen recordings to 1080p by default so 4K screens do not overload software encoders, without upscaling smaller captures.
- Keeps raw video buffering small and drops stale raw frames under encoder pressure so recording stays real-time instead of building huge lag.
- Captures the selected-area preview asynchronously after framing or refinement, without blocking GTK or repeatedly reading the desktop while idle.
- Uses a short fallback-preview animation, then stops its animation source completely until the preview state changes.
- Caps capture framerate without manufacturing duplicate frames and feeds software H.264/VP8 explicit `I420` input to reduce negotiation/conversion overhead.
- Skips unnecessary color conversion for direct X11/MJPEG capture.
- Chooses default H.264/VP8 bitrates from effective output size and FPS, while preserving explicit `--bitrate` exactly.
No recorder can save a file after `SIGKILL`, power loss, kernel crash, or disk failure, but this is built to preserve recordings for normal crashes, errors, and interrupts as much as GStreamer allows.
## Requirements
- Rust 1.92+
- GStreamer 1.22+
- GStreamer plugins: `matroskamux`, `jpegenc`, `videoscale`, `videocrop`, `pipewiresrc` for Wayland, `ximagesrc` for X11, `opusenc` for MKV audio
- Default MP4 plugins: `mp4mux`, `openh264enc` or a supported hardware H.264 encoder, `h264parse`, and an AAC encoder such as `fdkaacenc` for MP4 audio
- Optional GIF plugin: `gifenc`
- For Wayland: `pipewire`, `xdg-desktop-portal`, and a portal backend such as GTK, KDE, GNOME, or wlr
- For X11 fallback: `ximagesrc`
- X11/XWayland for on-screen interactive crop selection; on Wayland the actual recording still uses the desktop portal unless `--backend x11` is explicitly requested
- PulseAudio-compatible default input/output devices when `--audio mic`, `--audio system`, or `--audio both` is used
On Wayland, `--backend auto` uses the desktop portal for recording. Interactive crop selection may use an X11/XWayland overlay for the drag UI, then the selected area is applied to the portal stream so native Wayland desktops do not record as black X11/XWayland frames.
## Build
```sh
cargo build --release
```
Install from crates.io:
```sh
cargo install ocula --locked
```
## Use
### Desktop App
Launch the native desktop app:
```sh
cargo run --release --bin ocula
```
After install, launch it with:
```sh
ocula
```
The desktop app is a compact cyan capture console with:
- Screen, Window, and Area capture modes.
- Audio, cursor visibility, MP4/MKV/GIF format, encoder, and output controls.
- A fixed record dock that keeps status and start/stop controls visible while settings scroll.
- `Ctrl+R` to start or stop recording from anywhere in the window.
- A collapsible Details log that appears only when Ocula has something useful to report.
#### Area Workflow
1. Choose **Area**.
2. Click **Frame Area** or the preview panel.
3. Drag over the desktop and release to accept the new frame.
4. Click **Refine Frame** or the preview again to move or resize the existing frame.
5. Release after adjusting, or press Enter/Space without moving it, to keep the frame.
The preview is a single asynchronous snapshot captured immediately after selection or refinement. It is intentionally not a continuous desktop feed, so leaving Ocula open does not repeatedly capture and convert screen-sized images. The snapshot is discarded and replaced when the selected geometry changes.
When X11/XWayland overlays are available, Ocula keeps a thin cyan frame around the selected desktop region. The frame is stacked outside the capture bounds and behind Ocula. While dragging, the selector draws only a crisp lightweight border; handles, dimensions, grid, and Holo accents return when the frame is stationary.
On Wayland, the overlay is only used for interaction and framing. Recording still goes through the desktop portal, avoiding black X11/XWayland captures. Optional GLSL recording effects remain available from the CLI.
### CLI
Run the CLI directly after install:
```sh
oculo --mode screen
```
Start from an interactive chooser in the current directory:
```sh
cargo run --release --bin oculo --
```
The chooser supports screen or monitor, window, area, audio, pointer visibility, and output-path choices. Use explicit flags below when scripting or when you do not want a prompt.
Record to a directory:
```sh
cargo run --release --bin oculo -- --dir ~/Videos
```
Record with microphone audio:
```sh
cargo run --release --bin oculo -- --audio mic
```
Record a selected region by coordinates:
```sh
cargo run --release --bin oculo -- --area 100,100,1280,720
```
Record a screen through the normal backend chooser:
```sh
cargo run --release --bin oculo -- --mode screen
```
Record a specific X11 monitor:
```sh
cargo run --release --bin oculo -- --list-monitors
cargo run --release --bin oculo -- --backend x11 --monitor 1
```
Record a window through the desktop portal:
```sh
cargo run --release --bin oculo -- --mode window --backend portal
```
Select multiple monitor streams through the desktop portal:
```sh
cargo run --release --bin oculo -- --multiple
```
Record a selected region interactively with Ocula's built-in CLI selector:
```sh
cargo run --release --bin oculo -- --mode area
```
On Wayland laptops, Ocula uses X11/XWayland only for the on-screen drag overlay when available and records through the portal. Pass `--area X,Y,WIDTH,HEIGHT` directly when scripting or when no X11/XWayland display is available.
Selector controls:
- Drag and release to create a region.
- In refinement mode, move the frame or resize it from edge and corner handles, then release.
- Arrow keys move; Shift+arrows resize; Ctrl changes keyboard steps to 10 px.
- Delete or Backspace clears the region.
- Press Enter/Space to keep an unchanged frame; press Escape or right-click to cancel.
Record MKV instead of the default MP4:
```sh
cargo run --release --bin oculo -- --format mkv --output capture.mkv
```
MP4 uses H.264 video for compatibility. MKV remains available because it is faster to start, supports the MJPEG path, and is safer for interrupted recordings. GIF is video-only, defaults to 15 FPS unless `--fps` is provided, and requires `gifenc`.
Record with an optional GLSL effect from the CLI when GStreamer OpenGL elements are installed:
```sh
cargo run --release --bin oculo -- --effect neon
cargo run --release --bin oculo -- --effect heatmap
cargo run --release --bin oculo -- --effect glitch
cargo run --release --bin oculo -- --effect ripple
cargo run --release --bin oculo -- --effect glass
cargo run --release --bin oculo -- --effect crt
cargo run --release --bin oculo -- --effect holo
cargo run --release --bin oculo -- --effect vapor
cargo run --release --bin oculo -- --effect fracture
cargo run --release --bin oculo -- --effect prism
cargo run --release --bin oculo -- --effect aurora
cargo run --release --bin oculo -- --effect kaleido
```
Effects use `glupload`, `glshader`, and `gldownload`; Ocula preflights those plugins before capture starts. Available effects are `neon`, `heatmap`, `glitch`, `ripple`, `glass`, `crt`, `holo`, `vapor`, `fracture`, `prism`, `aurora`, and `kaleido`.
Record GIF when the GStreamer `gifenc` plugin is installed:
```sh
cargo run --release --bin oculo -- --format gif --audio none --output capture.gif
```
Record full resolution instead of the default 1080p safety downscale for large screens:
```sh
cargo run --release --bin oculo -- --no-scale
```
Stop with Ctrl-C. Press Ctrl-C a second time to abort immediately.
Audio capture is preflighted before area selection, portal consent, and output reservation. If the default microphone or system-audio monitor is unavailable, Ocula fails before creating an output file.
Useful flags:
```sh
--fps 30
--codec auto|mjpeg|h264|vp8
--h264-encoder auto|hardware|software
--effect none|neon|heatmap|glitch|ripple|glass|crt|holo|vapor|fracture|prism|aurora|kaleido
--format mp4|mkv|gif
--audio none|mic|system|both
--area 100,100,1280,720
--monitor 1
--multiple
--list-monitors
--select
--no-prompt
--scale 1920x1080
--no-scale
--output /path/to/file.mp4
--overwrite
--hide-pointer
--max-duration 60
--eos-timeout 15
```