removed :
- CameraWindow.java - CCTVManager.java changed : / Main.java (refactoring for classes) / pom.xml (went SWT Free) / readme.md ; some changes to dep. and future plans section Now this project does not rely on SWT (Eclipse) it now uses Swing, which is plenty and is protable
This commit is contained in:
7
pom.xml
7
pom.xml
@@ -51,12 +51,6 @@
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.platform</groupId>
|
||||
<artifactId>org.eclipse.swt.win32.win32.x86_64</artifactId>
|
||||
<version>3.132.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.sarxos</groupId>
|
||||
<artifactId>webcam-capture</artifactId>
|
||||
@@ -70,7 +64,6 @@
|
||||
</dependency>
|
||||
|
||||
<!-- for gl we use lwjgl -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.lwjgl</groupId>
|
||||
<artifactId>lwjgl</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@ If you want to build this project on yourself, you will need IntelliJ (or any ot
|
||||
|
||||
## Dependencies:
|
||||
- Webcam by Sarxos
|
||||
- SWT
|
||||
- Swing (AWT)
|
||||
- _lwjgl (with opengl)_ → This is important for our goals of rendering on the GPU.
|
||||
- junit for testing stuff
|
||||
- jcodec, in the future we will be recording using this
|
||||
@@ -14,10 +14,14 @@ If you want to build this project on yourself, you will need IntelliJ (or any ot
|
||||
### Future Plans:
|
||||
They arent too big, i want one thing more and that is some more utilities in the camera window.
|
||||
|
||||
Protable Jar which can be run with JRE 17 (already done but not too good!)
|
||||
|
||||
### Future Plans:
|
||||
|
||||
- [x] basic network cam interfacing
|
||||
- [ ] better multiplexer (or whatever the viewport is called in cctv)
|
||||
- [x] Protable .jar which can be run with **JRE 17**
|
||||
|
||||
|
||||
### Author(s):
|
||||
- rattatwinko
|
||||
@@ -1,192 +0,0 @@
|
||||
package io.swtc;
|
||||
|
||||
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.graphics.Font;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.*;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.List;
|
||||
|
||||
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) {
|
||||
Display display = new Display();
|
||||
Shell shell = new Shell(display);
|
||||
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();
|
||||
int columnCount = Math.min(3, Math.max(1, webcams.size()));
|
||||
|
||||
GridLayout mainLayout = new GridLayout(columnCount, true);
|
||||
mainLayout.marginWidth = 20;
|
||||
mainLayout.marginHeight = 20;
|
||||
shell.setLayout(mainLayout);
|
||||
|
||||
// Header Section
|
||||
Composite header = new Composite(shell, SWT.NONE);
|
||||
header.setLayout(new GridLayout(2, false));
|
||||
header.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, columnCount, 1));
|
||||
|
||||
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()) {
|
||||
Label note = new Label(shell, SWT.NONE);
|
||||
note.setText("No cameras detected. Add an IP camera to begin.");
|
||||
} else {
|
||||
for (Webcam webcam : webcams) {
|
||||
createCameraCard(shell, display, webcam);
|
||||
}
|
||||
}
|
||||
|
||||
shell.layout(true, true);
|
||||
}
|
||||
|
||||
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);
|
||||
card.setText(webcam.getName());
|
||||
card.setLayout(new GridLayout(2, false));
|
||||
card.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
|
||||
|
||||
Label info = new Label(card, SWT.WRAP);
|
||||
info.setText("Type: " + (isIpCam ? "Network IP" : "Local USB"));
|
||||
info.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
|
||||
|
||||
Button viewBtn = new Button(card, SWT.PUSH);
|
||||
viewBtn.setText("Launch");
|
||||
viewBtn.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
|
||||
viewBtn.addListener(SWT.Selection, e -> new CameraWindow(display, webcam).open());
|
||||
|
||||
Button deleteBtn = new Button(card, SWT.PUSH);
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
package io.swtc;
|
||||
|
||||
import com.github.sarxos.webcam.Webcam;
|
||||
import io.swtc.proccessing.CameraRenderer;
|
||||
import io.swtc.proccessing.WebcamCaptureLoop;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.layout.FillLayout;
|
||||
import org.eclipse.swt.opengl.GLData;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
|
||||
public class CameraWindow {
|
||||
private final Shell shell;
|
||||
private final CameraRenderer renderer;
|
||||
private final WebcamCaptureLoop captureLoop;
|
||||
|
||||
public CameraWindow(Display display, Webcam webcam) {
|
||||
this.shell = new Shell(display);
|
||||
this.shell.setText("swt-cctv@" + webcam.getName());
|
||||
this.shell.setLayout(new FillLayout());
|
||||
this.shell.setSize(640, 480);
|
||||
|
||||
GLData data = new GLData();
|
||||
data.doubleBuffer = true;
|
||||
this.renderer = new CameraRenderer(shell, data);
|
||||
|
||||
// this was inefficient before
|
||||
this.captureLoop = new WebcamCaptureLoop(webcam, (BufferedImage img) -> {
|
||||
if (!display.isDisposed() && !shell.isDisposed()) {
|
||||
display.asyncExec(() -> {
|
||||
if (!shell.isDisposed()) {
|
||||
// render the image to the shell using gl
|
||||
renderer.render(img);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.shell.addListener(SWT.Close, event -> {
|
||||
captureLoop.stop();
|
||||
});
|
||||
}
|
||||
|
||||
public void open() {
|
||||
shell.open();
|
||||
renderer.getCanvas().setCurrent();
|
||||
captureLoop.start();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Display display = new Display();
|
||||
Webcam webcam = Webcam.getDefault();
|
||||
|
||||
CameraWindow window = new CameraWindow(display, webcam);
|
||||
window.open();
|
||||
|
||||
while (!window.shell.isDisposed()) {
|
||||
if (!display.readAndDispatch()) {
|
||||
display.sleep();
|
||||
}
|
||||
}
|
||||
display.dispose();
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,6 @@ public class Main {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
System.out.println("Arg " + i + ": " + args[i]);
|
||||
}
|
||||
|
||||
if (args.length > 0 && "swing".equalsIgnoreCase(args[0])) {
|
||||
SwingCCTVManager.main(new String[0]);
|
||||
} else {
|
||||
CCTVManager.main(new String[0]);
|
||||
}
|
||||
SwingCCTVManager.main(null);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user