view src/com/aurellem/capture/video/AbstractVideoRecorder.java @ 15:be5ac56826be

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