diff src/com/aurellem/capture/AbstractVideoRecorder.java @ 3:a92de00f0414

migrating files
author Robert McIntyre <rlm@mit.edu>
date Tue, 25 Oct 2011 11:55:55 -0700
parents
children edaa7e7806e4
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/com/aurellem/capture/AbstractVideoRecorder.java	Tue Oct 25 11:55:55 2011 -0700
     1.3 @@ -0,0 +1,144 @@
     1.4 +package com.aurellem.capture;
     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.jme3.app.Application;
    1.12 +import com.jme3.app.state.AppState;
    1.13 +import com.jme3.app.state.AppStateManager;
    1.14 +import com.jme3.post.SceneProcessor;
    1.15 +import com.jme3.renderer.Camera;
    1.16 +import com.jme3.renderer.RenderManager;
    1.17 +import com.jme3.renderer.ViewPort;
    1.18 +import com.jme3.renderer.queue.RenderQueue;
    1.19 +import com.jme3.system.IsoTimer;
    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 +}