今天我来总结一下海康摄像头的录制功能的实现。
1.首先海康摄像头是有自己的官方文档的
https://www.hikvision.com/cn/download_61.html
在这个连接中我们可以找到海康摄像头的SDK,我下载的SDK如下图所示
其中有一个类是HCNetSDK.java,这个是sdk的核心类,使用这个类再加上dll(windows系统)或.so(Linux系统)文件即可实现摄像头的视频后台录制了。
这里博主用到了几个类截图如下:
由于代码行数比较多,这里就不再贴出来代码了,一会放个连接大家去下载吧 。
https://download.csdn.net/download/lp840312696/11267104
下边是需要引用的jar包
com.sun.jna
jna
3.0.9
com.sun.jna
jna-examples
1.0.0
还有一个调用工具类的service,使用这个service就可以实现视频的录制了
package com.youyou.quartz.service;
import com.youyou.util.StringUtils;
import com.youyou.util.camera.hk.Constant;
import com.youyou.util.camera.hk.HkvUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Service()
public class VideoRecordEOService {
/**
* 创建log
*/
private static final Logger logger = LoggerFactory.getLogger(VideoRecordEOService.class);
private static final ExecutorService EXECUTOR_SERVICE = Executors.newFixedThreadPool(50);
/**
* 用来保存摄像头录制对象,key为摄像头id
*/
private static Map hkvUtilMap = new ConcurrentHashMap<>();
/**
* 开始录制视频
*
* @param key 摄像头的唯一标识
* @param ip ip地址
* @param port 端口号
* @param username 用户名
* @param pass 密码
* @return
* @author 刘朋
*
date 2019-07-01
*/
public void startRecord(String key, String ip, String port, String username, String pass) {
//首先判断一下摄像头录制对象是否已经存在,如果存在则说明摄像头已经在录制视频了,需要保存视频,重新录制
HkvUtil hkvUtil1 = hkvUtilMap.get(key);
if (Objects.nonNull(hkvUtil1)) {
//重新开始录制
reStartRecord(hkvUtil1);
return;
}
String iChannelNum = "1";
String preset = "";//枪机没有预置点位
//参数Map
Map paramMap = new HashMap<>();
try {
//初始化
if (HkvUtil.init()) {
logger.info("开始初始化");
HkvUtil hkvUtil = new HkvUtil(ip, port, username,
pass, iChannelNum, preset);
//开始录制
paramMap = hkvUtil.jButtonStartSaveData();
//如果录制失败
if (StringUtils.equals(paramMap.get(Constant.Global.CODE), "-1")) {
hkvUtilMap.remove(key);
} else {
hkvUtilMap.put(key, hkvUtil);
}
paramMap.put(Constant.Global.IP, ip);
paramMap.put(Constant.Global.CAMERA_ID, key);
}
} catch (Exception e) {
logger.error("IP:" + ip + " 录制失败!");
e.printStackTrace();
paramMap.put(Constant.Global.CODE, "-1");
paramMap.put(Constant.Global.DESC, "录像失败");
}
}
/**
* 重新录制
*
* @param hkvUtil
* @return
* @author 刘朋
*
date 2019-06-26
*/
public void reStartRecord(HkvUtil hkvUtil) {
EXECUTOR_SERVICE.submit(new VideoRecordEOService.AutoStopThread(hkvUtil));
}
// AutoStopThread for Start Recording after minutes
class AutoStopThread implements Runnable {
private HkvUtil hkvUtil;
AutoStopThread(HkvUtil hkvUtil) {
this.hkvUtil = hkvUtil;
}
@Override
public void run() {
logger.info("自动停止录像线程已开始!");
/* try {
Thread.sleep(1 * 60 * 1000L);
} catch (InterruptedException e) {
logger.error(e.getMessage(), e);
//中断线程
Thread.currentThread().interrupt();
}*/
logger.info("停止录像");
//停止录像成功
if (hkvUtil != null && hkvUtil.jButtonStopSaveData()) {
logger.info("停止录像成功!");
//重新录制
Map paramMap = hkvUtil.jButtonStartSaveData();
//如果录制失败
if (StringUtils.equals(paramMap.get(Constant.Global.CODE), "-1")) {
logger.info("重新录像失败!");
hkvUtilMap.remove(paramMap.get(Constant.Global.CAMERA_ID));
}
logger.info("再次: {}", paramMap);
/*if (paramMap.get(Constant.Global.CODE).equals(Constant.Global.SUCCESS_CODE)) {
//重新录制
reStartRecord(hkvUtil);
}*/
logger.info("保存数据库完毕");
} else {
logger.info("停止录像失败!");
}
}
}
}
如果想要隔几分钟保存一次视频文件,还需要后边的两个类。
1.线程工具类
package com.youyou.util;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* 线程工具类
*
* @author 刘朋
*
date 2019-06-28
*/
public class ThreadUtils {
/**
* 延迟并以固定休息时间循环执行命令
*
* @param command 需要重复执行的线程
* @param delay 执行的时间间隔(秒)
* @return
* @author 刘朋
*
date 2018-10-11
*/
public static void scheduleWithFixedDelay(Runnable command, long delay) {
scheduleWithFixedDelayMillisecond(command, delay * 1000);
}
/**
* @param command 需要重复执行的线程
* @param delay 执行的时间间隔(毫秒)
* @return
* @author 刘朋
*
date 2019-04-29
*/
public static void scheduleWithFixedDelayMillisecond(Runnable command, long delay) {
//定义计划执行者服务,单线程执行器
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
//将线程放入到服务中,它就会自己去跑啦
executorService.scheduleWithFixedDelay(command, 0, delay, TimeUnit.MILLISECONDS);
}
}
2.跟随系统启动时的触发类
package com.youyou.quartz.starter;
import com.youyou.quartz.service.VideoRecordEOService;
import com.youyou.util.ThreadUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
/**
* //TODO 添加类/接口功能描述
*
* @author 刘朋
*
date 2019-07-01
*/
@Component
public class Starter implements CommandLineRunner {
private static final Logger LOGGER = LoggerFactory.getLogger(Starter.class);
@Autowired
private VideoRecordEOService videoRecordEOService ;
@Override
public void run(String... args) throws Exception {
videoRecord();
}
/**
* 园区摄像头录制视频
*/
private void videoRecord() {
LOGGER.info("摄像头测试开始!");
Runnable runnable = () -> {
//保存录制的视频
videoRecordEOService.startRecord("1","192.168.1.64","8000","admin","q1234567");
};
//5分钟执行一次
ThreadUtils.scheduleWithFixedDelay(runnable, 300);
}
}
这样就可以实现海康摄像头后台录制视频的功能了,如果有哪里写的不全面的话,可以留言来通知我,我会及时修改完善的。