Mercurial > vba-clojure
diff 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 |
line wrap: on
line diff
1.1 --- a/clojure/com/aurellem/run/final_cut.clj Mon Jun 25 19:46:48 2012 -0500 1.2 +++ b/clojure/com/aurellem/run/final_cut.clj Wed Jun 27 11:20:50 2012 -0500 1.3 @@ -15,6 +15,14 @@ 1.4 1.5 (def render-dir (File. user-home "proj/vba-clojure/render/test")) 1.6 1.7 +(defn force-sync 1.8 + "keep the entire movie to a certain fps" 1.9 + [fps] 1.10 + 1.11 + 1.12 + ) 1.13 + 1.14 + 1.15 (defn render-files! 1.16 ([^File target-dir initial-state moves] 1.17 (let [ram-map-dir (File. target-dir "ram-map") 1.18 @@ -24,32 +32,81 @@ 1.19 _ (.mkdir ram-map-dir) 1.20 _ (.mkdir frames-dir) 1.21 wave-writer (WaveWriter. audio-file) 1.22 - moves (vec moves)] 1.23 + moves (vec moves) 1.24 + desired-fps 60 1.25 + seconds-per-frame (/ 1.0 desired-fps) 1.26 + 1.27 + ] 1.28 (set-state! initial-state) 1.29 - (dorun 1.30 - (map 1.31 - (fn [index] 1.32 - (run-moves @current-state (vector (moves index))) 1.33 + ;; clear sound buffer 1.34 + (sound-bytes) 1.35 + (try 1.36 + (dorun 1.37 + (reduce 1.38 + (fn [[total-audio-samples 1.39 + total-video-samples] move] 1.40 + (run-moves @current-state (vector move)) 1.41 + (let [sound (sound-bytes) 1.42 + total-audio-samples (+ total-audio-samples 1.43 + (count sound)) 1.44 + total-audio-time 1.45 + (* 1.46 + (/ total-audio-samples 4) 1.47 + (/ 44100)) 1.48 + 1.49 + total-video-time (* total-video-samples 1.50 + seconds-per-frame) 1.51 1.52 - ;; record audio 1.53 - (.process wave-writer (sound-bytes) 1.54 - gb-sound-format) 1.55 - 1.56 - ;; write screenshot 1.57 - (write-png! 1.58 - @current-state 1.59 - (File. frames-dir (format "%07d.png" index))) 1.60 - 1.61 - ;; write ram-image 1.62 - (write-ram-image! 1.63 - @current-state 1.64 - (File. ram-map-dir (format "%07d.png" index)))) 1.65 - (range (count moves)))) 1.66 - (.cleanup wave-writer))) 1.67 - ([initial-state moves] 1.68 - (render-files! render-dir initial-state moves)) 1.69 - ([moves] 1.70 - (render-files! (root) moves))) 1.71 + av-diff (- total-audio-time 1.72 + total-video-time) 1.73 + write-video! 1.74 + (fn [index] 1.75 + ;; write screenshot 1.76 + 1.77 + 1.78 + (write-png! 1.79 + @current-state 1.80 + (File. frames-dir (format "%07d.png" index))) 1.81 + 1.82 + ;; write ram-image 1.83 + (write-ram-image! 1.84 + @current-state 1.85 + (File. ram-map-dir (format "%07d.png" index))))] 1.86 + ;;(println "audio-samples:" (count sound)) 1.87 + 1.88 + ;; record audio 1.89 + (.process wave-writer sound gb-sound-format) 1.90 + 1.91 + ;; duplicate or drop frames depending on 1.92 + ;; desired-fps 1.93 + (if (> (Math/abs av-diff) (* 2 seconds-per-frame)) 1.94 + (if (< 0 av-diff) 1.95 + ;; audio has gone past video, duplicate video. 1.96 + (do (println 1.97 + "duplicating frame, av-diff is" av-diff) 1.98 + (write-video! (+ 1 total-video-samples)) 1.99 + (write-video! (+ 2 total-video-samples)) 1.100 + [total-audio-samples 1.101 + (+ 2 total-video-samples)]) 1.102 + ;; video has gone past audio, drop frame. 1.103 + (do (println 1.104 + "dropping frame, av-diff is" av-diff) 1.105 + [total-audio-samples 1.106 + total-video-samples])) 1.107 + ;; no frame dropping or duplication required. 1.108 + (do ;;(println "all normal") 1.109 + (write-video! (+ 1 total-video-samples)) 1.110 + [total-audio-samples 1.111 + (+ 1 total-video-samples)])))) 1.112 + [0 0 0] moves)) 1.113 + (finally 1.114 + (do 1.115 + (println "cleanup audio.") 1.116 + (.cleanup wave-writer)))))) 1.117 + ([initial-state moves] 1.118 + (render-files! render-dir initial-state moves)) 1.119 + ([moves] 1.120 + (render-files! (root) moves))) 1.121 1.122 (defn file-names [#^File dir] 1.123 (mapv #(.getCanonicalPath %) (next (sort (file-seq dir))))) 1.124 @@ -96,12 +153,16 @@ 1.125 1.126 (defn final-cut! [^File render-dir] 1.127 (let [movie (File. render-dir "final.ogg") 1.128 + final-audio (File. render-dir "final.wav") 1.129 final (File. render-dir "final")] 1.130 (.delete movie) 1.131 (clojure.java.shell/sh 1.132 + "sox" (.getCanonicalPath (File. render-dir "audio.wav")) 1.133 + (.getCanonicalPath final-audio)) 1.134 + (clojure.java.shell/sh 1.135 "ffmpeg" "-r" "60" ;; maybe 59.7 ???! 1.136 "-i" (str (.getCanonicalPath final) "/" "%07d.bmp") 1.137 - "-i" (.getCanonicalPath (File. render-dir "audio.wav")) 1.138 + "-i" (.getCanonicalPath final-audio) 1.139 "-b:a" "128k" 1.140 "-b:v" "9000k" 1.141 "-c:a" "libvorbis"