1f43ffbf7d7da90bfd496452b42697a1bfdf4b1a
[kaka/cakelight.git] / src / kaka / cakelight / mode / VideoMode.java
1 package kaka.cakelight.mode;
2
3 import kaka.cakelight.Configuration;
4 import kaka.cakelight.FrameGrabber;
5 import kaka.cakelight.VideoDeviceListener;
6 import kaka.cakelight.VideoFrame;
7
8 import java.io.File;
9 import java.io.IOException;
10 import java.util.Optional;
11 import java.util.function.Consumer;
12
13 public class VideoMode extends Mode {
14     private Configuration config;
15     private Thread grabberThread;
16     private Consumer<VideoFrame> frameConsumer;
17     private VideoDeviceListener deviceListener;
18
19     public VideoMode() {
20         deviceListener = new VideoDeviceListener();
21         deviceListener.onVideoDeviceChange(this::onVideoDeviceChange);
22     }
23
24     @Override
25     public void enter(Configuration config) {
26         this.config = config;
27         deviceListener.startListening();
28     }
29
30     @Override
31     public void pause() {
32         try {
33             grabberThread.wait();
34         } catch (InterruptedException e) {
35             e.printStackTrace();
36         }
37     }
38
39     @Override
40     public void resume() {
41         grabberThread.notify();
42     }
43
44     @Override
45     public void exit() {
46         grabberThread.interrupt();
47         deviceListener.stopListening();
48     }
49
50     private void startGrabberThread(File videoDevice) {
51         assert frameConsumer != null;
52         grabberThread = new Thread() {
53             public void run() {
54                 try (FrameGrabber grabber = FrameGrabber.from(videoDevice, config)) {
55                     while (!isInterrupted()) {
56                         Optional<VideoFrame> frame = grabber.grabFrame();
57                         if (frameConsumer != null) frame.ifPresent(frameConsumer);
58                         frame.ifPresent(VideoMode.this::onVideoFrame);
59 //                        timeIt("frame", grabber::grabFrame);
60                     }
61                 } catch (IOException e) {
62                     e.printStackTrace();
63                 }
64             }
65         };
66         grabberThread.start();
67     }
68
69     public void onVideoFrame(Consumer<VideoFrame> consumer) {
70         frameConsumer = consumer;
71     }
72
73     private void onVideoFrame(VideoFrame frame) {
74         updateWithFrame(frame.getLedFrame());
75     }
76
77     public void onVideoDeviceChange(Optional<File> videoDevice) {
78         // Should only happen when this mode is active!
79         if (grabberThread != null) {
80             grabberThread.interrupt();
81         }
82         videoDevice.ifPresent(this::startGrabberThread);
83     }
84 }