25 surveillance and security camera overlay styles — CCTV, bodycam, dashcam, drone, thermal, night vision, motion detection, face blur, and evidence overlays
Project description
watch-cast
25 surveillance and security camera overlay styles for Python video pipelines.
What this is
watch-cast applies surveillance-aesthetic overlays to video clips: CCTV grain and timestamp burns, thermal and night-vision color treatments, bodycam and dashcam HUDs, motion-detection bounding boxes, face-blur and privacy-mask composites, drone telemetry readouts, and evidence-chain stamps. Each style is a named slug backed by a compositing pipeline that calls into video-fx for the underlying filter work.
Install
pip install watch-cast
With optional extras:
| Extra | Installs | Use case |
|---|---|---|
[overlay] |
web-overlay |
HTML/CSS overlay rendering |
[multicam] |
video-arrange |
Split-screen security wall layouts |
[dev] |
pytest, ruff, build | Development and testing |
Quickstart
from watch_cast import apply_overlay, SurveillanceConfig
cfg = SurveillanceConfig(
style="bodycam_overlay",
timestamp=True,
blur_faces=True,
)
apply_overlay(
input_path="interview_raw.mp4",
output_path="interview_bodycam.mp4",
config=cfg,
)
Render a looped security-wall feed from multiple clips:
from watch_cast import render_security_feed
render_security_feed(
inputs=["cam_a.mp4", "cam_b.mp4", "cam_c.mp4", "cam_d.mp4"],
output_path="security_wall.mp4",
style="multi_cam_security_wall",
grid=(2, 2),
)
List available styles at runtime:
from watch_cast import list_styles, get_style_info
for slug in list_styles():
print(slug)
info = get_style_info("thermal_camera")
print(info.name, info.categories)
The 25 styles
All 25 styles belong to the surveillance_security family.
Camera treatments
| Slug | Display name |
|---|---|
surveillance_camera |
Surveillance Camera |
night_vision |
Night Vision |
thermal_camera |
Thermal Camera |
infrared_security |
Infrared Security |
fisheye_cctv |
Fisheye CCTV |
low_fps_cctv |
Low FPS CCTV |
hidden_camera |
Hidden Camera |
perimeter_camera |
Perimeter Camera |
plate_reader_camera |
Plate Reader Camera |
doorbell_camera |
Doorbell Camera |
HUD and overlay composites
| Slug | Display name |
|---|---|
security_grid_overlay |
Security Grid Overlay |
security_timestamp_burn |
Security Timestamp Burn |
motion_detection_boxes |
Motion Detection Boxes |
tracking_target_box |
Tracking Target Box |
bodycam_overlay |
Bodycam Overlay |
dashcam_overlay |
Dashcam Overlay |
drone_surveillance |
Drone Surveillance |
recon_scope |
Recon Scope |
access_control_feed |
Access Control Feed |
restricted_access_monitor |
Restricted Access Monitor |
multi_cam_security_wall |
Multi-Cam Security Wall |
Privacy and evidence
| Slug | Display name |
|---|---|
face_blur_overlay |
Face Blur Overlay |
pixelated_privacy_mask |
Pixelated Privacy Mask |
evidence_tape_overlay |
Evidence Tape Overlay |
evidence_locker_stamp |
Evidence Locker Stamp |
Composition with the Trollfabriken stack
watch-cast sits on top of video-fx and can receive scene cuts from cut-fx. A typical documentary evidence-treatment pipeline combines all three:
from cut_fx import detect_scenes
from video_fx import apply_effect
from watch_cast import apply_overlay, SurveillanceConfig
scenes = detect_scenes("raw_footage.mp4")
for scene in scenes:
# Desaturate first with video-fx, then burn in evidence stamps
apply_effect(scene.path, scene.path, effect="desaturate")
apply_overlay(
scene.path,
scene.path.replace(".mp4", "_stamped.mp4"),
config=SurveillanceConfig(style="evidence_locker_stamp"),
)
CLI
# List all styles
watch-cast list
# Apply a style to a file
watch-cast apply --style bodycam_overlay input.mp4 output.mp4
# Apply with timestamp and face blur
watch-cast apply --style surveillance_camera --timestamp --blur-faces input.mp4 output.mp4
# Show metadata for a style
watch-cast info thermal_camera
# Render a security wall
watch-cast wall --style multi_cam_security_wall --grid 2x2 cam_a.mp4 cam_b.mp4 cam_c.mp4 cam_d.mp4 wall.mp4
Internal architecture
The package is organized into five sub-namespaces: styles (per-style compositing recipes),
hud (timestamp, telemetry, reticle, and classification overlay renderers), motion_detect
(background-subtraction helpers for bounding-box generation), schema (catalog loader and
SurveillanceStyle model), and api (the public surface). All compositing calls go through
video-fx for the pixel-level filter work.
What this is NOT
- Not a real-time camera driver or live RTSP processor
- Not a computer-vision object detector;
motion_detection_boxesrenders procedural or supplied bounding boxes, not detected ones - Not a replacement for video-fx; it depends on video-fx and composes over it
- Not designed to strip or defeat actual privacy protections; face-blur is aesthetic, not certified
- Not a broadcast-safe certification tool; output timing and color accuracy are not guaranteed
Provenance
Built at Trollfabriken AITrix AB for civic-journalism evidence treatment, municipal audit video processing, and Timelock Film AB festival slate documentary and drama work.
Author: Trollfabriken AITrix AB <dev@trollfabriken.se>
GitHub: tomastimelock
PyPI: watch-cast
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file watch_cast-0.1.0.tar.gz.
File metadata
- Download URL: watch_cast-0.1.0.tar.gz
- Upload date:
- Size: 31.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
275225205294b28da8dc5924a71e3b9ebafae8e22db5b8ae52a87d4808fc5e09
|
|
| MD5 |
8e9e86362f3656409dec2b224a437be1
|
|
| BLAKE2b-256 |
62f0dc39ea85e32281ddfeb051235cf8814ea52bfaf5409eb53eebd90049ebf1
|
Provenance
The following attestation bundles were made for watch_cast-0.1.0.tar.gz:
Publisher:
release.yml on tomastimelock/watch-cast
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
watch_cast-0.1.0.tar.gz -
Subject digest:
275225205294b28da8dc5924a71e3b9ebafae8e22db5b8ae52a87d4808fc5e09 - Sigstore transparency entry: 1626055011
- Sigstore integration time:
-
Permalink:
tomastimelock/watch-cast@285acba426f7042a408ec64ce3f5d92725d2deb6 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/tomastimelock
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@285acba426f7042a408ec64ce3f5d92725d2deb6 -
Trigger Event:
push
-
Statement type:
File details
Details for the file watch_cast-0.1.0-py3-none-any.whl.
File metadata
- Download URL: watch_cast-0.1.0-py3-none-any.whl
- Upload date:
- Size: 38.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
443a0673177857d560b4e3d568f50fc2fcd204adce20ca3dd477b613e0d62619
|
|
| MD5 |
441bea8ee829a5cbca5686894746b5e5
|
|
| BLAKE2b-256 |
edfa3ea16ba8963a66644ef57952e3a67bbb877819fd19e0733fde6c87a4f21f
|
Provenance
The following attestation bundles were made for watch_cast-0.1.0-py3-none-any.whl:
Publisher:
release.yml on tomastimelock/watch-cast
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
watch_cast-0.1.0-py3-none-any.whl -
Subject digest:
443a0673177857d560b4e3d568f50fc2fcd204adce20ca3dd477b613e0d62619 - Sigstore transparency entry: 1626055082
- Sigstore integration time:
-
Permalink:
tomastimelock/watch-cast@285acba426f7042a408ec64ce3f5d92725d2deb6 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/tomastimelock
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@285acba426f7042a408ec64ce3f5d92725d2deb6 -
Trigger Event:
push
-
Statement type: