annotate src/com/aurellem/capture/video/AbstractVideoRecorder.java @ 59:5afa49c5a7d3

adding wiki readme goodness
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Dec 2011 22:14:21 -0600
parents 3dc1f15e1e13
children
rev   line source
rlm@9 1 package com.aurellem.capture.video;
rlm@9 2
rlm@9 3 import java.awt.image.BufferedImage;
rlm@9 4 import java.io.File;
rlm@9 5 import java.io.IOException;
rlm@9 6 import java.nio.ByteBuffer;
rlm@9 7
rlm@9 8 import com.jme3.app.Application;
rlm@9 9 import com.jme3.app.state.AppState;
rlm@9 10 import com.jme3.app.state.AppStateManager;
rlm@9 11 import com.jme3.post.SceneProcessor;
rlm@9 12 import com.jme3.renderer.Camera;
rlm@9 13 import com.jme3.renderer.RenderManager;
rlm@9 14 import com.jme3.renderer.ViewPort;
rlm@9 15 import com.jme3.renderer.queue.RenderQueue;
rlm@9 16 import com.jme3.texture.FrameBuffer;
rlm@9 17 import com.jme3.util.BufferUtils;
rlm@9 18 import com.jme3.util.Screenshots;
rlm@9 19
rlm@9 20 /**
rlm@39 21 * <code>VideoRecorder</code> copies the frames it receives to video.
rlm@9 22 * To ensure smooth video at a constant framerate, you should set your
rlm@39 23 * application's timer to a new <code>IsoTimer</code>. This class will
rlm@9 24 * auto-determine the framerate of the video based on the time difference
rlm@9 25 * between the first two frames it receives, although you can manually set
rlm@9 26 * the framerate by calling <code>setFps(newFramerate)</code>. Be sure to
rlm@9 27 * place this processor *after* any other processors whose effects you want
rlm@9 28 * to be included in the output video. You can attach multiple
rlm@9 29 * <code>VideoProcessor</code>s to the same <code>ViewPort</code>.
rlm@9 30 *
rlm@9 31 * For example,
rlm@9 32 * <code>
rlm@9 33 * someViewPort.addProcessor(new VideoProcessor(file1));
rlm@9 34 * someViewPort.addProcessor(someShadowRenderer);
rlm@9 35 * someViewPort.addProcessor(new VideoProcessor(file2));
rlm@9 36 * </code>
rlm@9 37 *
rlm@9 38 * will output a video without shadows to <code>file1</code> and a video
rlm@9 39 * with shadows to <code>file2</code>
rlm@9 40 *
rlm@9 41 * @author Robert McIntyre
rlm@9 42 */
rlm@9 43
rlm@9 44 public abstract class AbstractVideoRecorder
rlm@39 45 implements SceneProcessor, VideoRecorder, AppState{
rlm@9 46
rlm@9 47 final File output;
rlm@9 48 Camera camera;
rlm@9 49 int width;
rlm@9 50 int height;
rlm@9 51 String targetFileName;
rlm@9 52 FrameBuffer frameBuffer;
rlm@9 53 Double fps = null;
rlm@9 54 RenderManager renderManager;
rlm@9 55 ByteBuffer byteBuffer;
rlm@9 56 BufferedImage rawFrame;
rlm@9 57 boolean isInitilized = false;
rlm@9 58 boolean paused = false;
rlm@9 59
rlm@9 60 public AbstractVideoRecorder(File output) throws IOException {
rlm@9 61 this.output = output;
rlm@9 62 this.targetFileName = this.output.getCanonicalPath();
rlm@9 63 }
rlm@9 64
rlm@9 65
rlm@9 66 public double getFps() {return this.fps;}
rlm@9 67
rlm@9 68 public AbstractVideoRecorder setFps(double fps) {
rlm@9 69 this.fps = fps;
rlm@9 70 return this;
rlm@9 71 }
rlm@9 72
rlm@9 73 public void initialize(RenderManager rm, ViewPort viewPort) {
rlm@9 74 Camera camera = viewPort.getCamera();
rlm@9 75 this.width = camera.getWidth();
rlm@9 76 this.height = camera.getHeight();
rlm@9 77
rlm@9 78 rawFrame = new BufferedImage(width, height,
rlm@9 79 BufferedImage.TYPE_4BYTE_ABGR);
rlm@9 80 byteBuffer = BufferUtils.createByteBuffer(width * height * 4 );
rlm@9 81 this.renderManager = rm;
rlm@9 82 this.isInitilized = true;
rlm@9 83 }
rlm@9 84
rlm@9 85 public void reshape(ViewPort vp, int w, int h) {}
rlm@9 86
rlm@9 87 public boolean isInitialized() {return this.isInitilized;}
rlm@9 88
rlm@9 89 public void preFrame(float tpf) {
rlm@9 90 if (null == this.fps){
rlm@9 91 this.setFps(1.0 / tpf);}
rlm@9 92 }
rlm@9 93
rlm@9 94 public void postQueue(RenderQueue rq) {}
rlm@9 95
rlm@9 96 public void postFrame(FrameBuffer out) {
rlm@9 97 if (!this.paused){
rlm@9 98 byteBuffer.clear();
rlm@9 99 renderManager.getRenderer().readFrameBuffer(out, byteBuffer);
rlm@9 100 Screenshots.convertScreenShot(byteBuffer, rawFrame);
rlm@9 101 record(rawFrame);
rlm@9 102 }
rlm@9 103 }
rlm@9 104
rlm@9 105 public void cleanup(){
rlm@9 106 this.pause();
rlm@9 107 this.finish();
rlm@9 108 };
rlm@9 109
rlm@9 110 public void pause(){
rlm@9 111 this.paused = true;
rlm@9 112 }
rlm@9 113
rlm@9 114 public void start(){
rlm@9 115 this.paused = false;
rlm@9 116 }
rlm@9 117
rlm@9 118 // methods from AppState
rlm@9 119 public void initialize(AppStateManager stateManager, Application app) {}
rlm@9 120
rlm@9 121 public void setEnabled(boolean active) {
rlm@9 122 if (active) {this.start();}
rlm@9 123 else {this.pause();}
rlm@9 124 }
rlm@9 125
rlm@9 126 public boolean isEnabled() {
rlm@9 127 return this.paused;
rlm@9 128 }
rlm@9 129
rlm@9 130 public void stateAttached(AppStateManager stateManager) {}
rlm@9 131
rlm@9 132
rlm@9 133 public void stateDetached(AppStateManager stateManager) {
rlm@9 134 this.pause();
rlm@9 135 this.finish();
rlm@9 136 }
rlm@9 137
rlm@9 138 public void update(float tpf) {}
rlm@9 139 public void render(RenderManager rm) {}
rlm@9 140 public void postRender() {}
rlm@9 141
rlm@9 142 }