rlm@1
|
1 (ns clojureDemo.Xuggle)
|
rlm@1
|
2
|
rlm@1
|
3 (import '(ij ImagePlus IJ))
|
rlm@1
|
4 (import '(java.awt Rectangle Robot Toolkit) )
|
rlm@1
|
5 (import '(java.awt.image BufferedImage) )
|
rlm@1
|
6 (import '(java.awt Graphics2D Panel))
|
rlm@1
|
7 (import '(java.io File) )
|
rlm@1
|
8 (import '(javax.imageio ImageIO) )
|
rlm@1
|
9 (import '(com.xuggle.mediatool ToolFactory))
|
rlm@1
|
10 (import '(com.xuggle.mediatool IMediaDebugListener IMediaDebugListener$Event))
|
rlm@1
|
11 (import '(com.xuggle.mediatool MediaToolAdapter MediaListenerAdapter))
|
rlm@1
|
12 (import '(com.xuggle.xuggler IContainer IContainer$Type IPacket))
|
rlm@1
|
13 (import '(javax.swing JFrame))
|
rlm@1
|
14 (import '(com.xuggle.mediatool IMediaWriter))
|
rlm@1
|
15 (import '(org.apache.commons.io FileUtils))
|
rlm@1
|
16 (import '(javax.imageio.stream FileImageOutputStream))
|
rlm@1
|
17 (import '(javax.imageio ImageWriteParam IIOImage))
|
rlm@1
|
18 (import '(com.xuggle.xuggler IRational))
|
rlm@1
|
19 (import '(java.util.concurrent TimeUnit))
|
rlm@1
|
20 (import '(com.xuggle.xuggler ICodec))
|
rlm@1
|
21
|
rlm@1
|
22 (use 'clojureDemo.Defines)
|
rlm@1
|
23 ;(use '[clojureDemo.OpenCv :only (video-data)])
|
rlm@1
|
24
|
rlm@1
|
25
|
rlm@1
|
26
|
rlm@1
|
27 (import '(java.io File))
|
rlm@1
|
28 (import '(org.apache.commons.io FileUtils))
|
rlm@1
|
29 (import '(javax.imageio ImageIO) )
|
rlm@1
|
30
|
rlm@1
|
31 (import '(ij.plugin PlugIn))
|
rlm@1
|
32 (import '(ij ImagePlus IJ))
|
rlm@1
|
33
|
rlm@1
|
34
|
rlm@1
|
35 (use 'clojure.contrib.repl-utils)
|
rlm@1
|
36 (use ['clojureDemo.Defines
|
rlm@1
|
37 :only '(
|
rlm@1
|
38 lian look getto human0 blow base app0 app1 app2 app3 app4 app5
|
rlm@1
|
39 bounce0 bounce1 bounce2 bounce3 bounce4 bounce5 bounce6
|
rlm@1
|
40 collide0 collide1 collide2 collide3 collide4
|
rlm@1
|
41 give0 give1 give2 give3 give4 target default)])
|
rlm@1
|
42
|
rlm@1
|
43
|
rlm@1
|
44 ;(def hamster (ImagePlus. "lklk" (first (video-seq look))))
|
rlm@1
|
45
|
rlm@1
|
46
|
rlm@1
|
47
|
rlm@1
|
48
|
rlm@1
|
49
|
rlm@1
|
50 (defn- makePanel [image] (proxy [Panel] [] (paint [g] (.drawImage g image 0 0 nil))))
|
rlm@1
|
51
|
rlm@1
|
52
|
rlm@1
|
53 (defmulti display "Creates a JFrame and displays a buffered image" class)
|
rlm@1
|
54
|
rlm@1
|
55 (defmethod display
|
rlm@1
|
56 BufferedImage [image]
|
rlm@1
|
57 (let [panel (makePanel image)
|
rlm@1
|
58 frame (JFrame. "Oh Yeah!")]
|
rlm@1
|
59 (.add frame panel)
|
rlm@1
|
60 (.pack frame)
|
rlm@1
|
61 (.setVisible frame true )
|
rlm@1
|
62 (.setSize frame(.getWidth image) (.getHeight image))))
|
rlm@1
|
63
|
rlm@1
|
64 (defmethod display
|
rlm@1
|
65 ImagePlus [image]
|
rlm@1
|
66 (display (.getBufferedImage image)))
|
rlm@1
|
67
|
rlm@1
|
68
|
rlm@1
|
69
|
rlm@1
|
70
|
rlm@1
|
71 (defn flash
|
rlm@1
|
72 [image]
|
rlm@1
|
73
|
rlm@1
|
74 (.start (Thread. (fn []
|
rlm@1
|
75 (do
|
rlm@1
|
76 (.show image)
|
rlm@1
|
77 (.updateAndRepaintWindow image)
|
rlm@1
|
78 (Thread/sleep 4000)
|
rlm@1
|
79 (.hide image))))))
|
rlm@1
|
80
|
rlm@1
|
81
|
rlm@1
|
82 (defn readerRecurse
|
rlm@1
|
83 "calls .readPacket until there's nothing left to do"
|
rlm@1
|
84 [reader]
|
rlm@1
|
85 (if (not (nil? (.readPacket reader))) ; here .readPacket actually does the processing as a side-effect.
|
rlm@1
|
86 nil ; it returns null when it has MORE to process, and signals an error when done...
|
rlm@1
|
87 (recur reader)))
|
rlm@1
|
88
|
rlm@1
|
89
|
rlm@1
|
90 (def *cache-directory* (File. "/home/r/Desktop/vision-cache"))
|
rlm@1
|
91 (def *ext* "jpg")
|
rlm@1
|
92
|
rlm@1
|
93
|
rlm@1
|
94
|
rlm@1
|
95
|
rlm@1
|
96 (defn writeJpg
|
rlm@1
|
97 "WTF is this shit?!"
|
rlm@1
|
98 [image target quality]
|
rlm@1
|
99 (let [jpgWriter (.next (ImageIO/getImageWritersByFormatName *ext*))]
|
rlm@1
|
100 (doto (.getDefaultWriteParam jpgWriter)
|
rlm@1
|
101 (.setCompressionMode ImageWriteParam/MODE_EXPLICIT)
|
rlm@1
|
102 (.setCompressionQuality quality))
|
rlm@1
|
103 (doto jpgWriter
|
rlm@1
|
104 (.setOutput (FileImageOutputStream. target))
|
rlm@1
|
105 (.write (IIOImage. image nil nil))
|
rlm@1
|
106 (.dispose))))
|
rlm@1
|
107
|
rlm@1
|
108
|
rlm@1
|
109
|
rlm@1
|
110 (defn cache-path
|
rlm@1
|
111 [video]
|
rlm@1
|
112 (File. *cache-directory* (.getName video)))
|
rlm@1
|
113
|
rlm@1
|
114 (defn video-frame-path
|
rlm@1
|
115 [video n]
|
rlm@1
|
116 (File. (cache-path video) (str n "." *ext*)))
|
rlm@1
|
117
|
rlm@1
|
118
|
rlm@1
|
119 (defn already-cached
|
rlm@1
|
120 "this is the simplest and most retarded way to do it"
|
rlm@1
|
121 [video]
|
rlm@1
|
122 (.exists (cache-path video)))
|
rlm@1
|
123
|
rlm@1
|
124
|
rlm@1
|
125
|
rlm@1
|
126
|
rlm@1
|
127
|
rlm@1
|
128
|
rlm@1
|
129 (defn make-incrementer [start increment] (let [a (ref (- start increment))] (fn [] (dosync (ref-set a (+ @a increment))))))
|
rlm@1
|
130
|
rlm@1
|
131 (defn make-frame-writer
|
rlm@1
|
132 [video]
|
rlm@1
|
133 (let [incrementer (make-incrementer 0 1)]
|
rlm@1
|
134 (proxy [MediaListenerAdapter] []
|
rlm@1
|
135
|
rlm@1
|
136 (onVideoPicture
|
rlm@1
|
137 [event]
|
rlm@1
|
138 ;(println (.getImage event))
|
rlm@1
|
139 ;(println (File. (cache-path video) (str (incrementer) "." *ext* ) ))
|
rlm@1
|
140
|
rlm@1
|
141 (let [target (File. (cache-path video) (str (incrementer) "." *ext* ))]
|
rlm@1
|
142 (if (= *ext* "jpg")
|
rlm@1
|
143 (writeJpg (.getImage event) target 1)
|
rlm@1
|
144 (ImageIO/write (.getImage event) *ext* target )))))))
|
rlm@1
|
145
|
rlm@1
|
146
|
rlm@1
|
147
|
rlm@1
|
148 (defn cache
|
rlm@1
|
149 "caching of frames without opencv"
|
rlm@1
|
150 [video]
|
rlm@1
|
151
|
rlm@1
|
152 (if (already-cached video)
|
rlm@1
|
153 nil
|
rlm@1
|
154 (time
|
rlm@1
|
155 (let [reader (ToolFactory/makeReader (str video))]
|
rlm@1
|
156 (println "slow cache!")
|
rlm@1
|
157 (FileUtils/forceMkdir (cache-path video))
|
rlm@1
|
158 (doto reader
|
rlm@1
|
159 (.setBufferedImageTypeToGenerate BufferedImage/TYPE_3BYTE_BGR)
|
rlm@1
|
160 (.addListener (make-frame-writer video))
|
rlm@1
|
161 (.addListener (ToolFactory/makeDebugListener (into-array [IMediaDebugListener$Event/META_DATA]))))
|
rlm@1
|
162 (readerRecurse reader)))))
|
rlm@1
|
163
|
rlm@1
|
164
|
rlm@1
|
165 (defn video-data
|
rlm@1
|
166 "get video data without opencv"
|
rlm@1
|
167 [video] (cache video)
|
rlm@1
|
168
|
rlm@1
|
169
|
rlm@1
|
170 {:length (- (count (file-seq (cache-path video))) 1)
|
rlm@1
|
171 :width (.getWidth (ImagePlus. (str (video-frame-path video 0))))
|
rlm@1
|
172 :height (.getHeight (ImagePlus. (str (video-frame-path video 0))))
|
rlm@1
|
173 :fps 30}) ; yeah --- I'll figure this out later.
|
rlm@1
|
174 (def video-data (memoize video-data))
|
rlm@1
|
175
|
rlm@1
|
176
|
rlm@1
|
177
|
rlm@1
|
178 (defn convert
|
rlm@1
|
179 "takes video and converts it to a new type of video"
|
rlm@1
|
180 [videoInput videoOutput]
|
rlm@1
|
181 (let [reader (ToolFactory/makeReader (str videoInput))]
|
rlm@1
|
182 (doto reader
|
rlm@1
|
183 (.addListener (ToolFactory/makeWriter (str videoOutput) reader))
|
rlm@1
|
184 (.addListener (ToolFactory/makeDebugListener (into-array [IMediaDebugListener$Event/META_DATA]))))
|
rlm@1
|
185 (readerRecurse reader)))
|
rlm@1
|
186
|
rlm@1
|
187
|
rlm@1
|
188 (import '(com.xuggle.xuggler.video ConverterFactory))
|
rlm@1
|
189
|
rlm@1
|
190
|
rlm@1
|
191 (defn trans-save
|
rlm@1
|
192 "this is a transitive way to save a stream to an avi file.
|
rlm@1
|
193 It uses meta data to determine what fps to use to encode."
|
rlm@1
|
194 [destination video-seq]
|
rlm@1
|
195 (let [data (meta video-seq)
|
rlm@1
|
196 writer (ToolFactory/makeWriter (str destination))
|
rlm@1
|
197 incrementer (make-incrementer 0 (/ 1 30))]
|
rlm@1
|
198 (.addVideoStream writer 0 0 (ICodec/findEncodingCodecByName "mpeg4")
|
rlm@1
|
199 (IRational/make (double (:fps data)))
|
rlm@1
|
200 (int (:width data)) (int (:height data)))
|
rlm@1
|
201 (dorun (map #(.encodeVideo writer 0
|
rlm@1
|
202 (ConverterFactory/convertToType (.getBufferedImage %) BufferedImage/TYPE_3BYTE_BGR)
|
rlm@1
|
203 (long (* 1000000000 (incrementer))) TimeUnit/NANOSECONDS) video-seq))
|
rlm@1
|
204 (.close writer))
|
rlm@1
|
205 video-seq)
|
rlm@1
|
206
|
rlm@1
|
207
|
rlm@1
|
208 (defn video-seq
|
rlm@1
|
209 "let's use ImagePlus stuff!"
|
rlm@1
|
210 ([video] (cache video)
|
rlm@1
|
211 (with-meta (map #(ImagePlus. (str (video-frame-path video %))) (range (:length (video-data video))) ) (video-data video))))
|
rlm@1
|
212
|
rlm@1
|
213
|
rlm@1
|
214
|
rlm@1
|
215
|
rlm@1
|
216
|
rlm@1
|
217
|
rlm@1
|
218 (comment
|
rlm@1
|
219 (do (use :reload-all 'clojureDemo.Xuggle) (in-ns 'clojureDemo.Xuggle))
|
rlm@1
|
220 )
|
rlm@1
|
221
|