Mercurial > jmeCapture
view src/com/aurellem/capture/Capture.java @ 71:2c50a0c99715
remove xuggle, since I will never use it.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Mon, 10 Mar 2014 18:54:35 -0400 |
parents | 302d5e9ad120 |
children | dd97f65f940c |
line wrap: on
line source
1 package com.aurellem.capture;3 import java.io.File;4 import java.io.IOException;5 import java.util.concurrent.Callable;7 import com.aurellem.capture.audio.MultiListener;8 import com.aurellem.capture.audio.WaveFileWriter;9 import com.aurellem.capture.video.AVIVideoRecorder;10 import com.aurellem.capture.video.AbstractVideoRecorder;11 import com.aurellem.capture.video.FileVideoRecorder;12 //import com.aurellem.capture.video.XuggleVideoRecorder;13 import com.jme3.app.Application;14 import com.jme3.audio.AudioRenderer;15 import com.jme3.renderer.ViewPort;16 import com.jme3.scene.Spatial;17 import com.jme3.system.AppSettings;18 import com.jme3.system.JmeSystem;20 /**21 * Use the methods in this class for capturing consistent,22 * high quality video and audio from a jMonkeyEngine323 * application. To capture audio or video do the following:24 *25 * 1.) Set your application's timer to an IsoTimer. Create26 * the IsoTimer with the desired video27 * frames-per-second.28 *29 * 2.) Call captureAudio and/or captureVideo on the30 * Application as desired before starting the31 * Application.32 *33 * See the Basic and Advanced demos in the examples section34 * for more information. If you have any trouble, please PM35 * me on the jMonkeyEngine forums. My username is bortreb.36 *37 * @author Robert McIntyre38 */40 public class Capture {42 /**43 * Use this function to capture video from your44 * application. You specify the framerate at which the45 * video will be recording by setting the Application's46 * timer to an IsoTimer created with the desired47 * frames-per-second.48 *49 * There are three ways to record and they are selected50 * by the properties of the file that you specify.51 *52 * 1.) (Preferred) If you supply an empty directory as53 * the file, then the video will be saved as a54 * sequence of .png files, one file per frame. The55 * files start at 0000000.png and increment from56 * there. You can then combine the frames into your57 * preferred container/codec. If the directory is58 * not empty, then writing video frames to it will59 * fail, and nothing will be written.60 *61 * 2.) If the filename ends in ".avi" then the frames62 * will be encoded as a RAW stream inside an AVI 1.063 * container. The resulting file will be quite64 * large and you will probably want to re-encode it65 * to your preferred container/codec format. Be66 * advised that some video payers cannot process AVI67 * with a RAW stream, and that AVI 1.0 files68 * generated by this method that exceed 2.0GB are69 * invalid according to the AVI 1.0 spec (but many70 * programs can still deal with them.) Thanks to71 * Werner Randelshofer for his excellent work which72 * made AVI file writer option possible.73 *74 * 3.) Any non-directory file ending in anything other75 * than ".avi" will be processed through Xuggle.76 * Xuggle provides the option to use many77 * codecs/containers, but you will have to install78 * it on your system yourself in order to use this79 * option. Please visit http://www.xuggle.com/ to80 * learn how to do this.81 *82 * @param app The Application from which you wish to record Video.83 * @param file The file to which the video will be captured.84 * @throws IOException85 */87 public static void captureVideo88 (final Application app, final File file) throws IOException{89 final AbstractVideoRecorder videoRecorder;91 if (file.getCanonicalPath().endsWith(".avi")){92 videoRecorder = new AVIVideoRecorder(file);}93 else if (file.isDirectory()){94 videoRecorder = new FileVideoRecorder(file);}95 else {96 //videoRecorder = new XuggleVideoRecorder(file);97 }99 Callable<Object> thunk = new Callable<Object>(){100 public Object call(){102 ViewPort viewPort =103 app.getRenderManager()104 .createPostView("aurellem video record",105 app.getCamera());107 viewPort.setClearFlags(false, false, false);109 // get GUI node stuff110 for (Spatial s : app.getGuiViewPort().getScenes()){111 viewPort.attachScene(s);112 }114 app.getStateManager().attach(videoRecorder);115 viewPort.addProcessor(videoRecorder);116 return null;117 }118 };119 app.enqueue(thunk);120 }123 /**124 * Use this function to capture audio from your125 * application. Audio data will be saved in linear PCM126 * format at 44,100 hertz in the wav container format to127 * the file that you specify.128 *129 * Note that you *have* to use an IsoTimer for your130 * Application's timer while recording audio or the131 * recording will fail. Also ensure that your IsoTimer132 * obeys the following constraints:133 *134 * 1.) The frames-per-second value of the IsoTimer135 * cannot be lower than 10 frames-per-second.136 *137 * 2.) The frames-per-second value of the IsoTimer must138 * evenly divide 44,100.139 *140 * @param app The Application from which you wish to141 * record Audio.142 * @param file the target file to which you want to143 * record audio data.144 * @throws IOException145 */147 public static void captureAudio148 (final Application app, final File file) throws IOException{149 AppSettings settings = null;150 if (app.getContext() != null){151 settings = app.getContext().getSettings();}152 if (settings == null){settings = new AppSettings(true);}153 settings.setAudioRenderer("Send");154 app.setSettings(settings);156 JmeSystem.setSystemDelegate(new AurellemSystemDelegate());158 final WaveFileWriter writer = new WaveFileWriter(file);160 Callable<Object> thunk = new Callable<Object>(){161 public Object call(){162 AudioRenderer ar = app.getAudioRenderer();163 if (ar instanceof MultiListener){164 MultiListener ml = (MultiListener)ar;165 ml.registerSoundProcessor(writer);166 }167 return null;168 }169 };170 app.enqueue(thunk);171 }172 }