package com.boying.service; import com.alibaba.fastjson.JSON; import com.boying.entity.CameraSnapDto; import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.text.SimpleDateFormat; import java.util.Date; @Component public class PicJob { @Autowired private RedisTemplate redisTemplate; @Value("${allFilePath.imgPath}") private String imgPath; private String REDIS_KEY="snap:"; private Boolean runFlag = false; static HCNetSDK hCNetSDK = SdkInitService.hcNetSDK; static PlayCtrl playCtrl = SdkInitService.playCtrl; private FRealDataCallBack fRealDataCallBack;//预览回调函数实现 private int Count=0; int lPlay = -1; //预览句柄 int m_lLoadHandle; int iPlayBack; //回放句柄 int lUserID; IntByReference m_lPort= new IntByReference(-1); @Scheduled(cron = "0/1 * * * * *") public void work() throws InterruptedException { if(runFlag){ return; } CameraSnapDto cameraSnapDto = (CameraSnapDto)redisTemplate.boundListOps(REDIS_KEY).rightPop(); if(cameraSnapDto == null){ return; } String loginStatus = (String)redisTemplate.opsForValue().get("Login_Status:"+cameraSnapDto.getEqUrl()); if("true".equals(loginStatus)){ return; } if(cameraSnapDto != null){ try { runFlag = true; redisTemplate.opsForValue().set("Login_Status:"+cameraSnapDto.getEqUrl(),"true"); HCNetSDK.NET_DVR_DEVICEINFO_V30 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30(); lUserID = hCNetSDK.NET_DVR_Login_V30(cameraSnapDto.getEqUrl(),(short)8000,cameraSnapDto.getEqUser(),cameraSnapDto.getEqPassword(), m_strDeviceInfo); System.out.println("登录的userid为:"+lUserID); long userID = lUserID; if (userID == -1) { System.out.println("hksdk(视频)-海康sdk登录失败!"+hCNetSDK.NET_DVR_GetLastError()); return; } //实时取流 realPlay(lUserID,cameraSnapDto.getEqPort()); getPicbyPlayCtrl(cameraSnapDto.getImgName()); Thread.sleep(1000); //退出程序时调用,每一台设备分别注销 // if (hCNetSDK.NET_DVR_Logout(lUserID)) { // System.out.println("注销成功"); // } // // //SDK反初始化,释放资源,只需要退出时调用一次 // hCNetSDK.NET_DVR_Cleanup(); }catch (Exception e){ runFlag = false; }finally { runFlag = false; redisTemplate.opsForValue().set("Login_Status:"+cameraSnapDto.getEqUrl(),"false"); } } } public void realPlay(int userID, int iChannelNo) { if (userID == -1) { System.out.println("请先注册"); return; } HCNetSDK.NET_DVR_PREVIEWINFO strClientInfo = new HCNetSDK.NET_DVR_PREVIEWINFO(); strClientInfo.read(); strClientInfo.hPlayWnd = 0; //窗口句柄,从回调取流不显示一般设置为空 strClientInfo.lChannel = iChannelNo; //通道号 strClientInfo.dwStreamType=0; //0-主码流,1-子码流,2-三码流,3-虚拟码流,以此类推 strClientInfo.dwLinkMode=0; //连接方式:0- TCP方式,1- UDP方式,2- 多播方式,3- RTP方式,4- RTP/RTSP,5- RTP/HTTP,6- HRUDP(可靠传输) ,7- RTSP/HTTPS,8- NPQ strClientInfo.bBlocked=1; strClientInfo.byProtoType = 0; strClientInfo.write(); //回调函数定义必须是全局的 if (fRealDataCallBack == null) { fRealDataCallBack = new FRealDataCallBack(); } //开启预览 lPlay = hCNetSDK.NET_DVR_RealPlay_V40(userID, strClientInfo, fRealDataCallBack , null); if (lPlay == -1) { int iErr = hCNetSDK.NET_DVR_GetLastError(); System.out.println("取流失败" + iErr); return; } System.out.println("取流成功"); //设置裸码流回调函数 // if (fPlayescallback==null) // { // fPlayescallback=new fPlayEScallback(); // } // boolean setcallback=hCNetSDK.NET_DVR_SetESRealPlayCallBack(lPlay,fPlayescallback,null); // if (setcallback==false) // { // System.out.println("设置裸码流回调失败,错误码:"+hCNetSDK.NET_DVR_GetLastError()); // } //取流解码过程中播放库从解码码流中抓图 // getPicbyPlayCtrl(); /** * 预览一段时间;如果要一直取流预览,需要保证程序一直运行 */ try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } String path = ".\\savevideo.mp4"; Boolean bSaveVideo = hCNetSDK.NET_DVR_SaveRealData_V30(lPlay,0x2,path); if (bSaveVideo == false) { int iErr = hCNetSDK.NET_DVR_GetLastError(); System.out.println("NET_DVR_SaveRealData_V30 failed" + iErr); return; } System.out.println("NET_DVR_SaveRealData_V30 suss"); try { Thread.sleep(0); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Boolean bStopSaveVideo = hCNetSDK.NET_DVR_StopSaveRealData(lPlay); if (bStopSaveVideo == false) { int iErr = hCNetSDK.NET_DVR_GetLastError(); System.out.println("NET_DVR_StopSaveRealData failed" + iErr); return; } System.out.println("NET_DVR_StopSaveRealData suss"); if (lPlay>=0) { if (hCNetSDK.NET_DVR_StopRealPlay(lPlay)) { System.out.println("停止预览成功"); return; } } } //播放库抓图 public void getPicbyPlayCtrl(String imgName){ //取流成功后,延时一段时间保证播放库解码开始 try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } IntByReference pWidth = new IntByReference(0); IntByReference pHieght = new IntByReference(0); boolean bFlag = playCtrl.PlayM4_GetPictureSize(m_lPort.getValue(), pWidth, pHieght); if (!bFlag) { System.out.println("获取失败:" + playCtrl.PlayM4_GetLastError(m_lPort.getValue())); } System.out.println(pWidth.getValue()); System.out.println(pHieght.getValue()); IntByReference RealPicSize = new IntByReference(0); int picsize = pWidth.getValue() * pHieght.getValue() * 5; HCNetSDK.BYTE_ARRAY picByte = new HCNetSDK.BYTE_ARRAY(picsize); picByte.write(); Pointer pByte = picByte.getPointer(); boolean b_GetPic = playCtrl.PlayM4_GetJPEG(m_lPort.getValue(), pByte, picsize, RealPicSize); if (!b_GetPic) { System.out.println("抓图失败:" + playCtrl.PlayM4_GetLastError(m_lPort.getValue())); } picByte.read(); SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss"); String newName = sf.format(new Date()); FileOutputStream fout = null; try { File file = new File(imgPath+imgName); if(!file.exists()){ file.getParentFile().mkdir(); file.createNewFile(); } fout = new FileOutputStream(file); //将字节写入文件 long offset = 0; ByteBuffer buffers = pByte.getByteBuffer(offset, RealPicSize.getValue()); byte[] bytes = new byte[RealPicSize.getValue()]; buffers.rewind(); buffers.get(bytes); fout.write(bytes); fout.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("抓图成功!"); //退出程序时调用,每一台设备分别注销 if (hCNetSDK.NET_DVR_Logout(lUserID)) { System.out.println("注销成功"); } //SDK反初始化,释放资源,只需要退出时调用一次 // hCNetSDK.NET_DVR_Cleanup(); return; } class FRealDataCallBack implements HCNetSDK.FRealDataCallBack_V30 { //预览回调 public void invoke(int lRealHandle, int dwDataType, Pointer pBuffer, int dwBufSize, Pointer pUser) { if (Count == 100) {//降低打印频率 System.out.println("码流数据回调...dwBufSize="+dwBufSize); Count = 0; } Count++; //播放库解码 switch (dwDataType) { case HCNetSDK.NET_DVR_SYSHEAD: //系统头 if (!playCtrl.PlayM4_GetPort(m_lPort)) //获取播放库未使用的通道号 { break; } if (dwBufSize > 0) { if (!playCtrl.PlayM4_SetStreamOpenMode(m_lPort.getValue(), PlayCtrl.STREAME_REALTIME)) //设置实时流播放模式 { break; } if (!playCtrl.PlayM4_OpenStream(m_lPort.getValue(), pBuffer, dwBufSize, 1024 * 1024)) //打开流接口 { break; } if (!playCtrl.PlayM4_Play(m_lPort.getValue(), null)) //播放开始 { break; } } case HCNetSDK.NET_DVR_STREAMDATA: //码流数据 if ((dwBufSize > 0) && (m_lPort.getValue() != -1)) { if (!playCtrl.PlayM4_InputData(m_lPort.getValue(), pBuffer, dwBufSize)) //输入流数据 { break; } } } } } }