some fixes
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -42,3 +42,6 @@ build/
|
|||||||
|
|
||||||
.mvn
|
.mvn
|
||||||
.idea
|
.idea
|
||||||
|
|
||||||
|
## This is for our app, cause it likes to store stuff ##
|
||||||
|
network_cameras.json
|
||||||
32
pom.xml
32
pom.xml
@@ -28,6 +28,11 @@
|
|||||||
<version>0.3.12</version>
|
<version>0.3.12</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.sarxos</groupId>
|
||||||
|
<artifactId>webcam-capture-driver-ipcam</artifactId>
|
||||||
|
<version>0.3.12</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- for gl we use lwjgl -->
|
<!-- for gl we use lwjgl -->
|
||||||
|
|
||||||
@@ -62,5 +67,32 @@
|
|||||||
<version>6.1.0-M1</version>
|
<version>6.1.0-M1</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
|
||||||
|
<!-- For serializing network cameras we need json, well we dont need it but its certainly a quality
|
||||||
|
of life feature -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<version>2.20.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.jcodec/jcodec -->
|
||||||
|
<!--
|
||||||
|
Saving into Files
|
||||||
|
-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jcodec</groupId>
|
||||||
|
<artifactId>jcodec</artifactId>
|
||||||
|
<version>0.2.5</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.jcodec/jcodec-javase -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jcodec</groupId>
|
||||||
|
<artifactId>jcodec-javase</artifactId>
|
||||||
|
<version>0.2.5</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
@@ -8,10 +8,16 @@ If you want to build this project on yourself, you will need IntelliJ (or any ot
|
|||||||
- SWT
|
- SWT
|
||||||
- _lwjgl (with opengl)_ → This is important for our goals of rendering on the GPU.
|
- _lwjgl (with opengl)_ → This is important for our goals of rendering on the GPU.
|
||||||
- junit for testing stuff
|
- junit for testing stuff
|
||||||
|
- jcodec, in the future we will be recording using this
|
||||||
|
- Jackson (fasterxml) → serializing the config for network cams
|
||||||
|
|
||||||
### Future Plans:
|
### Future Plans:
|
||||||
They arent too big, i want one thing more and that is some more utilities in the camera window.
|
They arent too big, i want one thing more and that is some more utilities in the camera window.
|
||||||
Also some Network streaming but i am too lazy to do that
|
|
||||||
|
### Future Plans:
|
||||||
|
|
||||||
|
- [x] basic network cam interfacing
|
||||||
|
- [ ] better multiplexer (or whatever the viewport is called in cctv)
|
||||||
|
|
||||||
### Author(s):
|
### Author(s):
|
||||||
- rattatwinko
|
- rattatwinko
|
||||||
@@ -1,74 +1,192 @@
|
|||||||
package io.swtc;
|
package io.swtc;
|
||||||
|
|
||||||
import com.github.sarxos.webcam.Webcam;
|
import com.github.sarxos.webcam.Webcam;
|
||||||
|
import com.github.sarxos.webcam.WebcamCompositeDriver;
|
||||||
|
|
||||||
|
import com.github.sarxos.webcam.ds.buildin.WebcamDefaultDriver;
|
||||||
|
import com.github.sarxos.webcam.ds.ipcam.IpCamDeviceRegistry;
|
||||||
|
import com.github.sarxos.webcam.ds.ipcam.IpCamDriver;
|
||||||
|
import com.github.sarxos.webcam.ds.ipcam.IpCamMode;
|
||||||
|
import io.swtc.networking.CameraConfig;
|
||||||
|
import io.swtc.networking.CameraSettings;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.graphics.Font;
|
import org.eclipse.swt.graphics.Font;
|
||||||
import org.eclipse.swt.layout.GridData;
|
import org.eclipse.swt.layout.GridData;
|
||||||
import org.eclipse.swt.layout.GridLayout;
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
import org.eclipse.swt.widgets.*;
|
import org.eclipse.swt.widgets.*;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class CCTVManager {
|
public class CCTVManager {
|
||||||
|
|
||||||
|
static {
|
||||||
|
Webcam.setDriver(new WebcamCompositeDriver() {{
|
||||||
|
add(new WebcamDefaultDriver());
|
||||||
|
add(new IpCamDriver());
|
||||||
|
}});
|
||||||
|
|
||||||
|
for (CameraConfig config : CameraSettings.load()) {
|
||||||
|
try {
|
||||||
|
IpCamDeviceRegistry.register(config.getName(), config.getUrl(), IpCamMode.PUSH);
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Display display = new Display();
|
Display display = new Display();
|
||||||
Shell shell = new Shell(display, SWT.SHELL_TRIM | SWT.ON_TOP);
|
Shell shell = new Shell(display);
|
||||||
shell.setText("Dashboard");
|
shell.setText("Dashboard");
|
||||||
|
shell.setSize(900, 600);
|
||||||
|
|
||||||
|
renderUI(shell, display);
|
||||||
|
|
||||||
|
shell.open();
|
||||||
|
while (!shell.isDisposed()) {
|
||||||
|
if (!display.readAndDispatch()) display.sleep();
|
||||||
|
}
|
||||||
|
display.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void renderUI(Shell shell, Display display) {
|
||||||
|
// Clear existing children if refreshing
|
||||||
|
for (Control child : shell.getChildren()) child.dispose();
|
||||||
|
|
||||||
List<Webcam> webcams = Webcam.getWebcams();
|
List<Webcam> webcams = Webcam.getWebcams();
|
||||||
int columnCount = webcams.size() > 3 ? 3 : Math.max(1, webcams.size());
|
int columnCount = Math.min(3, Math.max(1, webcams.size()));
|
||||||
|
|
||||||
GridLayout mainLayout = new GridLayout(columnCount, true);
|
GridLayout mainLayout = new GridLayout(columnCount, true);
|
||||||
mainLayout.marginWidth = 20;
|
mainLayout.marginWidth = 20;
|
||||||
mainLayout.marginHeight = 20;
|
mainLayout.marginHeight = 20;
|
||||||
mainLayout.horizontalSpacing = 15;
|
|
||||||
mainLayout.verticalSpacing = 15;
|
|
||||||
shell.setLayout(mainLayout);
|
shell.setLayout(mainLayout);
|
||||||
|
|
||||||
// Header (Spans across all columns)
|
// Header Section
|
||||||
Label title = new Label(shell, SWT.NONE);
|
Composite header = new Composite(shell, SWT.NONE);
|
||||||
title.setText("Connected Devices");
|
header.setLayout(new GridLayout(2, false));
|
||||||
title.setFont(new Font(display, "Segoe UI", 14, SWT.BOLD));
|
header.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, columnCount, 1));
|
||||||
GridData titleData = new GridData(SWT.FILL, SWT.CENTER, true, false, columnCount, 1);
|
|
||||||
title.setLayoutData(titleData);
|
Label title = new Label(header, SWT.NONE);
|
||||||
|
title.setText("Connected Devices (" + webcams.size() + ")");
|
||||||
|
title.setFont(new Font(display, "Segoe UI", 16, SWT.BOLD));
|
||||||
|
title.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
|
||||||
|
|
||||||
|
Button addBtn = new Button(header, SWT.PUSH);
|
||||||
|
addBtn.setText("+ Add IP Camera");
|
||||||
|
addBtn.addListener(SWT.Selection, e -> showAddCameraDialog(shell, display));
|
||||||
|
|
||||||
if (webcams.isEmpty()) {
|
if (webcams.isEmpty()) {
|
||||||
Label error = new Label(shell, SWT.NONE);
|
Label note = new Label(shell, SWT.NONE);
|
||||||
error.setText("no available cameras!");
|
note.setText("No cameras detected. Add an IP camera to begin.");
|
||||||
} else {
|
} else {
|
||||||
for (Webcam webcam : webcams) {
|
for (Webcam webcam : webcams) {
|
||||||
createCameraCard(shell, display, webcam);
|
createCameraCard(shell, display, webcam);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shell.pack();
|
shell.layout(true, true);
|
||||||
shell.open();
|
|
||||||
|
|
||||||
while (!shell.isDisposed()) {
|
|
||||||
if (!display.readAndDispatch()) {
|
|
||||||
display.sleep();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
display.dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void createCameraCard(Composite parent, Display display, Webcam webcam) {
|
private static void createCameraCard(Composite parent, Display display, Webcam webcam) {
|
||||||
|
// We check if its a IP Cam by getting the class, if it is then we show the delete button
|
||||||
|
boolean isIpCam = webcam.getDevice().getClass().getSimpleName().contains("IpCam");
|
||||||
|
|
||||||
Group card = new Group(parent, SWT.NONE);
|
Group card = new Group(parent, SWT.NONE);
|
||||||
card.setText(webcam.getName());
|
card.setText(webcam.getName());
|
||||||
card.setLayout(new GridLayout(1, false));
|
card.setLayout(new GridLayout(2, false));
|
||||||
card.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
|
card.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
|
||||||
|
|
||||||
Button btn = new Button(card, SWT.PUSH);
|
Label info = new Label(card, SWT.WRAP);
|
||||||
btn.setText("View");
|
info.setText("Type: " + (isIpCam ? "Network IP" : "Local USB"));
|
||||||
btn.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
|
info.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
|
||||||
|
|
||||||
btn.addListener(SWT.Selection, e -> {
|
Button viewBtn = new Button(card, SWT.PUSH);
|
||||||
/**
|
viewBtn.setText("Launch");
|
||||||
* This is where magic happens! We start the Window Here! As arguments, we give our display and webcam index!
|
viewBtn.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
|
||||||
* */
|
viewBtn.addListener(SWT.Selection, e -> new CameraWindow(display, webcam).open());
|
||||||
System.out.println("Starting: " + webcam.getName());
|
|
||||||
CameraWindow window = new CameraWindow(display,webcam);
|
Button deleteBtn = new Button(card, SWT.PUSH);
|
||||||
window.open();
|
deleteBtn.setText("Delete");
|
||||||
|
deleteBtn.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
|
||||||
|
|
||||||
|
// this is where we do that, this is where the ipcam class is used
|
||||||
|
deleteBtn.setEnabled(isIpCam);
|
||||||
|
|
||||||
|
deleteBtn.addListener(SWT.Selection, e -> {
|
||||||
|
MessageBox mb = new MessageBox(parent.getShell(), SWT.ICON_QUESTION | SWT.YES | SWT.NO);
|
||||||
|
mb.setText("Confirm");
|
||||||
|
mb.setMessage("Remove " + webcam.getName() + "?");
|
||||||
|
if (mb.open() == SWT.YES) {
|
||||||
|
CameraSettings.delete(webcam.getName());
|
||||||
|
IpCamDeviceRegistry.unregister(webcam.getName());
|
||||||
|
renderUI(parent.getShell(), display);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void showAddCameraDialog(Shell parent, Display display) {
|
||||||
|
Shell dialog = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
|
||||||
|
dialog.setText("Register New IP Camera");
|
||||||
|
dialog.setLayout(new GridLayout(2, false));
|
||||||
|
|
||||||
|
new Label(dialog, SWT.NONE).setText("Name:");
|
||||||
|
Text nameIn = new Text(dialog, SWT.BORDER);
|
||||||
|
nameIn.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
|
||||||
|
|
||||||
|
new Label(dialog, SWT.NONE).setText("MJPEG URL:");
|
||||||
|
Text urlIn = new Text(dialog, SWT.BORDER);
|
||||||
|
urlIn.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
|
||||||
|
urlIn.setMessage("http://10.0.0.x/mjpeg");
|
||||||
|
|
||||||
|
// Error message label
|
||||||
|
Label errorLabel = new Label(dialog, SWT.NONE);
|
||||||
|
errorLabel.setForeground(display.getSystemColor(SWT.COLOR_RED));
|
||||||
|
errorLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
|
||||||
|
errorLabel.setVisible(false);
|
||||||
|
|
||||||
|
Button save = new Button(dialog, SWT.PUSH);
|
||||||
|
save.setText("Add Camera");
|
||||||
|
save.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
|
||||||
|
|
||||||
|
// error handling for stoopid people
|
||||||
|
save.addListener(SWT.Selection, e -> {
|
||||||
|
String name = nameIn.getText().trim();
|
||||||
|
String urlString = urlIn.getText().trim();
|
||||||
|
|
||||||
|
if (name.isEmpty() || urlString.isEmpty()) {
|
||||||
|
errorLabel.setText("Error: All fields are required.");
|
||||||
|
errorLabel.setVisible(true);
|
||||||
|
dialog.pack();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!urlString.toLowerCase().startsWith("http://") && !urlString.toLowerCase().startsWith("https://")) {
|
||||||
|
throw new MalformedURLException("URL must start with http:// or https://");
|
||||||
|
}
|
||||||
|
|
||||||
|
java.net.URL validatedUrl = new java.net.URL(urlString);
|
||||||
|
|
||||||
|
IpCamDeviceRegistry.register(name, validatedUrl.toExternalForm(), IpCamMode.PUSH);
|
||||||
|
|
||||||
|
CameraSettings.save(new CameraConfig(name, validatedUrl.toExternalForm()));
|
||||||
|
|
||||||
|
dialog.close();
|
||||||
|
renderUI(parent, display);
|
||||||
|
|
||||||
|
} catch (MalformedURLException ex) {
|
||||||
|
errorLabel.setText("Invalid URL: " + ex.getMessage());
|
||||||
|
errorLabel.setVisible(true);
|
||||||
|
dialog.pack();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
errorLabel.setText("Registration failed: " + ex.getMessage());
|
||||||
|
errorLabel.setVisible(true);
|
||||||
|
dialog.pack();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
dialog.pack();
|
||||||
|
dialog.open();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -27,10 +27,15 @@ public class CameraWindow {
|
|||||||
data.doubleBuffer = true;
|
data.doubleBuffer = true;
|
||||||
this.renderer = new CameraRenderer(shell, data);
|
this.renderer = new CameraRenderer(shell, data);
|
||||||
|
|
||||||
|
// this was inefficient before
|
||||||
this.captureLoop = new WebcamCaptureLoop(webcam, (BufferedImage img) -> {
|
this.captureLoop = new WebcamCaptureLoop(webcam, (BufferedImage img) -> {
|
||||||
if (!display.isDisposed() && !shell.isDisposed()) {
|
if (!display.isDisposed() && !shell.isDisposed()) {
|
||||||
// terribly uneficcient. very stupid tbh
|
display.asyncExec(() -> {
|
||||||
display.syncExec(() -> renderer.render(img));
|
if (!shell.isDisposed()) {
|
||||||
|
// render the image to the shell using gl
|
||||||
|
renderer.render(img);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
23
src/main/java/io/swtc/networking/CameraConfig.java
Normal file
23
src/main/java/io/swtc/networking/CameraConfig.java
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package io.swtc.networking;
|
||||||
|
|
||||||
|
public class CameraConfig {
|
||||||
|
public String name;
|
||||||
|
public String url;
|
||||||
|
|
||||||
|
// Default constructor for Jackson
|
||||||
|
public CameraConfig() {}
|
||||||
|
|
||||||
|
public CameraConfig(String name, String url) {
|
||||||
|
this.name = name;
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}
|
||||||
45
src/main/java/io/swtc/networking/CameraSettings.java
Normal file
45
src/main/java/io/swtc/networking/CameraSettings.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package io.swtc.networking;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some JSON stuff for camera config saving
|
||||||
|
* */
|
||||||
|
public class CameraSettings {
|
||||||
|
private static final File storage_file = new File("network_cameras.json");
|
||||||
|
private static final ObjectMapper mapper = new ObjectMapper();
|
||||||
|
|
||||||
|
public static List<CameraConfig> load() {
|
||||||
|
if (!storage_file.exists() || storage_file.length() == 0) return new ArrayList<>();
|
||||||
|
try {
|
||||||
|
return mapper.readValue(storage_file, new TypeReference<List<CameraConfig>>() {});
|
||||||
|
} catch (IOException e) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void save(CameraConfig newCam) {
|
||||||
|
List<CameraConfig> current = load();
|
||||||
|
current.add(newCam);
|
||||||
|
write(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void delete(String name) {
|
||||||
|
List<CameraConfig> current = load();
|
||||||
|
current.removeIf(cam -> cam.getName().equals(name));
|
||||||
|
write(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void write(List<CameraConfig> list) {
|
||||||
|
try {
|
||||||
|
mapper.writerWithDefaultPrettyPrinter().writeValue(storage_file, list);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
src/main/java/io/swtc/networking/bk.gif
Normal file
BIN
src/main/java/io/swtc/networking/bk.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 76 KiB |
51
src/main/java/io/swtc/networking/server.py
Normal file
51
src/main/java/io/swtc/networking/server.py
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
"""
|
||||||
|
|
||||||
|
A short test script which tests network cams
|
||||||
|
|
||||||
|
"""
|
||||||
|
import time
|
||||||
|
import io
|
||||||
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||||
|
from PIL import Image, ImageSequence
|
||||||
|
|
||||||
|
GIF_PATH = "bk.gif"
|
||||||
|
FPS = 15
|
||||||
|
|
||||||
|
class MJPEGHandler(BaseHTTPRequestHandler):
|
||||||
|
def do_GET(self):
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header(
|
||||||
|
"Content-Type",
|
||||||
|
"multipart/x-mixed-replace; boundary=frame"
|
||||||
|
)
|
||||||
|
self.end_headers()
|
||||||
|
|
||||||
|
gif = Image.open(GIF_PATH)
|
||||||
|
frames = [
|
||||||
|
frame.convert("RGB")
|
||||||
|
for frame in ImageSequence.Iterator(gif)
|
||||||
|
]
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
for frame_img in frames:
|
||||||
|
buf = io.BytesIO()
|
||||||
|
frame_img.save(buf, format="JPEG", quality=80)
|
||||||
|
frame = buf.getvalue()
|
||||||
|
|
||||||
|
self.wfile.write(b"--frame\r\n")
|
||||||
|
self.wfile.write(b"Content-Type: image/jpeg\r\n")
|
||||||
|
self.wfile.write(
|
||||||
|
f"Content-Length: {len(frame)}\r\n\r\n".encode()
|
||||||
|
)
|
||||||
|
self.wfile.write(frame)
|
||||||
|
self.wfile.write(b"\r\n")
|
||||||
|
|
||||||
|
time.sleep(1 / FPS)
|
||||||
|
|
||||||
|
except BrokenPipeError:
|
||||||
|
pass # client disconnected
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("MJPEG GIF stream running at http://localhost:8080/")
|
||||||
|
HTTPServer(("", 8080), MJPEGHandler).serve_forever()
|
||||||
@@ -14,9 +14,13 @@ public class WebcamCaptureLoop {
|
|||||||
this.webcam = webcam;
|
this.webcam = webcam;
|
||||||
this.onFrameCaptured = onFrameCaptured;
|
this.onFrameCaptured = onFrameCaptured;
|
||||||
|
|
||||||
// Configure webcam
|
// this is some of the most stupid shit ive seen in years, this is needed for opening the stream.
|
||||||
Dimension[] sizes = webcam.getViewSizes();
|
// the webcam package may not know the res before its opened and well this is before we open it. that is below in the thread.
|
||||||
webcam.setViewSize(sizes[sizes.length - 1]);
|
// so this freaks out and doesnt want to cooperate.
|
||||||
|
if (!webcam.getName().toLowerCase().contains("ipcam")) {
|
||||||
|
Dimension[] sizes = webcam.getViewSizes();
|
||||||
|
webcam.setViewSize(sizes[sizes.length - 1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
@@ -24,11 +28,13 @@ public class WebcamCaptureLoop {
|
|||||||
running = true;
|
running = true;
|
||||||
|
|
||||||
Thread captureThread = new Thread(() -> {
|
Thread captureThread = new Thread(() -> {
|
||||||
|
// this is where we open it. if the res isnt known then it fucks up.
|
||||||
webcam.open();
|
webcam.open();
|
||||||
|
|
||||||
while (running) {
|
while (running) {
|
||||||
BufferedImage img = webcam.getImage();
|
BufferedImage img = webcam.getImage();
|
||||||
if (img != null) {
|
if (img != null) {
|
||||||
|
//System.err.println(img);
|
||||||
onFrameCaptured.accept(img);
|
onFrameCaptured.accept(img);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user