6da36f27a6cb946592955ef359b93ffe07fc9bfe
[kaka/cakelight.git] / src / kaka / cakelight / VideoMode.java
1 package kaka.cakelight;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.util.Optional;
6 import java.util.function.Consumer;
7
8 public class VideoMode extends Mode {
9     private Configuration config;
10     private Thread thread;
11     private Consumer<Frame> frameConsumer;
12     private VideoDeviceListener deviceListener;
13
14     public VideoMode() {
15         deviceListener = new VideoDeviceListener();
16         deviceListener.onVideoDeviceChange(this::onVideoDeviceChange);
17     }
18
19     @Override
20     public void enter(Configuration config) {
21         this.config = config;
22         deviceListener.startListening();
23     }
24
25     @Override
26     public void exit() {
27         thread.interrupt();
28         deviceListener.stopListening();
29     }
30
31     private void startGrabberThread(File videoDevice) {
32         assert frameConsumer != null;
33         thread = new Thread() {
34             public void run() {
35                 try (FrameGrabber grabber = FrameGrabber.from(videoDevice, config)) {
36                     while (!isInterrupted()) {
37                         Optional<Frame> frame = grabber.grabFrame();
38                         if (frameConsumer != null) frame.ifPresent(frameConsumer);
39                         frame.ifPresent(VideoMode.this::onFrame);
40 //                        timeIt("frame", grabber::grabFrame);
41                         // TODO: process frame
42                         // TODO: save where the LedController can access it
43                     }
44                 } catch (IOException e) {
45                     e.printStackTrace();
46                 }
47             }
48         };
49         thread.start();
50     }
51
52     public void onVideoFrame(Consumer<Frame> consumer) {
53         frameConsumer = consumer;
54     }
55
56     private void onFrame(Frame frame) {
57         updateWithFrame(frame.getLedFrame());
58     }
59
60     public void onVideoDeviceChange(Optional<File> videoDevice) {
61         // Should only happen when this mode is active!
62         if (thread != null) {
63             thread.interrupt();
64         }
65         videoDevice.ifPresent(this::startGrabberThread);
66     }
67 }