How to gdpr-compliant face pixelator at scale
- Step 1Open the tool — you land on the video face pixelator — The bulk face pixelator routes through to the JAD video pixelate engine at /video-tools/face-pixelate. That is the actual tool that does the work: it takes a single video and applies a mosaic to every detected face across its frames. If your source is a still image rather than a video, this engine expects a video stream and will report 'Source has no video stream' — convert the still to a short clip first, or use a still-image redactor.
- Step 2Drop ONE video file — Drag a single video onto the tool (it does not accept multiple files at once for this engine). Common containers like
.mp4,.mov, and.webmload via the browser's<video>element; if the browser cannot decode the codec it reports 'Could not load source video for face detection.' Keep file size under your tier's security limit (Free 10 MB; Pro 100 MB; Pro-media 500 MB; Developer 2 GB). - Step 3Set the Sample rate (Hz) — Sample rate controls how many frames per second are inspected for faces (range 1–15, default 4). Higher = better tracking of fast movement but more detection time; lower = faster but a face that appears for under a second between samples may be missed. 4 Hz is a good default for talking-head and walking-pace footage.
- Step 4Set the Pixel size (mosaic coarseness) — Pixel size is the mosaic block size, range 4–40, default 16. Internally each face crop is scaled down by this factor with nearest-neighbour sampling then scaled back up, so a larger number = chunkier, more obviously redacted blocks. 16 reads clearly as 'anonymised'; 4 is subtle and risks leaving recognisable structure; 32–40 is the heavy documentary mosaic.
- Step 5Set Padding to cover the whole head — Padding (0–1, default 0.25) grows each detected box outward by that fraction of its size before the mosaic is applied, so hairline, jaw, and ears are covered, not just the tight face rectangle. Raise it toward 0.4–0.5 for profile or partially-turned faces; keep it lower if faces are close together and you don't want adjacent regions to merge.
- Step 6Run, then check every face is covered before you publish — Press run. You'll see a one-time 'Loading face detector (WebGPU + model warm-up)' stage, then 'Detecting faces · sample n/N', then 'Pixelating faces · k faces'. When the
.mp4downloads, scrub the whole clip — detection is not perfect on profiles, motion blur, masks, or tiny/distant faces, and only the 12 most-detected face tracks are kept. Anything missed needs a manual pass. For non-face PII (plates, screens, badges) use a region redactor instead.
Real controls (video face pixelate engine)
These are the only three controls the pixelate panel exposes. There is no sensitivity / confidence slider, no preview-and-commit toggle, no per-face on/off, and no blur-strength control (blur strength belongs to the separate face-blur tool). Defaults are applied if you change nothing.
| Control | Range | Default | What it does |
|---|---|---|---|
| Sample rate (Hz) | 1 – 15 | 4 | Frames inspected per second. Higher tracks fast motion better but is slower; faces appearing briefly between samples can be missed at low rates |
| Pixel size | 4 – 40 | 16 | Mosaic block size. Each face is downscaled by this factor (nearest-neighbour) then upscaled back — larger = chunkier, more obviously redacted blocks |
| Padding (0–1) | 0 – 1 | 0.25 | Fraction the detected box is grown on every side before pixelation, so hair, jaw, and ears are covered. 0.25 = 25 percent margin |
How detection and the mosaic actually work
The pipeline that runs when you press go. Browser path and JAD Runner path use the same BlazeFace short-range model and produce the same nearest-neighbour mosaic; they differ only in the runtime that hosts the detector and encoder.
| Stage | Browser (in-page) | JAD Runner (local CLI) | Notes |
|---|---|---|---|
| Face detection model | @tensorflow-models/face-detection, MediaPipeFaceDetector, model type short | @mediapipe/tasks-vision FaceDetector, blaze_face_short_range.tflite | Both are the BlazeFace short-range model — optimised for near-frontal faces; profiles and tiny/distant faces are weaker |
| Compute backend | WebGPU → WebGL → CPU (first available) | Headless Chromium on the runner | First run pays a one-time model + shader warm-up shown as 'Loading face detector' |
| Frame sampling | Seeks the source <video> at 1/sampleHz intervals and detects per frame | Same — samples OffscreenCanvas frames at sampleHz | Detection confidence is fixed (0.5) internally; there is no exposed sensitivity control |
| Tracking / cap | Detections clustered into spatial tracks, kept for the time range each face appears | Same clustering | Capped at the 12 most-detected tracks — extra clusters are dropped, ranked by hit count so noise loses to real faces |
| Pixelation | ffmpeg.wasm: crop → scale down (flags=neighbor) → scale up (flags=neighbor) → overlay enabled over the face's time window | Canvas 2D nearest-neighbour pixelation + WebCodecs H.264 + mp4-muxer | Result is destructive — original face pixels are gone, not blurred |
| Output | Single .mp4 (H.264) download | Single .mp4 (H.264) | Always MP4 regardless of the input container |
File-size limits by plan (security family)
This is a file-based tool so tier size limits apply. The engine takes one video at a time, so the per-file size is the constraint that matters most.
| Plan | Max file size | Files at once | Practical note |
|---|---|---|---|
| Free | 10 MB | 1 | Fine for short, low-res test clips; most real footage exceeds this quickly |
| Pro | 100 MB | 5 (other tools) | Covers most short interview / event clips at 1080p |
| Pro-media | 500 MB | 50 (other tools) | The realistic tier for longer or higher-resolution video work |
| Developer | 2 GB | unlimited (other tools) | Long-form footage; detection + encode time grows with duration and resolution |
Cookbook
Concrete walk-throughs grounded in what the engine actually does — single video in, mosaic MP4 out. Stage labels shown are the real progress messages the tool emits.
Anonymise bystanders in an event recap before posting
A 1080p event clip with several attendees in frame. Goal: faces clearly redacted for GDPR, but not so blocky it looks like a mistake. Default pixel size 16 with default padding covers heads cleanly.
Source: event-recap.mp4 (1080p, 45s) Controls: Sample rate 4 Hz · Pixel size 16 · Padding 0.25 Progress: Loading face detector (one-time WebGPU + model warm-up) Detecting faces · sample 181/181 Pixelating faces · 7 faces · 45.0s / 45.0s Output: event-recap pixelated .mp4 (H.264) → 7 face tracks mosaicked across the frames each appears in.
Heavy documentary mosaic for a sensitive source
Source-protection footage where the look should read as deliberately censored. Crank pixel size for chunky blocks and raise padding so a turning head stays covered.
Source: interview.mp4 Controls: Sample rate 6 Hz · Pixel size 36 · Padding 0.45 Why these values: pixelSize 36 → large, obviously-redacted blocks padding 0.45 → wide margin so profile turns stay covered sampleHz 6 → catches faster head movement between samples Output: interview pixelated .mp4 → Verify the full clip: BlazeFace short-range is weakest on hard profiles, so scrub for any frame where the box dropped.
Fast-moving subject keeps slipping out of the mosaic
A handheld walking shot where a face appears for under a second between sampled frames at the default rate, so the mosaic flickers off. Raise the sample rate so more frames are inspected.
Problem at default: Sample rate 4 Hz → 1 sample every 0.25s A face visible 0.3s gets ~1 detection → track is thin / flickers Fix: Sample rate 12 Hz → 1 sample every ~0.083s Same face now gets ~3-4 detections → solid track Trade-off: detection time roughly scales with sample rate. Max is 15 Hz.
More than 12 faces in frame — only the top 12 tracks survive
A crowded scene produces more than 12 face clusters. The engine keeps the 12 most-detected tracks (ranked by hit count) and drops the rest, so faint/edge faces may be left exposed.
Detected clusters: 18 Track limit: 12 (most-detected kept) Console: face-blur · 18 clusters, capped to 12 most-detected Result: the 6 lowest-hit clusters are NOT mosaicked. Mitigation: - Tighter framing / split the shot so <=12 faces per pass - Raise sample rate so real faces accumulate hits and rank high - Manual region pass for any face left exposed
Source is a still photo, not a video
This engine is the video pixelator — it needs a decodable video stream. A JPEG/PNG has no video stream and is rejected. The image fixture in the tool's own test set is only a redirect smoke-test, not a supported still-image path.
Input: portrait.jpg
Result: error — "Source has no video stream"
(browser path: "Could not load source video")
Fix options:
- Wrap the still in a 1-2s video clip, then pixelate
- Use an image/region redactor for a single still
- For non-face PII (plates, screens) use a region redactor,
not a face detectorEdge cases and what actually happens
Pixelation cannot be undone
By designEach face crop is scaled down by the pixel-size factor with nearest-neighbour sampling and scaled back up, so the original sub-block detail is discarded — there is no key, seed, or reverse pass. This is the point: GDPR / CCPA publication needs irreversible anonymisation, unlike a Gaussian blur which can sometimes be partially deconvolved. Keep your un-pixelated master separately if you ever need the original.
It opens the video tool, not a photo batch tool
ExpectedChoosing the bulk face pixelator redirects to /video-tools/face-pixelate. That engine processes one video and tracks faces over its frames — it is not a multi-photo uploader and does not loop a folder of images. The 'bulk' framing refers to redacting every face the detector finds within the clip, not to batching many separate files.
No faces detected
No facesIf no frame yields a face, the tool stops with 'No faces detected. Try lowering the sample rate or use a clearer source.' Causes: faces too small/distant for the short-range model, hard profiles, heavy motion blur, masks/occlusion, or extreme lighting. Try a higher sample rate, a clearer source, or accept that this model targets near-frontal faces and use a manual region pass.
Faces found but cannot be grouped into a region
No tracksDetections existed but clustering produced no usable spatial track ('Faces detected but could not be grouped into a redaction region'). This happens with sparse, scattered single-frame hits — typically a too-low sample rate so the same face never lands in two nearby samples. Raise the sample rate so detections accumulate into a coherent track.
Detected face falls outside the frame after clamping
No regionsAfter padding and clamping to the frame and rounding dimensions to even numbers, a box can shrink below the 4-pixel minimum and be skipped; if all do, you get 'Detected faces fell outside the frame after clamping.' Usually means faces are right at the edge with high padding. Lower the padding or reframe so faces are not flush against the border.
More than 12 face tracks in the clip
12-track capThe engine keeps only the 12 most-detected tracks (ranked by hit count) and logs 'capped to 12 most-detected'. Real, frequently-seen faces win; brief/edge faces can be dropped and left exposed. Split crowded shots, raise the sample rate so genuine faces rank higher, and always scrub the output to confirm no face was skipped.
Browser cannot decode the input container/codec
Load failedDetection loads the source through an HTML <video> element, so it depends on the browser's codec support. An exotic codec or corrupt header gives 'Could not load source video for face detection.' (browser) or 'Cannot load source video' (runner). Re-encode to a standard H.264 MP4 first, then pixelate.
Profiles, masks, and tiny faces are missed
Detection limitThe BlazeFace short-range model is tuned for near-frontal faces. Hard side profiles, masked or partially occluded faces, sunglasses-plus-hat combos, and small/distant faces are detected unreliably regardless of settings. Raising padding helps cover a face once detected, but it cannot create a detection that never happened — review the clip and manually redact any miss.
First run is slow before any face appears
ExpectedThe detector model, WASM graph, and (on WebGPU) shaders compile on first use — shown honestly as 'Loading face detector (one-time WebGPU + model warm-up)'. This one-time cost (often several seconds) happens before sampling starts; subsequent runs in the same session reuse the cached detector and skip it.
Output is always MP4
SupportedWhatever the input container (.mov, .webm, etc.), the result is encoded as an H.264 .mp4. There is no option to preserve the original container or pick a codec. If you need a different container, re-mux the downloaded MP4 afterward with a video converter.
Frequently asked questions
Is the pixelation reversible?
No. Each face region is downscaled with nearest-neighbour sampling and scaled back up, which permanently destroys the underlying detail — there is no key or reverse pass. That irreversibility is exactly what GDPR / CCPA publication needs, and it is the practical advantage of mosaic over a soft blur (blurs can sometimes be partially recovered).
Does it work on still photos, or only video?
The engine you land on is the video pixelator: it needs a decodable video stream and tracks faces across frames. A still JPEG/PNG is rejected with 'Source has no video stream'. If you only have a still, wrap it in a short clip first, or use an image/region redactor for a single image.
Can I upload a whole folder of files at once?
No — the face-pixelate engine takes one video per run (it does not accept multiple files). 'Bulk' here means it pixelates every face the detector finds inside that one clip, not that it batches many separate files. Run clips one at a time.
Where does processing happen — is anything uploaded?
Nothing is uploaded. Detection runs in your browser via TensorFlow.js (WebGPU, then WebGL, then CPU) and the mosaic is encoded with ffmpeg.wasm, or it runs locally on the JAD Runner in headless Chromium. The footage never leaves your machine, which is why it is suitable for healthcare, education, legal, and journalism material.
What face-detection model does it use — is it really BlazeFace?
Yes. In the browser it uses @tensorflow-models/face-detection with the MediaPipe FaceDetector, model type 'short'; on the runner it uses @mediapipe/tasks-vision loading blaze_face_short_range.tflite. Both are the BlazeFace short-range model — optimised for near-frontal faces, weaker on hard profiles and small/distant faces.
Is there a detection-sensitivity or confidence slider?
No. The only controls are Sample rate (Hz), Pixel size, and Padding. Detection confidence is fixed internally (0.5). To catch more faces you raise the sample rate and/or use a clearer source — you cannot lower a confidence threshold from the UI.
How do I make the mosaic blockier or subtler?
Use Pixel size (range 4–40, default 16). Larger values produce chunkier, more obviously redacted blocks (32–40 is the heavy documentary look); smaller values (4–8) are subtler but risk leaving recognisable face structure. For most GDPR work, 16 reads clearly as 'anonymised'.
Some faces near the edge of frame aren't covered. Why?
Two common reasons: with high padding a box can clamp to the frame edge and shrink below the 4-pixel minimum and be skipped, or you exceeded the 12-track cap so a low-hit edge face was dropped. Lower padding, reframe so faces aren't flush against the border, raise the sample rate, and scrub the full clip to catch misses.
Why did it process the most faces but skip a few in a crowd?
The engine keeps only the 12 most-detected face tracks (ranked by hit count) and drops the rest, so faint or briefly-seen faces in a crowd can be left exposed. Split crowded shots into passes of 12 or fewer faces, raise the sample rate so real faces accumulate detections and rank higher, and manually redact anything still exposed.
What format is the output?
Always a single H.264 .mp4, regardless of the input container. There's no option to keep the original container or choose a codec; re-mux the downloaded MP4 afterward if you need something else.
Can I use this for journalism or source protection?
Yes — local processing plus irreversible mosaic is the standard workflow for protecting sources, and it pairs naturally with stripping metadata so location/device data doesn't leak alongside the footage. For non-face PII in frame (license plates, screens, ID badges) use a region-based redactor, since a face detector won't find those. Always review the full clip before publishing.
How big a file can I process?
Security-family file limits apply: Free 10 MB, Pro 100 MB, Pro-media 500 MB, Developer 2 GB. The engine works on one video at a time, so per-file size is the binding constraint. Pro-media is the realistic tier for longer or higher-resolution footage; detection and encode time both grow with duration and resolution.
Should I pixelate or blur faces, and where do I redact metadata or other PII?
Pixelate (this tool) reads as deliberately censored and is irreversible — ideal for GDPR publication. If you want a softer, natural depth-of-field look instead, use the blur variant at /video-tools/face-blur. To strip GPS/device metadata from the video afterward use /video-tools/metadata-scrubber. For text-based PII in documents or data, see signature-burner and email-phone-scrubber.
Privacy first
Every JAD Security operation runs entirely in your browser. Files, passwords, and PGP private keys never leave your device — verified by zero outbound network requests during processing.