作者 钟来

模块整理

正在显示 29 个修改的文件 包含 675 行增加296 行删除
package com.zhonglai.luhui.smart.feeder.config;
import com.google.gson.Gson;
import com.ruoyi.common.utils.GsonConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import java.util.ArrayList;
import java.util.List;
//@Configuration
//public class HttpMessageConverterConfig {
// @Autowired
// public void configureHttpMessageConverters(HttpMessageConverters converters, Gson gson) {
// List<HttpMessageConverter<?>> converterList = new ArrayList<>(converters.getConverters());
// for (HttpMessageConverter<?> converter : converterList) {
// if (converter instanceof MappingJackson2HttpMessageConverter) {
// converterList.remove(converter);
// break;
// }
// }
//
// converterList.add(new GsonHttpMessageConverter(gson));
// }
//
//}
package com.zhonglai.luhui.smart.feeder.config;
import com.zhonglai.luhui.smart.feeder.dto.*;
/**
* 运行数据
*/
public class OperatingData {
public static SysConfig sysConfig = new SysConfig(); //系统配置
public static CameraData cameraData = new CameraData(); //摄像头数据
public static CameraConfig cameraConfig = new CameraConfig() ; //摄像头配置
public static FeederData feederData = new FeederData() ; //投料机数据
public static FeederConfig feederConfig = new FeederConfig() ; //投料机配置
}
... ...
... ... @@ -2,7 +2,7 @@ package com.zhonglai.luhui.smart.feeder.config.manager;
import com.zhonglai.luhui.smart.feeder.service.SrsService;
import com.zhonglai.luhui.smart.feeder.service.EhCacheService;
import com.zhonglai.luhui.smart.feeder.service.SerialPortService;
import com.zhonglai.luhui.smart.feeder.service.device.SerialPortService;
import com.zhonglai.luhui.smart.feeder.service.TerminalService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
... ...
package com.zhonglai.luhui.smart.feeder.controller;
import com.fazecast.jSerialComm.SerialPort;
import com.ruoyi.common.core.domain.AjaxResult;
import com.zhonglai.luhui.smart.feeder.dto.ConfigDto;
import com.zhonglai.luhui.smart.feeder.dto.commd.*;
import com.zhonglai.luhui.smart.feeder.service.DeviceService;
import com.zhonglai.luhui.smart.feeder.service.SerialPortService;
import com.zhonglai.luhui.smart.feeder.service.device.SerialPortService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
... ...
package com.zhonglai.luhui.smart.feeder.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.ArrayList;
@Data
@Accessors(chain = true) //链式写法
public class CameraConfig {
/**
* 摄像头编号
*/
private Integer captureNumber;
/**
* 摄像头接口类型
* USB(通过控制盒子上的usb接口连接)
* RTSP(通过局域网ip为192.168.0.198并且支持rtsp直播协议的摄像头连接)
*/
private String cameraInterfaceType;
/**
* 反光阈值
*/
private Integer reflectionThreshold;
/**
* 去噪调整内核大小,用来消除小的物体或噪声
*/
private Integer kernelSize;
/**
* 最大反光阈值
*/
private Integer maxValue;
/**
* 斜率范围对应的档位
*/
private ArrayList<FishCurveControlCondition> absValue_command;
/**
* 是否显示原图
*/
private Boolean veiwDto_isFrame;
/**
* 是否显示临时图
*/
private Boolean veiwDto_isBinaryImage;
/**
* 是否显示面积
*/
private Boolean veiwDto_isSize;
/**
* 是否显示斜率
*/
private Boolean veiwDto_isAbsValue;
/**
* 鱼群图像识别的频率
*/
private Long identificationFrequency;
/**
* 鱼群图像识别是否开启
*/
private Boolean fishGroupImageRecognition;
/**
* 鱼群图像识别投料控制是否开启
*/
private Boolean feedingControl;
}
... ...
package com.zhonglai.luhui.smart.feeder.dto;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true) //链式写法
public class CameraData {
/**
* 斜率
*/
private Double absValue;
/**
* 面积大小
*/
private Integer size;
/**
* 视频是否打开
*/
private boolean videoIsOpen;
}
... ...
package com.zhonglai.luhui.smart.feeder.dto;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true) //链式写法
public class FeederConfig {
private SerialPortConfig serialPortConfig;
}
... ...
package com.zhonglai.luhui.smart.feeder.dto;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true) //链式写法
public class FeederData {
}
... ...
package com.zhonglai.luhui.smart.feeder.dto;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true) //链式写法
public class SysConfig {
/**
* 是否上报数据
*/
private Boolean ifUpLoadData;
/**
* 是否显示
*/
private Boolean ifVeiw;
}
... ...
package com.zhonglai.luhui.smart.feeder.dto.mqtt;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
@Data
@Accessors(chain = true) //链式写法
public class CfgdataRequest {
private String cmd; //操作指令 devicedata
private String type; //设备网络型号 字符串("4G.hs")
private Condata condata;
private Info info;
private List<Integer[]> timer; //开启、关闭、使能 8:00开启-9:00关闭,状态:启用
}
... ...
package com.zhonglai.luhui.smart.feeder.dto.mqtt;
import io.swagger.models.auth.In;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true) //链式写法
public class CfgdataResponse {
private String cmd; //操作指令 devicedata
private String type; //设备网络型号 字符串("4G.hs")
private Integer backstate; //返回状态
private Integer errorcode; //错误代码
}
... ...
package com.zhonglai.luhui.smart.feeder.dto.mqtt;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true) //链式写法
public class Condata
{
private Integer runmode; //运行模式 0手动、1自动
private Integer runspeed; //运行速度(档位) 0-99档
private Integer worktime; //工作时间 1-18秒
private Integer interval; //时间间隔 1-18秒
private Integer runstate; //运行状态 1运行、3停止(平台可以设置0启动中,2关闭中,4异常)
private Integer stopfeedcnt; //手动投料倒计时时间 单位分
private Integer onoff; //运行状态 1运行、3停止(平台可以设置0启动中,2关闭中,4异常)
}
... ...
package com.zhonglai.luhui.smart.feeder.dto.mqtt;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
@Data
@Accessors(chain = true) //链式写法
public class DevicedatRequest {
private String cmd; //操作指令 devicedata
private String type; //设备网络型号 字符串("4G.hs")
private String signal; //信号量
private String machstate; //机器状态
private String battlevel; //电池电量
private Condata condata;
private Info info;
private List<Integer[]> timer; //开启、关闭、使能 8:00开启-9:00关闭,状态:启用
}
... ...
package com.zhonglai.luhui.smart.feeder.dto.mqtt;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true) //链式写法
public class DevicedatResponse {
private String cmd; //操作指令 devicedata
private String type; //设备网络型号 字符串("4G.hs")
private Integer backstate; //返回状态
private Integer errorcode; //错误代码
}
... ...
package com.zhonglai.luhui.smart.feeder.dto.mqtt;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true) //链式写法
public class Info
{
private String mfrs; //厂家名称 字符串("中渔科技")
private Integer equitype; //设备网络型号 0:投料机,1:增氧机,2:网络摄像头云台控制器
private Integer equimode; //设备子类型 0:振动式,1:螺旋式A,2:螺旋式B
private Integer faultcode; //故障代码 0正常,1-99故障
private Integer fodderstate; //饲料状态 0无料,1有料
private Float fodderweight; //饲料重量 0-9999(0-999)公斤
private Integer feednum; //投料次数 1-N
private Integer feedweight; //本次投料量 0-9999公斤
}
\ No newline at end of file
... ...
package com.zhonglai.luhui.smart.feeder.dto.mqtt;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true) //链式写法
public class ManualcontrolRequest {
private String cmd; //操作指令 devicedata
private String type; //设备网络型号 字符串("4G.hs")
private Condata condata;
}
... ...
package com.zhonglai.luhui.smart.feeder.dto.mqtt;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true) //链式写法
public class ManualcontrolResponse {
private String cmd; //操作指令 devicedata
private String type; //设备网络型号 字符串("4G.hs")
private Integer backstate; //返回状态
private Integer errorcode; //错误代码
}
... ...
... ... @@ -24,87 +24,7 @@ public class OpenCVUtil {
}
public static VideoCapture readVideoCaptureForRtsp()
{
// FFmCameraService fFmCameraService = new FFmCameraService();
// String ip = fFmCameraService.findCameraIp();
String ip = "192.168.0.198";
if(StringUtils.isEmpty(ip))
{
logger.info("未检测到摄像头{},尝试打开本地视频",MP4_FILE_PATH);
//如果找不到摄像头就找本地视频文件
File file = new File(MP4_FILE_PATH);
if(file.exists() && file.isFile())
{
VideoCapture videoCapture = OpenCVUtil.readVideoCaptureForVideo(MP4_FILE_PATH);
return videoCapture;
}
logger.info("未检测到摄像头!!!");
}
String rtspUrl = "rtsp://admin:Luhui586@"+ip+":554/h264/ch1/main/av_stream";
VideoCapture videoCapture = new VideoCapture(rtspUrl);
while (!videoCapture.isOpened())
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
return videoCapture;
}
public static VideoCapture readVideoCaptureForVideo(int i)
{
logger.info("初始化摄像头");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
VideoCapture videoCapture = new VideoCapture();
boolean isopen = videoCapture.open(i);
if(isopen)
{
logger.info("打开化摄像头"+i+"成功");
return videoCapture;
}else {
logger.info("打开化摄像头"+i+"失败");
}
return null;
}
private static final String MP4_FILE_PATH = "D:/lh-smart-feeder/mp4/2.mp4";
public static VideoCapture openCapture()
{
for(int i=0;i<10;i++)
{
VideoCapture videoCapture = readVideoCaptureForVideo(i);
if(null != videoCapture)
{
return videoCapture; //拿到的第一个摄像头返回
}
}
logger.info("未检测到摄像头{},尝试打开本地视频",MP4_FILE_PATH);
//如果找不到摄像头就找本地视频文件
File file = new File(MP4_FILE_PATH);
if(file.exists() && file.isFile())
{
VideoCapture videoCapture = OpenCVUtil.readVideoCaptureForVideo(MP4_FILE_PATH);
return videoCapture;
}
logger.info("未检测到摄像头!!!");
return null;
}
public static VideoCapture readVideoCaptureForVideo(String videoPath )
{
// 创建VideoCapture对象
VideoCapture videoCapture = new VideoCapture();
boolean isopen = videoCapture.open(videoPath);
System.out.println(isopen);
return videoCapture;
}
/**
* 抠图
... ...
... ... @@ -2,15 +2,11 @@ package com.zhonglai.luhui.smart.feeder.service;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonObject;
import com.ruoyi.common.utils.GsonConstructor;
import com.zhonglai.luhui.smart.feeder.Main;
import com.zhonglai.luhui.smart.feeder.dto.ConfigurationParameter;
import com.zhonglai.luhui.smart.feeder.dto.ModbusDto;
import com.zhonglai.luhui.smart.feeder.dto.StateData;
import com.zhonglai.luhui.smart.feeder.dto.VeiwDto;
import com.zhonglai.luhui.smart.feeder.dto.commd.FeederCommd03Response;
import com.zhonglai.luhui.smart.feeder.dto.commd.FeederCommdDto;
import com.zhonglai.luhui.smart.feeder.service.device.SerialPortService;
import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.slf4j.Logger;
... ... @@ -18,8 +14,6 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
... ...
... ... @@ -2,6 +2,7 @@ package com.zhonglai.luhui.smart.feeder.service;
import com.ruoyi.common.utils.GsonConstructor;
import com.zhonglai.luhui.smart.feeder.dto.*;
import com.zhonglai.luhui.smart.feeder.service.device.SerialPortService;
import com.zhonglai.luhui.smart.feeder.util.FeederCommd06ResponseType;
import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil;
import org.slf4j.Logger;
... ...
... ... @@ -2,11 +2,13 @@ package com.zhonglai.luhui.smart.feeder.service;
import cn.hutool.core.util.ArrayUtil;
import com.ruoyi.common.utils.StringUtils;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.*;
import org.bytedeco.javacv.Frame;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.awt.*;
... ... @@ -14,6 +16,8 @@ import java.awt.image.BufferedImage;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Service
public class FFmCameraService {
... ... @@ -23,6 +27,11 @@ public class FFmCameraService {
private OpenCVFrameConverter.ToOrgOpenCvCoreMat converter2 = new OpenCVFrameConverter.ToOrgOpenCvCoreMat();
@Autowired
private ScheduledExecutorService scheduledExecutorService;
@Autowired
private SrsService srsService;
private static String MAC = "78-a6-a0-d2-bd-e1";
... ... @@ -37,6 +46,58 @@ public class FFmCameraService {
loadCamera();
}
public static void main(String[] args) {
pushCamera();
}
public static void pushCamera()
{
String ip = "192.168.0.198";
String inputUrl = "rtsp://admin:Luhui586@" + ip + ":554/h264/ch1/main/av_stream";
String outputUrl = "rtmp://119.23.218.181:21935/live/70094a59d1d991d";
try {
FFmpegFrameGrabber.tryLoad();
} catch (Exception e) {
throw new RuntimeException("Failed to load FFmpeg", e);
}
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputUrl);
grabber.setVideoOption("fflags", "nobuffer");
grabber.setVideoOption("rtsp_transport", "tcp");
grabber.setOption("stimeout", "2000000");
avutil.av_log_set_level(avutil.AV_LOG_ERROR);
try {
grabber.start();
Frame frame = grabber.grabImage();
while (0 == frame.imageWidth)
{
Thread.sleep(1000);
}
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputUrl, frame.imageWidth, frame.imageHeight);
recorder.setFormat("flv");
recorder.setFrameRate(30);
recorder.setVideoBitrate(2000000);
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
recorder.start();
Frame capturedFrame;
while ((capturedFrame = grabber.grabImage()) != null) {
recorder.record(capturedFrame);
}
grabber.stop();
recorder.stop();
System.out.println("摄像头流推送完成");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 加载摄像头
*/
... ... @@ -59,6 +120,7 @@ public class FFmCameraService {
grabber = new FFmpegFrameGrabber(rtspUrl);
grabber.setVideoOption("fflags", "nobuffer"); // 禁用缓冲
grabber.setVideoOption("rtsp_transport", "tcp"); // 使用TCP传输
grabber.setOption("stimeout", "2000000");
avutil.av_log_set_level(avutil.AV_LOG_ERROR); // 设置日志级别
try {
... ... @@ -67,6 +129,18 @@ public class FFmCameraService {
close();
e.printStackTrace();
}
// scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
// @Override
// public void run() {
// if()
// {
// srsService.push(getFrame());
// }
//
// }
// },0,0, TimeUnit.MILLISECONDS);
}
public Boolean isOk()
... ... @@ -119,9 +193,9 @@ public class FFmCameraService {
Frame frame = null;
try {
frame = grabber.grabImage();
if (frame == null) {
if (frame == null || frame.imageHeight==0) {
//TODO:连续n次为null,进行重连
System.out.println("frame is null");
logger.info("读取不到画面,当前grabber状态:hasAudio {},hasVideo {},isCloseInputStream {},isDeinterlace {},isTriggerMode {}",grabber.hasAudio(),grabber.hasVideo(),grabber.isCloseInputStream(),grabber.isDeinterlace(),grabber.isTriggerMode());
return null;
}
else{
... ...
... ... @@ -40,8 +40,6 @@ public class FishGroupImageRecognitionService {
@Autowired
private DeviceService deviceService;
@Autowired
private SrsService srsService;
private static Boolean isRun = false;
... ... @@ -216,8 +214,6 @@ public class FishGroupImageRecognitionService {
veiwDto = new VeiwDto(new Double(area).intValue(),absValue);
srsService.timepush(frame,absValue);
// 显示图像
logger.info("是否显示{},客户端数量{}",configurationParameterService.getConfig(ConfigurationParameter.ifVeiw),WebSocketClien.webSocketSet.size());
// 在图像上显示结果
... ...
... ... @@ -8,8 +8,8 @@ import com.zhonglai.luhui.smart.feeder.dto.VeiwDto;
import com.zhonglai.luhui.smart.feeder.dto.commd.FeederCommd06Response;
import com.zhonglai.luhui.smart.feeder.dto.commd.FeederCommdDto;
import com.zhonglai.luhui.smart.feeder.dto.commd.FeederTimer;
import com.zhonglai.luhui.smart.feeder.service.device.SerialPortService;
import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil;
import com.zhonglai.luhui.smart.feeder.util.PenetrateUtil;
import org.eclipse.paho.client.mqttv3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
... ... @@ -20,7 +20,6 @@ import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
@Component
public class MqttCallback implements MqttCallbackExtended {
... ...
... ... @@ -314,41 +314,41 @@ public class SrsService {
public static void main(String[] args) {
OpenCVConfig.loadOpenCv(args);
SrsService srsService = new SrsService();
FishRegionPanel fishRegionPanel = new FishRegionPanel();
int i=0;
while (i++<10)
{
VideoCapture videoCapture = OpenCVUtil.readVideoCaptureForVideo("");
Mat previousFrame = new Mat();
if (!videoCapture.read(previousFrame)) {
System.out.println("无法读取视频帧");
return;
}
try {
if(null == srsService.recorder || !srsService.recorder.isInterleaved())
{
srsService.init(previousFrame.width(),previousFrame.height());
}
} catch (Exception e) {
throw new RuntimeException(e);
}
Mat src = new Mat();
while (videoCapture.read(src))
{
Mat mat = srsService.fish(src);
fishRegionPanel.getLblImage().setIcon(new ImageIcon(convertMatToImage(mat)));
fishRegionPanel.getFrame().repaint();
OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat();
Frame frame = converter.convert(mat);
srsService.push(frame);
}
}
srsService.close();
// OpenCVConfig.loadOpenCv(args);
// SrsService srsService = new SrsService();
// FishRegionPanel fishRegionPanel = new FishRegionPanel();
// int i=0;
// while (i++<10)
// {
// VideoCapture videoCapture = OpenCVUtil.readVideoCaptureForVideo("");
// Mat previousFrame = new Mat();
// if (!videoCapture.read(previousFrame)) {
// System.out.println("无法读取视频帧");
// return;
// }
//
// try {
// if(null == srsService.recorder || !srsService.recorder.isInterleaved())
// {
// srsService.init(previousFrame.width(),previousFrame.height());
// }
// } catch (Exception e) {
// throw new RuntimeException(e);
// }
//
// Mat src = new Mat();
// while (videoCapture.read(src))
// {
// Mat mat = srsService.fish(src);
// fishRegionPanel.getLblImage().setIcon(new ImageIcon(convertMatToImage(mat)));
// fishRegionPanel.getFrame().repaint();
// OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat();
// Frame frame = converter.convert(mat);
// srsService.push(frame);
// }
//
// }
// srsService.close();
}
}
... ...
package com.zhonglai.luhui.smart.feeder.service.device;
import org.bytedeco.javacv.Frame;
public interface CameraHandle {
public void init();
public org.opencv.core.Mat getMat();
}
... ...
package com.zhonglai.luhui.smart.feeder.service;
package com.zhonglai.luhui.smart.feeder.service.device;
import com.ruoyi.common.utils.StringUtils;
import com.zhonglai.luhui.smart.feeder.config.OperatingData;
import com.zhonglai.luhui.smart.feeder.dto.ConfigurationParameter;
import com.zhonglai.luhui.smart.feeder.opencv.OpenCVUtil;
import org.bytedeco.javacv.FrameGrabber;
import org.opencv.videoio.VideoCapture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.net.DatagramSocket;
import java.io.File;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.io.IOException;
/**
* 摄像头
*/
... ... @@ -24,23 +21,35 @@ import java.io.IOException;
public class CameraService {
private static final Logger logger = LoggerFactory.getLogger(CameraService.class);
@Value("${sys.network_camera_ip}")
private String ip;
@Value("${sys.mp4_file_path}")
private String MP4_FILE_PATH;
private VideoCapture videoCapture;
private boolean videoIsOpen;
private ScheduledFuture scheduledFuture;
@Autowired
private ScheduledExecutorService scheduledExecutorService;
@Autowired
private ConfigurationParameterService configurationParameterService;
/**
* 初始化摄像头
*/
private void openCapture()
{
videoCapture = OpenCVUtil.readVideoCaptureForRtsp();
switch (OperatingData.cameraConfig.getCameraInterfaceType().toUpperCase())
{
case "USB":
videoCapture = readVideoCaptureForUSB();
break;
case "RTSP":
videoCapture = readVideoCaptureForRtsp();
break;
default:
videoCapture = readVideoCaptureForFile();
}
if(null == videoCapture)
{
return;
... ... @@ -56,11 +65,10 @@ public class CameraService {
{
// 检查视频是否成功打开
if (null !=videoCapture && videoCapture.isOpened()) {
videoIsOpen = true;
OperatingData.cameraData.setVideoIsOpen(true);
return;
}
System.out.println("无法打开视频文件"+ configurationParameterService.getConfig(ConfigurationParameter.captureNumber));
videoIsOpen = false;
OperatingData.cameraData.setVideoIsOpen(false);
}
/**
... ... @@ -71,8 +79,8 @@ public class CameraService {
if(null == scheduledFuture || scheduledFuture.isDone())
{
scheduledFuture = scheduledExecutorService.scheduleWithFixedDelay(() -> {
logger.info("摄像头状态{}",videoIsOpen);
if(!videoIsOpen)
logger.info("摄像头状态{}",OperatingData.cameraData.isVideoIsOpen());
if(!OperatingData.cameraData.isVideoIsOpen())
{
openCapture();
}
... ... @@ -91,9 +99,9 @@ public class CameraService {
scheduledFuture.cancel(true);
}
if(videoIsOpen)
if(OperatingData.cameraData.isVideoIsOpen())
{
videoIsOpen = false;
OperatingData.cameraData.setVideoIsOpen(false);
// 释放资源
videoCapture.release();
}
... ... @@ -105,9 +113,9 @@ public class CameraService {
*/
public void clean()
{
if(videoIsOpen)
if(OperatingData.cameraData.isVideoIsOpen())
{
videoIsOpen = false;
OperatingData.cameraData.setVideoIsOpen(false);
// 释放资源
videoCapture.release();
}
... ... @@ -118,130 +126,76 @@ public class CameraService {
return videoCapture;
}
public Boolean getVideoIsOpen()
{
return videoIsOpen;
}
public static void main(String[] args) throws Exception{
MulticastSocket socket = null;
try {
// 创建 MulticastSocket 对象
socket = new MulticastSocket();
// 指定多播地址和端口
InetAddress group = InetAddress.getByName("239.255.255.250");
int port = 37020;
while (true)
/**
* 读取网络摄像头
* @return
*/
public VideoCapture readVideoCaptureForRtsp()
{
// 创建要发送的消息
String message = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Probe><Uuid>B0F5E9C7-EBD5-4A03-99F7-B069B141C619</Uuid><Types>inquiry</Types></Probe>";
byte[] buffer = message.getBytes();
// 创建 DatagramPacket 对象
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, group, port);
// 发送数据包
socket.send(packet);
Thread.sleep(10000);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
socket.close();
String rtspUrl = "rtsp://admin:Luhui586@"+ip+":554/h264/ch1/main/av_stream";
VideoCapture videoCapture = new VideoCapture(rtspUrl);
while (!videoCapture.isOpened())
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
return videoCapture;
}
private static void sendclien()
/**
* 读取USB口的摄像头
* @return
*/
public VideoCapture readVideoCaptureForUSB()
{
for(int i=0;i<10;i++)
{
logger.info("初始化摄像头");
try {
// 创建组播Socket
MulticastSocket multicastSocket = new MulticastSocket();
// 创建组播地址
InetAddress group = InetAddress.getByName("239.255.255.250");
// 发送消息
String message = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Probe><Uuid>B0F5E9C7-EBD5-4A03-99F7-B069B141C619</Uuid><Types>inquiry</Types></Probe>";
byte[] buffer = message.getBytes();
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, group, 37020);
multicastSocket.send(packet);
// 关闭Socket
multicastSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
public static void onClien()
VideoCapture videoCapture = new VideoCapture();
boolean isopen = videoCapture.open(i);
if(isopen)
{
DatagramSocket socket = null;
try {
// 创建 DatagramSocket 对象,监听指定的端口
socket = new DatagramSocket(37020);
while (true) {
// 创建 DatagramPacket 对象,用于接收数据
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
// 接收数据
socket.receive(packet);
// 转换并打印接收到的数据
String received = new String(packet.getData(), 0, packet.getLength());
System.out.println("Received data: " + received);
logger.info("打开化摄像头"+i+"成功");
return videoCapture;
}else {
logger.info("打开化摄像头"+i+"失败");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
socket.close();
if(null != videoCapture)
{
return videoCapture; //拿到的第一个摄像头返回
}
}
logger.info("未检测到USB摄像头!!!");
return null;
}
public static void clien()
{
try {
// 创建组播Socket
MulticastSocket multicastSocket = new MulticastSocket(37020);
// 加入组播地址
InetAddress group = InetAddress.getByName("239.255.255.250");
multicastSocket.joinGroup(group);
boolean isip = true;
while (isip)
/**
* 读取本地视频文件
* @return
*/
private VideoCapture readVideoCaptureForFile()
{
// 接收消息
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
multicastSocket.receive(packet);
// 处理消息
String message = new String(packet.getData(), packet.getOffset(), packet.getLength());
System.out.println("Received: " + message);
if(message.indexOf("ip")>=0)
logger.info("未检测到摄像头{},尝试打开本地视频",MP4_FILE_PATH);
//如果找不到摄像头就找本地视频文件
File file = new File(MP4_FILE_PATH);
if(file.exists() && file.isFile())
{
isip = false;
}
}
// 关闭Socket
multicastSocket.leaveGroup(group);
multicastSocket.close();
} catch (IOException e) {
e.printStackTrace();
VideoCapture videoCapture = new VideoCapture();
boolean isopen = videoCapture.open(MP4_FILE_PATH);
System.out.println(isopen);
return videoCapture;
}
return null;
}
}
... ...
package com.zhonglai.luhui.smart.feeder.service;
package com.zhonglai.luhui.smart.feeder.service.device;
import com.fazecast.jSerialComm.SerialPort;
... ... @@ -9,6 +9,7 @@ import com.zhonglai.luhui.smart.feeder.dto.ConfigurationParameter;
import com.zhonglai.luhui.smart.feeder.dto.ModbusDto;
import com.zhonglai.luhui.smart.feeder.dto.SerialPortConfig;
import com.zhonglai.luhui.smart.feeder.dto.commd.FeederCommdDto;
import com.zhonglai.luhui.smart.feeder.service.ConfigurationParameterService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
... ...
package com.zhonglai.luhui.smart.feeder.service.device.handle;
import com.ruoyi.common.utils.ByteUtil;
import com.sun.jna.Pointer;
import com.zhonglai.luhui.smart.feeder.service.device.CameraHandle;
import com.zhonglai.luhui.smart.feeder.service.device.CameraService;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.*;
import org.bytedeco.opencv.opencv_core.IplImage;
import org.opencv.core.Mat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.*;
import java.util.Enumeration;
import java.util.Random;
import java.util.UUID;
public class CameraRtspHandle implements CameraHandle {
private static final Logger logger = LoggerFactory.getLogger(CameraRtspHandle.class);
private FFmpegFrameGrabber grabber;
private String ip = "192.168.0.198";
@Override
public void init() {
try {
FFmpegFrameGrabber.tryLoad();
String rtspUrl = "rtsp://admin:Luhui586@"+ip+":554/h264/ch1/main/av_stream";
grabber = new FFmpegFrameGrabber(rtspUrl);
// grabber.setOption("framerate", "30"); // 设置帧率为30帧/秒
grabber.setVideoOption("fflags", "nobuffer");
grabber.setVideoOption("rtsp_transport", "tcp");
grabber.setOption("stimeout", "2000000");
avutil.av_log_set_level(avutil.AV_LOG_ERROR);
grabber.start();
} catch (Exception e) {
logger.error("摄像头初始化失败",e);
}
}
@Override
public Mat getMat() {
return null;
}
public static void main(String[] args) {
// CameraRtspHandle cameraRtspHandle = new CameraRtspHandle();
// cameraRtspHandle.init();
// FFmpegFrameGrabber grabber = cameraRtspHandle.grabber;
//
// CanvasFrame previewCanvas = new CanvasFrame("摄像头预览", CanvasFrame.getDefaultGamma() / grabber.getGamma());
// previewCanvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// previewCanvas.setAlwaysOnTop(true);
//
// // 创建一个FFmpegFrameFilter对象,用于图像压缩
// FFmpegFrameFilter filter = new FFmpegFrameFilter("scale=640:-1", grabber.getImageWidth(), grabber.getImageHeight());
// try {
// filter.start();
// } catch (FFmpegFrameFilter.Exception e) {
// throw new RuntimeException(e);
// }
//
//
// while (true)
// {
// logger.info("当前grabber状态:hasAudio {},hasVideo {},isCloseInputStream {},isDeinterlace {},isTriggerMode {}",grabber.hasAudio(),grabber.hasVideo(),grabber.isCloseInputStream(),grabber.isDeinterlace(),grabber.isTriggerMode());
// try {
// filter.push(grabber.grabImage());
// Frame filteredFrame = filter.pull();
// if(null != filteredFrame)
// {
// previewCanvas.showImage(filteredFrame);
// }
// } catch (FFmpegFrameGrabber.Exception e) {
// logger.info("无法显示");
// } catch (FFmpegFrameFilter.Exception e) {
// throw new RuntimeException(e);
// }
// }
// 创建UDP Socket
MulticastSocket socket = null;
try {
socket = new MulticastSocket (37020);
socket.setTimeToLive(1);
// socket.setSoTimeout(10000);
socket.joinGroup( InetAddress.getByName("239.255.255.250"));
} catch (SocketException e) {
throw new RuntimeException(e);
} catch (UnknownHostException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
for (int i=0;i<3;i++)
{
UUID uuid = UUID.randomUUID();
String uuidString = uuid.toString().toUpperCase();
// 构造sadp请求数据包
String str = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Probe><Uuid>"+uuidString+"</Uuid><Types>inquiry</Types></Probe>";
byte[] requestData = str.getBytes();
DatagramPacket requestPacket = new DatagramPacket(requestData, requestData.length, InetAddress.getByName("239.255.255.250"), 37020);
Thread.sleep(1000);
// 发送请求数据包
socket.send(requestPacket);
}
while (true)
{
// 接收响应数据包
byte[] responseData = new byte[4096];
DatagramPacket responsePacket = new DatagramPacket(responseData, responseData.length);
socket.receive(responsePacket);
// 解析响应数据包
String response = new String(responsePacket.getData(), 0, responsePacket.getLength());
System.out.println("Response: " + response);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
socket.leaveGroup( InetAddress.getByName("239.255.255.250"));
} catch (IOException e) {
throw new RuntimeException(e);
}
// 关闭Socket
socket.close();
}
}
public static String formatUuid(String uuid) {
return uuid.substring(0, 8) + "-" +
uuid.substring(8, 12) + "-" +
uuid.substring(12, 16) + "-" +
uuid.substring(16, 20) + "-" +
uuid.substring(20);
}
public static void sendudp()
{
try {
// 创建组播Socket
InetAddress group = InetAddress.getByName("239.255.255.250");
MulticastSocket socket = new MulticastSocket(37020);
// 加入组播组
socket.joinGroup(group);
while (socket.isConnected())
{
// 接收消息
byte[] buffer = new byte[4096];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
// 解析消息并处理
String message = new String(packet.getData(), 0, packet.getLength());
System.out.println("Received message: " + message);
}
// 退出组播组
socket.leaveGroup(group);
// 关闭Socket
socket.close();
} catch (Exception e) {
e.printStackTrace();
}finally {
}
}
/**
* 生成UUID的方法
* @return 返回 UUID 字符串
*/
public static String generateUUID() {
// 获取当前时间戳
long timeMillis = 1697789348000l;
// 获取机器MAC地址
String macAddress = "G24198441";
// 生成随机数
int randomInt = new Random().nextInt();
// 获取个人或组织的标识码(这里设为 001)
int nodeId = 001;
// 组合 UUID 字符串
String uuid = String.format("%016x", timeMillis) //
+ String.format("%016x", randomInt) //
+ String.format("%016x", nodeId) //
+ macAddress;
// 返回 UUID 字符串
return uuid;
}
}
... ...
# 开发环境配置 server: # 服务器的HTTP端口,默认为8080 port: 8064 servlet: # 应用的访问路径 context-path: / tomcat: # tomcat的URI编码 uri-encoding: UTF-8 # 连接数满后的排队数,默认为100 accept-count: 1000 threads: # tomcat最大线程数,默认为200 max: 800 # Tomcat启动初始化的线程数,默认值10 min-spare: 100 # 日志配置 logging: level: com.ruoyi: debug org.springframework: warn # Swagger配置 swagger: # 是否开启swagger enabled: true # 请求前缀 pathMapping: /dev-api # 防止XSS攻击 xss: # 过滤开关 enabled: true # 排除链接(多个用逗号分隔) excludes: /system/notice # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/* sys: staticPath: "file:/opt/lh-smart-feeder/lh-smart-feeder/html/" srs_push_address: rtmp://119.23.218.181:21935/live/${mqtt.clientId} mp4_file_path: D:/lh-smart-feeder/2.mp4 # MyBatis配置 mybatis: # 搜索指定包别名 typeAliasesPackage: com.ruoyi.**.domain,com.zhonglai.**.domain # 配置mapper的扫描,找到所有的mapper.xml映射文件 mapperLocations: classpath*:mapper/**/*Mapper.xml # 加载全局的配置文件 configLocation: classpath:mybatis/mybatis-config.xml # 数据源配置 spring: # autoconfigure: # exclude: org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration datasource: type: com.alibaba.druid.pool.DruidDataSource driverClassName: org.sqlite.JDBC druid: # 主库数据源 master: url: jdbc:sqlite:db/my.db username: password: # 从库数据源 slave: # 从数据源开关/默认关闭 enabled: false url: username: password: # 初始连接数 initialSize: 5 # 最小连接池数量 minIdle: 10 # 最大连接池数量 maxActive: 20 # 配置获取连接等待超时的时间 maxWait: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 timeBetweenEvictionRunsMillis: 60000 # 配置一个连接在池中最小生存的时间,单位是毫秒 minEvictableIdleTimeMillis: 300000 # 配置一个连接在池中最大生存的时间,单位是毫秒 maxEvictableIdleTimeMillis: 900000 # 配置检测连接是否有效 validationQuery: SELECT 1 testWhileIdle: true testOnBorrow: false testOnReturn: false webStatFilter: enabled: true statViewServlet: enabled: true # 设置白名单,不填则允许所有访问 allow: url-pattern: /druid/* # 控制台管理用户名和密码 login-username: ruoyi login-password: 123456 filter: stat: enabled: true # 慢SQL记录 log-slow-sql: true slow-sql-millis: 1000 merge-sql: true wall: config: multi-statement-allow: true mqtt: #链接地址 broker: tcp://175.24.61.68:1883 #唯一标识 clientId: 70094a59d1d991d #订阅的topic topics: PUT/+,GET_REQ/+, READ/+,POST_REQ/+ username: 12_ZNZY password: Luhui586 client: #客户端操作时间 operationTime: 10
\ No newline at end of file
# 开发环境配置 server: # 服务器的HTTP端口,默认为8080 port: 8064 servlet: # 应用的访问路径 context-path: / tomcat: # tomcat的URI编码 uri-encoding: UTF-8 # 连接数满后的排队数,默认为100 accept-count: 1000 threads: # tomcat最大线程数,默认为200 max: 800 # Tomcat启动初始化的线程数,默认值10 min-spare: 100 # 日志配置 logging: level: com.ruoyi: debug org.springframework: warn # Swagger配置 swagger: # 是否开启swagger enabled: true # 请求前缀 pathMapping: /dev-api # 防止XSS攻击 xss: # 过滤开关 enabled: true # 排除链接(多个用逗号分隔) excludes: /system/notice # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/* sys: staticPath: "file:/opt/lh-smart-feeder/lh-smart-feeder/html/" srs_push_address: rtmp://119.23.218.181:21935/live/${mqtt.clientId} mp4_file_path: D:/lh-smart-feeder/mp4/2.mp4 network_camera_ip: 192.168.0.198 # MyBatis配置 mybatis: # 搜索指定包别名 typeAliasesPackage: com.ruoyi.**.domain,com.zhonglai.**.domain # 配置mapper的扫描,找到所有的mapper.xml映射文件 mapperLocations: classpath*:mapper/**/*Mapper.xml # 加载全局的配置文件 configLocation: classpath:mybatis/mybatis-config.xml # 数据源配置 spring: # autoconfigure: # exclude: org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration datasource: type: com.alibaba.druid.pool.DruidDataSource driverClassName: org.sqlite.JDBC druid: # 主库数据源 master: url: jdbc:sqlite:db/my.db username: password: # 从库数据源 slave: # 从数据源开关/默认关闭 enabled: false url: username: password: # 初始连接数 initialSize: 5 # 最小连接池数量 minIdle: 10 # 最大连接池数量 maxActive: 20 # 配置获取连接等待超时的时间 maxWait: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 timeBetweenEvictionRunsMillis: 60000 # 配置一个连接在池中最小生存的时间,单位是毫秒 minEvictableIdleTimeMillis: 300000 # 配置一个连接在池中最大生存的时间,单位是毫秒 maxEvictableIdleTimeMillis: 900000 # 配置检测连接是否有效 validationQuery: SELECT 1 testWhileIdle: true testOnBorrow: false testOnReturn: false webStatFilter: enabled: true statViewServlet: enabled: true # 设置白名单,不填则允许所有访问 allow: url-pattern: /druid/* # 控制台管理用户名和密码 login-username: ruoyi login-password: 123456 filter: stat: enabled: true # 慢SQL记录 log-slow-sql: true slow-sql-millis: 1000 merge-sql: true wall: config: multi-statement-allow: true mqtt: #链接地址 broker: tcp://175.24.61.68:1883 #唯一标识 clientId: 70094a59d1d991d #订阅的topic topics: PUT/+,GET_REQ/+, READ/+,POST_REQ/+ username: 12_ZNZY password: Luhui586 client: #客户端操作时间 operationTime: 10
\ No newline at end of file
... ...