Mercurial > jmeCapture
comparison 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 |
comparison
equal
deleted
inserted
replaced
2:59509c585530 | 3:a92de00f0414 |
---|---|
1 package com.aurellem.capture; | |
2 | |
3 import java.awt.image.BufferedImage; | |
4 import java.io.File; | |
5 import java.io.IOException; | |
6 import java.nio.ByteBuffer; | |
7 | |
8 import com.jme3.app.Application; | |
9 import com.jme3.app.state.AppState; | |
10 import com.jme3.app.state.AppStateManager; | |
11 import com.jme3.post.SceneProcessor; | |
12 import com.jme3.renderer.Camera; | |
13 import com.jme3.renderer.RenderManager; | |
14 import com.jme3.renderer.ViewPort; | |
15 import com.jme3.renderer.queue.RenderQueue; | |
16 import com.jme3.system.IsoTimer; | |
17 import com.jme3.texture.FrameBuffer; | |
18 import com.jme3.util.BufferUtils; | |
19 import com.jme3.util.Screenshots; | |
20 | |
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 */ | |
45 | |
46 public abstract class AbstractVideoRecorder | |
47 implements SceneProcessor, IVideoRecorder, AppState{ | |
48 | |
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; | |
61 | |
62 public AbstractVideoRecorder(File output) throws IOException { | |
63 this.output = output; | |
64 this.targetFileName = this.output.getCanonicalPath(); | |
65 } | |
66 | |
67 | |
68 public double getFps() {return this.fps;} | |
69 | |
70 public AbstractVideoRecorder setFps(double fps) { | |
71 this.fps = fps; | |
72 return this; | |
73 } | |
74 | |
75 public void initialize(RenderManager rm, ViewPort viewPort) { | |
76 Camera camera = viewPort.getCamera(); | |
77 this.width = camera.getWidth(); | |
78 this.height = camera.getHeight(); | |
79 | |
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 } | |
86 | |
87 public void reshape(ViewPort vp, int w, int h) {} | |
88 | |
89 public boolean isInitialized() {return this.isInitilized;} | |
90 | |
91 public void preFrame(float tpf) { | |
92 if (null == this.fps){ | |
93 this.setFps(1.0 / tpf);} | |
94 } | |
95 | |
96 public void postQueue(RenderQueue rq) {} | |
97 | |
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 } | |
106 | |
107 public void cleanup(){ | |
108 this.pause(); | |
109 this.finish(); | |
110 }; | |
111 | |
112 public void pause(){ | |
113 this.paused = true; | |
114 } | |
115 | |
116 public void start(){ | |
117 this.paused = false; | |
118 } | |
119 | |
120 // methods from AppState | |
121 public void initialize(AppStateManager stateManager, Application app) {} | |
122 | |
123 public void setEnabled(boolean active) { | |
124 if (active) {this.start();} | |
125 else {this.pause();} | |
126 } | |
127 | |
128 public boolean isEnabled() { | |
129 return this.paused; | |
130 } | |
131 | |
132 public void stateAttached(AppStateManager stateManager) {} | |
133 | |
134 | |
135 public void stateDetached(AppStateManager stateManager) { | |
136 this.pause(); | |
137 this.finish(); | |
138 } | |
139 | |
140 public void update(float tpf) {} | |
141 public void render(RenderManager rm) {} | |
142 public void postRender() {} | |
143 | |
144 } |