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;
|
}
|
}
|
}
|
}
|
}
|
|
|
}
|