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:
63
libs/all-effects.sexp
Normal file
63
libs/all-effects.sexp
Normal file
@@ -0,0 +1,63 @@
|
||||
;; All 42 Sexp Effects
|
||||
;; Include with: (include :path "libs/all-effects.sexp")
|
||||
;; Or from cache: (include :cid "bafy...")
|
||||
|
||||
;; Color effects
|
||||
(effect invert :path "sexp_effects/effects/invert.sexp")
|
||||
(effect grayscale :path "sexp_effects/effects/grayscale.sexp")
|
||||
(effect sepia :path "sexp_effects/effects/sepia.sexp")
|
||||
(effect brightness :path "sexp_effects/effects/brightness.sexp")
|
||||
(effect contrast :path "sexp_effects/effects/contrast.sexp")
|
||||
(effect saturation :path "sexp_effects/effects/saturation.sexp")
|
||||
(effect hue_shift :path "sexp_effects/effects/hue_shift.sexp")
|
||||
(effect color_cycle :path "sexp_effects/effects/color_cycle.sexp")
|
||||
(effect threshold :path "sexp_effects/effects/threshold.sexp")
|
||||
(effect posterize :path "sexp_effects/effects/posterize.sexp")
|
||||
|
||||
;; Blur/sharpen
|
||||
(effect blur :path "sexp_effects/effects/blur.sexp")
|
||||
(effect sharpen :path "sexp_effects/effects/sharpen.sexp")
|
||||
(effect bloom :path "sexp_effects/effects/bloom.sexp")
|
||||
(effect color-adjust :path "sexp_effects/effects/color-adjust.sexp")
|
||||
|
||||
;; Distortion
|
||||
(effect swirl :path "sexp_effects/effects/swirl.sexp")
|
||||
(effect fisheye :path "sexp_effects/effects/fisheye.sexp")
|
||||
(effect wave :path "sexp_effects/effects/wave.sexp")
|
||||
(effect ripple :path "sexp_effects/effects/ripple.sexp")
|
||||
(effect kaleidoscope :path "sexp_effects/effects/kaleidoscope.sexp")
|
||||
(effect zoom :path "sexp_effects/effects/zoom.sexp")
|
||||
(effect rotate :path "sexp_effects/effects/rotate.sexp")
|
||||
(effect mirror :path "sexp_effects/effects/mirror.sexp")
|
||||
|
||||
;; Stylization
|
||||
(effect pixelate :path "sexp_effects/effects/pixelate.sexp")
|
||||
(effect ascii_art :path "sexp_effects/effects/ascii_art.sexp")
|
||||
(effect ascii_zones :path "sexp_effects/effects/ascii_zones.sexp")
|
||||
(effect edge_detect :path "sexp_effects/effects/edge_detect.sexp")
|
||||
(effect emboss :path "sexp_effects/effects/emboss.sexp")
|
||||
(effect outline :path "sexp_effects/effects/outline.sexp")
|
||||
(effect neon_glow :path "sexp_effects/effects/neon_glow.sexp")
|
||||
|
||||
;; Retro/film
|
||||
(effect crt :path "sexp_effects/effects/crt.sexp")
|
||||
(effect scanlines :path "sexp_effects/effects/scanlines.sexp")
|
||||
(effect film_grain :path "sexp_effects/effects/film_grain.sexp")
|
||||
(effect vignette :path "sexp_effects/effects/vignette.sexp")
|
||||
(effect noise :path "sexp_effects/effects/noise.sexp")
|
||||
|
||||
;; Chromatic
|
||||
(effect rgb_split :path "sexp_effects/effects/rgb_split.sexp")
|
||||
|
||||
;; Temporal
|
||||
(effect echo :path "sexp_effects/effects/echo.sexp")
|
||||
(effect trails :path "sexp_effects/effects/trails.sexp")
|
||||
(effect strobe :path "sexp_effects/effects/strobe.sexp")
|
||||
|
||||
;; Geometric
|
||||
(effect flip :path "sexp_effects/effects/flip.sexp")
|
||||
(effect tile_grid :path "sexp_effects/effects/tile_grid.sexp")
|
||||
|
||||
;; Glitch
|
||||
(effect pixelsort :path "sexp_effects/effects/pixelsort.sexp")
|
||||
(effect datamosh :path "sexp_effects/effects/datamosh.sexp")
|
||||
68
libs/plan
Normal file
68
libs/plan
Normal file
@@ -0,0 +1,68 @@
|
||||
Exactly. You're describing a DAG of pipelines that can branch and merge:
|
||||
|
||||
audio-a ─→ analyze ─→ plan-a ─┐
|
||||
├─→ combine ─→ final
|
||||
audio-b ─→ analyze ─→ plan-b ─┘
|
||||
|
||||
videos ─→ analyze ─────────────┴─→ (shared by both plans)
|
||||
|
||||
Each node is independently cacheable. Parallel branches run in tandem.
|
||||
|
||||
A clean syntax might be:
|
||||
|
||||
(recipe "multi-track-video"
|
||||
:encoding (...)
|
||||
|
||||
;; Sources (stage 0 - always available)
|
||||
(def audio-a (source "track1.mp3"))
|
||||
(def audio-b (source "track2.mp3"))
|
||||
(def videos (source-glob "videos/*.mp4"))
|
||||
|
||||
;; Analysis stages (run in parallel, cached by input hash)
|
||||
(stage :analyze-a
|
||||
(def beats-a (-> audio-a (analyze beats))))
|
||||
|
||||
(stage :analyze-b
|
||||
(def beats-b (-> audio-b (analyze beats))))
|
||||
|
||||
(stage :analyze-videos
|
||||
(def video-infos (-> videos (analyze-each video-info))))
|
||||
|
||||
;; Planning stages (depend on analysis, explicit deps)
|
||||
(stage :plan-a :requires [:analyze-a :analyze-videos]
|
||||
(def segments-a (make-segments :beats beats-a :video-infos video-infos)))
|
||||
|
||||
(stage :plan-b :requires [:analyze-b :analyze-videos]
|
||||
(def segments-b (make-segments :beats beats-b :video-infos video-infos)))
|
||||
|
||||
;; Render stages (can parallelize)
|
||||
(stage :render-a :requires [:plan-a]
|
||||
(def rendered-a (-> segments-a (sequence))))
|
||||
|
||||
(stage :render-b :requires [:plan-b]
|
||||
(def rendered-b (-> segments-b (sequence))))
|
||||
|
||||
;; Final combine
|
||||
(stage :output :requires [:render-a :render-b]
|
||||
(-> (list rendered-a rendered-b)
|
||||
(concat)
|
||||
(crossfade :duration 2)
|
||||
(mux audio-a audio-b))))
|
||||
|
||||
What this gives you:
|
||||
|
||||
1. Explicit data availability - :requires declares what's available
|
||||
2. Parallel execution - :analyze-a and :analyze-b run simultaneously
|
||||
3. Granular caching - each stage output cached by its inputs' hashes
|
||||
4. Flexible composition - add more tracks, branches, merge points as needed
|
||||
5. Clear errors - referencing beats-a before :analyze-a is a compile error
|
||||
|
||||
Changes needed to sexp system:
|
||||
|
||||
1. stage form with :requires dependency declaration
|
||||
2. Stage scheduler that builds execution DAG
|
||||
3. Cache layer keyed by stage + input hashes
|
||||
4. Dict iteration (keys, for-each) for generic constructs
|
||||
|
||||
Want to prototype this direction?
|
||||
|
||||
11
libs/standard-analyzers.sexp
Normal file
11
libs/standard-analyzers.sexp
Normal file
@@ -0,0 +1,11 @@
|
||||
;; Standard Analyzers (Audio + Video)
|
||||
;; Include with: (include :path "libs/standard-analyzers.sexp")
|
||||
;; Or from cache: (include :cid "bafy...")
|
||||
|
||||
;; Audio analyzers
|
||||
(analyzer beats :path "../artdag-analyzers/beats/analyzer.py")
|
||||
(analyzer bass :path "../artdag-analyzers/bass/analyzer.py")
|
||||
(analyzer energy :path "../artdag-analyzers/energy/analyzer.py")
|
||||
|
||||
;; Video analyzers
|
||||
(analyzer video-info :path "../artdag-analyzers/video-info/analyzer.py")
|
||||
6
libs/standard-constructs.sexp
Normal file
6
libs/standard-constructs.sexp
Normal file
@@ -0,0 +1,6 @@
|
||||
;; Standard Constructs
|
||||
;; Include with: (include :path "libs/standard-constructs.sexp")
|
||||
;; Or from cache: (include :cid "bafy...")
|
||||
|
||||
(construct slice-every-n :path "constructs/slice-every-n.sexp")
|
||||
(construct cycle-effects-preset :path "constructs/cycle-effects-preset.sexp")
|
||||
Reference in New Issue
Block a user