Mercurial > jmeCapture
diff src/com/aurellem/capture/video/AbstractVideoRecorder.java @ 9:5dfc9e768816
moved files
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Wed, 26 Oct 2011 08:54:12 -0700 |
parents | |
children | 784a3f4e6202 |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/com/aurellem/capture/video/AbstractVideoRecorder.java Wed Oct 26 08:54:12 2011 -0700 1.3 @@ -0,0 +1,144 @@ 1.4 +package com.aurellem.capture.video; 1.5 + 1.6 +import java.awt.image.BufferedImage; 1.7 +import java.io.File; 1.8 +import java.io.IOException; 1.9 +import java.nio.ByteBuffer; 1.10 + 1.11 +import com.aurellem.capture.IsoTimer; 1.12 +import com.jme3.app.Application; 1.13 +import com.jme3.app.state.AppState; 1.14 +import com.jme3.app.state.AppStateManager; 1.15 +import com.jme3.post.SceneProcessor; 1.16 +import com.jme3.renderer.Camera; 1.17 +import com.jme3.renderer.RenderManager; 1.18 +import com.jme3.renderer.ViewPort; 1.19 +import com.jme3.renderer.queue.RenderQueue; 1.20 +import com.jme3.texture.FrameBuffer; 1.21 +import com.jme3.util.BufferUtils; 1.22 +import com.jme3.util.Screenshots; 1.23 + 1.24 +/** 1.25 + * <code>VideoProcessor</code> copies the frames it receives to video. 1.26 + * To ensure smooth video at a constant framerate, you should set your 1.27 + * application's timer to a new {@link IsoTimer}. This class will 1.28 + * auto-determine the framerate of the video based on the time difference 1.29 + * between the first two frames it receives, although you can manually set 1.30 + * the framerate by calling <code>setFps(newFramerate)</code>. Be sure to 1.31 + * place this processor *after* any other processors whose effects you want 1.32 + * to be included in the output video. You can attach multiple 1.33 + * <code>VideoProcessor</code>s to the same <code>ViewPort</code>. 1.34 + * 1.35 + * For example, 1.36 + * <code> 1.37 + * someViewPort.addProcessor(new VideoProcessor(file1)); 1.38 + * someViewPort.addProcessor(someShadowRenderer); 1.39 + * someViewPort.addProcessor(new VideoProcessor(file2)); 1.40 + * </code> 1.41 + * 1.42 + * will output a video without shadows to <code>file1</code> and a video 1.43 + * with shadows to <code>file2</code> 1.44 + * 1.45 + * @author Robert McIntyre 1.46 + * 1.47 + */ 1.48 + 1.49 +public abstract class AbstractVideoRecorder 1.50 + implements SceneProcessor, IVideoRecorder, AppState{ 1.51 + 1.52 + final File output; 1.53 + Camera camera; 1.54 + int width; 1.55 + int height; 1.56 + String targetFileName; 1.57 + FrameBuffer frameBuffer; 1.58 + Double fps = null; 1.59 + RenderManager renderManager; 1.60 + ByteBuffer byteBuffer; 1.61 + BufferedImage rawFrame; 1.62 + boolean isInitilized = false; 1.63 + boolean paused = false; 1.64 + 1.65 + public AbstractVideoRecorder(File output) throws IOException { 1.66 + this.output = output; 1.67 + this.targetFileName = this.output.getCanonicalPath(); 1.68 + } 1.69 + 1.70 + 1.71 + public double getFps() {return this.fps;} 1.72 + 1.73 + public AbstractVideoRecorder setFps(double fps) { 1.74 + this.fps = fps; 1.75 + return this; 1.76 + } 1.77 + 1.78 + public void initialize(RenderManager rm, ViewPort viewPort) { 1.79 + Camera camera = viewPort.getCamera(); 1.80 + this.width = camera.getWidth(); 1.81 + this.height = camera.getHeight(); 1.82 + 1.83 + rawFrame = new BufferedImage(width, height, 1.84 + BufferedImage.TYPE_4BYTE_ABGR); 1.85 + byteBuffer = BufferUtils.createByteBuffer(width * height * 4 ); 1.86 + this.renderManager = rm; 1.87 + this.isInitilized = true; 1.88 + } 1.89 + 1.90 + public void reshape(ViewPort vp, int w, int h) {} 1.91 + 1.92 + public boolean isInitialized() {return this.isInitilized;} 1.93 + 1.94 + public void preFrame(float tpf) { 1.95 + if (null == this.fps){ 1.96 + this.setFps(1.0 / tpf);} 1.97 + } 1.98 + 1.99 + public void postQueue(RenderQueue rq) {} 1.100 + 1.101 + public void postFrame(FrameBuffer out) { 1.102 + if (!this.paused){ 1.103 + byteBuffer.clear(); 1.104 + renderManager.getRenderer().readFrameBuffer(out, byteBuffer); 1.105 + Screenshots.convertScreenShot(byteBuffer, rawFrame); 1.106 + record(rawFrame); 1.107 + } 1.108 + } 1.109 + 1.110 + public void cleanup(){ 1.111 + this.pause(); 1.112 + this.finish(); 1.113 + }; 1.114 + 1.115 + public void pause(){ 1.116 + this.paused = true; 1.117 + } 1.118 + 1.119 + public void start(){ 1.120 + this.paused = false; 1.121 + } 1.122 + 1.123 + // methods from AppState 1.124 + public void initialize(AppStateManager stateManager, Application app) {} 1.125 + 1.126 + public void setEnabled(boolean active) { 1.127 + if (active) {this.start();} 1.128 + else {this.pause();} 1.129 + } 1.130 + 1.131 + public boolean isEnabled() { 1.132 + return this.paused; 1.133 + } 1.134 + 1.135 + public void stateAttached(AppStateManager stateManager) {} 1.136 + 1.137 + 1.138 + public void stateDetached(AppStateManager stateManager) { 1.139 + this.pause(); 1.140 + this.finish(); 1.141 + } 1.142 + 1.143 + public void update(float tpf) {} 1.144 + public void render(RenderManager rm) {} 1.145 + public void postRender() {} 1.146 + 1.147 +}