Initial commit: video effects processing system

Add S-expression based video effects pipeline with modular effect
definitions, constructs, and recipe files.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
gilesb
2026-01-19 12:34:45 +00:00
commit 406cc7c0c7
171 changed files with 13406 additions and 0 deletions

85
effects/threshold.py Normal file
View File

@@ -0,0 +1,85 @@
# /// script
# requires-python = ">=3.10"
# dependencies = ["numpy"]
# ///
"""
@effect threshold
@version 1.0.0
@author artdag
@description
Threshold effect. Converts to high-contrast black and white.
Creates stark, graphic look by converting grayscale to pure
black/white based on a threshold value.
@param level int
@range 0 255
@default 128
Threshold level. Pixels above = white, below = black.
@param invert bool
@default false
Swap black and white.
@param color_mode string
@enum bw color
@default bw
Output mode:
- bw: pure black and white
- color: keep original colors where above threshold
@example
(effect threshold :level 100)
@example
;; Beat-reactive threshold
(effect threshold :level (bind bass :range [80 180]) :invert true)
"""
import numpy as np
def process_frame(frame: np.ndarray, params: dict, state: dict) -> tuple:
"""
Apply threshold effect to a video frame.
Args:
frame: Input frame as numpy array (H, W, 3) RGB uint8
params: Effect parameters
- level: threshold 0-255 (default 128)
- invert: swap black/white (default False)
- color_mode: bw or color (default bw)
state: Persistent state dict
Returns:
Tuple of (processed_frame, new_state)
"""
level = int(np.clip(params.get("level", 128), 0, 255))
invert = params.get("invert", False)
color_mode = params.get("color_mode", "bw")
if state is None:
state = {}
# Convert to grayscale for threshold comparison
if len(frame.shape) == 3:
gray = np.mean(frame, axis=2)
else:
gray = frame
# Apply threshold
mask = gray > level
if invert:
mask = ~mask
if color_mode == "bw":
# Pure black and white
result = np.where(mask[:, :, np.newaxis], 255, 0).astype(np.uint8)
if len(frame.shape) == 3:
result = np.repeat(result, frame.shape[2], axis=2)
else:
# Keep original colors where above threshold
result = np.where(mask[:, :, np.newaxis], frame, 0).astype(np.uint8)
return result, state