rlm@59
|
1 ======Capture Audio/Video to a File======
|
rlm@59
|
2
|
rlm@59
|
3 So you've made your cool new JMonkeyEngine3 game and you want to
|
rlm@59
|
4 create a demo video to show off your hard work. Or maybe you want to
|
rlm@59
|
5 make a cutscene for your game using the physics and characters in the
|
rlm@59
|
6 game itself. Screen capturing is the most straightforward way to do
|
rlm@59
|
7 this, but it can slow down your game and produce low-quality video and
|
rlm@59
|
8 audio as a result. A better way is to record video and audio directly
|
rlm@59
|
9 from the game while it is running.
|
rlm@59
|
10
|
rlm@59
|
11 There's a full solution for doing this already made for you here:
|
rlm@59
|
12
|
rlm@59
|
13 http://www.aurellem.com/releases/jmeCapture-latest.zip
|
rlm@59
|
14 http://www.aurellem.com/releases/jmeCapture-latest.tar.bz2
|
rlm@59
|
15
|
rlm@59
|
16 Download the archive in your preferred format, extract,
|
rlm@59
|
17 add the jars to your project, and you are ready to go.
|
rlm@59
|
18
|
rlm@59
|
19 The javadoc is here:
|
rlm@59
|
20 http://www.aurellem.com/jmeCapture/docs/
|
rlm@59
|
21
|
rlm@59
|
22 Here is a complete example showing how to capture both audio and video
|
rlm@59
|
23 from one of jMonkeyEngine3's advenced demo applications.
|
rlm@59
|
24
|
rlm@59
|
25 <code java>
|
rlm@59
|
26 import java.io.File;
|
rlm@59
|
27 import java.io.IOException;
|
rlm@59
|
28
|
rlm@59
|
29 import jme3test.water.TestPostWater;
|
rlm@59
|
30
|
rlm@59
|
31 import com.aurellem.capture.Capture;
|
rlm@59
|
32 import com.aurellem.capture.IsoTimer;
|
rlm@59
|
33 import com.jme3.app.SimpleApplication;
|
rlm@59
|
34
|
rlm@59
|
35
|
rlm@59
|
36 /**
|
rlm@59
|
37 * Demonstrates how to use basic Audio/Video capture with a
|
rlm@59
|
38 * jMonkeyEngine application. You can use these techniques to make
|
rlm@59
|
39 * high quality cutscenes or demo videos, even on very slow laptops.
|
rlm@59
|
40 *
|
rlm@59
|
41 * @author Robert McIntyre
|
rlm@59
|
42 */
|
rlm@59
|
43
|
rlm@59
|
44 public class Basic {
|
rlm@59
|
45
|
rlm@59
|
46 public static void main(String[] ignore) throws IOException{
|
rlm@59
|
47 File video = File.createTempFile("JME-water-video", ".avi");
|
rlm@59
|
48 File audio = File.createTempFile("JME-water-audio", ".wav");
|
rlm@59
|
49
|
rlm@59
|
50 SimpleApplication app = new TestPostWater();
|
rlm@59
|
51 app.setTimer(new IsoTimer(60));
|
rlm@59
|
52 app.setShowSettings(false);
|
rlm@59
|
53
|
rlm@59
|
54 Capture.captureVideo(app, video);
|
rlm@59
|
55 Capture.captureAudio(app, audio);
|
rlm@59
|
56
|
rlm@59
|
57 app.start();
|
rlm@59
|
58
|
rlm@59
|
59 System.out.println(video.getCanonicalPath());
|
rlm@59
|
60 System.out.println(audio.getCanonicalPath());
|
rlm@59
|
61 }
|
rlm@59
|
62 }
|
rlm@59
|
63 </java>
|
rlm@59
|
64
|
rlm@59
|
65
|
rlm@59
|
66 As you can see, to capture video and audio you use the
|
rlm@59
|
67 ''com.aurellem.capture.Capture'' class, which has two methods,
|
rlm@59
|
68 ''captureAudio'' and ''captureVideo'', and the
|
rlm@59
|
69 ''com.aurellem.capture.IsoTimer class'', which sets the audio and
|
rlm@59
|
70 video framerate.
|
rlm@59
|
71
|
rlm@59
|
72 The steps are as simple as:
|
rlm@59
|
73
|
rlm@59
|
74 <code java>
|
rlm@59
|
75 yourApp.setTimer(new IsoTimer(desiredFramesPerSecond));
|
rlm@59
|
76 </code>
|
rlm@59
|
77
|
rlm@59
|
78 This causes jMonkeyEngine to take as much time as it needs to fully
|
rlm@59
|
79 calculate every frame of the video and audio. You will see your game
|
rlm@59
|
80 speed up and slow down depending on how computationally demanding your
|
rlm@59
|
81 game is, but the final recorded audio and video will be perfectly
|
rlm@59
|
82 sychronized and will run at exactly the fps which you specified.
|
rlm@59
|
83
|
rlm@59
|
84 <code java>
|
rlm@59
|
85 captureVideo(yourApp, targetVideoFile);
|
rlm@59
|
86 captureAudio(yourApp, targetAudioFile);
|
rlm@59
|
87 </code>
|
rlm@59
|
88
|
rlm@59
|
89 These will cause the app to record audio and video when it is run.
|
rlm@59
|
90 Audio and video will stop being recorded when the app stops. Your
|
rlm@59
|
91 audio will be recorded as a 44,100 Hz linear PCM wav file, while the
|
rlm@59
|
92 video will be recorded according to the following rules:
|
rlm@59
|
93
|
rlm@59
|
94 1.) (Preferred) If you supply an empty directory as the file, then
|
rlm@59
|
95 the video will be saved as a sequence of .png files, one file per
|
rlm@59
|
96 frame. The files start at 0000000.png and increment from there.
|
rlm@59
|
97 You can then combine the frames into your preferred
|
rlm@59
|
98 container/codec. If the directory is not empty, then writing
|
rlm@59
|
99 video frames to it will fail, and nothing will be written.
|
rlm@59
|
100
|
rlm@59
|
101 2.) If the filename ends in ".avi" then the frames will be encoded as
|
rlm@59
|
102 a RAW stream inside an AVI 1.0 container. The resulting file
|
rlm@59
|
103 will be quite large and you will probably want to re-encode it to
|
rlm@59
|
104 your preferred container/codec format. Be advised that some
|
rlm@59
|
105 video payers cannot process AVI with a RAW stream, and that AVI
|
rlm@59
|
106 1.0 files generated by this method that exceed 2.0GB are invalid
|
rlm@59
|
107 according to the AVI 1.0 spec (but many programs can still deal
|
rlm@59
|
108 with them.) Thanks to Werner Randelshofer for his excellent work
|
rlm@59
|
109 which made AVI file writer option possible.
|
rlm@59
|
110
|
rlm@59
|
111 3.) Any non-directory file ending in anything other than ".avi" will
|
rlm@59
|
112 be processed through Xuggle. Xuggle provides the option to use
|
rlm@59
|
113 many codecs/containers, but you will have to install it on your
|
rlm@59
|
114 system yourself in order to use this option. Please visit
|
rlm@59
|
115 http://www.xuggle.com/ to learn how to do this.
|
rlm@59
|
116
|