- 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>
66 lines
2.7 KiB
Common Lisp
66 lines
2.7 KiB
Common Lisp
;; cycle-crossfade template
|
|
;;
|
|
;; Generalized cycling zoom-crossfade for any number of video layers.
|
|
;; Cycles through videos with smooth zoom-based crossfade transitions.
|
|
;;
|
|
;; Parameters:
|
|
;; beat-data - beat analysis node (drives timing)
|
|
;; input-videos - list of video nodes to cycle through
|
|
;; init-clen - initial cycle length in beats
|
|
;;
|
|
;; NOTE: The parameter is named "input-videos" (not "videos") because
|
|
;; template substitution replaces param names everywhere in the AST.
|
|
;; The planner's _expand_slice_on injects env["videos"] at plan time,
|
|
;; so (len videos) inside the lambda references that injected value.
|
|
|
|
(deftemplate cycle-crossfade
|
|
(beat-data input-videos init-clen)
|
|
|
|
(slice-on beat-data
|
|
:videos input-videos
|
|
:init {:cycle 0 :beat 0 :clen init-clen}
|
|
:fn (lambda [acc i start end]
|
|
(let [beat (get acc "beat")
|
|
clen (get acc "clen")
|
|
active (get acc "cycle")
|
|
n (len videos)
|
|
phase3 (* beat 3)
|
|
wt (lambda [p]
|
|
(let [prev (mod (+ p (- n 1)) n)]
|
|
(if (= active p)
|
|
(if (< phase3 clen) 1.0
|
|
(if (< phase3 (* clen 2))
|
|
(- 1.0 (* (/ (- phase3 clen) clen) 1.0))
|
|
0.0))
|
|
(if (= active prev)
|
|
(if (< phase3 clen) 0.0
|
|
(if (< phase3 (* clen 2))
|
|
(* (/ (- phase3 clen) clen) 1.0)
|
|
1.0))
|
|
0.0))))
|
|
zm (lambda [p]
|
|
(let [prev (mod (+ p (- n 1)) n)]
|
|
(if (= active p)
|
|
;; Active video: normal -> zoom out during transition -> tiny
|
|
(if (< phase3 clen) 1.0
|
|
(if (< phase3 (* clen 2))
|
|
(+ 1.0 (* (/ (- phase3 clen) clen) 1.0))
|
|
0.1))
|
|
(if (= active prev)
|
|
;; Incoming video: tiny -> zoom in during transition -> normal
|
|
(if (< phase3 clen) 0.1
|
|
(if (< phase3 (* clen 2))
|
|
(+ 0.1 (* (/ (- phase3 clen) clen) 0.9))
|
|
1.0))
|
|
0.1))))
|
|
new-acc (if (< (+ beat 1) clen)
|
|
(dict :cycle active :beat (+ beat 1) :clen clen)
|
|
(dict :cycle (mod (+ active 1) n) :beat 0
|
|
:clen (+ 40 (mod (* i 7) 41))))]
|
|
{:layers (map (lambda [p]
|
|
{:video p :effects [{:effect zoom :amount (zm p)}]})
|
|
(range 0 n))
|
|
:compose {:effect blend_multi :mode "alpha"
|
|
:weights (map (lambda [p] (wt p)) (range 0 n))}
|
|
:acc new-acc}))))
|