annotate clojure/com/aurellem/run/final_cut.clj @ 542:614eddc5b38c

working on generating first major video.
author Robert McIntyre <rlm@mit.edu>
date Mon, 25 Jun 2012 16:08:56 -0500
parents 3f2072b8e457
children 6c379ee3d46e
rev   line source
rlm@530 1 (ns com.aurellem.run.final-cut
rlm@530 2 (:use (com.aurellem.gb saves gb-driver util constants
rlm@530 3 items vbm characters money
rlm@530 4 rlm-assembly))
rlm@530 5 (:use (com.aurellem.run util sound music title save-corruption
rlm@530 6 bootstrap-0 bootstrap-1
rlm@530 7 ram-display
rlm@530 8 ))
rlm@530 9 (:require clojure.string)
rlm@530 10 (:import [com.aurellem.gb.gb_driver SaveState])
rlm@530 11 (:import java.awt.image.BufferedImage)
rlm@530 12 (:import java.io.File)
rlm@530 13 (:import com.aurellem.gb.WaveWriter))
rlm@530 14
rlm@530 15
rlm@542 16 (def render-dir (File. user-home "proj/vba-clojure/render/test"))
rlm@530 17
rlm@530 18 (defn render-files!
rlm@530 19 ([^File target-dir initial-state moves]
rlm@530 20 (let [ram-map-dir (File. target-dir "ram-map")
rlm@530 21 frames-dir (File. target-dir "frames")
rlm@530 22 audio-file (File. target-dir "audio.wav")
rlm@533 23 _ (.mkdir target-dir)
rlm@533 24 _ (.mkdir ram-map-dir)
rlm@533 25 _ (.mkdir frames-dir)
rlm@530 26 wave-writer (WaveWriter. audio-file)
rlm@530 27 moves (vec moves)]
rlm@530 28 (set-state! initial-state)
rlm@530 29 (dorun
rlm@530 30 (map
rlm@530 31 (fn [index]
rlm@530 32 (run-moves @current-state (vector (moves index)))
rlm@530 33
rlm@530 34 ;; record audio
rlm@530 35 (.process wave-writer (sound-bytes)
rlm@530 36 gb-sound-format)
rlm@530 37
rlm@530 38 ;; write screenshot
rlm@530 39 (write-png!
rlm@530 40 @current-state
rlm@530 41 (File. frames-dir (format "%07d.png" index)))
rlm@530 42
rlm@530 43 ;; write ram-image
rlm@530 44 (write-ram-image!
rlm@530 45 @current-state
rlm@530 46 (File. ram-map-dir (format "%07d.png" index))))
rlm@530 47 (range (count moves))))
rlm@530 48 (.cleanup wave-writer)))
rlm@530 49 ([initial-state moves]
rlm@530 50 (render-files! render-dir initial-state moves))
rlm@530 51 ([moves]
rlm@530 52 (render-files! (root) moves)))
rlm@530 53
rlm@531 54 (defn file-names [#^File dir]
rlm@531 55 (mapv #(.getCanonicalPath %) (next (sort (file-seq dir)))))
rlm@531 56
rlm@531 57 (defn composite-frames-command
rlm@532 58 [screenshot ram-map target move]
rlm@532 59 (let [actual-keys (set move)
rlm@532 60 keys [:a :b :start :select :u :d :l :r]
rlm@532 61 button-on-name ["-size" "5x5" "xc:red"]
rlm@534 62 button-off-name ["-size" "5x5" "xc:white"]]
rlm@532 63 ["convert"
rlm@532 64 "-size" "318x276" "xc:white"
rlm@532 65 (map
rlm@532 66 (fn [index]
rlm@532 67 (let [position ["-geometry"
rlm@532 68 (str "+" (+ 30 (* index 8))
rlm@532 69 "+" "225") "-composite"]]
rlm@532 70 (if (actual-keys (keys index))
rlm@532 71 [button-on-name position]
rlm@532 72 [button-off-name position])))
rlm@532 73 (range (count keys)))
rlm@532 74 screenshot "-geometry" "+10+10" "-composite"
rlm@532 75 ram-map "-geometry" "+180+10" "-composite"
rlm@532 76 target]))
rlm@531 77
rlm@531 78 (defn generate-composite-frames!
rlm@532 79 [^File rendered-dir moves]
rlm@532 80 (let [final-frames (File. rendered-dir "final")
rlm@532 81 _ (.mkdir final-frames)
rlm@532 82 screenshots (file-names (File. rendered-dir "frames"))
rlm@532 83 ram-maps (file-names (File. rendered-dir "ram-map"))
rlm@532 84 targets (map #(.getCanonicalPath
rlm@532 85 (File. final-frames (format "%07d.bmp" %)))
rlm@532 86 (range (count screenshots)))]
rlm@532 87 (dorun
rlm@532 88 (map
rlm@532 89 (comp
rlm@532 90 (partial apply clojure.java.shell/sh)
rlm@532 91 flatten
rlm@532 92 (partial apply composite-frames-command)
rlm@532 93 (fn [a b c d] (println c) [a b c d]))
rlm@532 94 screenshots ram-maps targets moves))))
rlm@531 95
rlm@532 96
rlm@532 97 (defn final-cut! [^File render-dir]
rlm@532 98 (let [movie (File. render-dir "final.ogg")
rlm@532 99 final (File. render-dir "final")]
rlm@532 100 (.delete movie)
rlm@532 101 (clojure.java.shell/sh
rlm@532 102 "ffmpeg" "-r" "60"
rlm@532 103 "-i" (str (.getCanonicalPath final) "/" "%07d.bmp")
rlm@532 104 "-i" (.getCanonicalPath (File. render-dir "audio.wav"))
rlm@532 105 "-b:a" "128k"
rlm@532 106 "-b:v" "9000k"
rlm@532 107 "-c:a" "libvorbis"
rlm@532 108 "-c:v" "libtheora"
rlm@532 109 (.getCanonicalPath movie)) nil))
rlm@532 110
rlm@531 111
rlm@532 112 (comment
rlm@531 113
rlm@532 114 ;; step 1
rlm@532 115
rlm@532 116 (render-files!
rlm@532 117 render-dir (root)
rlm@532 118 (take 9000 (first (control-checkpoint))))
rlm@531 119
rlm@532 120 ;; step 2
rlm@532 121
rlm@532 122 (generate-composite-frames!
rlm@532 123 render-dir
rlm@532 124 (take 9000 (first (control-checkpoint))))
rlm@532 125
rlm@532 126 ;; step 3
rlm@532 127 (final-cut! render-dir)
rlm@532 128 )