Metadata-Version: 2.4
Name: open-redactor
Version: 0.2.0
Summary: Open-source CLI to make video share-safe with SAM 3.1 prompt-driven redaction
Author: Yuriy H
License: Apache-2.0
Keywords: video,redaction,sam,privacy,cli
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.26
Requires-Dist: Pillow>=10.0
Requires-Dist: opencv-python-headless>=4.8
Requires-Dist: httpx>=0.25
Provides-Extra: dev
Requires-Dist: pytest>=7.4; extra == "dev"
Requires-Dist: pytest-cov>=4.1; extra == "dev"
Provides-Extra: pii
Requires-Dist: pytesseract>=0.3.10; extra == "pii"
Requires-Dist: pandas>=2.0; extra == "pii"
Provides-Extra: local
Requires-Dist: torch>=2.2; extra == "local"
Requires-Dist: transformers>=4.44; extra == "local"
Requires-Dist: accelerate>=0.33; extra == "local"
Dynamic: license-file

# Open Redactor

**Drop in a clip or a photo, name what to hide, get a share-safe copy out.**

Open Redactor finds people, faces, documents, numbers, codes, and places in your media and covers them with tracking that holds across every frame. Blur it, pixelate it, or swap it for a generated stand-in. Audit before you redact, prove coverage after, and keep private footage on your own machine when it matters.

![Redacted output](examples/media/hero.gif)

*Original on the left, redacted output on the right, from a live SAM 3.1 run. The face track held across all 50 frames.*

## Try it in 30 seconds

```bash
pip install open-redactor

open-redactor clip.mp4 --preview --preset family     # 3 second sample first
cat clip.redacted.coverage.txt                        # one result line to trust
open-redactor clip.mp4 --preset family                # the full run
open-redactor clip.mp4 --preset family --mode pixelate  # re-render free, detection is cached
```

## What it catches

**People and places, by phrase.** Person, face, license plate, screen, and anything else you name in a short noun phrase. The tracker holds each one across time, pads the mask, and carries it through brief dropouts so the output never flashes clean.

**Sensitive documents.** Passports, credit cards, driver licenses, ID cards, documents, and name badges with the documents preset.

**Printed secrets.** The text layer OCRs frames and covers verified credit card numbers, Social Security numbers, phone numbers, and emails. Card numbers must pass the Luhn check, so order numbers stay untouched.

**Codes.** QR codes and barcodes, which carry Wi-Fi passwords, payment links, and contact cards.

**Location clues.** Street signs, house numbers, plates, and mailboxes with the location preset.

**Voices.** Audio stays, gets muted, or gets pitch shifted so speech remains but the speaker does not.

## Three ways to hide something

| Mode | What you see | Reach for it when |
| --- | --- | --- |
| blur | A soft gaussian cover | You want the default, clean look |
| pixelate | Chunky mosaic blocks | You want the classic redaction look |
| replace | A generated stand-in | You want the scene to still feel natural |

![Replace demo](examples/media/replace-demo.jpg)

*Replace mode on the real showcase portrait. The face becomes a neutral synthetic avatar while the photo around it stays untouched. The same treatment swaps plates and house numbers for fake plaques and card numbers for format valid fakes in the reserved test range. Fakes are deterministic per track, so the same person keeps the same stand-in for the whole clip.*

```bash
open-redactor clip.mp4 --mode replace --preset location
```

## Trust first, share second

Redaction fails silently in most tools. Open Redactor is built to show its work.

**Preview.** Render only the first 3 seconds with a contact sheet before committing to a full clip.

**Shadow audit.** Run detection and change nothing. You get a written audit with every element, its frames, and a severity grade, critical for passports and card numbers, high for faces and house numbers, medium for plates and signs.

```bash
open-redactor clip.mp4 --shadow --preset documents --sensitive
```

**Coverage report.** Every real run writes one. Any gap longer than the carry window is flagged NEEDS REVIEW in plain words.

**Analytics.** Every run ends with frames affected, elements by severity, an exposure score, and a machine readable .summary.json next to the output.

A sample audit lives at [examples/shadow-audit-sample.txt](examples/shadow-audit-sample.txt).

## One flag presets

```bash
open-redactor clip.mp4 --preset family        # kids, faces, plates, screens, generous blur
open-redactor clip.mp4 --preset street        # bystanders and plates, pixelated
open-redactor clip.mp4 --preset screen-share  # monitors and faces in recordings
open-redactor clip.mp4 --preset documents     # passports, cards, IDs, badges, strong blur
open-redactor clip.mp4 --preset location      # street signs, house numbers, mailboxes
```

Add `--sensitive` to any run to switch on the text and codes layers together. Add `--audio mute` or `--audio pitch` when voices identify someone.

## Run SAM wherever you trust it

SAM 3.1 is an open weights model, so the backend is your choice.

**API, the default.** Meta Model API, best quality with no GPU. Your clip goes to api.meta.ai with your key.

```bash
open-redactor clip.mp4 --backend api
```

**Hosted.** The same request shape pointed at your own endpoint, a team server, or a cloud GPU box.

```bash
open-redactor clip.mp4 --backend hosted --endpoint https://your-host.example/v1/responses
```

**Local.** Grounding DINO plus SAM 2 with IoU tracking on your own hardware. Nothing leaves the device. This is the mode for source footage, medical clips, and family video that should never be uploaded.

```bash
pip install "open-redactor[local]"
open-redactor clip.mp4 --backend local
```

Pixel-perfect SAM masks decode through @meta-sam/parser when Node is present, with a box fallback that still pads and carries safely.

## Photos, formats, and the local page

Photos work exactly like video. JPG, PNG, WebP, and BMP in, redacted photo out in the same format, with every preset and layer available.

```bash
open-redactor photo.jpg --preset documents --sensitive
```

Video inputs cover MP4, MOV, MKV, WebM, AVI, and M4V from phones, OBS, browsers, and older cameras. Output is always MP4. Batch mode takes a whole folder. Output naming never overwrites your original or an earlier redacted copy.

Prefer clicking? `open-redactor --ui` opens a drag and drop page that runs only on your own machine at 127.0.0.1.

## The full demo

```bash
# 1. Audit a folder of interview footage without changing a byte
open-redactor interview.mp4 --shadow --preset street --audio pitch

# 2. Preview the fix on the first 3 seconds
open-redactor interview.mp4 --preview --preset street --audio pitch

# 3. Run it, with analytics and a coverage report written next to the output
open-redactor interview.mp4 --preset street --audio pitch --contact-sheet

# 4. Read what was caught
cat interview.redacted.summary.json
```

More worked examples with frames and coverage proof live in [examples/README.md](examples/README.md). The longer guide, privacy notes, and honest limits live in [docs/using-open-redactor.md](docs/using-open-redactor.md).

## Why this exists

**Thesis:** Consumer video redaction is either manual or enterprise-priced and a prompt-driven open-source CLI makes share-safe video a one-command default.

**Value-add:** Real video tracking quality without per-frame manual work plus a local mode that keeps private footage off any API.

## How it stays covered

A detector that drops a face for two frames leaks those two frames. So the pipeline pads every mask by a margin, carries tracks forward after they vanish, smooths mask edges over time, fills single-frame gaps, and flags any longer gap in the coverage report instead of hiding it. Defaults are a product decision too: person, face, license plate, and screen run when you name nothing.

## CLI reference

```text
open-redactor input.mp4 [--output out.mp4]
  --target PHRASE (repeatable)      --targets-default  --add-target PHRASE
  --preset family|street|screen-share|documents|location
  --mode blur|pixelate|replace      --strength N       --mask-margin N  --carry-frames N
  --preview                         --shadow           --contact-sheet
  --report (default)                --no-report
  --sensitive                       --pii-text         --codes
  --audio keep|mute|pitch          --pitch-factor 0.8
  --backend api|hosted|local        --provider sam|grounding-sam
  --endpoint URL                    --api-key-env MODEL_API_KEY
  --no-cache                        --batch            --ui
```

Exit code is 0 on success. A run that finds zero matches still exits 0 and writes a clean copy with a log line saying nothing matched.

## Install

```bash
pip install open-redactor
pip install "open-redactor[local]"   # optional local models
pip install "open-redactor[pii]"     # optional text scanning, also needs the tesseract binary
```

You need ffmpeg and ffprobe on your PATH. From source: clone this repo and `pip install -e .`

## Project layout

- `cli.py` the command line, presets, and routing for video and photos
- `pipeline.py` and `image_pipeline.py` ingest, detection, padding, rendering, reports
- `sam_client.py` the SAM 3.1 API and hosted client with caching
- `local_gsam.py` Grounding DINO plus SAM 2 local provider with IoU tracking
- `masks.py` padding, carry-forward, smoothing, and coverage reports
- `pii.py`, `codes.py` the text and codes layers
- `analytics.py`, `replace.py` severity, summaries, shadow audits, and generated stand-ins

## License

Apache-2.0. See LICENSE.
