A lightweight, modular camera video enhancement middleware for Linux that outputs to a universal V4L2 virtual camera (/dev/videoX) using v4l2loopback + FFmpeg. Includes both a CLI and a GTK GUI for effect management.
- V4L2-only backend (no PipeWire in core)
- Real-time effect chain (live switching via D-Bus)
- Effects:
blur(background blur)replace(background replacement)brightness(+ optional--face-only)beautify(skin smoothing)autoframe(face-centered framing)gaze-correct(experimental eye warp)
- MediaPipe Tasks backend for segmentation + landmarks (lazy init + cached models)
- Tests: unit tests for effect chaining and device helpers (
pytest)
- ✅ Effects + effect chaining via CLI/D-Bus
- ✅ V4L2 loopback virtual camera output
- ✅ MediaPipe Tasks models + segmentation/landmarks effects
- ✅ GTK GUI (including preview stability improvements)
⚠️ Performance depends on your webcam + transport (some webcams can’t sustain 30 FPS at 1080p)
ffmpegv4l2loopbackkernel module (creates/dev/videoX)- Python 3.12
- A working camera exposed as
/dev/video*
- GUI: GTK4 + PyGObject (
pip install -e ".[gui]") - D-Bus control:
dbus-python(pip install -e ".[dbus]")
# 1) Python venv (Python 3.12)
python3.12 -m venv .venv
source .venv/bin/activate
# 2) Upgrade tooling
python -m pip install -U pip wheel setuptools
# 3) Dependencies
pip install -r requirements.txt
# 4) Install package (editable for dev)
pip install -e .For v0.2.0a1, download the RPM from GitHub Releases, then:
cd ~/Downloads
sudo dnf install -y ./camfx-0.2.0a1-*.x86_64.rpm
systemctl --user daemon-reload
systemctl --user enable --now camfx
systemctl --user status camfx --no-pagerThe Fedora RPM also installs a GNOME app launcher (camfx) for the GUI.
Important for v0.2.0a1: configure V4L2 loopback manually first:
sudo dnf install -y v4l2loopback akmod-v4l2loopback v4l-utils
sudo modprobe v4l2loopback exclusive_caps=1 card_label="camfx" video_nr=-1
v4l2-ctl --list-devicesRelease notes/install snippet for maintainers:
docs/releases/v0.2.0a1.md
Optional extras:
- GUI:
pip install -e ".[gui]"
- D-Bus:
pip install -e ".[dbus]"
Models are downloaded lazily on first use, cached locally, and can be pre-downloaded:
camfx models-downloadCache location:
- default:
~/.cache/camfx/models - override:
CAMFX_MODELS_DIR=/path/to/models
camfx auto-discovers the virtual node by card_label (defaults to --name / camfx).
Examples (Fedora):
sudo dnf install -y v4l2loopback akmod-v4l2loopback
# Load module (let kernel choose video_nr)
sudo modprobe v4l2loopback exclusive_caps=1 card_label="camfx" video_nr=-1
# Verify
v4l2-ctl --list-devices
ls -l /dev/video*camfx start --dbus --name camfxcamfx camera-startList effects:
camfx effectsExample:
camfx set-effect --effect blur --strength 25Background replace:
camfx add-effect --effect replace --image /path/to/background.jpgFace-only brightness:
camfx add-effect --effect brightness --brightness 20 --face-onlycamfx camera-stopPreview virtual output:
camfx preview-virtual --name camfx --v4l2-device autoPreview physical camera directly (bypasses the v4l2 loopback):
camfx preview-camera --input 0camfx start [--dbus] [--name] [--input] [--width] [--height] [--fps] [--v4l2-device]
camfx camera-startcamfx camera-stopcamfx camera-status
camfx effects(list effect options)camfx set-effect --effect <key> [params...](replace chain)camfx add-effect --effect <key> [params...](update if key already exists)camfx remove-effect --index <n>or--effect <key>camfx get-effects
Launch the GTK control panel:
camfx guiThe GUI expects camfx start --dbus to control camera/effects. It also lets you toggle preview.
Step 1 (open the GUI and connect preview):

camfxoutputs frames to v4l2loopback via FFmpeg. Your achievable FPS depends on:- camera supported formats (compressed MJPEG vs raw YUYV, etc.)
- USB bandwidth and sustained capture
- whether ML effects are enabled
- If you request
--fps 30but your webcam can’t sustain it, you may observe lower FPS or buffer drops.
If your camera offers MJPEG at high resolution, prefer MJPEG. camfx attempts to switch to MJPEG for “large” resolutions automatically.
lsmod | rg v4l2loopback
v4l2-ctl --list-devices
ls -l /dev/video*If auto-discovery fails, pass an explicit node:
camfx start --v4l2-device /dev/videoX ...
If /dev/videoX exists but GNOME Camera/other PipeWire apps do not show it yet,
restart user services so PipeWire/WirePlumber re-discover the node:
systemctl --user restart pipewire wireplumber xdg-desktop-portal xdg-desktop-portal-gnomeIf opening /dev/videoX fails:
sudo usermod -aG video "$USER"(log out/in or reboot)
- Run
camfx models-downloadto prefetch models. - Ensure
mediapipeis installed in your venv.
pytest -q
pytest -v
pytest tests/test_effect_chaining.py -v
pytest tests/test_camera_devices.py -vMIT
