Face tracking, background blur/replacement, crop, brightness and bounded replay for a virtual camera. Python 3.14 processing runs on macOS and Linux. macOS also has an optional native menu bar app. Windows adapters exist but current Windows installation and hardware behavior are unverified.
Requires uv and just. Run from this checkout:
just install
webcam_mods --helpInstallation builds a wheel snapshot and includes platform extras. The command
works outside the checkout; rerun just install after source changes. See
installation details for PATH and development setup.
On macOS, install OBS 30 or newer, open it once, and start its Virtual Camera to install/enable the camera extension. If necessary enable it under System Settings
General > Login Items & Extensions > Camera Extensions. Stop Virtual Camera and close OBS. Webcam Mods then sends directly to OBS Virtual Camera. Select that camera in the receiving app. No custom camera extension or paid Apple membership is required. Preview output requires no OBS installation.
Linux requires v4l2loopback. Configure the module outside the application, for
example sudo modprobe v4l2loopback devices=1 exclusive_caps=1 video_nr=10 card_label="v4l2-cam". Existing device use may prevent module changes; the app
does not unload modules or terminate other video processes.
webcam_mods bg-blur --brighten 20
webcam_mods track-face --blur
webcam_mods bg-swap /path/to/background.jpg
webcam_mods crop-cam --output preview
webcam_mods list-cameras --capture-backend avfoundationCommon options work before or after commands; command-side values override root
values. Use webcam_mods COMMAND --help for the complete option set.
--no-controls disables keyboard and stdin controls. Camera capture needs Camera
permission for the launching application. macOS terminal runs offer a numbered
camera picker unless an explicit index or VIDEO_IN is set; noninteractive runs
never prompt. OBS output, closed-lid built-in cameras and unavailable inputs are
excluded. Indices belong to the chosen backend.
Capture defaults to auto: AVFoundation on macOS with installed bindings,
otherwise OpenCV. Auto retains OpenCV indices and maps the selected identity into
native capture; explicit avfoundation uses its filtered native indices. Startup
errors never silently switch cameras or backends. Requested resolution/FPS must
be supported together by the camera.
--output preview opens a bare window containing the final output frame; close
it or press Escape to stop. --output virtual-cam is default. gui remains a
legacy preview alias. Quality settings describe
independent capture/output dimensions and FPS. Repeat mode
keeps delivery cadence independent of processing by repeating the latest frame:
webcam_mods bg-blur --repeat-frames --processing-fps 15 --output-fps 30See native menu guide for building/installing the optional SwiftUI app, saved profiles and local session control. Profiles retain native camera identity and allow independent capture/output dimensions and FPS. Explicit Start/Stop owns one Python worker session. Existing CLI commands remain available.
Background modes use MediaPipe by default; optional --segmentation-backend vision
and --processing-backend coreimage select native macOS implementations. OpenCV
blur is box blur; Core Image blur is Gaussian. These are behavioral choices,
not a demonstrated general performance advantage. --segmentation-backend chroma
keys a green screen instead of detecting the person (profiles can set any key
color). --mask-smoothing enables motion-aware segmentation smoothing; it
remains opt-in.
--mirror (or MIRROR=true) flips camera input left to right before crop,
tracking and effects. Receivers see the mirrored view; background images and
loading pictures stay unmirrored. The native app exposes this as Mirror video.
Face tracking follows the nearest compatible face after initially choosing the largest. This is geometric continuity, not identity recognition. Defaults target 40% face height, horizontal center, vertical position 42%, and at most 2x digital zoom within source bounds. Output aspect ratio is preserved. Tuning:
webcam_mods track-face --face-height 0.35 --max-zoom 1.5 --target-y 0.4--pan-deadzone and --zoom-deadzone suppress small movements;
--pan-seconds and --zoom-seconds set independent response time constants.
--lost-after holds framing before widening/reselection. Legacy --x-padding
/ --y-padding replace face-height framing with minimum crop-to-face ratios.
Tracking disables interactive crop/replay controls.
For prepared camera modes, Ctrl+arrows move crop, Ctrl+Shift+arrows resize it,
and Alt+arrows adjust padding. Stdin accepts record, stop, replay and reset.
Empty replay is rejected. Recording defaults to a 256 MiB memory cap, adjustable
with --recording-limit-mb. Crop/padding persists atomically in
~/.webcam-mods.conf; saved launch profiles are separate.
webcam_mods share-screen --width 1280 --height 720 --output preview --no-controls
webcam_mods share-screen --select area --output virtual-cam --no-controlsExplicit coordinates use --left, --top, --width, --height; negative
coordinates support other displays. macOS --select area|screen|visible requires
select-region on PATH (installed separately from ~/scripts/compat). Selection
cannot combine with coordinates. Area selection fits output aspect ratio; a
click-through border follows later crop changes. --no-border hides it.
Screen runs use fresh crop state, MSS capture and the same output/control path.
Grant Screen Recording permission to the launching application. The macOS app
shares a display from Source > Screen without select-region; saved profiles keep
the area for profile-run. Show camera adds the camera over the screen as a round
bubble or a cutout of the person.
CLI startup settings resolve once: CLI > environment > defaults. Invalid values
fail before devices open; help remains available. env.example
lists supported names. Booleans accept true/false or 1/0. Input/output default to
640x480/30. Native capture ignores OpenCV's IN_FORMAT FOURCC.
MediaPipe uses checksum-verified models under ~/.cache/webcam-mods/models,
honoring XDG_CACHE_HOME. just models downloads them ahead of use. macOS ARM64
uses the bundled Metal-enabled wheel; vendor provenance
describes rebuilding it. Other platforms use the official release.
On macOS ARM64, CPU and Metal are compared on first use of each model/frame shape.
Three warmed comparisons include input conversion and result readback; GPU must
be over 5% faster in every round. Probe failures use CPU. Successful decisions
persist with hardware/software identity and expiry; warm launches skip probes.
Cold calibration runs all three warmed CPU/Metal comparisons in one isolated
worker per model, avoiding repeated Python imports. Runtime-specific cache files
keep checkout and installed-tool calibrations separate. Other platforms use CPU.
uv run scripts/benchmark_startup.py --compare-legacy measures cold calibration
against the former six-worker approach using cached models and synthetic input,
without opening a camera or changing calibration caches.
Interactive sessions open output before capture/model startup. Both preview and
virtual camera receive TV color bars until the first processed frame. Loading
frames are picture-only; status text stays in the terminal or app window. Choose
animated TV static with --signal-pattern noise (or SIGNAL_PATTERN=noise);
native profiles expose Loading picture in Advanced.
Color bars are cached; static refreshes at most 8 times/second and stops when
live video arrives. Bounded capture/export runs contain only live frames.
just deps
just run --help
just check
just test
just e2e
just verifycheck runs Flake8, Black and strict mypy; test runs headless regression tests.
E2E uses real models and deterministic image input through the production loop,
writing PNG output and metrics under dist/e2e. It needs no camera, OBS or display.
Native app opens a settings window with processed video preview, PNG snapshots,
a recorded loop that can stand in for the camera, a desk view that straightens a
whiteboard or page, experimental eye-contact correction, gesture reactions, lip
color and blush, and camera hardware exposure, focus and anti-flicker where the
camera supports them. Preview-only
mode tests without OBS; the menu bar provides status, Start/Stop, Pause video, profile switching and Open window.
Native app setup and checks: macOS app guide.
These checks establish processing and lifecycle behavior. They do not establish conferencing reception, 720p effects/output, realistic moving-person quality or power consumption. Those checks are deferred. Historical benchmarks retain exact workload context in macOS backends.
Developer documentation contains architecture, current state and the backlog. Report bugs through GitHub Issues. Historical demos: January 2022, earlier demo; they are not current acceptance evidence.
Webcam Mods is free. If it saves you time, you can support us with a tip.
- MediaPipe, face/person models.
- Linux-Fake-Background-Webcam, mask/on-demand inspiration.
- pyvirtualcam, virtual camera output.