1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package org.openimaj.content.slideshow;
31
32 import java.awt.Component;
33 import java.awt.Dimension;
34 import java.awt.event.KeyEvent;
35 import java.awt.event.KeyListener;
36 import java.awt.image.BufferedImage;
37 import java.io.File;
38 import java.io.IOException;
39 import java.net.URL;
40
41 import org.apache.commons.io.FileUtils;
42 import org.openimaj.image.DisplayUtilities.ImageComponent;
43 import org.openimaj.image.ImageUtilities;
44 import org.openimaj.image.MBFImage;
45 import org.openimaj.image.processing.transform.MBFProjectionProcessor;
46 import org.openimaj.video.VideoDisplay;
47 import org.openimaj.video.VideoDisplay.EndAction;
48 import org.openimaj.video.VideoDisplayListener;
49 import org.openimaj.video.xuggle.XuggleVideo;
50
51 import Jama.Matrix;
52
53
54
55
56
57
58
59
60 public class VideoSlide implements Slide, VideoDisplayListener<MBFImage>, KeyListener {
61 URL url;
62 VideoDisplay<MBFImage> display;
63 private URL background;
64 protected PictureSlide pictureSlide;
65 private final Matrix transform;
66 private ImageComponent panel;
67 private BufferedImage bimg;
68 private MBFImage mbfImage;
69 private XuggleVideo video;
70 private EndAction endAction = EndAction.LOOP;
71
72
73
74
75
76
77
78
79
80
81 public VideoSlide(final URL video, final URL background, final Matrix transform, EndAction endAction)
82 throws IOException
83 {
84 this.url = makeURL(video);
85 this.background = background;
86 this.pictureSlide = new PictureSlide(this.background);
87 this.transform = transform;
88 this.endAction = endAction;
89 }
90
91
92
93
94
95
96
97
98
99 public VideoSlide(final URL video, final Matrix transform, EndAction endAction) throws IOException {
100 this.url = makeURL(video);
101 this.transform = transform;
102 this.endAction = endAction;
103 }
104
105 private URL makeURL(URL url) throws IOException {
106 if (url.getProtocol().startsWith("jar")) {
107 final File tmp = File.createTempFile("movie", ".tmp");
108 tmp.deleteOnExit();
109 FileUtils.copyURLToFile(url, tmp);
110 url = tmp.toURI().toURL();
111 }
112 return url;
113 }
114
115
116
117
118
119
120
121
122
123 public VideoSlide(final URL video, final URL background, EndAction endAction) throws IOException {
124 this(video, background, null, endAction);
125 }
126
127 @Override
128 public Component getComponent(final int width, final int height) throws IOException {
129 if (this.pictureSlide == null) {
130 this.mbfImage = new MBFImage(width, height, 3);
131 this.panel = (ImageComponent) new PictureSlide(this.mbfImage).getComponent(width, height);
132 }
133 else {
134 this.panel = (ImageComponent) this.pictureSlide.getComponent(width, height);
135 this.mbfImage = this.pictureSlide.mbfImage.clone();
136 }
137
138 this.panel.setSize(width, height);
139 this.panel.setPreferredSize(new Dimension(width, height));
140
141 this.video = new XuggleVideo(this.url, false);
142 this.display = VideoDisplay.createOffscreenVideoDisplay(this.video);
143 this.display.setEndAction(this.endAction);
144
145 this.display.addVideoListener(this);
146
147 return this.panel;
148 }
149
150 @Override
151 public void close() {
152 this.display.close();
153 }
154
155 @Override
156 public void afterUpdate(final VideoDisplay<MBFImage> display) {
157
158 }
159
160 @Override
161 public void beforeUpdate(final MBFImage frame) {
162 if (this.transform != null) {
163 final MBFImage bgCopy = this.mbfImage.clone();
164 final MBFProjectionProcessor proj = new MBFProjectionProcessor();
165 proj.setMatrix(this.transform);
166 proj.accumulate(frame);
167 proj.performProjection(0, 0, bgCopy);
168 this.panel.setImage(this.bimg = ImageUtilities.createBufferedImageForDisplay(bgCopy, this.bimg));
169 }
170 else
171 this.panel.setImage(this.bimg = ImageUtilities.createBufferedImageForDisplay(frame, this.bimg));
172 }
173
174 @Override
175 public void keyPressed(final KeyEvent key) {
176 final int code = key.getKeyCode();
177 if (code >= KeyEvent.VK_0 && code <= KeyEvent.VK_9) {
178 final double prop = (code - KeyEvent.VK_0) / 10.0;
179 final long dur = this.video.getDuration();
180 this.display.seek((long) (dur * prop));
181 }
182 if (code == KeyEvent.VK_SPACE) {
183 this.display.togglePause();
184 }
185 }
186
187 @Override
188 public void keyReleased(final KeyEvent arg0) {
189
190 }
191
192 @Override
193 public void keyTyped(final KeyEvent arg0) {
194
195 }
196 }