Metadata-Version: 2.3
Name: bgvidya
Version: 0.1.0
Summary: Real-time background removal CLI for webcam livestreaming
Author: gluck
Author-email: gluck <gluck@kelliher.info>
Requires-Dist: click>=8.1
Requires-Dist: opencv-python-headless>=4.8
Requires-Dist: numpy>=1.26
Requires-Dist: pyvirtualcam>=0.14
Requires-Dist: torch>=2.0
Requires-Dist: torchvision>=0.15
Requires-Dist: tomli-w>=1.0
Requires-Python: >=3.13
Description-Content-Type: text/markdown

# vidya

Real-time background removal for webcam livestreaming on Linux. Uses
[Robust Video Matting](https://github.com/PeterL1n/RobustVideoMatting) to
strip the background from your webcam feed and write the result to a virtual
camera that OBS (or any other app) can pick up.

## How it works

```
Physical webcam (/dev/video0)
  → vidya captures frames
  → RVM neural network removes the background (GPU, ~10ms/frame)
  → composites foreground onto green / black / image / blurred background
  → writes to v4l2loopback virtual camera (/dev/video10)
  → OBS reads /dev/video10 as if it were a normal webcam
```

## Prerequisites

- **Linux** with the `v4l2loopback` kernel module available
- **NVIDIA GPU** with CUDA drivers (RTX series recommended)
- **[Nix](https://nixos.org/download/)** with flakes enabled
- **[uv](https://docs.astral.sh/uv/)** (provided by the flake)

## Bootstrap

First time setup, in order:

```bash
# 1. Enter the dev shell (provides Python, uv, v4l2-ctl, native libs)
nix develop

# 2. Install Python dependencies (downloads PyTorch with CUDA — ~2.5 GB)
uv sync

# 3. Download the RVM model and verify your system
uv run vidya setup

# 4. Create the virtual camera device (prompts for sudo password)
uv run vidya loopback up

# 5. See what cameras are available
uv run vidya cameras

# 6. Configure your source camera and background
uv run vidya config set camera.source /dev/video0
uv run vidya config set background.color '#00B140'

# 7. Start background removal
uv run vidya run
```

Then in OBS: **Sources → Add → Video Capture Device → select "VidyaCam"**.

On subsequent sessions:

```bash
nix develop            # enter the shell
uv run vidya loopback up   # create the virtual camera (doesn't persist across reboots)
uv run vidya run           # start background removal
```

## Commands

### `vidya cameras`

Discovers all physical webcams and virtual camera devices on your system.
Shows each device's supported resolutions, pixel formats, and frame rates.

```
$ uv run vidya cameras
📷 Capture Devices:
  /dev/video0  Microsoft Modern Webcam  (uvcvideo)
    MJPG  1920x1080 @ 30 fps
    MJPG  1280x720 @ 30 fps
    YUYV  640x360 @ 30 fps

🖥️  Virtual Cameras (v4l2loopback):
  /dev/video10  VidyaCam
```

### `vidya loopback <subcommand>`

Manages the v4l2loopback kernel module — the virtual camera device that vidya
writes processed frames to.

| Subcommand | Description |
|---|---|
| `loopback up` | Load the kernel module and create the virtual camera (prompts for sudo) |
| `loopback down` | Unload the module and remove the device (prompts for sudo) |
| `loopback status` | Check whether the module is loaded and the device exists |

The device path comes from `camera.output` in your config (default
`/dev/video10`). Under the hood, `loopback up` runs:

```
sudo modprobe v4l2loopback devices=1 video_nr=10 card_label=VidyaCam exclusive_caps=1
```

To persist the virtual camera across reboots instead of running `loopback up`
each time:

```bash
echo "v4l2loopback" | sudo tee /etc/modules-load.d/v4l2loopback.conf
echo "options v4l2loopback devices=1 video_nr=10 card_label=VidyaCam exclusive_caps=1" \
  | sudo tee /etc/modprobe.d/v4l2loopback.conf
```

### `vidya config <subcommand>`

Reads and writes persistent configuration at `~/.config/vidya/config.toml`.

| Subcommand | Description |
|---|---|
| `config show` | Print the current configuration |
| `config set <key> <value>` | Set a value (e.g. `config set camera.fps 30`) |
| `config reset` | Reset everything to defaults |
| `config path` | Print the config file path |

### `vidya setup`

One-time setup that:
1. Checks that v4l2loopback and v4l2-ctl are available
2. Verifies CUDA / GPU access
3. Downloads the RVM model (~14 MB for mobilenetv3) via PyTorch Hub

### `vidya run [OPTIONS]`

Starts the background removal pipeline. Reads config, captures from your
webcam, runs RVM inference on the GPU, and writes to the virtual camera.
Press Ctrl+C to stop.

| Option | Description |
|---|---|
| `--preview` | Open a window showing original, output, and alpha mask side-by-side |
| `--source PATH` | Override `camera.source` for this run |
| `--output PATH` | Override `camera.output` for this run |
| `--resolution WxH` | Override `camera.resolution` for this run |
| `--bg-mode MODE` | Override `background.mode` (`color`, `image`, or `blur`) |
| `--bg-color COLOR` | Override `background.color` (hex `#RRGGBB` or `R,G,B`) |
| `--bg-image PATH` | Override `background.image` (also sets mode to `image`) |

## Config reference

| Key | Default | Description |
|---|---|---|
| `camera.source` | `/dev/video0` | Webcam device to capture from |
| `camera.output` | `/dev/video10` | Virtual camera device to write to |
| `camera.resolution` | `1920x1080` | Capture and output resolution |
| `camera.fps` | `30` | Target frame rate |
| `model.name` | `mobilenetv3` | RVM model variant (`mobilenetv3` or `resnet50`) |
| `model.downsample_ratio` | `0.25` | Internal downscale factor (lower = faster) |
| `model.fp16` | `true` | Use half precision on CUDA (faster on RTX GPUs) |
| `background.mode` | `color` | What to put behind you: `color`, `image`, or `blur` |
| `background.color` | `#00B140` | Solid background color when mode is `color` |
| `background.image` | _(empty)_ | Path to background image when mode is `image` |
| `background.blur_strength` | `51` | Gaussian blur kernel size when mode is `blur` |

## Resource usage

With the default mobilenetv3 model at 1080p30 on an RTX 3070:

| Resource | Usage |
|---|---|
| VRAM | ~600 MB |
| GPU compute | <10% |
| CPU | ~10–15% of one core |
| RAM | ~500–700 MB |

Lightweight enough to run alongside OBS with NVENC encoding.
