海康錄像機還是國內市場比較火的錄像機吧!反正我也不知道,我也不敢問啊!╮(︶﹏︶)╭話不多說!趕緊去海康官網選擇一個相應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++文檔吧!或許可以幫到你。
▄█▀█●各位老鐵,如果我的代碼能夠幫助到你,請給我一個贊吧!有啥子不懂的地方或者開發與遇到啥問題請評論。懂就給你解答。不懂的話,我也沒辦法啊!