comparison org/capture-video.org @ 306:7e7f8d6d9ec5

massive spellchecking
author Robert McIntyre <rlm@mit.edu>
date Sat, 18 Feb 2012 10:59:41 -0700
parents 7351c9c0c471
children ebdedb039cbb
comparison
equal deleted inserted replaced
305:19c43ec6958d 306:7e7f8d6d9ec5
1 #+title: Capture Live Video Feeds from JMonkeyEngine 1 #+title: Capture Live Video Feeds from JMonkeyEngine
2 #+author: Robert McIntyre 2 #+author: Robert McIntyre
3 #+email: rlm@mit.edu 3 #+email: rlm@mit.edu
4 #+description: Capture video from a JMonkeyEngine3 Application with Xuggle, and use gstreamer to compress the video to upload to YouTube. 4 #+description: Capture video from a JMonkeyEngine3 Application with Xuggle, and use gstreamer to compress the video to upload to YouTube.
5 #+keywords: JME3, video, Xuggle, JMonkeyEngine, youtube, capture video, Java 5 #+keywords: JME3, video, Xuggle, JMonkeyEngine, YouTube, capture video, Java
6 #+SETUPFILE: ../../aurellem/org/setup.org 6 #+SETUPFILE: ../../aurellem/org/setup.org
7 #+INCLUDE: ../../aurellem/org/level-0.org 7 #+INCLUDE: ../../aurellem/org/level-0.org
8 8
9 9
10 * The Problem 10 * The Problem
68 # your wall, then the ball should have traveled exactly one 68 # your wall, then the ball should have traveled exactly one
69 # game-mile. In order to keep sync with the real world, the game 69 # game-mile. In order to keep sync with the real world, the game
70 # throttles its physics engine and graphics display. If the 70 # throttles its physics engine and graphics display. If the
71 # computations involved in running the game are too intense, then the 71 # computations involved in running the game are too intense, then the
72 # game will first skip frames, then sacrifice physics accuracy. If 72 # game will first skip frames, then sacrifice physics accuracy. If
73 # there are particuraly demanding computations, then you may only get 73 # there are particularly demanding computations, then you may only get
74 # 1 fps, and the ball may tunnel through the floor or obstacles due to 74 # 1 fps, and the ball may tunnel through the floor or obstacles due to
75 # inaccurate physics simulation, but after the end of one user-hour, 75 # inaccurate physics simulation, but after the end of one user-hour,
76 # that ball will have traveled one game-mile. 76 # that ball will have traveled one game-mile.
77 77
78 # When we're recording video, we don't care if the game-time syncs 78 # When we're recording video, we don't care if the game-time syncs
132 $\frac{1}{60}$ of a user-second to render to screen, then JME3 has 132 $\frac{1}{60}$ of a user-second to render to screen, then JME3 has
133 it's work cut out for it. In order to render to the screen, it will 133 it's work cut out for it. In order to render to the screen, it will
134 first step the game forward by up to four physics ticks before 134 first step the game forward by up to four physics ticks before
135 rendering to the screen. If it still isn't fast enough then it will 135 rendering to the screen. If it still isn't fast enough then it will
136 decrease the accuracy of the physics engine until game-time and user 136 decrease the accuracy of the physics engine until game-time and user
137 time are synched or a certain threshold is reached, at which point the 137 time are synced or a certain threshold is reached, at which point the
138 game visibly slows down. In this case, JME3 continuously repeat a 138 game visibly slows down. In this case, JME3 continuously repeat a
139 cycle of two physics ticks, and one screen render. For every 139 cycle of two physics ticks, and one screen render. For every
140 user-second that passes, one game-second will pass, but the game will 140 user-second that passes, one game-second will pass, but the game will
141 run at 30 fps instead of 60 fps like before. 141 run at 30 fps instead of 60 fps like before.
142 142
196 The basic functions that a =VideoRecorder= should support are 196 The basic functions that a =VideoRecorder= should support are
197 recording, starting, stopping, and possibly a cleanup step 197 recording, starting, stopping, and possibly a cleanup step
198 where it finalizes the recording (e.g. by writing headers for a video 198 where it finalizes the recording (e.g. by writing headers for a video
199 file). 199 file).
200 200
201 An appropiate interface describing this behaviour 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 206
212 However, it is also important to properly close the video stream and 212 However, it is also important to properly close the video stream and
213 write headers and such, and even though =SceneProcessor= has a 213 write headers and such, and even though =SceneProcessor= has a
214 =.cleanup()= method, it is only called when the =SceneProcessor= is 214 =.cleanup()= method, it is only called when the =SceneProcessor= is
215 removed from the =RenderManager=, not when the game is shutting down 215 removed from the =RenderManager=, not when the game is shutting down
216 when the user pressed ESC, for example. To obtain reliable shutdown 216 when the user pressed ESC, for example. To obtain reliable shutdown
217 behaviour, we also have to implement =AppState=, which provides a 217 behavior, we also have to implement =AppState=, which provides a
218 =.cleanup()= method that /is/ called on shutdown. 218 =.cleanup()= method that /is/ called on shutdown.
219 219
220 Here is an AbstractVideoRecorder class that takes care of the details 220 Here is an AbstractVideoRecorder class that takes care of the details
221 of setup and teardown. 221 of setup and teardown.
222 222
309 309
310 Now that you have a =captureVideo= method, you use it like this: 310 Now that you have a =captureVideo= method, you use it like this:
311 311
312 - Establish an =Isotimer= and set its framerate :: For example, if 312 - Establish an =Isotimer= and set its framerate :: For example, if
313 you want to record video with a framerate of 30 fps, include 313 you want to record video with a framerate of 30 fps, include
314 the following line of code somewhere in the initializtion of 314 the following line of code somewhere in the initialization of
315 your application: 315 your application:
316 #+begin_src java :exports code 316 #+begin_src java :exports code
317 this.setTimer(new IsoTimer(30)); 317 this.setTimer(new IsoTimer(30));
318 #+end_src 318 #+end_src
319 319
360 360
361 #+results: 361 #+results:
362 : 932K hello-video/hello-video-moving.flv 362 : 932K hello-video/hello-video-moving.flv
363 : 640K hello-video/hello-video-static.flv 363 : 640K hello-video/hello-video-static.flv
364 364
365 And can be immediately uploaded to youtube 365 And can be immediately uploaded to YouTube
366 366
367 - [[http://www.youtube.com/watch?v=C8gxVAySaPg][hello-video-moving.flv]] 367 - [[http://www.youtube.com/watch?v=C8gxVAySaPg][hello-video-moving.flv]]
368 #+BEGIN_HTML 368 #+BEGIN_HTML
369 <iframe width="425" height="349" 369 <iframe width="425" height="349"
370 src="http://www.youtube.com/embed/C8gxVAySaPg" 370 src="http://www.youtube.com/embed/C8gxVAySaPg"
469 469
470 #+results: 470 #+results:
471 : 180M physics-videos/helloPhysics.flv 471 : 180M physics-videos/helloPhysics.flv
472 472
473 473
474 Thats a terribly large size! 474 That's a terribly large size!
475 Let's compress it: 475 Let's compress it:
476 476
477 ** COMMENT Compressing the HelloPhysics Video 477 ** COMMENT Compressing the HelloPhysics Video
478 First, we'll scale the video, then, we'll decrease it's bitrate. The 478 First, we'll scale the video, then, we'll decrease it's bit-rate. The
479 end result will be perfect for upload to YouTube. 479 end result will be perfect for upload to YouTube.
480 480
481 #+begin_src sh :results silent 481 #+begin_src sh :results silent
482 cd youtube 482 cd youtube
483 483