Mercurial > jmeCapture
view src/com/aurellem/capture/Capture.java @ 55:b05f629fc296
add contact info
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Dec 2011 19:18:38 -0600 |
parents | 6484a820e27d |
children | afc437f637bd |
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 video and audio from a22 * jMonkeyEngine3 application. To capture audio or video do the following:23 *24 * 1.) Set your application's timer to an IsoTimer. Create the IsoTimer with the desired video25 * frames-per-second.26 * 2.) Call captureAudio and/or captureVideo on the Application as desired before starting the Application.27 *28 * See the Basic and Advanced demos in the examples section for more information. If you have any trouble,29 * please PM me on the jMonkeyEngine forums. My username is bortreb.30 *31 * @author Robert McIntyre32 */34 public class Capture {36 /**37 * Use this function to capture video from your application. You specify the framerate at which38 * the video will be recording by setting the Application's timer to an IsoTimer created with the39 * desired frames-per-second.40 *41 * There are three ways to record and they are selected by the properties of the file that you42 * specify.43 *44 * 1.) (Preferred)45 * If you supply an empty directory as the file, then the video will46 * be saved as a sequence of .png files, one file per frame. The files start at47 * 0000000.png and increment from there. You can then combine the frames into your48 * preferred container/codec. If the directory is not empty, then writing video frames49 * to it will fail, and nothing will be written.50 *51 * 2.) If the filename ends in ".avi" then the frames will be encoded as a RAW stream52 * inside an AVI 1.0 container. The resulting file will be quite large and you will53 * probably want to re-encode it to your preferred container/codec format. Be advised54 * that some video payers cannot process AVI with a RAW stream, and that AVI 1.0 files55 * generated by this method that exceed 2.0GB are invalid according to the AVI 1.0 spec56 * (but many programs can still deal with them.) Thanks to Werner Randelshofer for his57 * excellent work which made AVI file writer option possible.58 *59 * 3.) Any non-directory file ending in anything other than ".avi" will be processed through60 * Xuggle. Xuggle provides the option to use many codecs/containers, but you will have to61 * install it on your system yourself in order to use this option. Please visit62 * http://www.xuggle.com/ to learn how to do this.63 *64 * @param app The Application from which you wish to record Video.65 * @param file The file to which the video will be captured.66 * @throws IOException67 */69 public static void captureVideo(final Application app, final File file) throws IOException{70 final AbstractVideoRecorder videoRecorder;72 if (file.getCanonicalPath().endsWith(".avi")){73 videoRecorder = new AVIVideoRecorder(file);}74 else if (file.isDirectory()){75 videoRecorder = new FileVideoRecorder(file);}76 else { videoRecorder = new XuggleVideoRecorder(file);}78 Callable<Object> thunk = new Callable<Object>(){79 public Object call(){81 ViewPort viewPort =82 app.getRenderManager()83 .createPostView("aurellem video record", app.getCamera());85 viewPort.setClearFlags(false, false, false);87 // get GUI node stuff88 for (Spatial s : app.getGuiViewPort().getScenes()){89 viewPort.attachScene(s);90 }92 app.getStateManager().attach(videoRecorder);93 viewPort.addProcessor(videoRecorder);94 return null;95 }96 };97 app.enqueue(thunk);98 }101 /**102 * Use this function to capture audio from your application. Audio data will be saved in linear103 * PCM format at 44,100 hertz in the wav container format to the file that you specify.104 *105 * Note that you *have* to use an IsoTimer for your Application's timer while recording audio or106 * the recording will fail. Also ensure that your IsoTimer obeys the following constraints:107 *108 * - The frames-per-second value of the IsoTimer cannot be lower than 10 frames-per-second.109 * - The frames-per-second value of the IsoTimer must evenly divide 44,100.110 *111 * @param app The Application from which you wish to record Audio.112 * @param file the target file to which you want to record audio data.113 * @throws IOException114 */116 public static void captureAudio(final Application app, final File file) throws IOException{117 AppSettings settings = null;118 if (app.getContext() != null){settings = app.getContext().getSettings();}119 if (settings == null){settings = new AppSettings(true);}120 settings.setAudioRenderer("Send");121 app.setSettings(settings);123 JmeSystem.setSystemDelegate(new AurellemSystemDelegate());125 final WaveFileWriter writer = new WaveFileWriter(file);127 Callable<Object> thunk = new Callable<Object>(){128 public Object call(){129 AudioRenderer ar = app.getAudioRenderer();130 if (ar instanceof MultiListener){131 MultiListener ml = (MultiListener)ar;132 ml.registerSoundProcessor(writer);133 }134 return null;135 }136 };137 app.enqueue(thunk);138 }139 }