Skip to content

Deface — Face Obfuscation

Deface is a privacy processor plugin modelled on ORB-HD/deface: a Python worker runs CenterFace face detection (the ONNX model deface itself uses) over the app’s live HLS stream and streams normalized face boxes into the framework’s plugin live-data channel. The player overlay polls that channel and obfuscates each detected region client-side — blur, mosaic or a solid mask.

Plugin id deface
Category processor
UI slot player-overlay
Needs worker Yes
HLS /hls/<app>/<room>/index.m3u8
│ (sampled at `fps`)
CenterFace (centerface.onnx — onnxruntime CPU/CUDA, or OpenCV DNN)
│ (thresh filter → mask-scale expansion → normalize 0–1)
POST plugin live-data channel (worker → core, per-start ingest token)
GET /apps/:app/plugins/deface/live?room=<room> (public, no auth)
Player overlay: blur / mosaic / solid over each face (smoothed between polls)

The worker POSTs every sampled frame — an empty faces list clears the overlay masks (unlike yolo, which only posts on a hit). Boxes are already expanded by maskScale before they’re sent, so the overlay never re-expands them.

Deface anonymizes the player only. The masks are drawn by the viewer’s browser on top of the <video> element:

  • the raw stream (WebRTC, HLS segments, RTMP restreams) still contains the faces — anyone consuming the stream outside the StreamHub player sees them;
  • recordings, VODs and snapshots still contain the faces — nothing about the recording pipeline is touched;
  • a viewer with DevTools can remove the overlay.

Treat it as a presentation-layer privacy feature (kiosk displays, public embeds, demo screens) — not as anonymization of the media itself. Server-side anonymization of recordings (re-encoding with the masks burned in, which is what the original deface CLI does to files) is not implemented.

Every field has a default — a fresh install is valid immediately; only room must be set before the plugin can be enabled.

Field Type Default Description
room string `` (empty) Required. HLS room name to process — /hls/<app>/<room>/index.m3u8.
thresh number 0.2 Detection threshold, 01. Lower catches more faces but adds false positives; raise it if too much is masked.
replacewith select blur Anonymization method. Options: blur (gaussian), mosaic (pixelate), solid (black fill), none (detect only).
maskScale number 1.3 Enlarge detected boxes by this factor (13) to cover hair/chin. Applied worker-side; the payload carries the value so the overlay never double-expands.
boxes boolean false On draws rectangular masks; off (default) draws ellipses.
mosaicSize number 20 Pixel size of mosaic blocks (2200). Only used when replacewith is mosaic.
scale string `` (empty) WxH to downscale frames for detection, e.g. 640x360. Empty = native size. A big CPU saver on HD sources at a small accuracy cost.
backend select auto Inference backend. Options: auto (ONNX Runtime if importable, else OpenCV), onnxrt (ONNX Runtime), opencv (OpenCV DNN).
cuda boolean false On uses the CUDA execution provider (needs onnxruntime-gpu); off runs on CPU. Falls back to CPU automatically — with a log note — when CUDA is unavailable.
fps number 2 Frames per second sampled from the stream (0.130, lower = less CPU). The overlay polls at ~this rate and smooths between updates.
drawScores boolean false Show the detection confidence next to each mask (debugging).

Render-side options (replacewith, boxes, mosaicSize, drawScores, maskScale) reach the anonymous player through the sanitized public config (GET /apps/:app/plugins/public); detection options are mapped to DEFACE_* environment variables by the worker’s spawn(ctx).

When enabled, the framework spawns the worker from the repo-root deface-worker/ Python package:

Terminal window
python3 -m deface_worker --app <app>
  • Modelcenterface.onnx (~7.4 MB) is downloaded on first run to <DATA_DIR>/models/deface/ (shared across every app on the node), the same pattern yolo uses for its weights. Override the source with DEFACE_MODEL_URL, or pre-seed the file for air-gapped hosts.
  • Backend & GPU fallback — CenterFace is much lighter than YOLO, so CPU handles a few FPS comfortably. backend: auto picks ONNX Runtime when it’s importable, otherwise OpenCV DNN. Setting cuda: true uses the CUDA execution provider (requires onnxruntime-gpu in the worker’s Python env) and is only worth it for high fps (>10) or many simultaneous rooms — if CUDA can’t initialize, the worker logs a note and continues on CPU; it never crash-loops over a missing GPU.
  • Live-data channel — the worker-hook injects a fresh STREAMHUB_INGEST_URL / STREAMHUB_INGEST_TOKEN per start; the worker POSTs its detections there. An operator can divert the feed with DEFACE_CALLBACK_URL (same payload shape).
  • Overridable env: PLUGIN_PYTHON (interpreter, default python3) and DEFACE_WORKER_DIR (path to the deface-worker/ checkout, defaults to the copy at the repo root).

Lifecycle is framework-owned, exactly like every needsWorker plugin: enabling (re)starts the worker, disabling stops it, and start/stop/status/logs are exposed over the API.

Dashboard: open the app’s Plugins tab → Install Deface — Face Obfuscation → Configure the room (required) plus the mask style, thresholds and backend → toggle Active to start the worker. Use the plugin’s Logs to watch the worker output.

API:

Terminal window
curl -X PATCH https://YOUR-DOMAIN/api/v1/apps/live/plugins/deface \
-H "Authorization: Bearer sk_..." \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"config": {
"room": "live",
"thresh": 0.2,
"replacewith": "blur",
"maskScale": 1.3,
"boxes": false,
"mosaicSize": 20,
"scale": "640x360",
"backend": "auto",
"cuda": false,
"fps": 2,
"drawScores": false
}
}'

Worker lifecycle and logs use the same routes as every worker plugin:

Terminal window
curl -X POST https://YOUR-DOMAIN/api/v1/apps/live/plugins/deface/worker/start \
-H "Authorization: Bearer sk_..."
curl https://YOUR-DOMAIN/api/v1/apps/live/plugins/deface/worker/status \
-H "Authorization: Bearer sk_..."
curl "https://YOUR-DOMAIN/api/v1/apps/live/plugins/deface/logs?limit=200" \
-H "Authorization: Bearer sk_..."