rlm@59: ======Capture Audio/Video to a File====== rlm@59: rlm@59: So you've made your cool new JMonkeyEngine3 game and you want to rlm@59: create a demo video to show off your hard work. Or maybe you want to rlm@59: make a cutscene for your game using the physics and characters in the rlm@59: game itself. Screen capturing is the most straightforward way to do rlm@59: this, but it can slow down your game and produce low-quality video and rlm@59: audio as a result. A better way is to record video and audio directly rlm@59: from the game while it is running. rlm@59: rlm@59: There's a full solution for doing this already made for you here: rlm@59: rlm@59: http://www.aurellem.com/releases/jmeCapture-latest.zip rlm@59: http://www.aurellem.com/releases/jmeCapture-latest.tar.bz2 rlm@59: rlm@59: Download the archive in your preferred format, extract, rlm@59: add the jars to your project, and you are ready to go. rlm@59: rlm@59: The javadoc is here: rlm@59: http://www.aurellem.com/jmeCapture/docs/ rlm@59: rlm@59: Here is a complete example showing how to capture both audio and video rlm@59: from one of jMonkeyEngine3's advenced demo applications. rlm@59: rlm@59: rlm@59: import java.io.File; rlm@59: import java.io.IOException; rlm@59: rlm@59: import jme3test.water.TestPostWater; rlm@59: rlm@59: import com.aurellem.capture.Capture; rlm@59: import com.aurellem.capture.IsoTimer; rlm@59: import com.jme3.app.SimpleApplication; rlm@59: rlm@59: rlm@59: /** rlm@59: * Demonstrates how to use basic Audio/Video capture with a rlm@59: * jMonkeyEngine application. You can use these techniques to make rlm@59: * high quality cutscenes or demo videos, even on very slow laptops. rlm@59: * rlm@59: * @author Robert McIntyre rlm@59: */ rlm@59: rlm@59: public class Basic { rlm@59: rlm@59: public static void main(String[] ignore) throws IOException{ rlm@59: File video = File.createTempFile("JME-water-video", ".avi"); rlm@59: File audio = File.createTempFile("JME-water-audio", ".wav"); rlm@59: rlm@59: SimpleApplication app = new TestPostWater(); rlm@59: app.setTimer(new IsoTimer(60)); rlm@59: app.setShowSettings(false); rlm@59: rlm@59: Capture.captureVideo(app, video); rlm@59: Capture.captureAudio(app, audio); rlm@59: rlm@59: app.start(); rlm@59: rlm@59: System.out.println(video.getCanonicalPath()); rlm@59: System.out.println(audio.getCanonicalPath()); rlm@59: } rlm@59: } rlm@59: rlm@59: rlm@59: rlm@59: As you can see, to capture video and audio you use the rlm@59: ''com.aurellem.capture.Capture'' class, which has two methods, rlm@59: ''captureAudio'' and ''captureVideo'', and the rlm@59: ''com.aurellem.capture.IsoTimer class'', which sets the audio and rlm@59: video framerate. rlm@59: rlm@59: The steps are as simple as: rlm@59: rlm@59: rlm@59: yourApp.setTimer(new IsoTimer(desiredFramesPerSecond)); rlm@59: rlm@59: rlm@59: This causes jMonkeyEngine to take as much time as it needs to fully rlm@59: calculate every frame of the video and audio. You will see your game rlm@59: speed up and slow down depending on how computationally demanding your rlm@59: game is, but the final recorded audio and video will be perfectly rlm@59: sychronized and will run at exactly the fps which you specified. rlm@59: rlm@59: rlm@59: captureVideo(yourApp, targetVideoFile); rlm@59: captureAudio(yourApp, targetAudioFile); rlm@59: rlm@59: rlm@59: These will cause the app to record audio and video when it is run. rlm@59: Audio and video will stop being recorded when the app stops. Your rlm@59: audio will be recorded as a 44,100 Hz linear PCM wav file, while the rlm@59: video will be recorded according to the following rules: rlm@59: rlm@59: 1.) (Preferred) If you supply an empty directory as the file, then rlm@59: the video will be saved as a sequence of .png files, one file per rlm@59: frame. The files start at 0000000.png and increment from there. rlm@59: You can then combine the frames into your preferred rlm@59: container/codec. If the directory is not empty, then writing rlm@59: video frames to it will fail, and nothing will be written. rlm@59: rlm@59: 2.) If the filename ends in ".avi" then the frames will be encoded as rlm@59: a RAW stream inside an AVI 1.0 container. The resulting file rlm@59: will be quite large and you will probably want to re-encode it to rlm@59: your preferred container/codec format. Be advised that some rlm@59: video payers cannot process AVI with a RAW stream, and that AVI rlm@59: 1.0 files generated by this method that exceed 2.0GB are invalid rlm@59: according to the AVI 1.0 spec (but many programs can still deal rlm@59: with them.) Thanks to Werner Randelshofer for his excellent work rlm@59: which made AVI file writer option possible. rlm@59: rlm@59: 3.) Any non-directory file ending in anything other than ".avi" will rlm@59: be processed through Xuggle. Xuggle provides the option to use rlm@59: many codecs/containers, but you will have to install it on your rlm@59: system yourself in order to use this option. Please visit rlm@59: http://www.xuggle.com/ to learn how to do this. rlm@59: