海康录像机还是国内市场比较火的录像机吧!反正我也不知道,我也不敢问啊!╮(︶﹏︶)╭话不多说!赶紧去海康官网选择一个相应sdk开放包下载,这里给老铁们奉上地址:盘他⁽⁽ƪ(•̩̩̩̩_•̩̩̩̩)ʃ⁾⁾ᵒᵐᵍᵎᵎ。
第一步:海康官网提供的开发文档和操作手册是c++版本,我一个学过c++都看得不是很懂,可能是我比较菜吧!如果你没学过的话,可能会你会比较~%?…;# *’☆&℃$︿★? 乱码!好吧,我来介绍java如何使用,看下图,这是我从官网下载的sdk,你需要把依赖jar包导入到项目中,我使用maven导入的依赖
<!--海康录像机二次开发依赖jar包-->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>3.0.9</version>
</dependency>
<!--海康录像机sdk官方提供jar包-->
<dependency>
<groupId>com.qy</groupId>
<artifactId>examples</artifactId><!--需要在maven自行安装这个jar包-->
<version>1.0.0</version>
</dependency>
第二步:修改程序代码,我们找到官方提供的sdk,找到java示例代码,在下图第一张图所示所显示路径中找到HCNetSDK.java导入项目当中,把海康sdk中库文件里的HCNetSDK.dll、HCCore.dll、PlayCtrl.dll、SuperRender.dll、HCNetSDKCom文件夹等文件均拷贝到本地路径。HCNetSDKCom文件夹(包含里面的功能组件dll库文件)需要和HCNetSDK.dll、HCCore.dll一起加载,放在同一个目录下,且HCNetSDKCom文件夹名不能修改。把HCNetSDK.java文件复制一份到本地路径,如下图第二张图所示。其中HCNetSDK.java文件自己指定loadlibrary加载库的路径,如下图第三张图所示。
第三步:这一步对抓图功能很关键,我们要修改HCNetSDK.java里面的内容(修改之后要保证和本地磁盘下HCNetSDK.java文件一致,复制过去就可以了),把sJpegPicBuffer的String类型改成ByteBuffer就可以了
第四步:开始编码通过时间下载录像这个功能,通过时间下载功能测试在play类的main方法中
public class VideoDowload {
private static Logger logger = LoggerFactory.getLogger(VideoDowload.class);
private static HCNetSDK hcNetSDK = HCNetSDK.INSTANCE;
private NativeLong userId;//用户句柄
private NativeLong loadHandle;//下载句柄
private Timer downloadTimer;
/**
*按时间下载视频
* @param dvr
* @param startTime
* @param endTime
* @param filePath
* @param channel
* @return
*/
public boolean downloadVideo(Dvr dvr,Date startTime, Date endTime, String filePath, int channel) {
boolean initFlag = hcNetSDK.NET_DVR_Init();
if(!initFlag) { //返回值为布尔值 fasle初始化失败
logger.warn("hksdk(视频)-海康sdk初始化失败!");
return false;
}
HCNetSDK.NET_DVR_DEVICEINFO_V30 deviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30();
userId = hcNetSDK.NET_DVR_Login_V30(dvr.getDvrip(),(short)dvr.getDvrport(),dvr.getDvrusername(),dvr.getDvrpassword(),deviceInfo);
logger.info("hksdk(视频)-登录海康录像机信息,状态值:"+hcNetSDK.NET_DVR_GetLastError());
long lUserId = userId.longValue();
if(lUserId==-1) {
logger.warn("hksdk(视频)-海康sdk登录失败!");
return false;
}
loadHandle =new NativeLong(-1);
if(loadHandle.intValue()==-1) {
loadHandle = hcNetSDK.NET_DVR_GetFileByTime(userId,new NativeLong(channel),getHkTime(startTime),getHkTime(endTime),filePath);
logger.info("hksdk(视频)-获取播放句柄信息,状态值:"+hcNetSDK.NET_DVR_GetLastError());
if(loadHandle.intValue()>=0) {
boolean downloadFlag = hcNetSDK.NET_DVR_PlayBackControl(loadHandle,hcNetSDK.NET_DVR_PLAYSTART,0,null);
int tmp = -1;
IntByReference pos = new IntByReference();
while(true) {
boolean backFlag = hcNetSDK.NET_DVR_PlayBackControl(loadHandle,hcNetSDK.NET_DVR_PLAYGETPOS,0,pos);
if(!backFlag) {//防止单个线程死循环
return downloadFlag;
}
int produce =pos.getValue();
if((produce%10)==0&&tmp!=produce) {//输出进度
tmp = produce;
logger.info("hksdk(视频)-视频下载进度:"+"=="+produce+"%");
}
if(produce ==100) {//下载成功
hcNetSDK.NET_DVR_StopGetFile(loadHandle);
loadHandle.setValue(-1);
hcNetSDK.NET_DVR_Logout(userId);//退出录像机
logger.info("hksdk(视频)-退出状态"+hcNetSDK.NET_DVR_GetLastError());
//hcNetSDK.NET_DVR_Cleanup();
return true;
}
if(produce>100) {//下载失败
hcNetSDK.NET_DVR_StopGetFile(loadHandle);
loadHandle.setValue(-1);
logger.warn("hksdk(视频)-海康sdk由于网络原因或DVR忙,下载异常终止!错误原因:"+ hcNetSDK.NET_DVR_GetLastError());
//hcNetSDK.NET_DVR_Logout(userId);//退出录像机
//logger.info("hksdk(视频)-退出状态"+hcNetSDK.NET_DVR_GetLastError());
return false;
}
}
}else{
System.out.println("hksdk(视频)-下载失败" + hcNetSDK.NET_DVR_GetLastError());
return false;
}
}
return false;
}
/**
* 获取海康录像机格式的时间
* @param time
* @return
*/
public HCNetSDK.NET_DVR_TIME getHkTime(Date time) {
HCNetSDK.NET_DVR_TIME structTime = new HCNetSDK.NET_DVR_TIME();
String str = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(time);
String[] times = str.split("-");
structTime.dwYear = Integer.parseInt(times[0]);
structTime.dwMonth = Integer.parseInt(times[1]);
structTime.dwDay = Integer.parseInt(times[2]);
structTime.dwHour = Integer.parseInt(times[3]);
structTime.dwMinute =Integer.parseInt(times[4]);
structTime.dwSecond = Integer.parseInt(times[5]);
return structTime;
}
public static void main(String[] args) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
Date startTime =null;
Date endTime = null;
try {
startTime = sdf.parse("20190712164200"); //开始时间
endTime = sdf.parse("20190712170000"); //结束时间
} catch (ParseException e) {
e.printStackTrace();
}
VideoDowload test = new VideoDowload();
Dvr dvr = new Dvr(0,"录像机ip",8000,"录像机用户名","录像机密码",null,0);
int channel =2//通道
System.out.print(test.downloadVideo(dvr,startTime,endTime,"G:\\test\\test.mp4",chanel));
}
}
第四步:开始编码抓图功能,抓图功能测试在Camera的main方法里面。
public class Camera {
private static HCNetSDK hcNetSDK = HCNetSDK.INSTANCE;
private Logger logger = LoggerFactory.getLogger(Camera.class);
private NativeLong userId;//用户句柄
/**
* 抓拍图片
* @param dvr
*/
public void getDVRPic(Dvr dvr, int chan, String imgpath) {
NativeLong chanLong = new NativeLong(chan);
if(!hcNetSDK.NET_DVR_Init()) {
logger.warn("hksdk(抓图)-海康sdk初始化失败!");
return ;
}
HCNetSDK.NET_DVR_DEVICEINFO_V30 devinfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30();// 设备信息
//注册设备
userId = hcNetSDK.NET_DVR_Login_V30(dvr.getDvrip(),(short)dvr.getDvrport(),dvr.getDvrusername(), dvr.getDvrpassword(), devinfo);// 返回一个用户编号,同时将设备信息写入devinfo
if (userId.intValue() < 0) {
logger.warn("hksdk(抓图)-设备注册失败,错误码:"+hcNetSDK.NET_DVR_GetLastError());
return;
}
HCNetSDK.NET_DVR_WORKSTATE_V30 devwork = new HCNetSDK.NET_DVR_WORKSTATE_V30();
if (!hcNetSDK.NET_DVR_GetDVRWorkState_V30(userId, devwork)) {
// 返回Boolean值,判断是否获取设备能力
logger.info("hksdk(抓图)-返回设备状态失败");
}
//图片质量
HCNetSDK.NET_DVR_JPEGPARA jpeg = new HCNetSDK.NET_DVR_JPEGPARA();
//设置图片分辨率
jpeg.wPicSize=5;
//设置图片质量
jpeg.wPicQuality=0;
IntByReference a = new IntByReference();
//设置图片大小
ByteBuffer jpegBuffer = ByteBuffer.allocate(1024 * 1024);
//String jpegBuffer ="1024 * 1024";
File file = new File(imgpath);
// 抓图到内存,单帧数据捕获并保存成JPEG存放在指定的内存空间中
//需要加入通道
boolean is = hcNetSDK.NET_DVR_CaptureJPEGPicture_NEW(userId, chanLong, jpeg, jpegBuffer, 1024 * 1024, a);
if(is) {
logger.info("hksdk(抓图)-结果状态值(0表示成功):"+hcNetSDK.NET_DVR_GetLastError());
//存储到本地
BufferedOutputStream outputStream = null;
try {
outputStream = new BufferedOutputStream(new FileOutputStream(file));
outputStream.write(jpegBuffer.array(),0,a.getValue());
outputStream.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(outputStream!=null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}else{
logger.info("hksdk(抓图)-抓取失败,错误码:"+hcNetSDK.NET_DVR_GetLastError());
}
hcNetSDK.NET_DVR_Logout(userId);//退出登录
//hcNetSDK.NET_DVR_Cleanup();
}
public static void main(String[] args) {
Camera camera = new Camera();
Dvr dvr = new Dvr(0,"录像机ip",8000,"录像机用户名","密码",null,0);
String imgpath ="G:\\test\\test.jpg";
int channel = 2;//通道号
camera.getDVRPic(dvr,channel,imgpath);
}
}
注意:Dvr类就是录像机设备信息类,你自己建一个你自己的就可以了,海康录像机每一个摄像枪对应一个通道号,在通道号上选择,我这里选择通道号是1,2......。但是你可能会选择错误,有些录像机实际通道号是从33开始的,对应录像机设置通道1、通道2......,可能不同的录像机不太一样吧!
如果需要实现其他功能,各位老铁去看丧心病狂的c++文档吧!或许可以帮到你。
▄█▀█●各位老铁,如果我的代码能够帮助到你,请给我一个赞吧!有啥子不懂的地方或者开发与遇到啥问题请评论。懂就给你解答。不懂的话,我也没办法啊!