Files
celery/templates/process-pair.sexp
giles bb458aa924 Replace batch DAG system with streaming architecture
- Remove legacy_tasks.py, hybrid_state.py, render.py
- Remove old task modules (analyze, execute, execute_sexp, orchestrate)
- Add streaming interpreter from test repo
- Add sexp_effects with primitives and video effects
- Add streaming Celery task with CID-based asset resolution
- Support both CID and friendly name references for assets
- Add .dockerignore to prevent local clones from conflicting

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 19:10:11 +00:00

113 lines
4.4 KiB
Common Lisp

;; process-pair template
;;
;; Reusable video-pair processor: takes a single video source, creates two
;; clips (A and B) with opposite rotations and sporadic effects, blends them,
;; and applies a per-pair slow rotation driven by a beat scan.
;;
;; All sporadic triggers (invert, hue-shift, ascii) and pair-level controls
;; (blend opacity, rotation) are defined internally using seed offsets.
;;
;; Parameters:
;; video - source video node
;; energy - energy analysis node (drives rotation/zoom amounts)
;; beat-data - beat analysis node (drives sporadic triggers)
;; rng - RNG object from (make-rng seed) for auto-derived seeds
;; rot-dir - initial rotation direction: 1 (clockwise) or -1 (anti-clockwise)
;; rot-a/b - rotation ranges for clip A/B (e.g. [0 45])
;; zoom-a/b - zoom ranges for clip A/B (e.g. [1 1.5])
(deftemplate process-pair
(video energy beat-data rng rot-dir rot-a rot-b zoom-a zoom-b)
;; --- Sporadic triggers for clip A ---
;; Invert: 10% chance per beat, lasts 1-5 beats
(def inv-a (scan beat-data :rng rng :init 0
:step (if (> acc 0) (- acc 1) (if (< (rand) 0.1) (rand-int 1 5) 0))
:emit (if (> acc 0) 1 0)))
;; Hue shift: 10% chance, random hue 30-330 deg, lasts 1-5 beats
(def hue-a (scan beat-data :rng rng :init (dict :rem 0 :hue 0)
:step (if (> rem 0)
(dict :rem (- rem 1) :hue hue)
(if (< (rand) 0.1)
(dict :rem (rand-int 1 5) :hue (rand-range 30 330))
(dict :rem 0 :hue 0)))
:emit (if (> rem 0) hue 0)))
;; ASCII art: 5% chance, lasts 1-3 beats
(def ascii-a (scan beat-data :rng rng :init 0
:step (if (> acc 0) (- acc 1) (if (< (rand) 0.05) (rand-int 1 3) 0))
:emit (if (> acc 0) 1 0)))
;; --- Sporadic triggers for clip B (offset seeds) ---
(def inv-b (scan beat-data :rng rng :init 0
:step (if (> acc 0) (- acc 1) (if (< (rand) 0.1) (rand-int 1 5) 0))
:emit (if (> acc 0) 1 0)))
(def hue-b (scan beat-data :rng rng :init (dict :rem 0 :hue 0)
:step (if (> rem 0)
(dict :rem (- rem 1) :hue hue)
(if (< (rand) 0.1)
(dict :rem (rand-int 1 5) :hue (rand-range 30 330))
(dict :rem 0 :hue 0)))
:emit (if (> rem 0) hue 0)))
(def ascii-b (scan beat-data :rng rng :init 0
:step (if (> acc 0) (- acc 1) (if (< (rand) 0.05) (rand-int 1 3) 0))
:emit (if (> acc 0) 1 0)))
;; --- Pair-level controls ---
;; Internal A/B blend: randomly show A (0), both (0.5), or B (1), every 1-11 beats
(def pair-mix (scan beat-data :rng rng
:init (dict :rem 0 :opacity 0.5)
:step (if (> rem 0)
(dict :rem (- rem 1) :opacity opacity)
(dict :rem (rand-int 1 11) :opacity (* (rand-int 0 2) 0.5)))
:emit opacity))
;; Per-pair rotation: one full rotation every 20-30 beats, alternating direction
(def pair-rot (scan beat-data :rng rng
:init (dict :beat 0 :clen 25 :dir rot-dir :angle 0)
:step (if (< (+ beat 1) clen)
(dict :beat (+ beat 1) :clen clen :dir dir
:angle (+ angle (* dir (/ 360 clen))))
(dict :beat 0 :clen (rand-int 20 30) :dir (* dir -1)
:angle angle))
:emit angle))
;; --- Clip A processing ---
(def clip-a (-> video (segment :start 0 :duration (bind energy duration))))
(def rotated-a (-> clip-a
(effect rotate :angle (bind energy values :range rot-a))
(effect zoom :amount (bind energy values :range zoom-a))
(effect invert :amount (bind inv-a values))
(effect hue_shift :degrees (bind hue-a values))
;; ASCII disabled - too slow without GPU
;; (effect ascii_art
;; :char_size (bind energy values :range [4 32])
;; :mix (bind ascii-a values))
))
;; --- Clip B processing ---
(def clip-b (-> video (segment :start 0 :duration (bind energy duration))))
(def rotated-b (-> clip-b
(effect rotate :angle (bind energy values :range rot-b))
(effect zoom :amount (bind energy values :range zoom-b))
(effect invert :amount (bind inv-b values))
(effect hue_shift :degrees (bind hue-b values))
;; ASCII disabled - too slow without GPU
;; (effect ascii_art
;; :char_size (bind energy values :range [4 32])
;; :mix (bind ascii-b values))
))
;; --- Blend A+B and apply pair rotation ---
(-> rotated-a
(effect blend rotated-b
:mode "alpha" :opacity (bind pair-mix values) :resize_mode "fit")
(effect rotate
:angle (bind pair-rot values))))