1 package kaka.cakelight.mode;
3 import kaka.cakelight.Configuration;
4 import kaka.cakelight.FrameGrabber;
5 import kaka.cakelight.VideoDeviceListener;
6 import kaka.cakelight.VideoFrame;
9 import java.io.IOException;
10 import java.util.Optional;
11 import java.util.function.Consumer;
13 public class VideoMode extends Mode {
14 private Configuration config;
15 private Thread grabberThread;
16 private Consumer<VideoFrame> frameConsumer;
17 private VideoDeviceListener deviceListener;
18 private boolean isPaused = false;
21 deviceListener = new VideoDeviceListener();
22 deviceListener.onVideoDeviceChange(this::onVideoDeviceChange);
26 public void enter(Configuration config) {
28 if (config.video.deviceIsAutomatic) {
29 deviceListener.startListening();
31 File videoDevice = new File(config.video.device);
32 startGrabberThread(videoDevice);
42 public void resume() {
44 synchronized (grabberThread) {
45 grabberThread.notify();
51 grabberThread.interrupt();
52 if (config.video.deviceIsAutomatic) {
53 deviceListener.stopListening();
57 private void startGrabberThread(File videoDevice) {
58 assert frameConsumer != null;
59 grabberThread = new Thread() {
61 try (FrameGrabber grabber = FrameGrabber.from(videoDevice, config)) {
62 while (!isInterrupted()) {
63 Optional<VideoFrame> frame = grabber.grabFrame();
65 synchronized (grabberThread) {
69 if (frameConsumer != null) frame.ifPresent(frameConsumer);
70 frame.ifPresent(VideoMode.this::onVideoFrame);
71 // timeIt("frame", grabber::grabFrame);
73 } catch (IOException | InterruptedException e) {
78 grabberThread.start();
81 public void onVideoFrame(Consumer<VideoFrame> consumer) {
82 frameConsumer = consumer;
85 private void onVideoFrame(VideoFrame frame) {
86 updateWithFrame(frame.getLedFrame());
89 public void onVideoDeviceChange(Optional<File> videoDevice) {
90 // Should only happen when this mode is active!
91 if (grabberThread != null) {
92 grabberThread.interrupt();
94 videoDevice.ifPresent(this::startGrabberThread);