Mercurial > jmeCapture
comparison src/com/aurellem/capture/Capture.java @ 54:6484a820e27d
wrote main documentation.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Dec 2011 19:15:43 -0600 |
parents | 3dc1f15e1e13 |
children | b05f629fc296 |
comparison
equal
deleted
inserted
replaced
53:3dc1f15e1e13 | 54:6484a820e27d |
---|---|
16 import com.jme3.scene.Spatial; | 16 import com.jme3.scene.Spatial; |
17 import com.jme3.system.AppSettings; | 17 import com.jme3.system.AppSettings; |
18 import com.jme3.system.JmeSystem; | 18 import com.jme3.system.JmeSystem; |
19 | 19 |
20 /** | 20 /** |
21 * Use the methods in this class for capturing consistent, high quality video and audio from a | |
22 * jMonkeyEngine3 application. To capture audio or video do the following: | |
21 * | 23 * |
24 * 1.) Set your application's timer to an IsoTimer. Create the IsoTimer with the desired video | |
25 * frames-per-second. | |
26 * 2.) Call captureAudio and/or captureVideo on the Application as desired. | |
27 * | |
22 * @author Robert McIntyre | 28 * @author Robert McIntyre |
23 * | |
24 */ | 29 */ |
25 | 30 |
26 public class Capture { | 31 public class Capture { |
27 | 32 |
33 /** | |
34 * Use this function to capture video from your application. You specify the framerate at which | |
35 * the video will be recording by setting the Application's timer to an IsoTimer created with the | |
36 * desired frames-per-second. | |
37 * | |
38 * There are three ways to record and they are selected by the properties of the file that you | |
39 * specify. | |
40 * | |
41 * 1.) (Preferred) | |
42 * If you supply an empty directory as the file, then the video will | |
43 * be saved as a sequence of .png files, one file per frame. The files start at | |
44 * 0000000.png and increment from there. You can then combine the frames into your | |
45 * preferred container/codec. If the directory is not empty, then writing video frames | |
46 * to it will fail, and nothing will be written. | |
47 * | |
48 * 2.) If the filename ends in ".avi" then the frames will be encoded as a RAW stream | |
49 * inside an AVI 1.0 container. The resulting file will be quite large and you will | |
50 * probably want to re-encode it to your preferred container/codec format. Be advised | |
51 * that some video payers cannot process AVI with a RAW stream, and that AVI 1.0 files | |
52 * generated by this method that exceed 2.0GB are invalid according to the AVI 1.0 spec | |
53 * (but many programs can still deal with them.) Thanks to Werner Randelshofer for his | |
54 * excellent work which made AVI file writer option possible. | |
55 * | |
56 * 3.) Any non-directory file ending in anything other than ".avi" will be processed through | |
57 * Xuggle. Xuggle provides the option to use many codecs/containers, but you will have to | |
58 * install it on your system yourself in order to use this option. Please visit | |
59 * http://www.xuggle.com/ to learn how to do this. | |
60 * | |
61 * @param app The Application from which you wish to record Video. | |
62 * @param file The file to which the video will be captured. | |
63 * @throws IOException | |
64 */ | |
65 | |
28 public static void captureVideo(final Application app, final File file) throws IOException{ | 66 public static void captureVideo(final Application app, final File file) throws IOException{ |
29 | |
30 final AbstractVideoRecorder videoRecorder; | 67 final AbstractVideoRecorder videoRecorder; |
31 // The XuggleVideoRecorder is better than the AVIVideoRecorder in every way | |
32 // except for ease of installation. The excellent work by Werner Randelshofer | |
33 // is used as a fallback option. Please visit http://www.xuggle.com/ to learn | |
34 // how to set up the XuggleVideoRecorder. | |
35 | 68 |
36 if (file.getCanonicalPath().endsWith(".avi")){ | 69 if (file.getCanonicalPath().endsWith(".avi")){ |
37 videoRecorder = new AVIVideoRecorder(file);} | 70 videoRecorder = new AVIVideoRecorder(file);} |
38 else if (file.isDirectory()){ | 71 else if (file.isDirectory()){ |
39 videoRecorder = new FileVideoRecorder(file);} | 72 videoRecorder = new FileVideoRecorder(file);} |
59 } | 92 } |
60 }; | 93 }; |
61 app.enqueue(thunk); | 94 app.enqueue(thunk); |
62 } | 95 } |
63 | 96 |
97 | |
98 /** | |
99 * Use this function to capture audio from your application. Audio data will be saved in linear | |
100 * PCM format at 44,100 hertz in the wav container format to the file that you specify. | |
101 * | |
102 * Note that you *have* to use an IsoTimer for your Application's timer while recording audio or | |
103 * the recording will fail. Also ensure that your IsoTimer obeys the following constraints: | |
104 * | |
105 * - The frames-per-second value of the IsoTimer cannot be lower than 10 frames-per-second. | |
106 * - The frames-per-second value of the IsoTimer must evenly divide 44,100. | |
107 * | |
108 * @param app The Application from which you wish to record Audio. | |
109 * @param file the target file to which you want to record audio data. | |
110 * @throws IOException | |
111 */ | |
64 | 112 |
65 public static void captureAudio(final Application app, final File file) throws IOException{ | 113 public static void captureAudio(final Application app, final File file) throws IOException{ |
66 AppSettings settings = null; | 114 AppSettings settings = null; |
67 if (app.getContext() != null){settings = app.getContext().getSettings();} | 115 if (app.getContext() != null){settings = app.getContext().getSettings();} |
68 if (settings == null){settings = new AppSettings(true);} | 116 if (settings == null){settings = new AppSettings(true);} |
69 settings.setAudioRenderer("Send"); | 117 settings.setAudioRenderer("Send"); |
70 app.setSettings(settings); | 118 app.setSettings(settings); |
71 | 119 |
72 JmeSystem.setSystemDelegate(new AurellemSystemDelegate()); | 120 JmeSystem.setSystemDelegate(new AurellemSystemDelegate()); |
73 | |
74 | 121 |
75 final WaveFileWriter writer = new WaveFileWriter(file); | 122 final WaveFileWriter writer = new WaveFileWriter(file); |
76 | 123 |
77 Callable<Object> thunk = new Callable<Object>(){ | 124 Callable<Object> thunk = new Callable<Object>(){ |
78 public Object call(){ | 125 public Object call(){ |
82 ml.registerSoundProcessor(writer); | 129 ml.registerSoundProcessor(writer); |
83 } | 130 } |
84 return null; | 131 return null; |
85 } | 132 } |
86 }; | 133 }; |
87 | |
88 app.enqueue(thunk); | 134 app.enqueue(thunk); |
89 } | 135 } |
90 } | 136 } |