comparison src/com/aurellem/capture/Capture.java @ 68:302d5e9ad120

adjust format
author Robert McIntyre <rlm@mit.edu>
date Thu, 19 Jul 2012 12:28:55 -0500
parents afc437f637bd
children 2c50a0c99715
comparison
equal deleted inserted replaced
67:30cea3f0f30a 68:302d5e9ad120
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 21 * Use the methods in this class for capturing consistent,
22 * and audio from a jMonkeyEngine3 application. To capture audio or video do 22 * high quality video and audio from a jMonkeyEngine3
23 * the following: 23 * application. To capture audio or video do the following:
24 * 24 *
25 * 1.) Set your application's timer to an IsoTimer. Create the IsoTimer with the 25 * 1.) Set your application's timer to an IsoTimer. Create
26 * desired video frames-per-second. 26 * the IsoTimer with the desired video
27 * frames-per-second.
27 * 28 *
28 * 2.) Call captureAudio and/or captureVideo on the Application as desired 29 * 2.) Call captureAudio and/or captureVideo on the
29 * before starting the Application. 30 * Application as desired before starting the
31 * Application.
30 * 32 *
31 * See the Basic and Advanced demos in the examples section for more 33 * See the Basic and Advanced demos in the examples section
32 * information. If you have any trouble, please PM me on the jMonkeyEngine 34 * for more information. If you have any trouble, please PM
33 * forums. My username is bortreb. 35 * me on the jMonkeyEngine forums. My username is bortreb.
34 * 36 *
35 * @author Robert McIntyre 37 * @author Robert McIntyre
36 */ 38 */
37 39
38 public class Capture { 40 public class Capture {
39 41
40 /** 42 /**
41 * Use this function to capture video from your application. You 43 * Use this function to capture video from your
42 * specify the framerate at which the video will be recording by setting 44 * application. You specify the framerate at which the
43 * the Application's timer to an IsoTimer created with the desired 45 * video will be recording by setting the Application's
46 * timer to an IsoTimer created with the desired
44 * frames-per-second. 47 * frames-per-second.
45 * 48 *
46 * There are three ways to record and they are selected by the 49 * There are three ways to record and they are selected
47 * properties of the file that you specify. 50 * by the properties of the file that you specify.
48 * 51 *
49 * 1.) (Preferred) If you supply an empty directory as the file, then 52 * 1.) (Preferred) If you supply an empty directory as
50 * the video will be saved as a sequence of .png files, one file per 53 * the file, then the video will be saved as a
51 * frame. The files start at 0000000.png and increment from there. 54 * sequence of .png files, one file per frame. The
52 * You can then combine the frames into your preferred 55 * files start at 0000000.png and increment from
53 * container/codec. If the directory is not empty, then writing 56 * there. You can then combine the frames into your
54 * video frames to it will fail, and nothing will be written. 57 * preferred container/codec. If the directory is
58 * not empty, then writing video frames to it will
59 * fail, and nothing will be written.
55 * 60 *
56 * 2.) If the filename ends in ".avi" then the frames will be encoded as 61 * 2.) If the filename ends in ".avi" then the frames
57 * a RAW stream inside an AVI 1.0 container. The resulting file 62 * will be encoded as a RAW stream inside an AVI 1.0
58 * will be quite large and you will probably want to re-encode it to 63 * container. The resulting file will be quite
59 * your preferred container/codec format. Be advised that some 64 * large and you will probably want to re-encode it
60 * video payers cannot process AVI with a RAW stream, and that AVI 65 * to your preferred container/codec format. Be
61 * 1.0 files generated by this method that exceed 2.0GB are invalid 66 * advised that some video payers cannot process AVI
62 * according to the AVI 1.0 spec (but many programs can still deal 67 * with a RAW stream, and that AVI 1.0 files
63 * with them.) Thanks to Werner Randelshofer for his excellent work 68 * generated by this method that exceed 2.0GB are
64 * which made AVI file writer option possible. 69 * invalid according to the AVI 1.0 spec (but many
70 * programs can still deal with them.) Thanks to
71 * Werner Randelshofer for his excellent work which
72 * made AVI file writer option possible.
65 * 73 *
66 * 3.) Any non-directory file ending in anything other than ".avi" will 74 * 3.) Any non-directory file ending in anything other
67 * be processed through Xuggle. Xuggle provides the option to use 75 * than ".avi" will be processed through Xuggle.
68 * many codecs/containers, but you will have to install it on your 76 * Xuggle provides the option to use many
69 * system yourself in order to use this option. Please visit 77 * codecs/containers, but you will have to install
70 * http://www.xuggle.com/ to learn how to do this. 78 * it on your system yourself in order to use this
79 * option. Please visit http://www.xuggle.com/ to
80 * learn how to do this.
71 * 81 *
72 * @param app The Application from which you wish to record Video. 82 * @param app The Application from which you wish to record Video.
73 * @param file The file to which the video will be captured. 83 * @param file The file to which the video will be captured.
74 * @throws IOException 84 * @throws IOException
75 */ 85 */
76 86
77 public static void captureVideo(final Application app, final File file) throws IOException{ 87 public static void captureVideo
88 (final Application app, final File file) throws IOException{
78 final AbstractVideoRecorder videoRecorder; 89 final AbstractVideoRecorder videoRecorder;
79 90
80 if (file.getCanonicalPath().endsWith(".avi")){ 91 if (file.getCanonicalPath().endsWith(".avi")){
81 videoRecorder = new AVIVideoRecorder(file);} 92 videoRecorder = new AVIVideoRecorder(file);}
82 else if (file.isDirectory()){ 93 else if (file.isDirectory()){
83 videoRecorder = new FileVideoRecorder(file);} 94 videoRecorder = new FileVideoRecorder(file);}
84 else { videoRecorder = new XuggleVideoRecorder(file);} 95 else {
96 videoRecorder = new XuggleVideoRecorder(file);
97 }
85 98
86 Callable<Object> thunk = new Callable<Object>(){ 99 Callable<Object> thunk = new Callable<Object>(){
87 public Object call(){ 100 public Object call(){
88 101
89 ViewPort viewPort = 102 ViewPort viewPort =
90 app.getRenderManager() 103 app.getRenderManager()
91 .createPostView("aurellem video record", app.getCamera()); 104 .createPostView("aurellem video record",
105 app.getCamera());
92 106
93 viewPort.setClearFlags(false, false, false); 107 viewPort.setClearFlags(false, false, false);
94 108
95 // get GUI node stuff 109 // get GUI node stuff
96 for (Spatial s : app.getGuiViewPort().getScenes()){ 110 for (Spatial s : app.getGuiViewPort().getScenes()){
105 app.enqueue(thunk); 119 app.enqueue(thunk);
106 } 120 }
107 121
108 122
109 /** 123 /**
110 * Use this function to capture audio from your application. Audio data 124 * Use this function to capture audio from your
111 * will be saved in linear PCM format at 44,100 hertz in the wav container 125 * application. Audio data will be saved in linear PCM
112 * format to the file that you specify. 126 * format at 44,100 hertz in the wav container format to
127 * the file that you specify.
113 * 128 *
114 * Note that you *have* to use an IsoTimer for your Application's timer 129 * Note that you *have* to use an IsoTimer for your
115 * while recording audio or the recording will fail. Also ensure that your 130 * Application's timer while recording audio or the
116 * IsoTimer obeys the following constraints: 131 * recording will fail. Also ensure that your IsoTimer
132 * obeys the following constraints:
117 * 133 *
118 * 1.) The frames-per-second value of the IsoTimer cannot be lower than 10 134 * 1.) The frames-per-second value of the IsoTimer
119 * frames-per-second. 135 * cannot be lower than 10 frames-per-second.
120 * 136 *
121 * 2.) The frames-per-second value of the IsoTimer must evenly divide 137 * 2.) The frames-per-second value of the IsoTimer must
122 * 44,100. 138 * evenly divide 44,100.
123 * 139 *
124 * @param app The Application from which you wish to record Audio. 140 * @param app The Application from which you wish to
125 * @param file the target file to which you want to record audio data. 141 * record Audio.
142 * @param file the target file to which you want to
143 * record audio data.
126 * @throws IOException 144 * @throws IOException
127 */ 145 */
128 146
129 public static void captureAudio(final Application app, final File file) throws IOException{ 147 public static void captureAudio
148 (final Application app, final File file) throws IOException{
130 AppSettings settings = null; 149 AppSettings settings = null;
131 if (app.getContext() != null){settings = app.getContext().getSettings();} 150 if (app.getContext() != null){
151 settings = app.getContext().getSettings();}
132 if (settings == null){settings = new AppSettings(true);} 152 if (settings == null){settings = new AppSettings(true);}
133 settings.setAudioRenderer("Send"); 153 settings.setAudioRenderer("Send");
134 app.setSettings(settings); 154 app.setSettings(settings);
135 155
136 JmeSystem.setSystemDelegate(new AurellemSystemDelegate()); 156 JmeSystem.setSystemDelegate(new AurellemSystemDelegate());