comparison org/capture-video.org @ 573:ebdedb039cbb tip

add release.
author Robert McIntyre <rlm@mit.edu>
date Sun, 19 Apr 2015 04:01:53 -0700
parents 7e7f8d6d9ec5
children
comparison
equal deleted inserted replaced
572:202c6d19acad 573:ebdedb039cbb
23 smooth video output at a constant framerate. 23 smooth video output at a constant framerate.
24 24
25 25
26 * Video recording requires a steady framerate 26 * Video recording requires a steady framerate
27 ** The built-in =Timer= rushes to keep up. 27 ** The built-in =Timer= rushes to keep up.
28 #* Game-time vs. User-time vs. Video-time 28 # * Game-time vs. User-time vs. Video-time
29 29
30 Standard JME3 applications use a =Timer= object to manage time in the 30 Standard JME3 applications use a =Timer= object to manage time in the
31 simulated world. Because most JME3 applications (e.g. games) are 31 simulated world. Because most JME3 applications (e.g. games) are
32 supposed to happen \ldquo{}live\rdquo{}, the built-in =Timer= requires 32 supposed to happen \ldquo{}live\rdquo{}, the built-in =Timer= requires
33 simulated time to match real time. This means that the application 33 simulated time to match real time. This means that the application
57 # cut corners, giving fast, approximate answers instead of careful, 57 # cut corners, giving fast, approximate answers instead of careful,
58 # accurate ones. Although physical accuracy sometimes suffers as a 58 # accurate ones. Although physical accuracy sometimes suffers as a
59 # result, this policy ensures that the user will never be kept waiting 59 # result, this policy ensures that the user will never be kept waiting
60 # while the computer stops to make a complicated calculation. 60 # while the computer stops to make a complicated calculation.
61 61
62 #fast answers are more important than accurate ones. 62 # fast answers are more important than accurate ones.
63 63
64 # A standard JME3 application that extends =SimpleApplication= or 64 # A standard JME3 application that extends =SimpleApplication= or
65 # =Application= tries as hard as it can to keep in sync with 65 # =Application= tries as hard as it can to keep in sync with
66 # /user-time/. If a ball is rolling at 1 game-mile per game-hour in 66 # /user-time/. If a ball is rolling at 1 game-mile per game-hour in
67 # the game, and you wait for one user-hour as measured by the clock on 67 # the game, and you wait for one user-hour as measured by the clock on
176 timer that always reports the same framerate to JME3 every time it is 176 timer that always reports the same framerate to JME3 every time it is
177 called. 177 called.
178 178
179 179
180 =./src/com/aurellem/capture/IsoTimer.java= 180 =./src/com/aurellem/capture/IsoTimer.java=
181 #+include ../../jmeCapture/src/com/aurellem/capture/IsoTimer.java src java 181 #+INCLUDE: "../../jmeCapture/src/com/aurellem/capture/IsoTimer.java" src java
182 182
183 If an Application uses this =IsoTimer= instead of the normal one, we 183 If an Application uses this =IsoTimer= instead of the normal one, we
184 can be sure that every call to =simpleUpdate=, for example, 184 can be sure that every call to =simpleUpdate=, for example,
185 corresponds to exactly $(\frac{1}{fps})$ seconds of game-time. 185 corresponds to exactly $(\frac{1}{fps})$ seconds of game-time.
186 186
200 200
201 An appropriate interface describing this behavior could look like 201 An appropriate interface describing this behavior could look like
202 this: 202 this:
203 203
204 =./src/com/aurellem/capture/video/VideoRecorder.java= 204 =./src/com/aurellem/capture/video/VideoRecorder.java=
205 #+include ../../jmeCapture/src/com/aurellem/capture/video/VideoRecorder.java src java 205 #+include: "../../jmeCapture/src/com/aurellem/capture/video/VideoRecorder.java" src java
206
207 206
208 JME3 already provides exactly the class we need: the =SceneProcessor= 207 JME3 already provides exactly the class we need: the =SceneProcessor=
209 class can be attached to any viewport and the methods defined therein 208 class can be attached to any viewport and the methods defined therein
210 will be called at the appropriate points in the rendering process. 209 will be called at the appropriate points in the rendering process.
211 210
219 218
220 Here is an AbstractVideoRecorder class that takes care of the details 219 Here is an AbstractVideoRecorder class that takes care of the details
221 of setup and teardown. 220 of setup and teardown.
222 221
223 =./src/com/aurellem/capture/video/AbstractVideoRecorder.java= 222 =./src/com/aurellem/capture/video/AbstractVideoRecorder.java=
224 #+include ../../jmeCapture/src/com/aurellem/capture/video/AbstractVideoRecorder.java src java 223 #+include: ../../jmeCapture/src/com/aurellem/capture/video/AbstractVideoRecorder.java src java
225 224
226 225
227 ** There are many options for handling video files in Java 226 ** There are many options for handling video files in Java
228 227
229 If you want to generate video from Java, a great option is [[http://www.xuggle.com/][Xuggle]]. It 228 If you want to generate video from Java, a great option is [[http://www.xuggle.com/][Xuggle]]. It
233 232
234 Here is a =VideoRecorder= that uses [[http://www.xuggle.com/][Xuggle]] to write each frame to a 233 Here is a =VideoRecorder= that uses [[http://www.xuggle.com/][Xuggle]] to write each frame to a
235 video file. 234 video file.
236 235
237 =./src/com/aurellem/capture/video/XuggleVideoRecorder.java= 236 =./src/com/aurellem/capture/video/XuggleVideoRecorder.java=
238 #+include ../../jmeCapture/src/com/aurellem/capture/video/XuggleVideoRecorder.java src java 237 #+include: ../../jmeCapture/src/com/aurellem/capture/video/XuggleVideoRecorder.java src java
239 238
240 With this, we are able to record video! 239 With this, we are able to record video!
241 240
242 However, it can be hard to properly install Xuggle. If you would 241 However, it can be hard to properly install Xuggle. If you would
243 rather not use Xuggle, here is an alternate class that uses [[http://www.randelshofer.ch/blog/2008/08/writing-avi-videos-in-pure-java/][Werner 242 rather not use Xuggle, here is an alternate class that uses [[http://www.randelshofer.ch/blog/2008/08/writing-avi-videos-in-pure-java/][Werner
244 Randelshofer's]] excellent pure Java AVI file writer. 243 Randelshofer's]] excellent pure Java AVI file writer.
245 244
246 =./src/com/aurellem/capture/video/AVIVideoRecorder.java= 245 =./src/com/aurellem/capture/video/AVIVideoRecorder.java=
247 #+include ../../jmeCapture/src/com/aurellem/capture/video/AVIVideoRecorder.java src java 246 #+include: ../../jmeCapture/src/com/aurellem/capture/video/AVIVideoRecorder.java src java
248 247
249 This =AVIVideoRecorder= is more limited than the 248 This =AVIVideoRecorder= is more limited than the
250 =XuggleVideoRecorder=, but requires less external dependencies. 249 =XuggleVideoRecorder=, but requires less external dependencies.
251 250
252 Finally, for those of you who prefer to create the final video from a 251 Finally, for those of you who prefer to create the final video from a
254 each frame to a folder as a sequentially numbered image file. Note 253 each frame to a folder as a sequentially numbered image file. Note
255 that you have to remember the FPS at which you recorded the video, as 254 that you have to remember the FPS at which you recorded the video, as
256 this information is lost when saving each frame to a file. 255 this information is lost when saving each frame to a file.
257 256
258 =./src/com/aurellem/capture/video/FileVideoRecorder.java= 257 =./src/com/aurellem/capture/video/FileVideoRecorder.java=
259 #+include ../../jmeCapture/src/com/aurellem/capture/video/FileVideoRecorder.java src java 258 #+include: ../../jmeCapture/src/com/aurellem/capture/video/FileVideoRecorder.java src java
260
261
262
263 259
264 * How to record videos yourself 260 * How to record videos yourself
265 261
266 ** Include this code. 262 ** Include this code.
267 263
341 337
342 338
343 I've added support for this under a class called 339 I've added support for this under a class called
344 =com.aurellem.capture.Capture=. You can get it [[http://hg.bortreb.com/jmeCapture/][here]]. 340 =com.aurellem.capture.Capture=. You can get it [[http://hg.bortreb.com/jmeCapture/][here]].
345 341
346
347 ** Hello Video! example 342 ** Hello Video! example
348 343
349 I've taken [[http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/helloworld/HelloLoop.java][=./jme3/src/test/jme3test/helloworld/HelloLoop.java=]] and 344 I've taken [[http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/helloworld/HelloLoop.java][=./jme3/src/test/jme3test/helloworld/HelloLoop.java=]] and
350 augmented it with video output as follows: 345 augmented it with video output as follows:
351 346
352 =./src/com/aurellem/capture/examples/HelloVideo.java= 347 =./src/com/aurellem/capture/examples/HelloVideoRecording.java=
353 #+include ../../src/com/aurellem/capture/examples/HelloVideo.java src java 348 #+include: ../../jmeCapture/src/com/aurellem/capture/examples/HelloVideoRecording.java src java
354 349
355 The videos are created in the =hello-video= directory 350 The videos are created in the =hello-video= directory
356 351
357 #+begin_src sh :results verbatim :exports both 352 #+begin_src sh :results verbatim :exports both
358 du -h hello-video/* 353 du -h hello-video/*
364 359
365 And can be immediately uploaded to YouTube 360 And can be immediately uploaded to YouTube
366 361
367 - [[http://www.youtube.com/watch?v=C8gxVAySaPg][hello-video-moving.flv]] 362 - [[http://www.youtube.com/watch?v=C8gxVAySaPg][hello-video-moving.flv]]
368 #+BEGIN_HTML 363 #+BEGIN_HTML
369 <iframe width="425" height="349" 364 <iframe width="1062" height="872"
370 src="http://www.youtube.com/embed/C8gxVAySaPg" 365 src="http://www.youtube.com/embed/C8gxVAySaPg"
371 frameborder="0" allowfullscreen> 366 frameborder="0" allowfullscreen>
372 </iframe> 367 </iframe>
373 #+END_HTML 368 #+END_HTML
374 - [[http://www.youtube.com/watch?v=pHcFOtIS07Q][hello-video-static.flv]] 369 - [[http://www.youtube.com/watch?v=pHcFOtIS07Q][hello-video-static.flv]]
375 #+BEGIN_HTML 370 #+BEGIN_HTML
376 <iframe width="425" height="349" 371 <iframe width="1062" height="872"
377 src="http://www.youtube.com/embed/pHcFOtIS07Q" 372 src="http://www.youtube.com/embed/pHcFOtIS07Q"
378 frameborder="0" allowfullscreen> 373 frameborder="0" allowfullscreen>
379 </iframe> 374 </iframe>
380
381 #+END_HTML 375 #+END_HTML
382 376
383 377
384 * COMMENT More Examples 378 * COMMENT More Examples
385 ** COMMENT Hello Physics 379 ** COMMENT Hello Physics
389 383
390 This example is a modified version of =HelloPhysics= that creates four 384 This example is a modified version of =HelloPhysics= that creates four
391 simultaneous views of the same scene of cannonballs careening into a 385 simultaneous views of the same scene of cannonballs careening into a
392 brick wall. 386 brick wall.
393 387
394 =./jme3/src/test/jme3test/helloworld/HelloPhysicsWithVideo.java= 388 # =./jme3/src/test/jme3test/helloworld/HelloPhysicsWithVideo.java=
395 #+include ./jme3/src/test/jme3test/helloworld/HelloPhysicsWithVideo.java src java 389 # #+include: ./jme3/src/test/jme3test/helloworld/HelloPhysicsWithVideo.java src java
396 390
397 Running the program outputs four videos into the =./physics-videos= 391 Running the program outputs four videos into the =./physics-videos=
398 directory. 392 directory.
399 393
400 #+begin_src sh :exports both :results verbatim 394 #+begin_src sh :exports both :results verbatim
588 582
589 ** HelloTerrain 583 ** HelloTerrain
590 [[http://youtu.be/5_4wyDFwrVQ][HelloTerrain.avi]] 584 [[http://youtu.be/5_4wyDFwrVQ][HelloTerrain.avi]]
591 585
592 #+begin_html 586 #+begin_html
593 <iframe width="425" height="349" 587 <iframe width="1062" height="872"
594 src="http://www.youtube.com/embed/5_4wyDFwrVQ" 588 src="http://www.youtube.com/embed/5_4wyDFwrVQ"
595 frameborder="0" allowfullscreen> 589 frameborder="0" allowfullscreen>
596 </iframe> 590 </iframe>
597 #+end_html 591 #+end_html
598 592
599 ** HelloAssets 593 ** HelloAssets
600 [[http://www.youtube.com/watch?v=oGg-Q6k1BM4][HelloAssets.avi]] 594 [[http://www.youtube.com/watch?v=oGg-Q6k1BM4][HelloAssets.avi]]
601 595
602 #+begin_html 596 #+begin_html
603 <iframe width="425" height="349" 597 <iframe width="1062" height="872"
604 src="http://www.youtube.com/embed/oGg-Q6k1BM4?hl=en&fs=1" 598 src="http://www.youtube.com/embed/oGg-Q6k1BM4?hl=en&fs=1"
605 frameborder="0" allowfullscreen> 599 frameborder="0" allowfullscreen>
606 </iframe> 600 </iframe>
607 #+end_html 601 #+end_html
608 602
609 ** HelloEffects 603 ** HelloEffects
610 [[http://www.youtube.com/watch?v=TuxlLMe53hA][HelloEffects]] 604 [[http://www.youtube.com/watch?v=TuxlLMe53hA][HelloEffects]]
611 605
612 #+begin_html 606 #+begin_html
613 <iframe width="425" height="349" 607 <iframe width="1062" height="872"
614 src="http://www.youtube.com/embed/TuxlLMe53hA?hl=en&fs=1" 608 src="http://www.youtube.com/embed/TuxlLMe53hA?hl=en&fs=1"
615 frameborder="0" allowfullscreen> 609 frameborder="0" allowfullscreen>
616 </iframe> 610 </iframe>
617 #+end_html 611 #+end_html
618 612
619 ** HelloCollision 613 ** HelloCollision
620 [[http://www.youtube.com/watch?v=GPlvJkiZfFw][HelloCollision.avi]] 614 [[http://www.youtube.com/watch?v=GPlvJkiZfFw][HelloCollision.avi]]
621 615
622 #+begin_html 616 #+begin_html
623 <iframe width="425" height="349" 617 <iframe width="1062" height="872"
624 src="http://www.youtube.com/embed/GPlvJkiZfFw?hl=en&fs=1" 618 src="http://www.youtube.com/embed/GPlvJkiZfFw?hl=en&fs=1"
625 frameborder="0" allowfullscreen> 619 frameborder="0" allowfullscreen>
626 </iframe> 620 </iframe>
627 #+end_html 621 #+end_html
628 622
629 ** HelloAnimation 623 ** HelloAnimation
630 [[http://www.youtube.com/watch?v=SDCfOSPYUkg][HelloAnimation.avi]] 624 [[http://www.youtube.com/watch?v=SDCfOSPYUkg][HelloAnimation.avi]]
631 625
632 #+begin_html 626 #+begin_html
633 <iframe width="425" height="349" 627 <iframe width="1062" height="872"
634 src="http://www.youtube.com/embed/SDCfOSPYUkg?hl=en&fs=1" 628 src="http://www.youtube.com/embed/SDCfOSPYUkg?hl=en&fs=1"
635 frameborder="0" allowfullscreen>
636 </iframe>
637 #+end_html
638
639 ** HelloNode
640 [[http://www.youtube.com/watch?v=pL-0fR0-ilQ][HelloNode.avi]]
641
642 #+begin_html
643 <iframe width="425" height="349"
644 src="http://www.youtube.com/embed/pL-0fR0-ilQ?hl=en&fs=1"
645 frameborder="0" allowfullscreen> 629 frameborder="0" allowfullscreen>
646 </iframe> 630 </iframe>
647 #+end_html 631 #+end_html
648 632
649 ** HelloLoop 633 ** HelloLoop
650 [[http://www.youtube.com/watch?v=mosZzzcdE5w][HelloLoop.avi]] 634 [[http://www.youtube.com/watch?v=mosZzzcdE5w][HelloLoop.avi]]
651 635
652 #+begin_html 636 #+begin_html
653 <iframe width="425" height="349" 637 <iframe width="1062" height="872"
654 src="http://www.youtube.com/embed/mosZzzcdE5w?hl=en&fs=1" 638 src="http://www.youtube.com/embed/mosZzzcdE5w?hl=en&fs=1"
655 frameborder="0" allowfullscreen> 639 frameborder="0" allowfullscreen>
656 </iframe> 640 </iframe>
657 #+end_html 641 #+end_html
658 642