# 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.
- Keeps the GUI crop preview smooth while editing and quiets decorative redraws while recording.
- Refreshes the selected-area GUI preview while idle so the crop panel stays connected to the live desktop.
- 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 after release:

```sh
cargo install ocula --locked
```

## Use

Launch the native desktop app:

```sh
cargo run --release --bin ocula
```

After install, launch it with:

```sh
ocula
```

The desktop app provides polished studio-style capture controls, audio, pointer, MP4/MKV/GIF format controls, optional GLSL effects, an output picker, a large record/stop button, and a live recorder log. In Area mode, Ocula shows an effect-aware crop preview panel before selection; click the preview panel, focus it and press Enter/Space, or click Pick Crop, then drag an area on screen, drag inside the selected crop to move it, refine it with handles, and click Use Crop or press Enter before recording. Ocula keeps the selected area visually clear for a live view of the desktop underneath, adds effect-aware selector accents, reports when the on-screen selector is unavailable, and shows a click-through crop outline outside the selected area after selection and while recording when the X11 overlay is available. It launches the same fail-safe recorder engine as the CLI and stops recordings with a graceful interrupt so GStreamer can finalize the output file.

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 to create or move a region.
- Resize from edge or corner handles.
- Arrow keys move; Shift+arrows resize; Ctrl changes keyboard steps to 10 px.
- Delete or Backspace clears the region.
- Click `Use This Crop` or press Enter/Space to confirm; click `Cancel`, 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`.

Add an optional GLSL effect 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
--backend auto|portal|x11
--mode screen|window|area
--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
```
