comparison clojure/com/aurellem/run/final_cut.clj @ 544:86d23b6d433f

trying to fix AV sync issues.
author Robert McIntyre <rlm@mit.edu>
date Wed, 27 Jun 2012 11:20:50 -0500
parents 6c379ee3d46e
children 36e5fa62eb3c
comparison
equal deleted inserted replaced
543:6c379ee3d46e 544:86d23b6d433f
13 (:import com.aurellem.gb.WaveWriter)) 13 (:import com.aurellem.gb.WaveWriter))
14 14
15 15
16 (def render-dir (File. user-home "proj/vba-clojure/render/test")) 16 (def render-dir (File. user-home "proj/vba-clojure/render/test"))
17 17
18 (defn force-sync
19 "keep the entire movie to a certain fps"
20 [fps]
21
22
23 )
24
25
18 (defn render-files! 26 (defn render-files!
19 ([^File target-dir initial-state moves] 27 ([^File target-dir initial-state moves]
20 (let [ram-map-dir (File. target-dir "ram-map") 28 (let [ram-map-dir (File. target-dir "ram-map")
21 frames-dir (File. target-dir "frames") 29 frames-dir (File. target-dir "frames")
22 audio-file (File. target-dir "audio.wav") 30 audio-file (File. target-dir "audio.wav")
23 _ (.mkdir target-dir) 31 _ (.mkdir target-dir)
24 _ (.mkdir ram-map-dir) 32 _ (.mkdir ram-map-dir)
25 _ (.mkdir frames-dir) 33 _ (.mkdir frames-dir)
26 wave-writer (WaveWriter. audio-file) 34 wave-writer (WaveWriter. audio-file)
27 moves (vec moves)] 35 moves (vec moves)
36 desired-fps 60
37 seconds-per-frame (/ 1.0 desired-fps)
38
39 ]
28 (set-state! initial-state) 40 (set-state! initial-state)
29 (dorun 41 ;; clear sound buffer
30 (map 42 (sound-bytes)
31 (fn [index] 43 (try
32 (run-moves @current-state (vector (moves index))) 44 (dorun
45 (reduce
46 (fn [[total-audio-samples
47 total-video-samples] move]
48 (run-moves @current-state (vector move))
49 (let [sound (sound-bytes)
50 total-audio-samples (+ total-audio-samples
51 (count sound))
52 total-audio-time
53 (*
54 (/ total-audio-samples 4)
55 (/ 44100))
56
57 total-video-time (* total-video-samples
58 seconds-per-frame)
33 59
34 ;; record audio 60 av-diff (- total-audio-time
35 (.process wave-writer (sound-bytes) 61 total-video-time)
36 gb-sound-format) 62 write-video!
37 63 (fn [index]
38 ;; write screenshot 64 ;; write screenshot
39 (write-png! 65
40 @current-state 66
41 (File. frames-dir (format "%07d.png" index))) 67 (write-png!
42 68 @current-state
43 ;; write ram-image 69 (File. frames-dir (format "%07d.png" index)))
44 (write-ram-image! 70
45 @current-state 71 ;; write ram-image
46 (File. ram-map-dir (format "%07d.png" index)))) 72 (write-ram-image!
47 (range (count moves)))) 73 @current-state
48 (.cleanup wave-writer))) 74 (File. ram-map-dir (format "%07d.png" index))))]
49 ([initial-state moves] 75 ;;(println "audio-samples:" (count sound))
50 (render-files! render-dir initial-state moves)) 76
51 ([moves] 77 ;; record audio
52 (render-files! (root) moves))) 78 (.process wave-writer sound gb-sound-format)
79
80 ;; duplicate or drop frames depending on
81 ;; desired-fps
82 (if (> (Math/abs av-diff) (* 2 seconds-per-frame))
83 (if (< 0 av-diff)
84 ;; audio has gone past video, duplicate video.
85 (do (println
86 "duplicating frame, av-diff is" av-diff)
87 (write-video! (+ 1 total-video-samples))
88 (write-video! (+ 2 total-video-samples))
89 [total-audio-samples
90 (+ 2 total-video-samples)])
91 ;; video has gone past audio, drop frame.
92 (do (println
93 "dropping frame, av-diff is" av-diff)
94 [total-audio-samples
95 total-video-samples]))
96 ;; no frame dropping or duplication required.
97 (do ;;(println "all normal")
98 (write-video! (+ 1 total-video-samples))
99 [total-audio-samples
100 (+ 1 total-video-samples)]))))
101 [0 0 0] moves))
102 (finally
103 (do
104 (println "cleanup audio.")
105 (.cleanup wave-writer))))))
106 ([initial-state moves]
107 (render-files! render-dir initial-state moves))
108 ([moves]
109 (render-files! (root) moves)))
53 110
54 (defn file-names [#^File dir] 111 (defn file-names [#^File dir]
55 (mapv #(.getCanonicalPath %) (next (sort (file-seq dir))))) 112 (mapv #(.getCanonicalPath %) (next (sort (file-seq dir)))))
56 113
57 (defn composite-frames-command 114 (defn composite-frames-command
94 screenshots ram-maps targets moves)))) 151 screenshots ram-maps targets moves))))
95 152
96 153
97 (defn final-cut! [^File render-dir] 154 (defn final-cut! [^File render-dir]
98 (let [movie (File. render-dir "final.ogg") 155 (let [movie (File. render-dir "final.ogg")
156 final-audio (File. render-dir "final.wav")
99 final (File. render-dir "final")] 157 final (File. render-dir "final")]
100 (.delete movie) 158 (.delete movie)
101 (clojure.java.shell/sh 159 (clojure.java.shell/sh
160 "sox" (.getCanonicalPath (File. render-dir "audio.wav"))
161 (.getCanonicalPath final-audio))
162 (clojure.java.shell/sh
102 "ffmpeg" "-r" "60" ;; maybe 59.7 ???! 163 "ffmpeg" "-r" "60" ;; maybe 59.7 ???!
103 "-i" (str (.getCanonicalPath final) "/" "%07d.bmp") 164 "-i" (str (.getCanonicalPath final) "/" "%07d.bmp")
104 "-i" (.getCanonicalPath (File. render-dir "audio.wav")) 165 "-i" (.getCanonicalPath final-audio)
105 "-b:a" "128k" 166 "-b:a" "128k"
106 "-b:v" "9000k" 167 "-b:v" "9000k"
107 "-c:a" "libvorbis" 168 "-c:a" "libvorbis"
108 "-c:v" "libtheora" 169 "-c:v" "libtheora"
109 (.getCanonicalPath movie)) nil)) 170 (.getCanonicalPath movie)) nil))