Personal use · Local · GPU

██████-friendly cuts of the media you already own.

bowdler is a local, GPU-accelerated video filter that detects nudity and profanity and produces a family-friendly version by blurring sensitive regions and muting offending words. Named after Thomas Bowdler, whose Family Shakespeare (1818) was the same idea two centuries earlier.

~/movies — bowdler
$ bowdler run movie.mkv -o movie.bowdler.mkv
 probe         1h 47m · 1080p · h264 · stereo
 hash          blake3 · cache miss
 decode        NVDEC · 154,728 frames
 vision        NudeNet · 12 segments flagged
 audio         whisper-medium.en · 47 words flagged
 approve       11/12 video · 39/47 audio (auto)
 render        ffmpeg · libx264 · crf 23
$ 

How it works

Detection, review, and rendering — three separate stages.

input.mkv ──┬─ NVDEC decode ─→ NudeNet (ONNX/CUDA) ─→ tracker ─→ blur segments ──┐
            │                                                                     │
            └─ audio extract ─→ Whisper (Vulkan)    ─→ wordlist  ─→ mute ranges ─┤
                                                                                  ▼
                                                                  EditDecisionList
                                                                   (cached + reviewable)
                                                                                  │
                                                                                  ▼
                                                            ffmpeg compositor → output.mkv

Principles

Five things bowdler is opinionated about.

  1. 01

    Blur, don't cut.

    Cutting breaks runtime, audio sync, and keyframe alignment. Blurring detected regions is less destructive — a false-positive blur is recoverable; a false-positive cut is not.

  2. 02

    Mute words, don't drop audio.

    Word-level timestamps from Whisper let bowdler silence individual words without touching video — no lip-sync drift, no awkward gaps.

  3. 03

    Detection and rendering are separate.

    Run detection once, cache to RocksDB keyed by file hash, then render. Re-tuning thresholds doesn't re-infer.

  4. 04

    Manual review is first-class.

    The TUI is not optional. Every detection gets a thumbnail or transcript line and an approve/reject toggle before anything renders.

  5. 05

    GPU-resident pipeline.

    Frames stay in CUDA memory from NVDEC through inference through blur. No host roundtrips on the hot path.

Three CLI personas

Use the workflow that fits your patience.

bowdler detect

Run vision + audio detection. Cache the result to RocksDB keyed by the file hash.

bowdler detect movie.mkv \
  -o movie.edl.json

bowdler review

TUI for stepping through detections. Inline thumbnails via kitty/iTerm/sixel; halfblock fallback otherwise.

bowdler review movie.mkv

bowdler render

Single-pass FFmpeg filter_complex: boxblur each approved region, silence each approved word.

bowdler render movie.mkv \
  -o movie.bowdler.mkv

bowdler run

One-shot: detect → auto-approve high-confidence items → render. Items below the floor are auto-rejected with a warning; revisit with review if you disagree.

bowdler run movie.mkv \
  -o movie.bowdler.mkv

Ready to build it?

The quickstart walks through dependencies, models, and your first render. Budget ~10 minutes for the cold compile.