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:
53
constructs/slice-every-n.sexp
Normal file
53
constructs/slice-every-n.sexp
Normal file
@@ -0,0 +1,53 @@
|
||||
;; slice-every-n construct - group every N beats into one segment
|
||||
;;
|
||||
;; Usage:
|
||||
;; (construct slice-every-n :path "constructs/slice-every-n.sexp")
|
||||
;; (def segments (slice-every-n beats-data 4
|
||||
;; :init 0
|
||||
;; :reducer (fn [acc i start end]
|
||||
;; {:source video-a
|
||||
;; :effects (list {:effect invert})
|
||||
;; :acc (inc acc)})))
|
||||
;;
|
||||
;; Groups every N analysis times into one segment, calling reducer once per group
|
||||
|
||||
(define-construct slice-every-n
|
||||
"Group every N analysis beats into segments"
|
||||
(analysis n)
|
||||
;; 'init' and 'reducer' come from keyword args
|
||||
;; Reducer receives: (acc, i, start, end) where start/end are audio beat times
|
||||
;; Reducer returns: {:source src :effects fx :acc new-acc}
|
||||
;; Optionally include :start/:end to override (e.g., for wrapping/randomizing)
|
||||
;; :duration is calculated from start/end (use :duration to override)
|
||||
;; Return :skip true to skip this segment
|
||||
(let [times (get analysis :times)
|
||||
;; Group times into chunks of n
|
||||
grouped (chunk-every times n)]
|
||||
(nth
|
||||
(reduce
|
||||
(fn [state group]
|
||||
(let [acc (first state)
|
||||
segments (nth state 1)
|
||||
i (len segments)
|
||||
audio-start (first group)
|
||||
audio-end (last group)
|
||||
audio-duration (- audio-end audio-start)
|
||||
;; Call user's reducer with audio beat times
|
||||
result (reducer acc i audio-start audio-end)
|
||||
new-acc (get result :acc)]
|
||||
;; Skip if reducer returns :skip true
|
||||
(if (get result :skip false)
|
||||
(list new-acc segments)
|
||||
(let [;; Use reducer's start/end/duration if provided, else use audio times
|
||||
seg-start (get result :start audio-start)
|
||||
seg-end (get result :end audio-end)
|
||||
seg-duration (get result :duration (- seg-end seg-start))
|
||||
segment (dict :source (get result :source)
|
||||
:start seg-start
|
||||
:end seg-end
|
||||
:duration seg-duration
|
||||
:effects (get result :effects))]
|
||||
(list new-acc (append segments segment))))))
|
||||
(list init (list))
|
||||
grouped)
|
||||
1)))
|
||||
Reference in New Issue
Block a user