first commit
This commit is contained in:
122
src/main/java/Camera/GrabbingTask.java
Normal file
122
src/main/java/Camera/GrabbingTask.java
Normal file
@@ -0,0 +1,122 @@
|
||||
package Camera;
|
||||
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import Other.SomeCodes;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bytedeco.javacv.Frame;
|
||||
import org.bytedeco.javacv.FrameGrabber;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
|
||||
public class GrabbingTask implements Runnable {
|
||||
@Setter private Consumer<String> onMessageUpdate;
|
||||
@Setter private Consumer<Mat> onMatUpdate;
|
||||
@Setter private Consumer<Frame> onFrameUpdate;
|
||||
@Setter private Consumer<String> onBase64Update;
|
||||
@Setter private Consumer<String> onStreamingStatusUpdate;
|
||||
|
||||
private final AtomicBoolean isGrabbing;
|
||||
private final FrameGrabber grabber;
|
||||
@Getter private final int lowquality_width = 640;
|
||||
@Getter private final int lowquality_height = 360;
|
||||
@Getter @Setter private boolean HQ = false;
|
||||
@Getter private int streaming_width = 0;
|
||||
@Getter private int streaming_height = 0;
|
||||
@Getter private int streaming_fps = 0;
|
||||
AtomicBoolean streamingstatuschanged = new AtomicBoolean(false);
|
||||
|
||||
private void updateMessage(String message) {
|
||||
if (onMessageUpdate != null) {
|
||||
onMessageUpdate.accept(message);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateMat(Mat value) {
|
||||
if (onMatUpdate != null) {
|
||||
onMatUpdate.accept(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateBase64(String base64) {
|
||||
if (onBase64Update != null) {
|
||||
onBase64Update.accept(base64);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateFrame(Frame frame) {
|
||||
if (onFrameUpdate != null) {
|
||||
onFrameUpdate.accept(frame);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateStreamingStatus(String status) {
|
||||
if (onStreamingStatusUpdate != null) {
|
||||
onStreamingStatusUpdate.accept(status);
|
||||
}
|
||||
}
|
||||
|
||||
public GrabbingTask(AtomicBoolean isGrabbing, FrameGrabber grabber) {
|
||||
this.isGrabbing = isGrabbing;
|
||||
this.grabber = grabber;
|
||||
}
|
||||
|
||||
public String GetStreamingStatus(){
|
||||
return "Streaming at " + streaming_width + "x" + streaming_height + " " + streaming_fps + "fps";
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
isGrabbing.set(true);
|
||||
AtomicInteger framecount = new AtomicInteger(0);
|
||||
TimerTask task = new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (streaming_fps != framecount.get()) {
|
||||
streaming_fps = framecount.get();
|
||||
streamingstatuschanged.set(true);
|
||||
}
|
||||
framecount.set(0);
|
||||
if (streamingstatuschanged.get()) {
|
||||
updateStreamingStatus(GetStreamingStatus());
|
||||
streamingstatuschanged.set(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
Timer timer = new Timer();
|
||||
timer.scheduleAtFixedRate(task, 1000, 1000);
|
||||
while (isGrabbing.get()) {
|
||||
try {
|
||||
//Thread.sleep(100); // 10 fps
|
||||
Frame fr =grabber.grab();
|
||||
if (fr!=null){
|
||||
if (!HQ) fr = SomeCodes.ResizeFrame(fr, lowquality_width, lowquality_height);
|
||||
updateFrame(fr);
|
||||
updateBase64(SomeCodes.BufferedImageToBase64(SomeCodes.FrameToBufferedImage(fr)));
|
||||
Mat mat = SomeCodes.matConverter.convert(fr);
|
||||
updateMat(mat);
|
||||
if (streaming_width != fr.imageWidth) {
|
||||
streaming_width = fr.imageWidth;
|
||||
streamingstatuschanged.set(true);
|
||||
}
|
||||
if (streaming_height != fr.imageHeight) {
|
||||
streaming_height = fr.imageHeight;
|
||||
streamingstatuschanged.set(true);
|
||||
}
|
||||
framecount.incrementAndGet();
|
||||
|
||||
} else updateMessage("Grabber returned null frame");
|
||||
} catch (Exception e) {
|
||||
updateMessage("Error grabbing frame: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
117
src/main/java/Camera/PanTiltController.java
Normal file
117
src/main/java/Camera/PanTiltController.java
Normal file
@@ -0,0 +1,117 @@
|
||||
package Camera;
|
||||
|
||||
import com.fazecast.jSerialComm.SerialPort;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
/**
|
||||
* Pan Tilt Controller
|
||||
* Using PelcoD protocol
|
||||
* Source : https://www.commfront.com/pages/pelco-d-protocol-tutorial
|
||||
*/
|
||||
public class PanTiltController {
|
||||
private final SerialPort serialPort;
|
||||
private final byte cameraid;
|
||||
/**
|
||||
* Open Pan Tilt Controller
|
||||
* @param portname serial port name used
|
||||
* @param baudrate baudrate used
|
||||
*/
|
||||
public PanTiltController(String portname, int baudrate, int cameraid){
|
||||
serialPort = SerialPort.getCommPort(portname);
|
||||
serialPort.setBaudRate(baudrate);
|
||||
this.cameraid = (byte)cameraid;
|
||||
if (serialPort.openPort()){
|
||||
Logger.info("Serial Port {} opened successfully at {}", portname, baudrate);
|
||||
} else {
|
||||
Logger.info("Failed to open Serial Port {} at {}", portname, baudrate);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close Pan Tilt Controller
|
||||
*/
|
||||
public void Close(){
|
||||
serialPort.closePort();
|
||||
Logger.info("Serial Port closed");
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop Pan Tilt Movement
|
||||
*/
|
||||
public void StopMovement(){
|
||||
byte[] command = new byte[]{0, cameraid, 0, 0, 0, 0, 0};
|
||||
command[6] = Checksum(command); // add checksum
|
||||
command[0] = (byte) 0xFF; // add synchronization byte
|
||||
serialPort.writeBytes(command, command.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pan Left
|
||||
* @param speed speed of movement, 0-63
|
||||
*/
|
||||
public void PanLeft(byte speed){
|
||||
if (speed<0) speed = 0;
|
||||
if (speed>0x3F) speed = 0x3F;
|
||||
|
||||
byte[] command = new byte[]{0, cameraid, 0, 4, speed, 0, 0};
|
||||
command[6] = Checksum(command); // add checksum
|
||||
command[0] = (byte) 0xFF; // add synchronization byte
|
||||
serialPort.writeBytes(command, command.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pan Right
|
||||
* @param speed speed of movement, 0-63
|
||||
*/
|
||||
public void PanRight(byte speed){
|
||||
if (speed<0) speed = 0;
|
||||
if (speed>0x3F) speed = 0x3F;
|
||||
|
||||
byte[] command = new byte[]{0, cameraid, 0, 2, speed, 0, 0};
|
||||
command[6] = Checksum(command); // add checksum
|
||||
command[0] = (byte) 0xFF; // add synchronization byte
|
||||
serialPort.writeBytes(command, command.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tilt Up
|
||||
* @param speed speed of movement, 0-63
|
||||
*/
|
||||
public void TiltUp(byte speed){
|
||||
if (speed<0) speed = 0;
|
||||
if (speed>0x3F) speed = 0x3F;
|
||||
|
||||
byte[] command = new byte[]{0, cameraid, 0, 8, speed, 0, 0};
|
||||
command[6] = Checksum(command); // add checksum
|
||||
command[0] = (byte) 0xFF; // add synchronization byte
|
||||
serialPort.writeBytes(command, command.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tilt Down
|
||||
* @param speed speed of movement, 0-63
|
||||
*/
|
||||
public void TiltDown(byte speed){
|
||||
if (speed<0) speed = 0;
|
||||
if (speed>0x3F) speed = 0x3F;
|
||||
|
||||
byte[] command = new byte[]{0, cameraid, 0, 16, speed, 0, 0};
|
||||
command[6] = Checksum(command); // add checksum
|
||||
command[0] = (byte) 0xFF; // add synchronization byte
|
||||
serialPort.writeBytes(command, command.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sum of bytes, then modulo by 256
|
||||
* @param data data to be summed
|
||||
* @return checksum
|
||||
*/
|
||||
private byte Checksum(byte[] data){
|
||||
int sum = 0;
|
||||
for (byte b : data){
|
||||
sum += b;
|
||||
}
|
||||
|
||||
return (byte)(sum % 256);
|
||||
}
|
||||
}
|
||||
11
src/main/java/Camera/RtspEvent.java
Normal file
11
src/main/java/Camera/RtspEvent.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package Camera;
|
||||
|
||||
import org.bytedeco.javacv.Frame;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
|
||||
public interface RtspEvent {
|
||||
void onMatReceived(Mat mat);
|
||||
void onFrameReceived(Frame frame);
|
||||
void onBase64Received(String base64);
|
||||
void onStreamingStatusReceived(String status);
|
||||
}
|
||||
120
src/main/java/Camera/RtspGrabber.java
Normal file
120
src/main/java/Camera/RtspGrabber.java
Normal file
@@ -0,0 +1,120 @@
|
||||
package Camera;
|
||||
import lombok.Getter;
|
||||
import org.bytedeco.ffmpeg.global.avutil;
|
||||
import org.bytedeco.javacv.FFmpegFrameGrabber;
|
||||
import org.bytedeco.javacv.Frame;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class RtspGrabber {
|
||||
private final String rtspUrl;
|
||||
private FFmpegFrameGrabber grabber;
|
||||
private final AtomicBoolean isGrabbing = new AtomicBoolean(false);
|
||||
private @Getter Frame lastFrame = null;
|
||||
private @Getter String lastBase64 = null;
|
||||
private @Getter Mat lastMat = null;
|
||||
private GrabbingTask grabbingTask = null;
|
||||
|
||||
public RtspGrabber(String ip, int port, String username, String password, String path) {
|
||||
rtspUrl = "rtsp://" + username + ":" + password + "@" + ip + ":" + port + path;
|
||||
Logger.info("RtspGrabber created with url: " + rtspUrl);
|
||||
|
||||
}
|
||||
|
||||
public RtspGrabber(String ip, String path) {
|
||||
this.rtspUrl = "rtsp://" + ip + path;
|
||||
Logger.info("RtspGrabber created with url: " + rtspUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start grabbing frames from rtsp
|
||||
* @param useTcp Use tcp instead of udp
|
||||
* @param event Event to be called when frame is received
|
||||
*/
|
||||
public void Start(boolean useTcp, final int width, final int height, RtspEvent event){
|
||||
|
||||
try{
|
||||
grabber = FFmpegFrameGrabber.createDefault(rtspUrl);
|
||||
if (useTcp) grabber.setOption("rtsp_transport", "tcp");
|
||||
//grabber.setImageWidth(width);
|
||||
//grabber.setImageHeight(height);
|
||||
|
||||
grabber.setPixelFormat(avutil.AV_PIX_FMT_BGR24);
|
||||
grabber.start();
|
||||
avutil.av_log_set_level(avutil.AV_LOG_ERROR);
|
||||
|
||||
|
||||
|
||||
Logger.info("Grabber started");
|
||||
GrabbingTask tt = new GrabbingTask(isGrabbing, grabber);
|
||||
tt.setOnMessageUpdate(Logger::info);
|
||||
tt.setOnMatUpdate(value -> {
|
||||
// Kalau butuh Mat untuk diproses
|
||||
lastMat = value;
|
||||
if (event!=null) event.onMatReceived(value);
|
||||
});
|
||||
tt.setOnFrameUpdate(value -> {
|
||||
// Kalau butuh Frame untuk ditampilkan
|
||||
lastFrame = value;
|
||||
|
||||
if (event!=null) event.onFrameReceived(value);
|
||||
});
|
||||
tt.setOnBase64Update(value -> {
|
||||
// Kalau butuh Base64 untuk dikirim ke Websocket
|
||||
lastBase64 = value;
|
||||
if (event!=null) event.onBase64Received(value);
|
||||
});
|
||||
tt.setOnStreamingStatusUpdate(value -> {
|
||||
// Kalau butuh status streaming
|
||||
if (event!=null) event.onStreamingStatusReceived(value);
|
||||
});
|
||||
|
||||
new Thread(tt).start();
|
||||
grabbingTask = tt;
|
||||
|
||||
} catch (Exception e){
|
||||
Logger.error("Error starting grabber: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop grabbing frames
|
||||
*/
|
||||
public void Stop(){
|
||||
if (grabber!=null) {
|
||||
try{
|
||||
isGrabbing.set(false);
|
||||
grabber.stop();
|
||||
Logger.info("Grabber stopped");
|
||||
} catch (Exception e){
|
||||
Logger.error("Error stopping grabber: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if grabber is grabbing
|
||||
* @return True if grabbing
|
||||
*/
|
||||
public boolean IsGrabbing(){
|
||||
return isGrabbing.get();
|
||||
}
|
||||
|
||||
public void ChangeVideoQuality(boolean HQ){
|
||||
if (IsGrabbing()){
|
||||
if (grabbingTask!=null){
|
||||
grabbingTask.setHQ(HQ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String GetStreamingStatus(){
|
||||
if (grabbingTask!=null){
|
||||
return grabbingTask.GetStreamingStatus();
|
||||
}
|
||||
return "No Status";
|
||||
}
|
||||
}
|
||||
348
src/main/java/Camera/VapixProtocol.java
Normal file
348
src/main/java/Camera/VapixProtocol.java
Normal file
@@ -0,0 +1,348 @@
|
||||
package Camera;
|
||||
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.awt.*;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static Other.SomeCodes.ValidInteger;
|
||||
import static Other.SomeCodes.ValidString;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class VapixProtocol {
|
||||
|
||||
private final String url;
|
||||
private final HttpClient client;
|
||||
private String parameters;
|
||||
|
||||
private String ProductNumberValue = "";
|
||||
private String SerialNumberValue = "";
|
||||
private int CameraIDValue = 0;
|
||||
private int MaxZoomValue = 0;
|
||||
private int MinZoomValue = 0;
|
||||
private boolean PTZEnabledValue = false;
|
||||
private String[] ImageResolutions = new String[0];
|
||||
private String[] ImageFormats = new String[0];
|
||||
private int CurrentZoomValue = 0;
|
||||
|
||||
/**
|
||||
* Create a new VapixProtocol object
|
||||
* @param ip The IP address of the camera
|
||||
* @param port The HTTP port of the camera
|
||||
* @param username The username to access the camera (optional)
|
||||
* @param password The password to access the camera (optional)
|
||||
*/
|
||||
public VapixProtocol(String ip, int port, String username, String password) {
|
||||
url = "http://" + ip + ":" + port+"/axis-cgi/";
|
||||
String auth = username + ":" + password;
|
||||
//encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));
|
||||
client = HttpClient.newHttpClient();
|
||||
GetParameters(null);
|
||||
if (ValidString(parameters)){
|
||||
Pattern ProductNumber = Pattern.compile(".*ProdNbr=(.*)");
|
||||
Matcher m1 = ProductNumber.matcher(parameters);
|
||||
if (m1.find()) ProductNumberValue = m1.group(1);
|
||||
Pattern SerialNumber = Pattern.compile(".*SerialNumber=(.*)");
|
||||
Matcher m2 = SerialNumber.matcher(parameters);
|
||||
if (m2.find()) SerialNumberValue = m2.group(1);
|
||||
Pattern PTZCamId = Pattern.compile(".*CamId=(.*)");
|
||||
Matcher m3 = PTZCamId.matcher(parameters);
|
||||
if (m3.find()) {
|
||||
String value = m3.group(1);
|
||||
if (ValidInteger(value)) CameraIDValue = Integer.parseInt(value);
|
||||
}
|
||||
Pattern PTZMaxZoom = Pattern.compile(".*MaxZoom=(.*)");
|
||||
Matcher m4 = PTZMaxZoom.matcher(parameters);
|
||||
if (m4.find()) {
|
||||
String value = m4.group(1);
|
||||
if (ValidInteger(value)) MaxZoomValue = Integer.parseInt(value);
|
||||
}
|
||||
Pattern PTZMinZoom = Pattern.compile(".*MinZoom=(.*)");
|
||||
Matcher m5 = PTZMinZoom.matcher(parameters);
|
||||
if (m5.find()) {
|
||||
String value = m5.group(1);
|
||||
if (ValidInteger(value)) MinZoomValue = Integer.parseInt(value);
|
||||
}
|
||||
Pattern PTZEnabled = Pattern.compile(".*PTZ.PTZ=(.*)");
|
||||
Matcher m6 = PTZEnabled.matcher(parameters);
|
||||
if (m6.find()) PTZEnabledValue = m6.group(1).contains("yes");
|
||||
Pattern Resolution = Pattern.compile(".*Image.Resolution=(.*)");
|
||||
Matcher m7 = Resolution.matcher(parameters);
|
||||
if (m7.find()) {
|
||||
String value = m7.group(1);
|
||||
if (ValidString(value)) ImageResolutions = value.split(",");
|
||||
//Logger.info("Resolution: "+value);
|
||||
}
|
||||
Pattern Format = Pattern.compile(".*Image.Format=(.*)");
|
||||
Matcher m8 = Format.matcher(parameters);
|
||||
if (m8.find()) {
|
||||
String value = m8.group(1);
|
||||
if (ValidString(value)) ImageFormats = value.split(",");
|
||||
//Logger.info("Format: "+value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private void GetParameters(String group){
|
||||
String command = url+"param.cgi?action=list";
|
||||
if (ValidString(group)) command+="&group="+group;
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(java.net.URI.create(command))
|
||||
.build();
|
||||
parameters = "";
|
||||
try{
|
||||
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
if (response.statusCode()==200){
|
||||
parameters = response.body();
|
||||
} else Logger.info("Error getting parameters: "+response.statusCode());
|
||||
} catch (Exception e){
|
||||
Logger.error("Error getting parameters: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Product Number of the camera
|
||||
* @return Product Number, or empty string if not available
|
||||
*/
|
||||
public String GetProductNumber(){
|
||||
return ProductNumberValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Serial Number of the camera
|
||||
* @return Serial Number, or empty string if not available
|
||||
*/
|
||||
public String GetSerialNumber(){
|
||||
return SerialNumberValue;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get PTZ Camera ID
|
||||
* @return Camera ID
|
||||
*/
|
||||
public int GetPTZCameraID(){
|
||||
return CameraIDValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Maximum Zoom Value
|
||||
* @return Maximum Zoom Value
|
||||
*/
|
||||
public int GetPTZMaxZoom(){
|
||||
return MaxZoomValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Minimum Zoom Value
|
||||
* @return Minimum Zoom Value
|
||||
*/
|
||||
public int GetPTZMinZoom(){
|
||||
return MinZoomValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if PTZ Control enabled for this camera
|
||||
* @return true if PTZ Control enabled, false otherwise
|
||||
*/
|
||||
public boolean PTZEnabled() {
|
||||
return PTZEnabledValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Available Image Resolutions
|
||||
* @return array of String, in format "widthxheight"
|
||||
*/
|
||||
public String[] GetImageResolutions(){
|
||||
return ImageResolutions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Available Image Formats
|
||||
* @return array of String, example "jpeg","mjpeg","h264","bitmap"
|
||||
*/
|
||||
public String[] GetImageFormats(){
|
||||
return ImageFormats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close VapiX Protocol
|
||||
*/
|
||||
public void Close(){
|
||||
if (client!=null) client.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zoom In / Out
|
||||
* @param cameraid Camera ID, get it from GetPTZCameraID()
|
||||
* @param zoom Zoom value, value between GetPTZMinZoom and GetPTZMaxZoom()
|
||||
* @return true if successful, false otherwise
|
||||
*/
|
||||
public boolean Zoom(int cameraid, int zoom){
|
||||
if (zoom < MinZoomValue) zoom = MinZoomValue;
|
||||
if (zoom > MaxZoomValue) zoom = MaxZoomValue;
|
||||
String command = url+"com/ptz.cgi?zoom="+zoom+"&camera="+cameraid;
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(java.net.URI.create(command))
|
||||
.build();
|
||||
try{
|
||||
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
if (response.statusCode()==200){
|
||||
Logger.info("Zoom: "+response.body());
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e){
|
||||
Logger.error("Error zooming: "+e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Current Zoom Value
|
||||
* @return Current Zoom Value
|
||||
*/
|
||||
public int GetCurrentZoomValue(){
|
||||
update_ptz_query_position();
|
||||
return CurrentZoomValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Current Image Resolution
|
||||
* @param cameraid Camera ID, get it from GetPTZCameraID()
|
||||
* @return array of int, [0] = width, [1] = height
|
||||
*/
|
||||
public int[] GetCurrentResolution(int cameraid){
|
||||
int[] result = new int[]{0,0};
|
||||
String command = url+"imagesize.cgi?camera="+cameraid;
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(java.net.URI.create(command))
|
||||
.build();
|
||||
try{
|
||||
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
if (response.statusCode()==200){
|
||||
String values = response.body();
|
||||
//Something like this:
|
||||
//image width = 1920
|
||||
//image height = 1080
|
||||
for (String s : values.split("\n")) {
|
||||
String[] parts = s.split("=");
|
||||
if (parts.length==2){
|
||||
String part0 = parts[0].trim();
|
||||
String part1 = parts[1].trim();
|
||||
if (part0.contains("width")){
|
||||
if (ValidInteger(part1)) result[0] = Integer.parseInt(part1);
|
||||
}
|
||||
if (part0.contains("height")) {
|
||||
if (ValidInteger(part1)) result[1] = Integer.parseInt(part1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e){
|
||||
Logger.error("Error getting resolution: "+e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Image Resolution
|
||||
* @param cameraid Camera ID, get it from GetPTZCameraID()
|
||||
* @param width Width of the image
|
||||
* @param height Height of the image
|
||||
* @return true if successful, false otherwise
|
||||
*/
|
||||
public boolean SetResolution(int cameraid, int width, int height){
|
||||
String resolution = width+"x"+height;
|
||||
boolean supported = false;
|
||||
for(String r: ImageResolutions){
|
||||
if (r.equals(resolution)){
|
||||
supported = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (supported){
|
||||
String command = url+"imagesize.cgi?camera="+cameraid+"&resolution="+resolution;
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(java.net.URI.create(command))
|
||||
.build();
|
||||
try{
|
||||
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
if (response.statusCode()==200){
|
||||
|
||||
Logger.info("Resolution set: "+response.body());
|
||||
String values = response.body();
|
||||
//Something like this:
|
||||
//image width = 1920
|
||||
//image height = 1080
|
||||
boolean width_ok = false;
|
||||
boolean height_ok = false;
|
||||
for (String s : values.split("\n")) {
|
||||
String[] parts = s.split("=");
|
||||
if (parts.length==2){
|
||||
String part0 = parts[0].trim();
|
||||
String part1 = parts[1].trim();
|
||||
if (part0.contains("width")){
|
||||
if (ValidInteger(part1)) {
|
||||
if (Integer.parseInt(part1)==width)
|
||||
width_ok = true;
|
||||
else Logger.error("Width failed, target: "+width+" actual: "+part1);
|
||||
}
|
||||
}
|
||||
if (part0.contains("height")) {
|
||||
if (ValidInteger(part1)) {
|
||||
if (Integer.parseInt(part1)==height)
|
||||
height_ok = true;
|
||||
else Logger.error("Height failed, target: "+height+" actual: "+part1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return width_ok && height_ok;
|
||||
}
|
||||
} catch (Exception e){
|
||||
Logger.error("Error setting resolution: "+e.getMessage());
|
||||
}
|
||||
} else Logger.info("Resolution not supported: "+resolution);
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void update_ptz_query_position(){
|
||||
String command = url+"com/ptz.cgi?query=position";
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(java.net.URI.create(command))
|
||||
.build();
|
||||
try{
|
||||
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
if (response.statusCode()==200){
|
||||
String values = response.body();
|
||||
|
||||
//Something like this:
|
||||
//pan=0.0000
|
||||
//tilt=0.0000
|
||||
//zoom=1
|
||||
//iris=5000
|
||||
//focus=9574
|
||||
//brightness=5000
|
||||
//autofocus=on
|
||||
//autoiris=off
|
||||
for (String s : values.split("\n")) {
|
||||
String[] parts = s.split("=");
|
||||
if (parts.length==2){
|
||||
if (parts[0].equals("zoom")) CurrentZoomValue = Integer.parseInt(parts[1].trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e){
|
||||
Logger.error("Error getting PTZ position: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user