view clojure/com/aurellem/run/final_cut.clj @ 605:54644b08da1a

rendered final video.
author Robert McIntyre <rlm@mit.edu>
date Sun, 02 Sep 2012 14:28:53 -0500
parents c8cda378e1a0
children 47572d444485
line wrap: on
line source
1 (ns com.aurellem.run.final-cut
2 (:use (com.aurellem.gb saves gb-driver util constants
3 items vbm characters money
4 rlm-assembly))
5 (:use (com.aurellem.run util sound music title save-corruption
6 bootstrap-0 bootstrap-1
7 ram-display
8 ))
9 (:require clojure.string)
10 (:import [com.aurellem.gb.gb_driver SaveState])
11 (:import java.awt.image.BufferedImage)
12 (:import java.io.File)
13 (:import com.aurellem.gb.WaveWriter))
16 (def render-dir (File. user-home "proj/vba-clojure/render/test"))
19 (defn render-files!
20 ([^File target-dir
21 moves-render-fn
22 render-ram-map?
23 initial-state
24 moves]
25 (write-moves-to-file! moves (File. target-dir "rlm-yellow-hack.vbm"))
26 (let [ram-map-dir (File. target-dir "ram-map")
27 frames-dir (File. target-dir "frames")
28 moves-dir (File. target-dir "moves")
29 audio-file (File. target-dir "audio.wav")
30 _ (.mkdir target-dir)
31 _ (if render-ram-map? (.mkdir ram-map-dir))
32 _ (.mkdir frames-dir)
33 _ (.mkdir moves-dir)
34 wave-writer (WaveWriter. audio-file)
35 moves (vec moves)
36 desired-fps 60
37 seconds-per-frame (/ 1.0 desired-fps)]
38 (set-state! initial-state)
39 ;; clear sound buffer
40 (sound-bytes)
41 (try
42 (dorun
43 (reduce
44 (fn [[total-audio-samples
45 total-video-samples] move]
46 (run-moves @current-state (vector move))
47 (let [sound (sound-bytes)
48 total-audio-samples (+ total-audio-samples
49 (count sound))
50 total-audio-time
51 (*
52 (/ total-audio-samples 4)
53 (/ 44100))
55 total-video-time (* total-video-samples
56 seconds-per-frame)
58 av-diff (- total-audio-time
59 total-video-time)
60 write-video!
61 (fn [index]
62 ;; write screenshot
63 (moves-render-fn
64 move
65 (File. moves-dir (format "%07d.png" index)))
67 (write-png!
68 @current-state
69 (File. frames-dir (format "%07d.png" index)))
71 ;; write ram-image
72 (if render-ram-map?
73 (write-ram-image!
74 @current-state
75 (File. ram-map-dir (format "%07d.png" index)))))]
76 ;;(println "audio-samples:" (count sound))
78 ;; record audio
79 (.process wave-writer sound gb-sound-format)
81 ;; duplicate or drop frames depending on
82 ;; desired-fps
83 (if (> (Math/abs av-diff) (* 2 seconds-per-frame))
84 (if (< 0 av-diff)
85 ;; audio has gone past video, duplicate video.
86 (do (println
87 "duplicating frame, av-diff is" av-diff)
88 (write-video! (+ 1 total-video-samples))
89 (write-video! (+ 2 total-video-samples))
90 [total-audio-samples
91 (+ 2 total-video-samples)])
92 ;; video has gone past audio, drop frame.
93 (do (println
94 "dropping frame, av-diff is" av-diff)
95 [total-audio-samples
96 total-video-samples]))
97 ;; no frame dropping or duplication required.
98 (do ;;(println "all normal")
99 (write-video! (+ 1 total-video-samples))
100 [total-audio-samples
101 (+ 1 total-video-samples)]))))
102 [0 0 0] moves))
103 (finally
104 (do
105 (println "cleanup audio.")
106 (.cleanup wave-writer))))))
107 ([initial-state moves]
108 (render-files! render-dir initial-state moves))
109 ([moves]
110 (render-files! (root) moves)))
112 (defn file-names [#^File dir]
113 (mapv #(.getCanonicalPath %) (next (sort (file-seq dir)))))
117 ;; (defn final-cut! [^File render-dir]
118 ;; (let [movie (File. render-dir "final.ogg")
119 ;; final-audio (File. render-dir "final.wav")
120 ;; final (File. render-dir "final")]
121 ;; (.delete movie)
122 ;; (.delete final-audio)
123 ;; (clojure.java.shell/sh
124 ;; "sox" (.getCanonicalPath (File. render-dir "audio.wav"))
125 ;; (.getCanonicalPath final-audio))
126 ;; (clojure.java.shell/sh
127 ;; "ffmpeg" "-r" "60" ;; maybe 59.7 ???!
128 ;; "-i" (str (.getCanonicalPath final) "/" "%07d.bmp")
129 ;; "-i" (.getCanonicalPath final-audio)
130 ;; "-b:a" "128k"
131 ;; "-b:v" "9000k"
132 ;; "-c:a" "libvorbis"
133 ;; "-f" "webm"
134 ;; "-g" "200"
135 ;; (.getCanonicalPath movie)) nil))
137 (defn final-cut! [^File render-dir]
138 (let [movie (File. render-dir "final.avi")
139 final-audio (File. render-dir "final.mp3")
140 final (File. render-dir "final")]
141 (.delete movie)
142 (.delete final-audio)
143 (clojure.java.shell/sh
144 "sox" (.getCanonicalPath (File. render-dir "audio.wav"))
145 (.getCanonicalPath final-audio))
146 (clojure.java.shell/sh
147 "ffmpeg"
148 "-framerate" "60"
149 "-i" (str (.getCanonicalPath final) "/" "%07d.png")
150 "-i" (.getCanonicalPath final-audio)
151 "-b:a" "128k"
152 "-b:v" "9000k"
153 "-c:a" "libmp3lame"
154 "-c:v" "mpeg4"
155 "-r" "60"
156 (.getCanonicalPath movie)) nil))
159 (comment
161 ;; step 1
163 (render-files!
164 render-dir (root)
165 (take 9000 (first (control-checkpoint))))
167 ;; step 2
169 (generate-composite-frames!
170 render-dir
171 (take 9000 (first (control-checkpoint))))
173 ;; step 3
174 (final-cut! render-dir)