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>
68 lines
2.8 KiB
Common Lisp
68 lines
2.8 KiB
Common Lisp
; Beat-synced video demonstrating all node types
|
|
; Uses: source, segment, effect, resize, blend, layer, sequence, mux, analyze
|
|
(recipe "bound-effects"
|
|
:version "1.0"
|
|
:encoding (:codec "libx264" :crf 22 :preset "fast" :audio-codec "aac" :fps 30)
|
|
|
|
;; Analyzers
|
|
(analyzer beats :path "../artdag-analyzers/beats/analyzer.py")
|
|
(analyzer bass :path "../artdag-analyzers/bass/analyzer.py")
|
|
|
|
;; Effects (all sexp-based now)
|
|
(effect invert :path "../artdag-effects/invert/effect.py")
|
|
(effect sepia :path "sexp_effects/effects/sepia.sexp")
|
|
(effect color-adjust :path "sexp_effects/effects/color-adjust.sexp")
|
|
(effect resize-frame :path "sexp_effects/effects/resize-frame.sexp")
|
|
(effect blend :path "sexp_effects/effects/blend.sexp")
|
|
(effect layer :path "sexp_effects/effects/layer.sexp")
|
|
|
|
;; Construct
|
|
(construct slice-on :path "constructs/slice-on.sexp")
|
|
|
|
;; Sources
|
|
(def video-a (source :path "monday.webm" :description "Video A"))
|
|
(def video-b (source :path "new.webm" :description "Video B"))
|
|
(def video-c (source :path "ecstacy.mp4" :description "Video C"))
|
|
|
|
;; Audio with segment
|
|
(def audio (-> (source :path "dizzy.mp3" :description "Audio input")
|
|
(segment :start 0 :duration 10)))
|
|
|
|
;; Analysis
|
|
(def beats-data (-> audio (analyze beats)))
|
|
(def bass-data (-> audio (analyze bass)))
|
|
|
|
;; Create an overlay track: video-c resized small, with color adjustment
|
|
(def overlay-track (-> video-c
|
|
(segment :start 0 :duration 10)
|
|
(resize 320 180 :mode "linear")
|
|
(effect color-adjust :brightness 20 :contrast 1.2 :saturation 1.5)))
|
|
|
|
;; Main sliced video with effects
|
|
(def segments (slice-on beats-data
|
|
:init 0
|
|
:reducer (fn [acc i start end]
|
|
(let [idx (mod acc 3)
|
|
src (nth (list video-a video-b video-c) idx)
|
|
base-effects (list {:effect invert :intensity (bind bass-data :range [0 100])})
|
|
effects (if (= idx 1)
|
|
(concat base-effects (list {:effect sepia}))
|
|
base-effects)]
|
|
{:source src
|
|
:effects effects
|
|
:acc (inc acc)}))))
|
|
|
|
;; Sequence the beat-sliced segments
|
|
(def synced-video (-> segments
|
|
(sequence :resize-mode :fit :priority :width)))
|
|
|
|
;; Blend overlay with main video (picture-in-picture style)
|
|
(def with-overlay (layer synced-video overlay-track :x 20 :y 20 :opacity 0.8))
|
|
|
|
;; Final blend with original video-a for ghosting effect
|
|
(def final-video (-> video-a
|
|
(segment :start 0 :duration 10)
|
|
(blend with-overlay :mode "screen" :opacity 0.15)))
|
|
|
|
(mux final-video audio))
|