Mercurial > jmeCapture
comparison README @ 61:76581e11fb72
readme is UP
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Dec 2011 23:49:14 -0600 |
parents | 42bbb176b90f |
children |
comparison
equal
deleted
inserted
replaced
60:42bbb176b90f | 61:76581e11fb72 |
---|---|
1 ======Capture Audio/Video to a File====== | 1 ======Capture Audio/Video to a File====== |
2 | |
3 <note>A/V recording is still in development. It works for all of jMonkeyEngine's test cases. If you experience any problems or | |
4 of something isn't clear, please let me know. -- bortreb</note> | |
2 | 5 |
3 So you've made your cool new JMonkeyEngine3 game and you want to | 6 So you've made your cool new JMonkeyEngine3 game and you want to |
4 create a demo video to show off your hard work. Or maybe you want to | 7 create a demo video to show off your hard work. Or maybe you want to |
5 make a cutscene for your game using the physics and characters in the | 8 make a cutscene for your game using the physics and characters in the |
6 game itself. Screen capturing is the most straightforward way to do | 9 game itself. Screen capturing is the most straightforward way to do |
7 this, but it can slow down your game and produce low-quality video and | 10 this, but it can slow down your game and produce low-quality video and |
8 audio as a result. A better way is to record video and audio directly | 11 audio as a result. A better way is to record video and audio directly |
9 from the game while it is running. | 12 from the game while it is running. |
10 | 13 |
14 <note tip>Combine this method with jMonkeyEngine's [[:jme3:advanced:Cinematics]] feature to record high-quality game trailers!</note> | |
11 | 15 |
12 ===== Simple Way ===== | 16 ===== Simple Way ===== |
13 | 17 |
14 If all you just want to record video at 30fps with no sound, then look | 18 First off, if all you just want to record video at 30fps with no sound, then look |
15 no further then jMonkeyEngine3's build in ''VideoRecorderAppState'' | 19 no further then jMonkeyEngine3's build in ''VideoRecorderAppState'' |
16 class. | 20 class. |
17 | 21 |
18 Add the following code to your simpleInitApp() method. | 22 Add the following code to your ''simpleInitApp()'' method. |
19 | 23 |
20 <code java> | 24 <code java> |
21 stateManager.attach(new VideoRecorderAppState()); //start recording | 25 stateManager.attach(new VideoRecorderAppState()); //start recording |
22 </code> | 26 </code> |
23 | 27 |
34 If you want to record audio as well, record at different framerates, | 38 If you want to record audio as well, record at different framerates, |
35 or record from multiple viewpoints at once, then there's a full | 39 or record from multiple viewpoints at once, then there's a full |
36 solution for doing this already made for you here: | 40 solution for doing this already made for you here: |
37 | 41 |
38 http://www.aurellem.com/releases/jmeCapture-latest.zip | 42 http://www.aurellem.com/releases/jmeCapture-latest.zip |
43 | |
39 http://www.aurellem.com/releases/jmeCapture-latest.tar.bz2 | 44 http://www.aurellem.com/releases/jmeCapture-latest.tar.bz2 |
40 | 45 |
41 Download the archive in your preferred format, extract, | 46 Download the archive in your preferred format, extract, |
42 add the jars to your project, and you are ready to go. | 47 add the jars to your project, and you are ready to go. |
43 | 48 |
44 The javadoc is here: | 49 The javadoc is here: |
45 http://www.aurellem.com/jmeCapture/docs/ | 50 http://www.aurellem.com/jmeCapture/docs/ |
46 | 51 |
47 To capture video and audio you use the | 52 To capture video and audio you use the |
48 ''com.aurellem.capture.Capture'' class, which has two methods, | 53 ''com.aurellem.capture.Capture'' class, which has two methods, |
49 ''captureAudio'' and ''captureVideo'', and the | 54 ''captureAudio()'' and ''captureVideo()'', and the |
50 ''com.aurellem.capture.IsoTimer class'', which sets the audio and | 55 ''com.aurellem.capture.IsoTimer'' class, which sets the audio and |
51 video framerate. | 56 video framerate. |
52 | 57 |
53 The steps are as simple as: | 58 The steps are as simple as: |
54 | 59 |
55 <code java> | 60 <code java> |
71 Audio and video will stop being recorded when the app stops. Your | 76 Audio and video will stop being recorded when the app stops. Your |
72 audio will be recorded as a 44,100 Hz linear PCM wav file, while the | 77 audio will be recorded as a 44,100 Hz linear PCM wav file, while the |
73 video will be recorded according to the following rules: | 78 video will be recorded according to the following rules: |
74 | 79 |
75 1.) (Preferred) If you supply an empty directory as the file, then | 80 1.) (Preferred) If you supply an empty directory as the file, then |
76 the video will be saved as a sequence of .png files, one file per | 81 the video will be saved as a sequence of .png files, one file per |
77 frame. The files start at 0000000.png and increment from there. | 82 frame. The files start at 0000000.png and increment from there. |
78 You can then combine the frames into your preferred | 83 You can then combine the frames into your preferred |
79 container/codec. If the directory is not empty, then writing | 84 container/codec. If the directory is not empty, then writing |
80 video frames to it will fail, and nothing will be written. | 85 video frames to it will fail, and nothing will be written. |
81 | 86 |
82 2.) If the filename ends in ".avi" then the frames will be encoded as | 87 2.) If the filename ends in ".avi" then the frames will be encoded as |
83 a RAW stream inside an AVI 1.0 container. The resulting file | 88 a RAW stream inside an AVI 1.0 container. The resulting file |
84 will be quite large and you will probably want to re-encode it to | 89 will be quite large and you will probably want to re-encode it to |
85 your preferred container/codec format. Be advised that some | 90 your preferred container/codec format. Be advised that some |
86 video payers cannot process AVI with a RAW stream, and that AVI | 91 video payers cannot process AVI with a RAW stream, and that AVI |
87 1.0 files generated by this method that exceed 2.0GB are invalid | 92 1.0 files generated by this method that exceed 2.0GB are invalid |
88 according to the AVI 1.0 spec (but many programs can still deal | 93 according to the AVI 1.0 spec (but many programs can still deal |
89 with them.) Thanks to Werner Randelshofer for his excellent work | 94 with them.) Thanks to Werner Randelshofer for his excellent work |
90 which made the AVI file writer option possible. | 95 which made the AVI file writer option possible. |
91 | 96 |
92 3.) Any non-directory file ending in anything other than ".avi" will | 97 3.) Any non-directory file ending in anything other than ".avi" will |
93 be processed through Xuggle. Xuggle provides the option to use | 98 be processed through Xuggle. Xuggle provides the option to use |
94 many codecs/containers, but you will have to install it on your | 99 many codecs/containers, but you will have to install it on your |
95 system yourself in order to use this option. Please visit | 100 system yourself in order to use this option. Please visit |
96 http://www.xuggle.com/ to learn how to do this. | 101 http://www.xuggle.com/ to learn how to do this. |
97 | 102 |
98 Note that you will not hear any sound if you choose to record sound to | 103 Note that you will not hear any sound if you choose to record sound to |
99 a file. | 104 a file. |
100 | 105 |
101 ==== Basic Example ==== | 106 ==== Basic Example ==== |
143 } | 148 } |
144 </code> | 149 </code> |
145 | 150 |
146 ==== How it works ==== | 151 ==== How it works ==== |
147 | 152 |
148 A standard JME3 application that extends =SimpleApplication= or | 153 A standard JME3 application that extends ''SimpleApplication'' or |
149 =Application= tries as hard as it can to keep in sync with | 154 ''Application'' tries as hard as it can to keep in sync with |
150 /user-time/. If a ball is rolling at 1 game-mile per game-hour in the | 155 //user-time//. If a ball is rolling at 1 game-mile per game-hour in the |
151 game, and you wait for one user-hour as measured by the clock on your | 156 game, and you wait for one user-hour as measured by the clock on your |
152 wall, then the ball should have traveled exactly one game-mile. In | 157 wall, then the ball should have traveled exactly one game-mile. In |
153 order to keep sync with the real world, the game throttles its physics | 158 order to keep sync with the real world, the game throttles its physics |
154 engine and graphics display. If the computations involved in running | 159 engine and graphics display. If the computations involved in running |
155 the game are too intense, then the game will first skip frames, then | 160 the game are too intense, then the game will first skip frames, then |
162 When we're recording video, we don't care if the game-time syncs with | 167 When we're recording video, we don't care if the game-time syncs with |
163 user-time, but instead whether the time in the recorded video | 168 user-time, but instead whether the time in the recorded video |
164 (video-time) syncs with user-time. To continue the analogy, if we | 169 (video-time) syncs with user-time. To continue the analogy, if we |
165 recorded the ball rolling at 1 game-mile per game-hour and watched the | 170 recorded the ball rolling at 1 game-mile per game-hour and watched the |
166 video later, we would want to see 30 fps video of the ball rolling at | 171 video later, we would want to see 30 fps video of the ball rolling at |
167 1 video-mile per /user-hour/. It doesn't matter how much user-time it | 172 1 video-mile per //user-hour//. It doesn't matter how much user-time it |
168 took to simulate that hour of game-time to make the high-quality | 173 took to simulate that hour of game-time to make the high-quality |
169 recording. | 174 recording. |
170 | 175 |
171 The IsoTimer ignores real-time and always reports that the same amount | 176 The IsoTimer ignores real-time and always reports that the same amount |
172 of time has passed every time it is called. That way, one can put code | 177 of time has passed every time it is called. That way, one can put code |
495 } | 500 } |
496 | 501 |
497 } | 502 } |
498 </code> | 503 </code> |
499 | 504 |
500 <iframe width="420" height="315" | 505 {{http://www.youtube.com/v/oCEfK0yhDrY?.swf?400×333}} |
501 src="http://www.youtube.com/embed/oCEfK0yhDrY" | |
502 frameborder="0" allowfullscreen> | |
503 </iframe> | |
504 | 506 |
505 ===== More Information ===== | 507 ===== More Information ===== |
506 | 508 |
507 This is the old page showing the first version of this idea | 509 This is the old page showing the first version of this idea |
508 http://aurellem.org/cortex/html/capture-video.html | 510 http://aurellem.org/cortex/html/capture-video.html |
509 | 511 |
510 All source code can be found here: | 512 All source code can be found here: |
511 | 513 |
512 http://hg.bortreb.com/audio-send | 514 http://hg.bortreb.com/audio-send |
515 | |
513 http://hg.bortreb.com/jmeCapture | 516 http://hg.bortreb.com/jmeCapture |
514 | 517 |
515 More information on the modifications to OpenAL to support multiple | 518 More information on the modifications to OpenAL to support multiple |
516 listeners can be found here. | 519 listeners can be found here. |
517 | 520 |