Mercurial > jmeCapture
view src/com/aurellem/capture/Capture.java @ 65:23e3df41db3c
reformatting for web
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 11 Feb 2012 12:25:26 -0700 |
parents | afc437f637bd |
children | 302d5e9ad120 |
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, high quality video22 * and audio from a jMonkeyEngine3 application. To capture audio or video do23 * the following:24 *25 * 1.) Set your application's timer to an IsoTimer. Create the IsoTimer with the26 * desired video frames-per-second.27 *28 * 2.) Call captureAudio and/or captureVideo on the Application as desired29 * before starting the Application.30 *31 * See the Basic and Advanced demos in the examples section for more32 * information. If you have any trouble, please PM me on the jMonkeyEngine33 * forums. My username is bortreb.34 *35 * @author Robert McIntyre36 */38 public class Capture {40 /**41 * Use this function to capture video from your application. You42 * specify the framerate at which the video will be recording by setting43 * the Application's timer to an IsoTimer created with the desired44 * frames-per-second.45 *46 * There are three ways to record and they are selected by the47 * properties of the file that you specify.48 *49 * 1.) (Preferred) If you supply an empty directory as the file, then50 * the video will be saved as a sequence of .png files, one file per51 * frame. The files start at 0000000.png and increment from there.52 * You can then combine the frames into your preferred53 * container/codec. If the directory is not empty, then writing54 * video frames to it will fail, and nothing will be written.55 *56 * 2.) If the filename ends in ".avi" then the frames will be encoded as57 * a RAW stream inside an AVI 1.0 container. The resulting file58 * will be quite large and you will probably want to re-encode it to59 * your preferred container/codec format. Be advised that some60 * video payers cannot process AVI with a RAW stream, and that AVI61 * 1.0 files generated by this method that exceed 2.0GB are invalid62 * according to the AVI 1.0 spec (but many programs can still deal63 * with them.) Thanks to Werner Randelshofer for his excellent work64 * which made AVI file writer option possible.65 *66 * 3.) Any non-directory file ending in anything other than ".avi" will67 * be processed through Xuggle. Xuggle provides the option to use68 * many codecs/containers, but you will have to install it on your69 * system yourself in order to use this option. Please visit70 * http://www.xuggle.com/ to learn how to do this.71 *72 * @param app The Application from which you wish to record Video.73 * @param file The file to which the video will be captured.74 * @throws IOException75 */77 public static void captureVideo(final Application app, final File file) throws IOException{78 final AbstractVideoRecorder videoRecorder;80 if (file.getCanonicalPath().endsWith(".avi")){81 videoRecorder = new AVIVideoRecorder(file);}82 else if (file.isDirectory()){83 videoRecorder = new FileVideoRecorder(file);}84 else { videoRecorder = new XuggleVideoRecorder(file);}86 Callable<Object> thunk = new Callable<Object>(){87 public Object call(){89 ViewPort viewPort =90 app.getRenderManager()91 .createPostView("aurellem video record", app.getCamera());93 viewPort.setClearFlags(false, false, false);95 // get GUI node stuff96 for (Spatial s : app.getGuiViewPort().getScenes()){97 viewPort.attachScene(s);98 }100 app.getStateManager().attach(videoRecorder);101 viewPort.addProcessor(videoRecorder);102 return null;103 }104 };105 app.enqueue(thunk);106 }109 /**110 * Use this function to capture audio from your application. Audio data111 * will be saved in linear PCM format at 44,100 hertz in the wav container112 * format to the file that you specify.113 *114 * Note that you *have* to use an IsoTimer for your Application's timer115 * while recording audio or the recording will fail. Also ensure that your116 * IsoTimer obeys the following constraints:117 *118 * 1.) The frames-per-second value of the IsoTimer cannot be lower than 10119 * frames-per-second.120 *121 * 2.) The frames-per-second value of the IsoTimer must evenly divide122 * 44,100.123 *124 * @param app The Application from which you wish to record Audio.125 * @param file the target file to which you want to record audio data.126 * @throws IOException127 */129 public static void captureAudio(final Application app, final File file) throws IOException{130 AppSettings settings = null;131 if (app.getContext() != null){settings = app.getContext().getSettings();}132 if (settings == null){settings = new AppSettings(true);}133 settings.setAudioRenderer("Send");134 app.setSettings(settings);136 JmeSystem.setSystemDelegate(new AurellemSystemDelegate());138 final WaveFileWriter writer = new WaveFileWriter(file);140 Callable<Object> thunk = new Callable<Object>(){141 public Object call(){142 AudioRenderer ar = app.getAudioRenderer();143 if (ar instanceof MultiListener){144 MultiListener ml = (MultiListener)ar;145 ml.registerSoundProcessor(writer);146 }147 return null;148 }149 };150 app.enqueue(thunk);151 }152 }