|
|
|
package com.zhonglai.luhui.smart.feeder.service;
|
|
|
|
|
|
|
|
import org.bytedeco.javacv.CanvasFrame;
|
|
|
|
import org.bytedeco.javacv.FFmpegFrameGrabber;
|
|
|
|
import cn.hutool.core.util.ArrayUtil;
|
|
|
|
import cn.hutool.core.util.ReUtil;
|
|
|
|
import cn.hutool.core.util.RuntimeUtil;
|
|
|
|
import com.ruoyi.common.utils.StringUtils;
|
|
|
|
import org.bytedeco.ffmpeg.global.avutil;
|
|
|
|
import org.bytedeco.javacv.*;
|
|
|
|
import org.bytedeco.javacv.Frame;
|
|
|
|
import org.bytedeco.javacv.FrameGrabber;
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
import java.awt.*;
|
|
|
|
import java.awt.image.BufferedImage;
|
|
|
|
import java.time.LocalDateTime;
|
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
@Service
|
|
|
|
public class FFmCameraService {
|
|
|
|
public static void main(String[] args) {
|
|
|
|
// int maxCameraIndex = 10; // 最大尝试的摄像头索引数量
|
|
|
|
// for (int cameraIndex = 0; cameraIndex < maxCameraIndex; ++cameraIndex) {
|
|
|
|
// try {
|
|
|
|
// FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(cameraIndex);
|
|
|
|
// grabber.start(); // 尝试开始,如果失败将抛出异常
|
|
|
|
// try {
|
|
|
|
// // 创建一个窗口用于显示摄像头的视频流
|
|
|
|
// CanvasFrame frame = new CanvasFrame("Webcam");
|
|
|
|
//
|
|
|
|
// // 判断窗口是否关闭
|
|
|
|
// while (frame.isVisible()) {
|
|
|
|
// // 抓取一帧视频并将其放在窗口上显示,该操作会阻塞程序,直到下一帧视频可用
|
|
|
|
// Frame grabbedFrame = grabber.grab();
|
|
|
|
// frame.showImage(grabbedFrame);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// // 关闭窗口
|
|
|
|
// frame.dispose();
|
|
|
|
// } finally {
|
|
|
|
// // 停止抓取
|
|
|
|
// grabber.stop();
|
|
|
|
// }
|
|
|
|
// break; // 如果找到了摄像头并成功打开,就结束循环
|
|
|
|
// } catch (FrameGrabber.Exception e) {
|
|
|
|
// // 如果失败,就继续尝试下一个摄像头
|
|
|
|
// System.out.println("Failed to start the camera with device index: " + cameraIndex);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
private FFmpegFrameGrabber grabber;
|
|
|
|
|
|
|
|
private static String MAC = "78-a6-a0-d2-bd-e1";
|
|
|
|
/**
|
|
|
|
* 查找摄像头
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
public String findCameraIp()
|
|
|
|
{
|
|
|
|
List<String> list = RuntimeUtil.execForLines("arp", "-a");
|
|
|
|
for (String str:list)
|
|
|
|
{
|
|
|
|
if(str.indexOf(MAC)>=0)
|
|
|
|
{
|
|
|
|
// 使用Hutool提取字符串中的IP地址
|
|
|
|
List<String> ips = ReUtil.findAll("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}", str, 0, new ArrayList<>());
|
|
|
|
if(null != ips && ips.size()!=0)
|
|
|
|
{
|
|
|
|
return ips.get(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 加载摄像头
|
|
|
|
*/
|
|
|
|
public void loadCamera()
|
|
|
|
{
|
|
|
|
String ip = findCameraIp();
|
|
|
|
if(StringUtils.isEmpty(ip))
|
|
|
|
{
|
|
|
|
System.out.println("没有找到摄像头:"+MAC);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
String rtspUrl = "rtsp://admin:Luhui586@"+ip+":554/h264/ch1/main/av_stream";
|
|
|
|
|
|
|
|
try {
|
|
|
|
FFmpegFrameGrabber.tryLoad();
|
|
|
|
} catch (Exception e) {
|
|
|
|
throw new RuntimeException("Failed to load FFmpeg", e);
|
|
|
|
}
|
|
|
|
|
|
|
|
grabber = new FFmpegFrameGrabber(rtspUrl);
|
|
|
|
grabber.setVideoOption("fflags", "nobuffer"); // 禁用缓冲
|
|
|
|
grabber.setVideoOption("rtsp_transport", "tcp"); // 使用TCP传输
|
|
|
|
avutil.av_log_set_level(avutil.AV_LOG_ERROR); // 设置日志级别
|
|
|
|
|
|
|
|
try {
|
|
|
|
grabber.start();
|
|
|
|
} catch (Exception e) {
|
|
|
|
close();
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public Boolean isOk()
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
return null!=grabber && grabber.grab() != null;
|
|
|
|
} catch (FrameGrabber.Exception e) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void close()
|
|
|
|
{
|
|
|
|
if(null != grabber)
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
grabber.stop();
|
|
|
|
grabber.close();
|
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private void display(Frame frame) throws FrameGrabber.Exception {
|
|
|
|
CanvasFrame canvasFrame = new CanvasFrame("Key Frame Capture", CanvasFrame.getDefaultGamma() / grabber.getGamma());
|
|
|
|
canvasFrame.dispose();
|
|
|
|
while (true) {
|
|
|
|
canvasFrame.showImage(dream(getFrame()));
|
|
|
|
LocalDateTime now = LocalDateTime.now();
|
|
|
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
|
|
|
|
String formattedDateTime = now.format(formatter);
|
|
|
|
|
|
|
|
System.out.println("当前时间: " + formattedDateTime);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public Frame getFrame() {
|
|
|
|
Frame frame = null;
|
|
|
|
try {
|
|
|
|
frame = grabber.grabImage();
|
|
|
|
if (frame == null) {
|
|
|
|
//TODO:连续n次为null,进行重连
|
|
|
|
System.out.println("frame is null");
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
return frame;
|
|
|
|
}
|
|
|
|
} catch (FrameGrabber.Exception e) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private int maxX = 200;
|
|
|
|
private int POINT_RADIUS = 3;
|
|
|
|
private int quHeight = 200;
|
|
|
|
private java.util.List<Double> points = new ArrayList<>();
|
|
|
|
private BufferedImage dream(Frame frame)
|
|
|
|
{
|
|
|
|
BufferedImage image = Java2DFrameUtils.toBufferedImage(frame);
|
|
|
|
|
|
|
|
double point = Math.random();
|
|
|
|
points.add(point);
|
|
|
|
if (points.size() > maxX) {
|
|
|
|
points.remove(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
BufferedImage curveImage = new BufferedImage(image.getWidth(), image.getHeight()+quHeight,image.getType());
|
|
|
|
Graphics2D g2d = curveImage.createGraphics();
|
|
|
|
|
|
|
|
// 在图像上绘制曲线
|
|
|
|
g2d.setColor(Color.RED);
|
|
|
|
g2d.setStroke(new BasicStroke(POINT_RADIUS));
|
|
|
|
|
|
|
|
Double maxY = ArrayUtil.max(points.toArray(new Double[0]));
|
|
|
|
|
|
|
|
int vx = image.getWidth()/maxX;
|
|
|
|
Double vy = quHeight/maxY;
|
|
|
|
// 绘制动态曲线
|
|
|
|
for(int i=0;i<points.size()-1;i++)
|
|
|
|
{
|
|
|
|
int x = i*vx;
|
|
|
|
int y = new Double(points.get(i)*vy).intValue();
|
|
|
|
g2d.drawLine(x, y+image.getHeight(), x+vx, new Double(points.get(i+1)*vy).intValue()+image.getHeight());
|
|
|
|
}
|
|
|
|
|
|
|
|
// 将第一个帧绘制到合并图像的上方
|
|
|
|
curveImage.createGraphics().drawImage(image, 0, 0, null);
|
|
|
|
|
|
|
|
g2d.dispose();
|
|
|
|
return curveImage;
|
|
|
|
}
|
|
|
|
} |
...
|
...
|
|